Skip to content

Commit 99a6c25

Browse files
l46kokcopybara-github
authored andcommitted
Open source CEL-Java parser and type-checker
PiperOrigin-RevId: 549704559
1 parent 127ab55 commit 99a6c25

67 files changed

Lines changed: 12566 additions & 11 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,9 @@ package_group(
180180
"//...",
181181
],
182182
)
183+
184+
java_binary(
185+
name = "antlr4_tool",
186+
main_class = "org.antlr.v4.Tool",
187+
runtime_deps = ["@antlr4_jar//jar"],
188+
)

WORKSPACE

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ workspace(name = "cel_java")
1616

1717
register_toolchains("//:repository_default_toolchain_definition")
1818

19-
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
19+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_jar")
2020

2121
http_archive(
2222
name = "bazel_skylib",
@@ -51,6 +51,8 @@ load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
5151

5252
rules_jvm_external_setup()
5353

54+
ANTLR4_VERSION = "4.11.1"
55+
5456
# Important: there can only be one maven_install rule. Add new maven deps here.
5557
maven_install(
5658
# keep sorted
@@ -67,7 +69,7 @@ maven_install(
6769
"com.google.truth.extensions:truth-java8-extension:1.1.3",
6870
"com.google.truth.extensions:truth-proto-extension:1.1.3",
6971
"com.google.truth:truth:1.1.3",
70-
"org.antlr:antlr4-runtime:4.11.1",
72+
"org.antlr:antlr4-runtime:" + ANTLR4_VERSION,
7173
"org.jspecify:jspecify:0.2.0",
7274
"org.threeten:threeten-extra:1.7.1",
7375
],
@@ -150,6 +152,12 @@ http_archive(
150152
],
151153
)
152154

155+
http_jar(
156+
name = "antlr4_jar",
157+
sha256 = "62975e192b4af2622b72b5f0131553ee3cbce97f76dc2a41632dcc55e25473e1",
158+
urls = ["https://www.antlr.org/download/antlr-" + ANTLR4_VERSION + "-complete.jar"],
159+
)
160+
153161
# Load license rules.
154162
http_archive(
155163
name = "rules_license",

antlr.bzl

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# Copyright 2023 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Build rules to create Java code from an ANTLR4 grammar."""
16+
17+
def antlr4_java_lexer(name, src, package, visibility = None, imports = None, compatible_with = []):
18+
"""Generates the java source corresponding to an antlr4 lexer definition.
19+
20+
Args:
21+
name: The name of the build rule.
22+
src: The antlr4 g4 file containing the lexer rules.
23+
package: The Java package to place the output in.
24+
visibility: The standard Bazel visibility attribute.
25+
imports: A list of antlr4 source imports to use when building the lexer.
26+
compatible_with: The standard Bazel compatible_with attribute.
27+
"""
28+
suffixes = ("%s.java", "%s.tokens")
29+
imports = imports or []
30+
31+
import_srcs = []
32+
for imp in imports:
33+
import_srcs.append(imp)
34+
if not imp.endswith(".g4"):
35+
continue
36+
import_srcs.append("%s.tokens" % imp[:-3])
37+
file_prefix = src[:-3] if src.endswith(".g4") else src
38+
outs = _make_outs(file_prefix, suffixes)
39+
native.genrule(
40+
name = name,
41+
srcs = [src] + import_srcs,
42+
visibility = visibility,
43+
outs = outs,
44+
tags = _make_tags(package, outs),
45+
cmd = ("mkdir $$$$.tmp ; " + "cp $(SRCS) $$$$.tmp/ ; " + "cd $$$$.tmp ; " +
46+
("../$(location //:antlr4_tool) " + src +
47+
" -package " + package + " -Werror ; ") + "cd .. ; " + "".join(
48+
[
49+
" cp $$$$.tmp/%s $(@D)/ ;" % filepath
50+
for filepath in _make_outs(file_prefix, suffixes)
51+
],
52+
) + "rm -rf $$$$.tmp"),
53+
heuristic_label_expansion = 0,
54+
tools = [
55+
"//:antlr4_tool",
56+
],
57+
compatible_with = compatible_with,
58+
)
59+
60+
def antlr4_java_parser(
61+
name,
62+
src,
63+
package,
64+
visibility = None,
65+
imports = None,
66+
listener = True,
67+
visitor = False,
68+
compatible_with = []):
69+
"""Generates the java source corresponding to an antlr4 parser definition.
70+
71+
Args:
72+
name: The name of the build rule.
73+
src: The antlr4 g4 file containing the parser rules.
74+
package: The Java package to place the output in.
75+
visibility: The standard Blaze visibility attribute.
76+
imports: A list of antlr4 source imports to use when building the parser.
77+
listener: Whether or not to include listener generated files.
78+
visitor: Whether or not to include visitor generated files.
79+
compatible_with: The standard Blaze compatible_with attribute.
80+
"""
81+
suffixes = ("%s.java", "%s.tokens")
82+
visitor_flag = " "
83+
if visitor:
84+
visitor_flag = " -visitor"
85+
suffixes += ("%sBaseVisitor.java", "%sVisitor.java")
86+
listener_flag = " "
87+
if listener:
88+
suffixes += ("%sBaseListener.java", "%sListener.java")
89+
else:
90+
listener_flag = " -no-listener"
91+
imports = imports or []
92+
import_srcs = []
93+
for imp in imports:
94+
import_srcs.append(imp)
95+
if not imp.endswith(".g4"):
96+
continue
97+
import_srcs.append("%s.tokens" % imp[:-3])
98+
file_prefix = src[:-3] if src.endswith(".g4") else src
99+
outs = _make_outs(file_prefix, suffixes)
100+
101+
native.genrule(
102+
name = name,
103+
srcs = [src] + import_srcs,
104+
visibility = visibility,
105+
outs = outs,
106+
tags = _make_tags(package, outs),
107+
cmd = ("mkdir $$$$.tmp ; " + "cp $(SRCS) $$$$.tmp/ ; " + "cd $$$$.tmp ; " +
108+
("../$(location //:antlr4_tool) " + src +
109+
visitor_flag + listener_flag + " -package " + package + " ; ") +
110+
"cd .. ; " + (
111+
"".join([
112+
" cp $$$$.tmp/%s $(@D)/ ;" % filepath
113+
for filepath in _make_outs(
114+
file_prefix,
115+
suffixes,
116+
)
117+
])
118+
) + "rm -rf $$$$.tmp"),
119+
heuristic_label_expansion = 0,
120+
tools = [
121+
"//:antlr4_tool",
122+
],
123+
compatible_with = compatible_with,
124+
)
125+
126+
def antlr4_java_combined(
127+
name,
128+
src,
129+
package,
130+
visibility = None,
131+
imports = None,
132+
listener = True,
133+
visitor = False,
134+
compatible_with = []):
135+
"""Generates the java source corresponding to an antlr4 grammar definition.
136+
137+
This genrule assumes that 'src' starts with 'grammar' and not
138+
'(lexer|parser) grammar'
139+
140+
Args:
141+
name: The name of the build rule.
142+
src: The antlr4 g4 file containing the rules.
143+
package: The Java package to place the output in.
144+
visibility: The standard Blaze visibility attribute.
145+
imports: A list of antlr4 source imports to use when building the parser.
146+
listener: Whether or not to include listener generated files.
147+
visitor: Whether or not to include visitor generated files.
148+
compatible_with: The standard Blaze compatible_with attribute.
149+
"""
150+
suffixes = ("%sLexer.java", "%sParser.java", "%s.tokens")
151+
visitor_flag = " "
152+
if visitor:
153+
visitor_flag = " -visitor"
154+
suffixes += ("%sBaseVisitor.java", "%sVisitor.java")
155+
listener_flag = " "
156+
if listener:
157+
suffixes += ("%sBaseListener.java", "%sListener.java")
158+
else:
159+
listener_flag = " -no-listener"
160+
imports = imports or []
161+
import_srcs = []
162+
for imp in imports:
163+
import_srcs.append(imp)
164+
if not imp.endswith(".g4"):
165+
continue
166+
import_srcs.append("%s.tokens" % imp[:-3])
167+
file_prefix = src[:-3] if src.endswith(".g4") else src
168+
outs = _make_outs(file_prefix, suffixes)
169+
170+
native.genrule(
171+
name = name,
172+
srcs = [src] + import_srcs,
173+
visibility = visibility,
174+
outs = outs,
175+
tags = _make_tags(package, outs),
176+
cmd = ("mkdir $$$$.tmp ; " + "cp $(SRCS) $$$$.tmp/ ; " + "cd $$$$.tmp ; " +
177+
("../$(location //:antlr4_tool) " + src +
178+
visitor_flag + listener_flag + " -package " + package + " ; ") +
179+
"cd .. ; " + (
180+
"".join([
181+
" cp $$$$.tmp/%s $(@D)/ ;" % filepath
182+
for filepath in _make_outs(
183+
file_prefix,
184+
suffixes,
185+
)
186+
])
187+
) + "rm -rf $$$$.tmp"),
188+
heuristic_label_expansion = 0,
189+
tools = [
190+
"//:antlr4_tool",
191+
],
192+
compatible_with = compatible_with,
193+
)
194+
195+
def _make_outs(file_prefix, suffixes):
196+
return [file_suffix % file_prefix for file_suffix in suffixes]
197+
198+
def _make_tags(package, outs):
199+
tags = []
200+
for file in outs:
201+
if file.endswith(".java"):
202+
tags.append("generated_java_class=%s.%s" % (package, file[:-5]))
203+
return tags

checker/BUILD.bazel

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package(
2+
default_applicable_licenses = ["//:license"],
3+
default_visibility = ["//visibility:public"],
4+
)
5+
6+
java_library(
7+
name = "checker",
8+
exports = ["//checker/src/main/java/dev/cel/checker"],
9+
)
10+
11+
java_library(
12+
name = "checker_builder",
13+
exports = ["//checker/src/main/java/dev/cel/checker:checker_builder"],
14+
)
15+
16+
java_library(
17+
name = "proto_type_mask",
18+
exports = ["//checker/src/main/java/dev/cel/checker:proto_type_mask"],
19+
)
20+
21+
java_library(
22+
name = "provider_legacy",
23+
visibility = ["//visibility:public"],
24+
exports = ["//checker/src/main/java/dev/cel/checker:provider_legacy"],
25+
)
26+
27+
java_library(
28+
name = "cel_ident_decl",
29+
exports = ["//checker/src/main/java/dev/cel/checker:cel_ident_decl"],
30+
)
31+
32+
java_library(
33+
name = "checker_legacy_environment",
34+
visibility = ["//visibility:public"],
35+
exports = ["//checker/src/main/java/dev/cel/checker:checker_legacy_environment"],
36+
)
37+
38+
java_library(
39+
name = "type_inferencer",
40+
visibility = ["//visibility:public"], # Planned for use in a new type-checker.
41+
exports = ["//checker/src/main/java/dev/cel/checker:type_inferencer"],
42+
)

0 commit comments

Comments
 (0)