1616import static com .google .common .collect .ImmutableList .toImmutableList ;
1717import static com .google .common .collect .MoreCollectors .onlyElement ;
1818
19+ import com .google .auto .value .AutoValue ;
1920import com .google .common .collect .ImmutableList ;
2021import dev .cel .bundle .Cel ;
2122import dev .cel .common .CelAbstractSyntaxTree ;
4748 * calls and select statements with their evaluated result.
4849 */
4950public final class ConstantFoldingOptimizer implements CelAstOptimizer {
50- private static final int MAX_ITERATION_COUNT = 400 ;
51+ private static final ConstantFoldingOptimizer INSTANCE =
52+ new ConstantFoldingOptimizer (ConstantFoldingOptions .newBuilder ().build ());
5153
52- public static final ConstantFoldingOptimizer INSTANCE = new ConstantFoldingOptimizer ();
54+ /** Returns a default instance of constant folding optimizer with preconfigured defaults. */
55+ public static ConstantFoldingOptimizer getInstance () {
56+ return INSTANCE ;
57+ }
58+
59+ /**
60+ * Returns a new instance of constant folding optimizer configured with the provided {@link
61+ * ConstantFoldingOptions}.
62+ */
63+ public static ConstantFoldingOptimizer newInstance (
64+ ConstantFoldingOptions constantFoldingOptions ) {
65+ return new ConstantFoldingOptimizer (constantFoldingOptions );
66+ }
5367
5468 // Use optional.of and optional.none as sentinel function names for folding optional calls.
5569 // TODO: Leverage CelValue representation of Optionals instead when available.
@@ -58,6 +72,7 @@ public final class ConstantFoldingOptimizer implements CelAstOptimizer {
5872 private static final CelExpr OPTIONAL_NONE_EXPR =
5973 CelExpr .ofCallExpr (0 , Optional .empty (), OPTIONAL_NONE_FUNCTION , ImmutableList .of ());
6074
75+ private final ConstantFoldingOptions constantFoldingOptions ;
6176 private final MutableAst mutableAst ;
6277
6378 @ Override
@@ -67,7 +82,7 @@ public CelAbstractSyntaxTree optimize(CelNavigableAst navigableAst, Cel cel)
6782 int iterCount = 0 ;
6883 while (true ) {
6984 iterCount ++;
70- if (iterCount == MAX_ITERATION_COUNT ) {
85+ if (iterCount >= constantFoldingOptions . maxIterationLimit () ) {
7186 throw new IllegalStateException ("Max iteration count reached." );
7287 }
7388 Optional <CelExpr > foldableExpr =
@@ -553,7 +568,37 @@ private CelAbstractSyntaxTree pruneOptionalStructElements(
553568 return ast ;
554569 }
555570
556- private ConstantFoldingOptimizer () {
557- this .mutableAst = MutableAst .newInstance (MAX_ITERATION_COUNT );
571+ /** Options to configure how Constant Folding behave. */
572+ @ AutoValue
573+ public abstract static class ConstantFoldingOptions {
574+ public abstract int maxIterationLimit ();
575+
576+ /** Builder for configuring the {@link ConstantFoldingOptions}. */
577+ @ AutoValue .Builder
578+ public abstract static class Builder {
579+
580+ /**
581+ * Limit the number of iteration while performing constant folding. An exception is thrown if
582+ * the iteration count exceeds the set value.
583+ */
584+ public abstract Builder maxIterationLimit (int value );
585+
586+ public abstract ConstantFoldingOptions build ();
587+
588+ Builder () {}
589+ }
590+
591+ /** Returns a new options builder with recommended defaults pre-configured. */
592+ public static Builder newBuilder () {
593+ return new AutoValue_ConstantFoldingOptimizer_ConstantFoldingOptions .Builder ()
594+ .maxIterationLimit (400 );
595+ }
596+
597+ ConstantFoldingOptions () {}
598+ }
599+
600+ private ConstantFoldingOptimizer (ConstantFoldingOptions constantFoldingOptions ) {
601+ this .constantFoldingOptions = constantFoldingOptions ;
602+ this .mutableAst = MutableAst .newInstance (constantFoldingOptions .maxIterationLimit ());
558603 }
559604}
0 commit comments