Skip to content

Commit

Permalink
Migrate CelAttributeParser away from proto based expr to canonical ce…
Browse files Browse the repository at this point in the history
…l expr

PiperOrigin-RevId: 704823334
  • Loading branch information
l46kok authored and copybara-github committed Dec 10, 2024
1 parent e0d99d2 commit b5448e1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 37 deletions.
3 changes: 1 addition & 2 deletions runtime/src/main/java/dev/cel/runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,10 @@ java_library(
":unknown_attributes",
"//common",
"//common:compiler_common",
"//common:proto_ast",
"//common/ast",
"//parser",
"//parser:operator",
"//parser:parser_builder",
"@cel_spec//proto/cel/expr:expr_java_proto",
"@maven//:com_google_guava_guava",
],
)
Expand Down
62 changes: 30 additions & 32 deletions runtime/src/main/java/dev/cel/runtime/CelAttributeParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

import static com.google.common.collect.ImmutableList.toImmutableList;

import dev.cel.expr.Constant;
import dev.cel.expr.Expr;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.UnsignedLong;
import dev.cel.common.CelAbstractSyntaxTree;
import dev.cel.common.CelProtoAbstractSyntaxTree;
import dev.cel.common.CelValidationException;
import dev.cel.common.CelValidationResult;
import dev.cel.common.ast.CelConstant;
import dev.cel.common.ast.CelExpr;
import dev.cel.common.ast.CelExpr.CelCall;
import dev.cel.common.ast.CelExpr.ExprKind.Kind;
import dev.cel.parser.CelParser;
import dev.cel.parser.CelParserFactory;
import dev.cel.parser.Operator;
Expand Down Expand Up @@ -78,19 +78,18 @@ private static String unescape(String s) {
return b.toString();
}

private static CelAttribute.Qualifier parseConst(Constant constExpr) {
switch (constExpr.getConstantKindCase()) {
case BOOL_VALUE:
return CelAttribute.Qualifier.ofBool(constExpr.getBoolValue());
private static CelAttribute.Qualifier parseConst(CelConstant constExpr) {
switch (constExpr.getKind()) {
case BOOLEAN_VALUE:
return CelAttribute.Qualifier.ofBool(constExpr.booleanValue());
case INT64_VALUE:
return CelAttribute.Qualifier.ofInt(constExpr.getInt64Value());
return CelAttribute.Qualifier.ofInt(constExpr.int64Value());
case UINT64_VALUE:
return CelAttribute.Qualifier.ofUint(UnsignedLong.fromLongBits(constExpr.getUint64Value()));
return CelAttribute.Qualifier.ofUint(constExpr.uint64Value());
case STRING_VALUE:
return CelAttribute.Qualifier.ofString(unescape(constExpr.getStringValue()));
return CelAttribute.Qualifier.ofString(unescape(constExpr.stringValue()));
default:
throw new IllegalArgumentException(
"Unsupported const expr kind: " + constExpr.getConstantKindCase());
throw new IllegalArgumentException("Unsupported const expr kind: " + constExpr.getKind());
}
}

Expand All @@ -111,35 +110,34 @@ public static CelAttributePattern parsePattern(String attribute) {
try {
CelAbstractSyntaxTree ast = result.getAst();
ArrayDeque<CelAttribute.Qualifier> qualifiers = new ArrayDeque<>();
// TODO: Traverse using CelExpr
Expr node = CelProtoAbstractSyntaxTree.fromCelAst(ast).getExpr();
CelExpr node = ast.getExpr();
while (node != null) {
switch (node.getExprKindCase()) {
case IDENT_EXPR:
qualifiers.addFirst(CelAttribute.Qualifier.ofString(node.getIdentExpr().getName()));
switch (node.getKind()) {
case IDENT:
qualifiers.addFirst(CelAttribute.Qualifier.ofString(node.ident().name()));
node = null;
break;
case CALL_EXPR:
Expr.Call callExpr = node.getCallExpr();
if (!callExpr.getFunction().equals(Operator.INDEX.getFunction())
|| callExpr.getArgsCount() != 2
|| !callExpr.getArgs(1).hasConstExpr()) {
case CALL:
CelCall callExpr = node.call();
if (!callExpr.function().equals(Operator.INDEX.getFunction())
|| callExpr.args().size() != 2
|| !callExpr.args().get(1).getKind().equals(Kind.CONSTANT)) {
throw new IllegalArgumentException(
String.format(
"Unsupported call expr: %s(%s)",
callExpr.getFunction(),
callExpr.function(),
Joiner.on(", ")
.join(
callExpr.getArgsList().stream()
.map(Expr::getExprKindCase)
callExpr.args().stream()
.map(CelExpr::getKind)
.collect(toImmutableList()))));
}
qualifiers.addFirst(parseConst(callExpr.getArgs(1).getConstExpr()));
node = callExpr.getArgs(0);
qualifiers.addFirst(parseConst(callExpr.args().get(1).constant()));
node = callExpr.args().get(0);
break;
case SELECT_EXPR:
String field = node.getSelectExpr().getField();
node = node.getSelectExpr().getOperand();
case SELECT:
String field = node.select().field();
node = node.select().operand();
if (field.equals("_" + WILDCARD_ESCAPE)) {
qualifiers.addFirst(CelAttribute.Qualifier.ofWildCard());
break;
Expand All @@ -148,7 +146,7 @@ public static CelAttributePattern parsePattern(String attribute) {
break;
default:
throw new IllegalArgumentException(
"Unsupported expr kind in attribute: " + node.getExprKindCase());
"Unsupported expr kind in attribute: " + node.exprKind());
}
}
return CelAttributePattern.create(ImmutableList.copyOf(qualifiers));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,19 @@ public void parse_unsupportedExprKindThrows() {
Assert.assertThrows(
IllegalArgumentException.class, () -> CelAttributeParser.parse("1 / 2"));

assertThat(iae).hasMessageThat().contains("_/_(CONST_EXPR, CONST_EXPR)");
assertThat(iae).hasMessageThat().contains("_/_(CONSTANT, CONSTANT)");

iae =
Assert.assertThrows(
IllegalArgumentException.class, () -> CelAttributeParser.parse("123.field"));

assertThat(iae).hasMessageThat().contains("CONST_EXPR");
assertThat(iae).hasMessageThat().contains("CelConstant");

iae =
Assert.assertThrows(
IllegalArgumentException.class, () -> CelAttributeParser.parse("a && b"));

assertThat(iae).hasMessageThat().contains("_&&_(IDENT_EXPR, IDENT_EXPR)");
assertThat(iae).hasMessageThat().contains("_&&_(IDENT, IDENT)");
}

@Test
Expand Down

0 comments on commit b5448e1

Please sign in to comment.