Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
import dev.cel.common.types.CelTypes;
import dev.cel.common.types.ListType;
import dev.cel.common.types.SimpleType;
import dev.cel.common.types.TypeParamType;
import dev.cel.common.types.TypeType;
import dev.cel.common.values.CelByteString;
import dev.cel.optimizer.AstMutator;
import dev.cel.optimizer.CelAstOptimizer;
Expand Down Expand Up @@ -103,9 +105,9 @@
* <p>Expressions are rewritten into the following forms:
*
* <pre>
* // Selection chains (user message is 3-tuple, leaf scalar is 4-tuple)
* // Selection chains (user message is 3-tuple, leaf scalar is 4-tuple, leaf type is 3rd argument)
* request.user.age -&gt; cel.@attribute(request,
* [[user_num, "user", type_code], [age_num, "age", type_code, default_val]])
* [[user_num, "user", type_code], [age_num, "age", type_code, default_val]], int)
*
* // Presence tests (2-tuples)
* has(request.user.age) -&gt; cel.@hasField(request,
Expand All @@ -127,15 +129,18 @@ public final class SelectOptimizer implements CelAstOptimizer {
private static final String CEL_ATTRIBUTE_FUNCTION_NAME = "cel.@attribute";
private static final String CEL_HAS_FIELD_FUNCTION_NAME = "cel.@hasField";

private static final TypeParamType TYPE_PARAM_T = TypeParamType.create("T");

@VisibleForTesting
static final CelFunctionDecl CEL_ATTRIBUTE_FUNCTION_DECL =
CelFunctionDecl.newFunctionDeclaration(
CEL_ATTRIBUTE_FUNCTION_NAME,
CelOverloadDecl.newGlobalOverload(
"cel_attribute_list",
TYPE_PARAM_T,
SimpleType.DYN,
SimpleType.DYN,
ListType.create(SimpleType.DYN)));
ListType.create(SimpleType.DYN),
TypeType.create(TYPE_PARAM_T)));

@VisibleForTesting
static final CelFunctionDecl CEL_HAS_FIELD_FUNCTION_DECL =
Expand Down Expand Up @@ -295,8 +300,19 @@ private void rewriteSelectChain(

CelMutableExpr qualifiersExpr =
CelMutableExpr.ofList(idGenerator.nextExprId(), CelMutableList.create(qualifierLists));
String functionName = isHasField ? CEL_HAS_FIELD_FUNCTION_NAME : CEL_ATTRIBUTE_FUNCTION_NAME;
topNode.expr().setCall(CelMutableCall.create(functionName, currentExpr, qualifiersExpr));
if (isHasField) {
topNode
.expr()
.setCall(CelMutableCall.create(CEL_HAS_FIELD_FUNCTION_NAME, currentExpr, qualifiersExpr));
} else {
CelMutableExpr typeExpr =
CelMutableExpr.ofIdent(idGenerator.nextExprId(), resolveTypeIdent(topField));
topNode
.expr()
.setCall(
CelMutableCall.create(
CEL_ATTRIBUTE_FUNCTION_NAME, currentExpr, qualifiersExpr, typeExpr));
}
}

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

private static String resolveTypeIdent(FieldDescriptor field) {
if (field.isMapField()) {
return "map";
}
if (field.isRepeated()) {
return "list";
}
switch (field.getType()) {
case DOUBLE:
case FLOAT:
return "double";
case INT64:
case SINT64:
case SFIXED64:
case INT32:
case SINT32:
case SFIXED32:
case ENUM:
return "int";
case UINT64:
case FIXED64:
case UINT32:
case FIXED32:
return "uint";
case BOOL:
return "bool";
case STRING:
return "string";
case BYTES:
return "bytes";
case MESSAGE:
return field.getMessageType().getFullName();
default:
throw new IllegalArgumentException("Unsupported protobuf field type: " + field.getType());
}
}

private boolean isTopOfSelectChain(CelNavigableMutableAst navAst, CelNavigableMutableExpr node) {
return getOptimizableField(navAst, node).isPresent()
&& !node.parent().flatMap(parent -> getOptimizableField(navAst, parent)).isPresent();
Expand Down Expand Up @@ -414,13 +467,6 @@ private static CelAbstractSyntaxTree tagAstExtension(CelAbstractSyntaxTree ast)
return CelAbstractSyntaxTree.newParsedAst(ast.getExpr(), celSourceBuilder.build());
}

private SelectOptimizer(
SelectOptimizerOptions options, Iterable<FileDescriptor> fileDescriptors) {
this.options = checkNotNull(options);
this.astMutator = AstMutator.newInstance(options.iterationLimit());
this.descriptorPool = newDescriptorPool(options, checkNotNull(fileDescriptors));
}

private static CelDescriptorPool newDescriptorPool(
SelectOptimizerOptions options, Iterable<FileDescriptor> fileDescriptors) {
CelDescriptors celDescriptors =
Expand All @@ -432,6 +478,13 @@ private static CelDescriptorPool newDescriptorPool(
return CombinedDescriptorPool.create(descriptorPools.build());
}

private SelectOptimizer(
SelectOptimizerOptions options, Iterable<FileDescriptor> fileDescriptors) {
this.options = checkNotNull(options);
this.astMutator = AstMutator.newInstance(options.iterationLimit());
this.descriptorPool = newDescriptorPool(options, checkNotNull(fileDescriptors));
}

/** Options configuring the behavior of {@link SelectOptimizer}. */
@AutoValue
public abstract static class SelectOptimizerOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ java_library(
"//extensions:optional_library",
# "//java/com/google/testing/testsize:annotations",
"//optimizer",
"//optimizer:ast_optimizer",
"//optimizer:optimization_exception",
"//optimizer:optimizer_builder",
"//optimizer/optimizers:common_subexpression_elimination",
Expand Down
Loading
Loading