From 486a380903332f9882ad755ffe806ad58cab6e05 Mon Sep 17 00:00:00 2001 From: Sokwhan Huh Date: Tue, 17 Mar 2026 14:56:01 -0700 Subject: [PATCH] Allow specifying a set of optimizers to run to the policy compiler PiperOrigin-RevId: 885225062 --- .../src/main/java/dev/cel/policy/BUILD.bazel | 2 ++ .../cel/policy/CelPolicyCompilerBuilder.java | 6 ++++ .../dev/cel/policy/CelPolicyCompilerImpl.java | 36 ++++++++++--------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/policy/src/main/java/dev/cel/policy/BUILD.bazel b/policy/src/main/java/dev/cel/policy/BUILD.bazel index 52b0b1ba7..916f16f9b 100644 --- a/policy/src/main/java/dev/cel/policy/BUILD.bazel +++ b/policy/src/main/java/dev/cel/policy/BUILD.bazel @@ -138,6 +138,7 @@ java_library( ], deps = [ ":compiler", + "//optimizer:ast_optimizer", "@maven//:com_google_errorprone_error_prone_annotations", ], ) @@ -214,6 +215,7 @@ java_library( "//common/types", "//common/types:type_providers", "//optimizer", + "//optimizer:ast_optimizer", "//optimizer:optimization_exception", "//optimizer:optimizer_builder", "//optimizer/optimizers:common_subexpression_elimination", diff --git a/policy/src/main/java/dev/cel/policy/CelPolicyCompilerBuilder.java b/policy/src/main/java/dev/cel/policy/CelPolicyCompilerBuilder.java index 592a0120d..4089477a1 100644 --- a/policy/src/main/java/dev/cel/policy/CelPolicyCompilerBuilder.java +++ b/policy/src/main/java/dev/cel/policy/CelPolicyCompilerBuilder.java @@ -16,6 +16,8 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CheckReturnValue; +import dev.cel.optimizer.CelAstOptimizer; +import java.util.List; /** Interface for building an instance of {@link CelPolicyCompiler} */ public interface CelPolicyCompilerBuilder { @@ -38,6 +40,10 @@ public interface CelPolicyCompilerBuilder { @CanIgnoreReturnValue CelPolicyCompilerBuilder setAstDepthLimit(int iterationLimit); + /** Configures the policy compiler to run the provided optimizers on compiled policies. */ + @CanIgnoreReturnValue + CelPolicyCompilerBuilder setOptimizers(List optimizers); + @CheckReturnValue CelPolicyCompiler build(); } diff --git a/policy/src/main/java/dev/cel/policy/CelPolicyCompilerImpl.java b/policy/src/main/java/dev/cel/policy/CelPolicyCompilerImpl.java index f6f893c1c..7841b9827 100644 --- a/policy/src/main/java/dev/cel/policy/CelPolicyCompilerImpl.java +++ b/policy/src/main/java/dev/cel/policy/CelPolicyCompilerImpl.java @@ -33,6 +33,7 @@ import dev.cel.common.formats.ValueString; import dev.cel.common.types.CelType; import dev.cel.common.types.SimpleType; +import dev.cel.optimizer.CelAstOptimizer; import dev.cel.optimizer.CelOptimizationException; import dev.cel.optimizer.CelOptimizer; import dev.cel.optimizer.CelOptimizerFactory; @@ -63,6 +64,7 @@ final class CelPolicyCompilerImpl implements CelPolicyCompiler { private final Cel cel; private final String variablesPrefix; private final int iterationLimit; + private final ImmutableList optimizers; private final Optional astDepthValidator; @Override @@ -140,19 +142,7 @@ public CelAbstractSyntaxTree compose(CelPolicy policy, CelCompiledRule compiledR } CelOptimizer astOptimizer = - CelOptimizerFactory.standardCelOptimizerBuilder(cel) - .addAstOptimizers( - ConstantFoldingOptimizer.getInstance(), - SubexpressionOptimizer.newInstance( - SubexpressionOptimizerOptions.newBuilder() - // "record" is used for recording subexpression results via - // BlueprintLateFunctionBinding. Safely eliminable, since repeated - // invocation does not change the intermediate results. - .addEliminableFunctions("record") - .populateMacroCalls(true) - .enableCelBlock(true) - .build())) - .build(); + CelOptimizerFactory.standardCelOptimizerBuilder(cel).addAstOptimizers(optimizers).build(); try { // Optimize the composed graph using const fold and CSE ast = astOptimizer.optimize(ast); @@ -339,6 +329,7 @@ static final class Builder implements CelPolicyCompilerBuilder { private final Cel cel; private String variablesPrefix; private int iterationLimit; + private ImmutableList optimizers; private Optional astDepthLimitValidator; private Builder(Cel cel) { @@ -362,7 +353,7 @@ public Builder setIterationLimit(int iterationLimit) { @Override @CanIgnoreReturnValue - public CelPolicyCompilerBuilder setAstDepthLimit(int astDepthLimit) { + public Builder setAstDepthLimit(int astDepthLimit) { if (astDepthLimit < 0) { astDepthLimitValidator = Optional.empty(); } else { @@ -371,27 +362,40 @@ public CelPolicyCompilerBuilder setAstDepthLimit(int astDepthLimit) { return this; } + @Override + public Builder setOptimizers(List optimizers) { + this.optimizers = ImmutableList.copyOf(optimizers); + return this; + } + @Override public CelPolicyCompiler build() { return new CelPolicyCompilerImpl( - cel, this.variablesPrefix, this.iterationLimit, astDepthLimitValidator); + cel, this.variablesPrefix, this.iterationLimit, this.optimizers, astDepthLimitValidator); } } static Builder newBuilder(Cel cel) { return new Builder(cel) .setVariablesPrefix(DEFAULT_VARIABLE_PREFIX) - .setIterationLimit(DEFAULT_ITERATION_LIMIT); + .setIterationLimit(DEFAULT_ITERATION_LIMIT) + .setOptimizers( + ImmutableList.of( + ConstantFoldingOptimizer.getInstance(), + SubexpressionOptimizer.newInstance( + SubexpressionOptimizerOptions.newBuilder().populateMacroCalls(true).build()))); } private CelPolicyCompilerImpl( Cel cel, String variablesPrefix, int iterationLimit, + ImmutableList optimizers, Optional astDepthValidator) { this.cel = checkNotNull(cel); this.variablesPrefix = checkNotNull(variablesPrefix); this.iterationLimit = iterationLimit; + this.optimizers = optimizers; this.astDepthValidator = astDepthValidator; } }