CEL Library Internals. Do Not Use.
+ */
+@Internal
+@Immutable
+public interface InternalCelFunctionBinding extends CelFunctionBinding {
+ String getFunctionName();
+}
diff --git a/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java b/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java
index 0e5c5cf30..d58eb3be4 100644
--- a/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java
+++ b/runtime/src/main/java/dev/cel/runtime/LiteRuntimeImpl.java
@@ -162,9 +162,18 @@ public CelLiteRuntime build() {
functionBindingsBuilder
.buildOrThrow()
.forEach(
- (String overloadId, CelFunctionBinding func) ->
- dispatcherBuilder.addOverload(
- overloadId, func.getArgTypes(), func.isStrict(), func.getDefinition()));
+ (String overloadId, CelFunctionBinding func) -> {
+ String functionName = func.getOverloadId();
+ if (func instanceof InternalCelFunctionBinding) {
+ functionName = ((InternalCelFunctionBinding) func).getFunctionName();
+ }
+ dispatcherBuilder.addOverload(
+ functionName,
+ overloadId,
+ func.getArgTypes(),
+ func.isStrict(),
+ func.getDefinition());
+ });
Interpreter interpreter =
new DefaultInterpreter(
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java
index 7771da3e6..16eba3cce 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalBinary.java
@@ -25,6 +25,7 @@
final class EvalBinary extends PlannedInterpretable {
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
private final PlannedInterpretable arg1;
private final PlannedInterpretable arg2;
@@ -48,25 +49,29 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
return unknowns;
}
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVal1, argVal2);
+ return EvalHelpers.dispatch(
+ functionName, resolvedOverload, celValueConverter, argVal1, argVal2);
}
static EvalBinary create(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg1,
PlannedInterpretable arg2,
CelValueConverter celValueConverter) {
- return new EvalBinary(exprId, resolvedOverload, arg1, arg2, celValueConverter);
+ return new EvalBinary(exprId, functionName, resolvedOverload, arg1, arg2, celValueConverter);
}
private EvalBinary(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg1,
PlannedInterpretable arg2,
CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.arg1 = arg1;
this.arg2 = arg2;
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java
index a30f91880..220642f4a 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalHelpers.java
@@ -56,7 +56,10 @@ static Object evalStrictly(
}
static Object dispatch(
- CelResolvedOverload overload, CelValueConverter valueConverter, Object[] args)
+ String functionName,
+ CelResolvedOverload overload,
+ CelValueConverter valueConverter,
+ Object[] args)
throws CelEvaluationException {
try {
Object result = overload.invoke(args);
@@ -66,7 +69,11 @@ static Object dispatch(
}
}
- static Object dispatch(CelResolvedOverload overload, CelValueConverter valueConverter, Object arg)
+ static Object dispatch(
+ String functionName,
+ CelResolvedOverload overload,
+ CelValueConverter valueConverter,
+ Object arg)
throws CelEvaluationException {
try {
Object result = overload.invoke(arg);
@@ -77,7 +84,11 @@ static Object dispatch(CelResolvedOverload overload, CelValueConverter valueConv
}
static Object dispatch(
- CelResolvedOverload overload, CelValueConverter valueConverter, Object arg1, Object arg2)
+ String functionName,
+ CelResolvedOverload overload,
+ CelValueConverter valueConverter,
+ Object arg1,
+ Object arg2)
throws CelEvaluationException {
try {
Object result = overload.invoke(arg1, arg2);
@@ -97,7 +108,7 @@ private static RuntimeException handleDispatchException(
return new IllegalArgumentException(
String.format(
"Function '%s' failed with arg(s) '%s'",
- overload.getOverloadId(), Joiner.on(", ").join(args)),
+ overload.getFunctionName(), Joiner.on(", ").join(args)),
e);
}
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java
index cdee878ee..0bd251185 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalLateBoundCall.java
@@ -55,7 +55,7 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
.findOverload(functionName, overloadIds, argVals)
.orElseThrow(() -> new CelOverloadNotFoundException(functionName, overloadIds));
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVals);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, argVals);
}
static EvalLateBoundCall create(
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java
index 322648ee3..57834161f 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalUnary.java
@@ -24,6 +24,7 @@
final class EvalUnary extends PlannedInterpretable {
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
private final PlannedInterpretable arg;
private final CelValueConverter celValueConverter;
@@ -34,23 +35,26 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
resolvedOverload.isStrict()
? evalStrictly(arg, resolver, frame)
: evalNonstrictly(arg, resolver, frame);
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVal);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, argVal);
}
static EvalUnary create(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg,
CelValueConverter celValueConverter) {
- return new EvalUnary(exprId, resolvedOverload, arg, celValueConverter);
+ return new EvalUnary(exprId, functionName, resolvedOverload, arg, celValueConverter);
}
private EvalUnary(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable arg,
CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.arg = arg;
this.celValueConverter = celValueConverter;
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java
index eb8745632..fe7c6c430 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalVarArgsCall.java
@@ -25,6 +25,7 @@
final class EvalVarArgsCall extends PlannedInterpretable {
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
@SuppressWarnings("Immutable")
@@ -50,23 +51,26 @@ public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEval
return unknowns;
}
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, argVals);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, argVals);
}
static EvalVarArgsCall create(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable[] args,
CelValueConverter celValueConverter) {
- return new EvalVarArgsCall(exprId, resolvedOverload, args, celValueConverter);
+ return new EvalVarArgsCall(exprId, functionName, resolvedOverload, args, celValueConverter);
}
private EvalVarArgsCall(
long exprId,
+ String functionName,
CelResolvedOverload resolvedOverload,
PlannedInterpretable[] args,
CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.args = args;
this.celValueConverter = celValueConverter;
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java b/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java
index 5b3138207..7798c8253 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/EvalZeroArity.java
@@ -22,22 +22,30 @@
final class EvalZeroArity extends PlannedInterpretable {
private static final Object[] EMPTY_ARRAY = new Object[0];
+ private final String functionName;
private final CelResolvedOverload resolvedOverload;
private final CelValueConverter celValueConverter;
@Override
public Object eval(GlobalResolver resolver, ExecutionFrame frame) throws CelEvaluationException {
- return EvalHelpers.dispatch(resolvedOverload, celValueConverter, EMPTY_ARRAY);
+ return EvalHelpers.dispatch(functionName, resolvedOverload, celValueConverter, EMPTY_ARRAY);
}
static EvalZeroArity create(
- long exprId, CelResolvedOverload resolvedOverload, CelValueConverter celValueConverter) {
- return new EvalZeroArity(exprId, resolvedOverload, celValueConverter);
+ long exprId,
+ String functionName,
+ CelResolvedOverload resolvedOverload,
+ CelValueConverter celValueConverter) {
+ return new EvalZeroArity(exprId, functionName, resolvedOverload, celValueConverter);
}
private EvalZeroArity(
- long exprId, CelResolvedOverload resolvedOverload, CelValueConverter celValueConverter) {
+ long exprId,
+ String functionName,
+ CelResolvedOverload resolvedOverload,
+ CelValueConverter celValueConverter) {
super(exprId);
+ this.functionName = functionName;
this.resolvedOverload = resolvedOverload;
this.celValueConverter = celValueConverter;
}
diff --git a/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java b/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java
index 9bd5f3ecd..a0b74fc99 100644
--- a/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java
+++ b/runtime/src/main/java/dev/cel/runtime/planner/ProgramPlanner.java
@@ -308,15 +308,21 @@ private PlannedInterpretable planCall(CelExpr expr, PlannerContext ctx) {
switch (argCount) {
case 0:
- return EvalZeroArity.create(expr.id(), resolvedOverload, celValueConverter);
+ return EvalZeroArity.create(expr.id(), functionName, resolvedOverload, celValueConverter);
case 1:
- return EvalUnary.create(expr.id(), resolvedOverload, evaluatedArgs[0], celValueConverter);
+ return EvalUnary.create(
+ expr.id(), functionName, resolvedOverload, evaluatedArgs[0], celValueConverter);
case 2:
return EvalBinary.create(
- expr.id(), resolvedOverload, evaluatedArgs[0], evaluatedArgs[1], celValueConverter);
+ expr.id(),
+ functionName,
+ resolvedOverload,
+ evaluatedArgs[0],
+ evaluatedArgs[1],
+ celValueConverter);
default:
return EvalVarArgsCall.create(
- expr.id(), resolvedOverload, evaluatedArgs, celValueConverter);
+ expr.id(), functionName, resolvedOverload, evaluatedArgs, celValueConverter);
}
}
diff --git a/runtime/src/test/java/dev/cel/runtime/BUILD.bazel b/runtime/src/test/java/dev/cel/runtime/BUILD.bazel
index 577010971..7cd24f040 100644
--- a/runtime/src/test/java/dev/cel/runtime/BUILD.bazel
+++ b/runtime/src/test/java/dev/cel/runtime/BUILD.bazel
@@ -2,6 +2,7 @@ load("@rules_java//java:defs.bzl", "java_library")
load("//:cel_android_rules.bzl", "cel_android_local_test")
load("//:testing.bzl", "junit4_test_suites")
+# Invalidate cache after file removal
package(
default_applicable_licenses = ["//:license"],
default_testonly = True,
diff --git a/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java b/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java
index c1210c1ba..471282117 100644
--- a/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/CelResolvedOverloadTest.java
@@ -27,11 +27,13 @@ public final class CelResolvedOverloadTest {
CelResolvedOverload getIncrementIntOverload() {
return CelResolvedOverload.of(
- "increment_int",
- (args) -> {
- Long arg = (Long) args[0];
- return arg + 1;
- },
+ /* functionName= */ "increment_int",
+ /* overloadId= */ "increment_int_overload",
+ (CelFunctionOverload)
+ (args) -> {
+ Long arg = (Long) args[0];
+ return arg + 1;
+ },
/* isStrict= */ true,
Long.class);
}
@@ -45,14 +47,23 @@ public void canHandle_matchingTypes_returnsTrue() {
public void canHandle_nullMessageType_returnsFalse() {
CelResolvedOverload overload =
CelResolvedOverload.of(
- "identity", (args) -> args[0], /* isStrict= */ true, TestAllTypes.class);
+ /* functionName= */ "identity",
+ /* overloadId= */ "identity_overload",
+ (CelFunctionOverload) (args) -> args[0],
+ /* isStrict= */ true,
+ TestAllTypes.class);
assertThat(overload.canHandle(new Object[] {null})).isFalse();
}
@Test
public void canHandle_nullPrimitive_returnsFalse() {
CelResolvedOverload overload =
- CelResolvedOverload.of("identity", (args) -> args[0], /* isStrict= */ true, Long.class);
+ CelResolvedOverload.of(
+ /* functionName= */ "identity",
+ /* overloadId= */ "identity_overload",
+ (CelFunctionOverload) (args) -> args[0],
+ /* isStrict= */ true,
+ Long.class);
assertThat(overload.canHandle(new Object[] {null})).isFalse();
}
@@ -70,10 +81,12 @@ public void canHandle_nonMatchingArgCount_returnsFalse() {
public void canHandle_nonStrictOverload_returnsTrue() {
CelResolvedOverload nonStrictOverload =
CelResolvedOverload.of(
- "non_strict",
- (args) -> {
- return false;
- },
+ /* functionName= */ "non_strict",
+ /* overloadId= */ "non_strict_overload",
+ (CelFunctionOverload)
+ (args) -> {
+ return false;
+ },
/* isStrict= */ false,
Long.class,
Long.class);
@@ -87,10 +100,12 @@ public void canHandle_nonStrictOverload_returnsTrue() {
public void canHandle_nonStrictOverload_returnsFalse() {
CelResolvedOverload nonStrictOverload =
CelResolvedOverload.of(
- "non_strict",
- (args) -> {
- return false;
- },
+ /* functionName= */ "non_strict",
+ /* overloadId= */ "non_strict_overload",
+ (CelFunctionOverload)
+ (args) -> {
+ return false;
+ },
/* isStrict= */ false,
Long.class,
Long.class);
diff --git a/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java b/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java
index 255360ee1..d862ddb33 100644
--- a/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/DefaultDispatcherTest.java
@@ -37,11 +37,19 @@ public void setup() {
overloads.put(
"overload_1",
CelResolvedOverload.of(
- "overload_1", args -> (Long) args[0] + 1, /* isStrict= */ true, Long.class));
+ /* functionName= */ "overload_1",
+ /* overloadId= */ "overload_1",
+ args -> (Long) args[0] + 1,
+ /* isStrict= */ true,
+ Long.class));
overloads.put(
"overload_2",
CelResolvedOverload.of(
- "overload_2", args -> (Long) args[0] + 2, /* isStrict= */ true, Long.class));
+ /* functionName= */ "overload_2",
+ /* overloadId= */ "overload_2",
+ args -> (Long) args[0] + 2,
+ /* isStrict= */ true,
+ Long.class));
}
@Test
diff --git a/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java b/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java
index 1a8f45161..bd0e96856 100644
--- a/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java
+++ b/runtime/src/test/java/dev/cel/runtime/DefaultInterpreterTest.java
@@ -77,15 +77,21 @@ public Object adapt(String messageName, Object message) {
CelAbstractSyntaxTree ast = celCompiler.compile("[1].all(x, [2].all(y, error()))").getAst();
DefaultDispatcher.Builder dispatcherBuilder = DefaultDispatcher.newBuilder();
dispatcherBuilder.addOverload(
- "error",
- ImmutableList.of(long.class),
+ /* functionName= */ "error",
+ /* overloadId= */ "error_overload",
+ ImmutableList.