2121import com .google .common .base .Joiner ;
2222import com .google .common .base .Preconditions ;
2323import com .google .common .collect .ImmutableList ;
24+ import com .google .common .collect .ImmutableSet ;
2425import com .google .errorprone .annotations .CanIgnoreReturnValue ;
2526import com .google .errorprone .annotations .Immutable ;
2627import javax .annotation .concurrent .ThreadSafe ;
@@ -137,20 +138,24 @@ static final class DefaultInterpretable implements Interpretable, UnknownTrackin
137138 @ Override
138139 public Object eval (GlobalResolver resolver ) throws CelEvaluationException {
139140 // Result is already unwrapped from IntermediateResult.
140- return eval (resolver , CelEvaluationListener .noOpListener ());
141+ return evalTrackingUnknowns (
142+ RuntimeUnknownResolver .fromResolver (resolver ), Optional .empty (), Optional .empty ());
141143 }
142144
143145 @ Override
144146 public Object eval (GlobalResolver resolver , CelEvaluationListener listener )
145147 throws CelEvaluationException {
146148 return evalTrackingUnknowns (
147- RuntimeUnknownResolver .fromResolver (resolver ), Optional .empty (), listener );
149+ RuntimeUnknownResolver .fromResolver (resolver ), Optional .empty (), Optional . of ( listener ) );
148150 }
149151
150152 @ Override
151153 public Object eval (GlobalResolver resolver , FunctionResolver lateBoundFunctionResolver )
152154 throws CelEvaluationException {
153- return eval (resolver , lateBoundFunctionResolver , CelEvaluationListener .noOpListener ());
155+ return evalTrackingUnknowns (
156+ RuntimeUnknownResolver .fromResolver (resolver ),
157+ Optional .of (lateBoundFunctionResolver ),
158+ Optional .empty ());
154159 }
155160
156161 @ Override
@@ -162,19 +167,32 @@ public Object eval(
162167 return evalTrackingUnknowns (
163168 RuntimeUnknownResolver .fromResolver (resolver ),
164169 Optional .of (lateBoundFunctionResolver ),
165- listener );
170+ Optional . of ( listener ) );
166171 }
167172
168173 @ Override
169174 public Object evalTrackingUnknowns (
170175 RuntimeUnknownResolver resolver ,
171176 Optional <? extends FunctionResolver > functionResolver ,
172- CelEvaluationListener listener )
177+ Optional < CelEvaluationListener > listener )
173178 throws CelEvaluationException {
174179 ExecutionFrame frame = newExecutionFrame (resolver , functionResolver , listener );
175180 IntermediateResult internalResult = evalInternal (frame , ast .getExpr ());
176181
177- return internalResult .value ();
182+ Object underlyingValue = internalResult .value ();
183+
184+ return maybeAdaptToCelUnknownSet (underlyingValue );
185+ }
186+
187+ private static Object maybeAdaptToCelUnknownSet (Object val ) {
188+ if (!(val instanceof AccumulatedUnknowns )) {
189+ return val ;
190+ }
191+
192+ AccumulatedUnknowns unknowns = (AccumulatedUnknowns ) val ;
193+
194+ return CelUnknownSet .create (
195+ ImmutableSet .copyOf (unknowns .attributes ()), ImmutableSet .copyOf (unknowns .exprIds ()));
178196 }
179197
180198 /**
@@ -196,15 +214,13 @@ ExecutionFrame populateExecutionFrame(ExecutionFrame frame) throws CelEvaluation
196214 @ VisibleForTesting
197215 ExecutionFrame newTestExecutionFrame (GlobalResolver resolver ) {
198216 return newExecutionFrame (
199- RuntimeUnknownResolver .fromResolver (resolver ),
200- Optional .empty (),
201- CelEvaluationListener .noOpListener ());
217+ RuntimeUnknownResolver .fromResolver (resolver ), Optional .empty (), Optional .empty ());
202218 }
203219
204220 private ExecutionFrame newExecutionFrame (
205221 RuntimeUnknownResolver resolver ,
206222 Optional <? extends FunctionResolver > functionResolver ,
207- CelEvaluationListener listener ) {
223+ Optional < CelEvaluationListener > listener ) {
208224 int comprehensionMaxIterations =
209225 celOptions .enableComprehension () ? celOptions .comprehensionMaxIterations () : 0 ;
210226 return new ExecutionFrame (listener , resolver , functionResolver , comprehensionMaxIterations );
@@ -244,7 +260,11 @@ private IntermediateResult evalInternal(ExecutionFrame frame, CelExpr expr)
244260 throw new IllegalStateException (
245261 "unexpected expression kind: " + expr .exprKind ().getKind ());
246262 }
247- frame .getEvaluationListener ().callback (expr , result .value ());
263+
264+ frame
265+ .getEvaluationListener ()
266+ .ifPresent (
267+ listener -> listener .callback (expr , maybeAdaptToCelUnknownSet (result .value ())));
248268 return result ;
249269 } catch (CelRuntimeException e ) {
250270 throw CelEvaluationExceptionBuilder .newBuilder (e ).setMetadata (metadata , expr .id ()).build ();
@@ -257,7 +277,7 @@ private IntermediateResult evalInternal(ExecutionFrame frame, CelExpr expr)
257277 }
258278
259279 private static boolean isUnknownValue (Object value ) {
260- return value instanceof CelUnknownSet || InterpreterUtil .isUnknown (value );
280+ return InterpreterUtil .isAccumulatedUnknowns (value );
261281 }
262282
263283 private static boolean isUnknownOrError (Object value ) {
@@ -552,18 +572,20 @@ private IntermediateResult mergeBooleanUnknowns(IntermediateResult lhs, Intermed
552572 throws CelEvaluationException {
553573 // TODO: migrate clients to a common type that reports both expr-id unknowns
554574 // and attribute sets.
555- if (lhs .value () instanceof CelUnknownSet && rhs .value () instanceof CelUnknownSet ) {
575+ Object lhsVal = lhs .value ();
576+ Object rhsVal = rhs .value ();
577+ if (lhsVal instanceof AccumulatedUnknowns && rhsVal instanceof AccumulatedUnknowns ) {
556578 return IntermediateResult .create (
557- ((CelUnknownSet ) lhs . value ()) .merge ((CelUnknownSet ) rhs . value () ));
558- } else if (lhs . value () instanceof CelUnknownSet ) {
579+ ((AccumulatedUnknowns ) lhsVal ) .merge ((AccumulatedUnknowns ) rhsVal ));
580+ } else if (lhsVal instanceof AccumulatedUnknowns ) {
559581 return lhs ;
560- } else if (rhs . value () instanceof CelUnknownSet ) {
582+ } else if (rhsVal instanceof AccumulatedUnknowns ) {
561583 return rhs ;
562584 }
563585
564586 // Otherwise fallback to normal impl
565587 return IntermediateResult .create (
566- InterpreterUtil .shortcircuitUnknownOrThrowable (lhs . value (), rhs . value () ));
588+ InterpreterUtil .shortcircuitUnknownOrThrowable (lhsVal , rhsVal ));
567589 }
568590
569591 private enum ShortCircuitableOperators {
@@ -1050,7 +1072,7 @@ private LazyExpression(CelExpr celExpr) {
10501072
10511073 /** This class tracks the state meaningful to a single evaluation pass. */
10521074 static class ExecutionFrame {
1053- private final CelEvaluationListener evaluationListener ;
1075+ private final Optional < CelEvaluationListener > evaluationListener ;
10541076 private final int maxIterations ;
10551077 private final ArrayDeque <RuntimeUnknownResolver > resolvers ;
10561078 private final Optional <? extends FunctionResolver > lateBoundFunctionResolver ;
@@ -1059,7 +1081,7 @@ static class ExecutionFrame {
10591081 @ VisibleForTesting int scopeLevel ;
10601082
10611083 private ExecutionFrame (
1062- CelEvaluationListener evaluationListener ,
1084+ Optional < CelEvaluationListener > evaluationListener ,
10631085 RuntimeUnknownResolver resolver ,
10641086 Optional <? extends FunctionResolver > lateBoundFunctionResolver ,
10651087 int maxIterations ) {
@@ -1071,7 +1093,7 @@ private ExecutionFrame(
10711093 this .maxIterations = maxIterations ;
10721094 }
10731095
1074- private CelEvaluationListener getEvaluationListener () {
1096+ private Optional < CelEvaluationListener > getEvaluationListener () {
10751097 return evaluationListener ;
10761098 }
10771099
0 commit comments