Skip to content

Commit 4e3f147

Browse files
l46kokcopybara-github
authored andcommitted
Change cel.@Attribute to return a parameterized type to avoid dyn typed results
PiperOrigin-RevId: 979449723
1 parent 226484d commit 4e3f147

3 files changed

Lines changed: 232 additions & 70 deletions

File tree

optimizer/src/main/java/dev/cel/optimizer/optimizers/SelectOptimizer.java

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
import dev.cel.common.types.CelTypes;
6060
import dev.cel.common.types.ListType;
6161
import dev.cel.common.types.SimpleType;
62+
import dev.cel.common.types.TypeParamType;
63+
import dev.cel.common.types.TypeType;
6264
import dev.cel.common.values.CelByteString;
6365
import dev.cel.optimizer.AstMutator;
6466
import dev.cel.optimizer.CelAstOptimizer;
@@ -103,9 +105,9 @@
103105
* <p>Expressions are rewritten into the following forms:
104106
*
105107
* <pre>
106-
* // Selection chains (user message is 3-tuple, leaf scalar is 4-tuple)
108+
* // Selection chains (user message is 3-tuple, leaf scalar is 4-tuple, leaf type is 3rd argument)
107109
* request.user.age -&gt; cel.@attribute(request,
108-
* [[user_num, "user", type_code], [age_num, "age", type_code, default_val]])
110+
* [[user_num, "user", type_code], [age_num, "age", type_code, default_val]], int)
109111
*
110112
* // Presence tests (2-tuples)
111113
* has(request.user.age) -&gt; cel.@hasField(request,
@@ -127,15 +129,18 @@ public final class SelectOptimizer implements CelAstOptimizer {
127129
private static final String CEL_ATTRIBUTE_FUNCTION_NAME = "cel.@attribute";
128130
private static final String CEL_HAS_FIELD_FUNCTION_NAME = "cel.@hasField";
129131

132+
private static final TypeParamType TYPE_PARAM_T = TypeParamType.create("T");
133+
130134
@VisibleForTesting
131135
static final CelFunctionDecl CEL_ATTRIBUTE_FUNCTION_DECL =
132136
CelFunctionDecl.newFunctionDeclaration(
133137
CEL_ATTRIBUTE_FUNCTION_NAME,
134138
CelOverloadDecl.newGlobalOverload(
135139
"cel_attribute_list",
140+
TYPE_PARAM_T,
136141
SimpleType.DYN,
137-
SimpleType.DYN,
138-
ListType.create(SimpleType.DYN)));
142+
ListType.create(SimpleType.DYN),
143+
TypeType.create(TYPE_PARAM_T)));
139144

140145
@VisibleForTesting
141146
static final CelFunctionDecl CEL_HAS_FIELD_FUNCTION_DECL =
@@ -295,8 +300,19 @@ private void rewriteSelectChain(
295300

296301
CelMutableExpr qualifiersExpr =
297302
CelMutableExpr.ofList(idGenerator.nextExprId(), CelMutableList.create(qualifierLists));
298-
String functionName = isHasField ? CEL_HAS_FIELD_FUNCTION_NAME : CEL_ATTRIBUTE_FUNCTION_NAME;
299-
topNode.expr().setCall(CelMutableCall.create(functionName, currentExpr, qualifiersExpr));
303+
if (isHasField) {
304+
topNode
305+
.expr()
306+
.setCall(CelMutableCall.create(CEL_HAS_FIELD_FUNCTION_NAME, currentExpr, qualifiersExpr));
307+
} else {
308+
CelMutableExpr typeExpr =
309+
CelMutableExpr.ofIdent(idGenerator.nextExprId(), resolveTypeIdent(topField));
310+
topNode
311+
.expr()
312+
.setCall(
313+
CelMutableCall.create(
314+
CEL_ATTRIBUTE_FUNCTION_NAME, currentExpr, qualifiersExpr, typeExpr));
315+
}
300316
}
301317

302318
private static long resolveTypeCode(FieldDescriptor field) {
@@ -306,6 +322,43 @@ private static long resolveTypeCode(FieldDescriptor field) {
306322
return field.getType().toProto().getNumber();
307323
}
308324

325+
private static String resolveTypeIdent(FieldDescriptor field) {
326+
if (field.isMapField()) {
327+
return "map";
328+
}
329+
if (field.isRepeated()) {
330+
return "list";
331+
}
332+
switch (field.getType()) {
333+
case DOUBLE:
334+
case FLOAT:
335+
return "double";
336+
case INT64:
337+
case SINT64:
338+
case SFIXED64:
339+
case INT32:
340+
case SINT32:
341+
case SFIXED32:
342+
case ENUM:
343+
return "int";
344+
case UINT64:
345+
case FIXED64:
346+
case UINT32:
347+
case FIXED32:
348+
return "uint";
349+
case BOOL:
350+
return "bool";
351+
case STRING:
352+
return "string";
353+
case BYTES:
354+
return "bytes";
355+
case MESSAGE:
356+
return field.getMessageType().getFullName();
357+
default:
358+
throw new IllegalArgumentException("Unsupported protobuf field type: " + field.getType());
359+
}
360+
}
361+
309362
private boolean isTopOfSelectChain(CelNavigableMutableAst navAst, CelNavigableMutableExpr node) {
310363
return getOptimizableField(navAst, node).isPresent()
311364
&& !node.parent().flatMap(parent -> getOptimizableField(navAst, parent)).isPresent();
@@ -414,13 +467,6 @@ private static CelAbstractSyntaxTree tagAstExtension(CelAbstractSyntaxTree ast)
414467
return CelAbstractSyntaxTree.newParsedAst(ast.getExpr(), celSourceBuilder.build());
415468
}
416469

417-
private SelectOptimizer(
418-
SelectOptimizerOptions options, Iterable<FileDescriptor> fileDescriptors) {
419-
this.options = checkNotNull(options);
420-
this.astMutator = AstMutator.newInstance(options.iterationLimit());
421-
this.descriptorPool = newDescriptorPool(options, checkNotNull(fileDescriptors));
422-
}
423-
424470
private static CelDescriptorPool newDescriptorPool(
425471
SelectOptimizerOptions options, Iterable<FileDescriptor> fileDescriptors) {
426472
CelDescriptors celDescriptors =
@@ -432,6 +478,13 @@ private static CelDescriptorPool newDescriptorPool(
432478
return CombinedDescriptorPool.create(descriptorPools.build());
433479
}
434480

481+
private SelectOptimizer(
482+
SelectOptimizerOptions options, Iterable<FileDescriptor> fileDescriptors) {
483+
this.options = checkNotNull(options);
484+
this.astMutator = AstMutator.newInstance(options.iterationLimit());
485+
this.descriptorPool = newDescriptorPool(options, checkNotNull(fileDescriptors));
486+
}
487+
435488
/** Options configuring the behavior of {@link SelectOptimizer}. */
436489
@AutoValue
437490
public abstract static class SelectOptimizerOptions {

optimizer/src/test/java/dev/cel/optimizer/optimizers/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ java_library(
2626
"//extensions:optional_library",
2727
# "//java/com/google/testing/testsize:annotations",
2828
"//optimizer",
29+
"//optimizer:ast_optimizer",
2930
"//optimizer:optimization_exception",
3031
"//optimizer:optimizer_builder",
3132
"//optimizer/optimizers:common_subexpression_elimination",

0 commit comments

Comments
 (0)