Skip to content

Commit 3651b3d

Browse files
l46kokcopybara-github
authored andcommitted
Add CelProtoAbstractSyntaxTree and equivalent classes for converting from v1alpha1 to native types.
PiperOrigin-RevId: 510260524
1 parent b0d556e commit 3651b3d

20 files changed

Lines changed: 1509 additions & 33 deletions

common/src/main/java/dev/cel/common/BUILD.bazel

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ COMMON_SOURCES = [
1313
"CelSourceLocation.java",
1414
]
1515

16+
# keep sorted
17+
PROTO_AST_SOURCE = [
18+
"CelProtoAbstractSyntaxTree.java",
19+
]
20+
21+
# keep sorted
22+
PROTO_V1ALPHA1_AST_SOURCE = [
23+
"CelProtoV1Alpha1AbstractSyntaxTree.java",
24+
]
25+
1626
java_library(
1727
name = "common",
1828
srcs = COMMON_SOURCES,
@@ -50,3 +60,31 @@ java_library(
5060
"@maven//:com_google_guava_guava",
5161
],
5262
)
63+
64+
java_library(
65+
name = "proto_ast",
66+
srcs = PROTO_AST_SOURCE,
67+
deps = [
68+
":common",
69+
"//:auto_value",
70+
"//common/src/main/java/dev/cel/common/ast:expr_converter",
71+
"//common/src/main/java/dev/cel/common/types:cel_types",
72+
"@cel_spec//proto/expr:expr_java_proto",
73+
"@maven//:com_google_errorprone_error_prone_annotations",
74+
"@maven//:com_google_guava_guava",
75+
],
76+
)
77+
78+
java_library(
79+
name = "proto_v1alpha1_ast",
80+
srcs = PROTO_V1ALPHA1_AST_SOURCE,
81+
deps = [
82+
":common",
83+
"//:auto_value",
84+
"//common/src/main/java/dev/cel/common/ast:expr_v1alpha1_converter",
85+
"//common/src/main/java/dev/cel/common/types:cel_v1alpha1_types",
86+
"@com_google_googleapis//google/api/expr/v1alpha1:expr_java_proto",
87+
"@maven//:com_google_errorprone_error_prone_annotations",
88+
"@maven//:com_google_guava_guava",
89+
],
90+
)

common/src/main/java/dev/cel/common/CelAbstractSyntaxTree.java

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import dev.cel.expr.CheckedExpr;
2121
import dev.cel.expr.Expr;
2222
import dev.cel.expr.ParsedExpr;
23-
import dev.cel.expr.SourceInfo;
2423
import dev.cel.expr.Type;
2524
import com.google.common.collect.ImmutableList;
2625
import com.google.common.collect.ImmutableMap;
@@ -46,27 +45,39 @@
4645
public final class CelAbstractSyntaxTree {
4746

4847
private final CheckedExpr checkedExpr;
49-
private final CelSource source;
48+
private final CelSource celSource;
5049

5150
private final CelExpr celExpr;
5251

5352
private final ImmutableMap<Long, CelReference> references;
5453

5554
private final ImmutableMap<Long, CelType> types;
5655

57-
CelAbstractSyntaxTree(ParsedExpr parsedExpr, CelSource source) {
56+
CelAbstractSyntaxTree(
57+
CelExpr celExpr,
58+
CelSource celSource,
59+
ImmutableMap<Long, CelReference> references,
60+
ImmutableMap<Long, CelType> types) {
61+
this.checkedExpr = null;
62+
this.celExpr = celExpr;
63+
this.celSource = celSource;
64+
this.references = references;
65+
this.types = types;
66+
}
67+
68+
CelAbstractSyntaxTree(ParsedExpr parsedExpr, CelSource celSource) {
5869
this(
5970
CheckedExpr.newBuilder()
6071
.setExpr(parsedExpr.getExpr())
6172
.setSourceInfo(parsedExpr.getSourceInfo())
6273
.build(),
63-
source);
74+
celSource);
6475
}
6576

66-
CelAbstractSyntaxTree(CheckedExpr checkedExpr, CelSource source) {
77+
CelAbstractSyntaxTree(CheckedExpr checkedExpr, CelSource celSource) {
6778
this.checkedExpr = checkedExpr;
6879
this.celExpr = CelExprConverter.fromExpr(checkedExpr.getExpr());
69-
this.source = source;
80+
this.celSource = celSource;
7081
this.references =
7182
checkedExpr.getReferenceMapMap().entrySet().stream()
7283
.collect(
@@ -131,23 +142,18 @@ public Type getProtoResultType() {
131142
* Returns the {@link CelSource} that was used during construction of the abstract syntax tree.
132143
*/
133144
public CelSource getSource() {
134-
return source;
135-
}
136-
137-
/**
138-
* Returns the underlying {@link com.google.api.expr.SourceInfo} representation of the abstract
139-
* syntax tree.
140-
*/
141-
public SourceInfo getSourceInfo() {
142-
return checkedExpr.getSourceInfo();
145+
return celSource;
143146
}
144147

145148
/**
146149
* Returns the underlying {@link com.google.api.expr.ParsedExpr} representation of the abstract
147150
* syntax tree.
148151
*/
149152
public ParsedExpr toParsedExpr() {
150-
return ParsedExpr.newBuilder().setExpr(getExpr()).setSourceInfo(getSourceInfo()).build();
153+
return ParsedExpr.newBuilder()
154+
.setExpr(getProtoExpr())
155+
.setSourceInfo(checkedExpr.getSourceInfo())
156+
.build();
151157
}
152158

153159
/**
@@ -188,7 +194,12 @@ Optional<ImmutableList<String>> findOverloadIDs(long exprId) {
188194
: Optional.empty();
189195
}
190196

191-
/** Construct an abstract syntax tree from a {@link com.google.api.expr.CheckedExpr}. */
197+
/**
198+
* Construct an abstract syntax tree from a {@link com.google.api.expr.CheckedExpr}.
199+
*
200+
* @deprecated Use {@link CelProtoAbstractSyntaxTree#fromCheckedExpr(CheckedExpr)} instead.
201+
*/
202+
@Deprecated
192203
public static CelAbstractSyntaxTree fromCheckedExpr(CheckedExpr checkedExpr) {
193204
return new CelAbstractSyntaxTree(
194205
checkedExpr,
@@ -199,7 +210,12 @@ public static CelAbstractSyntaxTree fromCheckedExpr(CheckedExpr checkedExpr) {
199210
.build());
200211
}
201212

202-
/** Construct an abstract syntax tree from a {@link com.google.api.expr.ParsedExpr}. */
213+
/**
214+
* Construct an abstract syntax tree from a {@link com.google.api.expr.ParsedExpr}.
215+
*
216+
* @deprecated Use {@link CelProtoAbstractSyntaxTree#fromParsedExpr(ParsedExpr)} instead.
217+
*/
218+
@Deprecated
203219
public static CelAbstractSyntaxTree fromParsedExpr(ParsedExpr parsedExpr) {
204220
return new CelAbstractSyntaxTree(
205221
parsedExpr,
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright 2022 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+
package dev.cel.common;
16+
17+
import static com.google.common.base.Preconditions.checkState;
18+
import static com.google.common.collect.ImmutableMap.toImmutableMap;
19+
20+
import dev.cel.expr.CheckedExpr;
21+
import dev.cel.expr.Expr;
22+
import dev.cel.expr.ParsedExpr;
23+
import dev.cel.expr.SourceInfo;
24+
import dev.cel.expr.Type;
25+
import com.google.errorprone.annotations.CheckReturnValue;
26+
import dev.cel.common.ast.CelExprConverter;
27+
import dev.cel.common.types.CelTypes;
28+
import java.util.Map.Entry;
29+
30+
/**
31+
* An Adapter for {@link CelAbstractSyntaxTree} constructed from Canonical Protos of {@link
32+
* CheckedExpr} or {@link ParsedExpr} expressions.
33+
*
34+
* <p>Note: Keep this file in sync with {@link CelProtoV1Alpha1AbstractSyntaxTree}
35+
*/
36+
// LINT.IfChange
37+
public final class CelProtoAbstractSyntaxTree {
38+
private final CheckedExpr checkedExpr;
39+
private final CelAbstractSyntaxTree ast;
40+
41+
private CelProtoAbstractSyntaxTree(CheckedExpr checkedExpr) {
42+
this.checkedExpr = checkedExpr;
43+
this.ast =
44+
new CelAbstractSyntaxTree(
45+
CelExprConverter.fromExpr(checkedExpr.getExpr()),
46+
CelSource.newBuilder()
47+
.addAllLineOffsets(checkedExpr.getSourceInfo().getLineOffsetsList())
48+
.addPositionsMap(checkedExpr.getSourceInfo().getPositionsMap())
49+
.setDescription(checkedExpr.getSourceInfo().getLocation())
50+
.build(),
51+
checkedExpr.getReferenceMapMap().entrySet().stream()
52+
.collect(
53+
toImmutableMap(
54+
Entry::getKey,
55+
v -> CelExprConverter.exprReferenceToCelReference(v.getValue()))),
56+
checkedExpr.getTypeMapMap().entrySet().stream()
57+
.collect(toImmutableMap(Entry::getKey, v -> CelTypes.typeToCelType(v.getValue()))));
58+
}
59+
60+
/** Construct an abstract syntax tree from a {@link com.google.api.expr.CheckedExpr}. */
61+
public static CelProtoAbstractSyntaxTree fromCheckedExpr(CheckedExpr checkedExpr) {
62+
return new CelProtoAbstractSyntaxTree(checkedExpr);
63+
}
64+
65+
/** Construct an abstract syntax tree from a {@link com.google.api.expr.ParsedExpr}. */
66+
public static CelProtoAbstractSyntaxTree fromParsedExpr(ParsedExpr parsedExpr) {
67+
return new CelProtoAbstractSyntaxTree(
68+
CheckedExpr.newBuilder()
69+
.setExpr(parsedExpr.getExpr())
70+
.setSourceInfo(parsedExpr.getSourceInfo())
71+
.build());
72+
}
73+
74+
/**
75+
* Returns the native representation of the abstract syntax tree: {@link CelAbstractSyntaxTree}.
76+
*/
77+
@CheckReturnValue
78+
public CelAbstractSyntaxTree getAst() {
79+
return ast;
80+
}
81+
82+
/**
83+
* Returns the underlying {@link com.google.api.expr.Expr} representation of the abstract syntax
84+
* tree.
85+
*/
86+
@CheckReturnValue
87+
public Expr getExpr() {
88+
return checkedExpr.getExpr();
89+
}
90+
91+
/**
92+
* Returns the underlying {@link com.google.api.expr.CheckedExpr} representation of the abstract
93+
* syntax tree. Throws {@link java.lang.IllegalStateException} if {@link
94+
* CelAbstractSyntaxTree#isChecked} is false.
95+
*/
96+
@CheckReturnValue
97+
public CheckedExpr toCheckedExpr() {
98+
checkState(
99+
ast.isChecked(),
100+
"CelAbstractSyntaxTree must be checked before it can be converted to CheckedExpr");
101+
return checkedExpr;
102+
}
103+
104+
/**
105+
* Returns the underlying {@link com.google.api.expr.SourceInfo} representation of the abstract
106+
* syntax tree.
107+
*/
108+
@CheckReturnValue
109+
public SourceInfo getSourceInfo() {
110+
return checkedExpr.getSourceInfo();
111+
}
112+
113+
/**
114+
* Returns the underlying {@link com.google.api.expr.ParsedExpr} representation of the abstract
115+
* syntax tree.
116+
*/
117+
@CheckReturnValue
118+
public ParsedExpr toParsedExpr() {
119+
return ParsedExpr.newBuilder().setExpr(getExpr()).setSourceInfo(getSourceInfo()).build();
120+
}
121+
122+
/**
123+
* For a type checked abstract syntax tree the resulting type is returned in proto format
124+
* described in checked.proto. Otherwise, the dynamic type is returned.
125+
*/
126+
@CheckReturnValue
127+
public Type getProtoResultType() {
128+
return CelTypes.celTypeToType(ast.getResultType());
129+
}
130+
}
131+
// LINT.ThenChange(CelProtoV1Alpha1AbstractSyntaxTree.java)

0 commit comments

Comments
 (0)