Skip to content

Commit cd86884

Browse files
l46kokcopybara-github
authored andcommitted
Add late bound function resolver to lite runtime's program interface
PiperOrigin-RevId: 756834704
1 parent cce972a commit cd86884

File tree

9 files changed

+92
-19
lines changed

9 files changed

+92
-19
lines changed

runtime/BUILD.bazel

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,19 @@ java_library(
5151

5252
java_library(
5353
name = "function_binding",
54-
exports = [
55-
"//runtime/src/main/java/dev/cel/runtime:function_binding",
56-
],
54+
exports = ["//runtime/src/main/java/dev/cel/runtime:function_binding"],
5755
)
5856

5957
cel_android_library(
6058
name = "function_binding_android",
61-
exports = [
62-
"//runtime/src/main/java/dev/cel/runtime:function_binding_android",
63-
],
59+
exports = ["//runtime/src/main/java/dev/cel/runtime:function_binding_android"],
6460
)
6561

6662
java_library(
6763
name = "function_overload_impl",
6864
# used_by_android
6965
visibility = ["//:internal"],
70-
exports = [
71-
"//runtime/src/main/java/dev/cel/runtime:function_overload_impl",
72-
],
66+
exports = ["//runtime/src/main/java/dev/cel/runtime:function_overload_impl"],
7367
)
7468

7569
java_library(

runtime/src/main/java/dev/cel/runtime/BUILD.bazel

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,6 @@ java_library(
448448

449449
# keep sorted
450450
RUNTIME_SOURCES = [
451-
"CelFunctionResolver.java",
452451
"CelLateFunctionBindings.java",
453452
"CelResolvedOverload.java",
454453
"CelRuntime.java",
@@ -603,6 +602,19 @@ cel_android_library(
603602
],
604603
)
605604

605+
java_library(
606+
name = "function_resolver",
607+
srcs = ["CelFunctionResolver.java"],
608+
# used_by_android
609+
tags = [
610+
],
611+
deps = [
612+
":function_overload_impl",
613+
"@maven//:com_google_code_findbugs_annotations",
614+
"@maven//:com_google_errorprone_error_prone_annotations",
615+
],
616+
)
617+
606618
java_library(
607619
name = "function_overload",
608620
srcs = [
@@ -652,6 +664,7 @@ java_library(
652664
":function_binding",
653665
":function_overload",
654666
":function_overload_impl",
667+
":function_resolver",
655668
":interpretable",
656669
":interpreter",
657670
":lite_runtime",
@@ -689,6 +702,7 @@ java_library(
689702
deps = [
690703
":evaluation_exception",
691704
":function_binding",
705+
":function_resolver",
692706
":standard_functions",
693707
"//:auto_value",
694708
"//common:cel_ast",
@@ -710,7 +724,9 @@ java_library(
710724
":cel_value_runtime_type_provider",
711725
":dispatcher",
712726
":evaluation_exception",
727+
":evaluation_listener",
713728
":function_binding",
729+
":function_resolver",
714730
":interpretable",
715731
":interpreter",
716732
":lite_runtime",
@@ -738,7 +754,9 @@ cel_android_library(
738754
":cel_value_runtime_type_provider_android",
739755
":dispatcher_android",
740756
":evaluation_exception",
757+
":evaluation_listener_android",
741758
":function_binding_android",
759+
":function_resolver",
742760
":interpretable_android",
743761
":interpreter_android",
744762
":lite_runtime_android",
@@ -923,8 +941,7 @@ java_library(
923941
cel_android_library(
924942
name = "evaluation_listener_android",
925943
srcs = ["CelEvaluationListener.java"],
926-
tags = [
927-
],
944+
visibility = ["//visibility:private"],
928945
deps = [
929946
"//common/ast:ast_android",
930947
"@maven//:com_google_code_findbugs_annotations",
@@ -940,6 +957,7 @@ cel_android_library(
940957
deps = [
941958
":evaluation_exception",
942959
":function_binding_android",
960+
":function_resolver",
943961
":standard_functions_android",
944962
"//:auto_value",
945963
"//common:cel_ast_android",

runtime/src/main/java/dev/cel/runtime/CelLiteRuntime.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,18 @@ public interface CelLiteRuntime {
3636
/** Creates an evaluable {@code Program} instance which is thread-safe and immutable. */
3737
@Immutable
3838
interface Program {
39+
40+
/** Evaluate the expression without any variables. */
3941
Object eval() throws CelEvaluationException;
4042

43+
/** Evaluate the expression using a {@code mapValue} as the source of input variables. */
4144
Object eval(Map<String, ?> mapValue) throws CelEvaluationException;
45+
46+
/**
47+
* Evaluate a compiled program with {@code mapValue} and late-bound functions {@code
48+
* lateBoundFunctionResolver}.
49+
*/
50+
Object eval(Map<String, ?> mapValue, CelFunctionResolver lateBoundFunctionResolver)
51+
throws CelEvaluationException;
4252
}
4353
}

runtime/src/main/java/dev/cel/runtime/CelRuntime.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,11 @@ public interface CelRuntime {
4343
@Immutable
4444
abstract class Program implements CelLiteRuntime.Program {
4545

46-
/** Evaluate the expression without any variables. */
4746
@Override
4847
public Object eval() throws CelEvaluationException {
4948
return evalInternal(Activation.EMPTY);
5049
}
5150

52-
/** Evaluate the expression using a {@code mapValue} as the source of input variables. */
5351
@Override
5452
public Object eval(Map<String, ?> mapValue) throws CelEvaluationException {
5553
return evalInternal(Activation.copyOf(mapValue));
@@ -77,10 +75,7 @@ public Object eval(CelVariableResolver resolver, CelFunctionResolver lateBoundFu
7775
CelEvaluationListener.noOpListener());
7876
}
7977

80-
/**
81-
* Evaluate a compiled program with {@code mapValue} and late-bound functions {@code
82-
* lateBoundFunctionResolver}.
83-
*/
78+
@Override
8479
public Object eval(Map<String, ?> mapValue, CelFunctionResolver lateBoundFunctionResolver)
8580
throws CelEvaluationException {
8681
return evalInternal(

runtime/src/main/java/dev/cel/runtime/DefaultInterpreter.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ public Object eval(GlobalResolver resolver, CelEvaluationListener listener)
147147
RuntimeUnknownResolver.fromResolver(resolver), Optional.empty(), listener);
148148
}
149149

150+
@Override
151+
public Object eval(GlobalResolver resolver, FunctionResolver lateBoundFunctionResolver)
152+
throws CelEvaluationException {
153+
return eval(resolver,
154+
lateBoundFunctionResolver,
155+
CelEvaluationListener.noOpListener());
156+
}
157+
150158
@Override
151159
public Object eval(
152160
GlobalResolver resolver,

runtime/src/main/java/dev/cel/runtime/Interpretable.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ public interface Interpretable {
3737
Object eval(GlobalResolver resolver, CelEvaluationListener listener)
3838
throws CelEvaluationException;
3939

40+
/**
41+
* Runs interpretation with the given activation which supplies name/value bindings.
42+
*
43+
* <p>This method allows for late-binding functions to be provided per-evaluation, which can be
44+
* useful for binding functions which might have side-effects that are not observable to CEL
45+
* directly such as recording telemetry or evaluation state in a more granular fashion than a more
46+
* general evaluation listener might permit.
47+
*/
48+
Object eval(GlobalResolver resolver, FunctionResolver lateBoundFunctionResolver)
49+
throws CelEvaluationException;
50+
4051
/**
4152
* Runs interpretation with the given activation which supplies name/value bindings.
4253
*

runtime/src/main/java/dev/cel/runtime/LiteProgramImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ public Object eval(Map<String, ?> mapValue) throws CelEvaluationException {
3434
return interpretable().eval(Activation.copyOf(mapValue));
3535
}
3636

37+
@Override
38+
public Object eval(Map<String, ?> mapValue, CelFunctionResolver lateBoundFunctionResolver)
39+
throws CelEvaluationException {
40+
return interpretable()
41+
.eval(
42+
Activation.copyOf(mapValue),
43+
lateBoundFunctionResolver,
44+
CelEvaluationListener.noOpListener());
45+
}
46+
3747
static CelLiteRuntime.Program plan(Interpretable interpretable) {
3848
return new AutoValue_LiteProgramImpl(interpretable);
3949
}

runtime/src/test/java/dev/cel/runtime/CelLiteRuntimeTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
4242
import com.google.testing.junit.testparameterinjector.TestParameters;
4343
import dev.cel.common.CelAbstractSyntaxTree;
44+
import dev.cel.common.CelFunctionDecl;
45+
import dev.cel.common.CelOverloadDecl;
4446
import dev.cel.common.internal.ProtoTimeUtils;
4547
import dev.cel.common.types.SimpleType;
4648
import dev.cel.common.types.StructTypeReference;
@@ -605,4 +607,30 @@ public void nestedMessage_fromImportedProto() throws Exception {
605607

606608
assertThat(result).isEqualTo("foo");
607609
}
610+
611+
@Test
612+
public void eval_withLateBoundFunction() throws Exception {
613+
CelCompiler celCompiler =
614+
CelCompilerFactory.standardCelCompilerBuilder()
615+
.addFunctionDeclarations(
616+
CelFunctionDecl.newFunctionDeclaration(
617+
"lateBoundFunc",
618+
CelOverloadDecl.newGlobalOverload(
619+
"lateBoundFunc_string", SimpleType.STRING, SimpleType.STRING)))
620+
.build();
621+
CelLiteRuntime celRuntime = CelLiteRuntimeFactory.newLiteRuntimeBuilder().build();
622+
CelAbstractSyntaxTree ast = celCompiler.compile("lateBoundFunc('hello')").getAst();
623+
624+
String result =
625+
(String)
626+
celRuntime
627+
.createProgram(ast)
628+
.eval(
629+
ImmutableMap.of(),
630+
CelLateFunctionBindings.from(
631+
CelFunctionBinding.from(
632+
"lateBoundFunc_string", String.class, arg -> arg + " world")));
633+
634+
assertThat(result).isEqualTo("hello world");
635+
}
608636
}

testing/src/test/resources/protos/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ java_lite_proto_cel_library(
6565

6666
java_lite_proto_cel_library_impl(
6767
name = "multi_file_cel_java_proto",
68-
debug = True,
6968
java_descriptor_class_suffix = "CelDescriptor",
7069
java_proto_library_dep = ":multi_file_java_proto",
7170
deps = [

0 commit comments

Comments
 (0)