Skip to content
Merged
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
4 changes: 2 additions & 2 deletions runtime/src/main/java/dev/cel/runtime/CelRuntimeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ public Object trace(PartialVars partialVars, CelEvaluationListener listener)
}

@Override
public Object advanceEvaluation(UnknownContext context) {
throw new UnsupportedOperationException("Unsupported operation.");
public Object advanceEvaluation(UnknownContext context) throws CelEvaluationException {
return program.eval(context.toPartialVars());
}
};
}
Expand Down
5 changes: 5 additions & 0 deletions runtime/src/main/java/dev/cel/runtime/UnknownContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ public GlobalResolver variableResolver() {
return variableResolver;
}

PartialVars toPartialVars() {
return PartialVars.of(
name -> Optional.ofNullable(variableResolver.resolve(name)), unresolvedAttributes);
}

/**
* Creates a new unknown context that is a copy of the current context with the provided
* additional attribute values.
Expand Down
62 changes: 60 additions & 2 deletions runtime/src/test/java/dev/cel/runtime/CelRuntimeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,18 @@ public void evaluate_v1alpha1CheckedExpr() throws Exception {
public void advanceEvaluation_withUnknownTracking_noSelfReferenceInMerge(String expression)
throws Exception {
Cel cel =
CelFactory.standardCelBuilder()
runtimeFlavor
.builder()
.setStandardMacros(CelStandardMacro.STANDARD_MACROS)
.addCompilerLibraries(CelExtensions.bindings())
.setContainer(CelContainer.ofName("cel.expr.conformance.test"))
.addVar("unknown_attr", SimpleType.INT)
.addVar("my_list", ListType.create(SimpleType.INT))
.setOptions(CelOptions.current().enableUnknownTracking(true).build())
.setOptions(
CelOptions.current()
.enableHeterogeneousNumericComparisons(true)
.enableUnknownTracking(true)
.build())
.build();

CelUnknownSet result =
Expand All @@ -170,6 +175,59 @@ public void advanceEvaluation_withUnknownTracking_noSelfReferenceInMerge(String
assertThat(result.attributes()).containsExactly(CelAttribute.create("unknown_attr"));
}

@Test
public void advanceEvaluation_withUnknownContext_tracksUnknowns() throws Exception {
Cel cel =
runtimeFlavor
.builder()
.setOptions(
CelOptions.current()
.enableHeterogeneousNumericComparisons(true)
.enableUnknownTracking(true)
.build())
.setContainer(CelContainer.ofName("com.google"))
.addVar("com.google.a", SimpleType.BOOL)
.addVar("com.google.b", SimpleType.BOOL)
.setResultType(SimpleType.BOOL)
.build();
CelRuntime.Program program = cel.createProgram(cel.compile("b ? a : false").getAst());
UnknownContext context =
UnknownContext.create(
name -> name.equals("com.google.b") ? Optional.of(true) : Optional.empty(),
ImmutableList.of(CelAttributePattern.fromQualifiedIdentifier("com.google.a")));

CelUnknownSet unknownResult = (CelUnknownSet) program.advanceEvaluation(context);

assertThat(unknownResult.attributes())
.containsExactly(CelAttribute.fromQualifiedIdentifier("com.google.a"));
}

@Test
public void advanceEvaluation_withResolvedUnknownContext_evaluatesResult() throws Exception {
Cel cel =
runtimeFlavor
.builder()
.setOptions(
CelOptions.current()
.enableHeterogeneousNumericComparisons(true)
.enableUnknownTracking(true)
.build())
.setContainer(CelContainer.ofName("com.google"))
.addVar("com.google.a", SimpleType.BOOL)
.addVar("com.google.b", SimpleType.BOOL)
.setResultType(SimpleType.BOOL)
.build();
CelRuntime.Program program = cel.createProgram(cel.compile("a || b").getAst());
ImmutableMap<String, Boolean> vars =
ImmutableMap.of("com.google.a", true, "com.google.b", false);
UnknownContext context =
UnknownContext.create(name -> Optional.ofNullable(vars.get(name)), ImmutableList.of());

Object resolvedResult = program.advanceEvaluation(context);

assertThat(resolvedResult).isEqualTo(true);
}

@Test
public void newWellKnownTypeMessage_withDifferentDescriptorInstance() throws Exception {
CelCompiler celCompiler =
Expand Down
16 changes: 16 additions & 0 deletions runtime/src/test/java/dev/cel/runtime/UnknownContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,20 @@ public void withResolvedAttributes_attributeResolverPartialsShadowed() {
CelAttribute.fromQualifiedIdentifier("qualified.Identifier.field2")))
.isEmpty();
}

@Test
public void toPartialVars_preservesResolverAndUnknowns() {
CelAttributePattern pattern =
CelAttributePattern.fromQualifiedIdentifier("qualified.Identifier");
UnknownContext context =
UnknownContext.create(
name -> name.equals("x") ? Optional.of("val") : Optional.empty(),
ImmutableList.of(pattern));

PartialVars partialVars = context.toPartialVars();

assertThat(partialVars.resolver().find("x")).hasValue("val");
assertThat(partialVars.resolver().find("missing")).isEmpty();
assertThat(partialVars.unknowns()).containsExactly(pattern);
}
}
Loading