Skip to content

Commit 4dd3794

Browse files
committed
Dispatch using CelValue types
1 parent 72b51ef commit 4dd3794

16 files changed

Lines changed: 326 additions & 135 deletions

File tree

common/src/main/java/dev/cel/common/values/CelValueConverter.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ public CelValue fromJavaObjectToCelValue(Object value) {
8181
// TODO: CelConstant should hold this value instead of adapting it here
8282
return BytesValue.create(CelByteString.of(((ByteString) value).toByteArray()));
8383
} else if (value instanceof Iterable) {
84-
8584
return toListValue((Iterable<Object>) value);
8685
} else if (value instanceof Map) {
8786
return toMapValue((Map<Object, Object>) value);

runtime/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,3 +228,13 @@ cel_android_library(
228228
visibility = ["//:internal"],
229229
exports = ["//runtime/src/main/java/dev/cel/runtime:lite_runtime_impl_android"],
230230
)
231+
232+
java_library(
233+
name = "cel_value_function_binding",
234+
exports = ["//runtime/src/main/java/dev/cel/runtime:cel_value_function_binding"],
235+
)
236+
237+
java_library(
238+
name = "cel_value_function_overload",
239+
exports = ["//runtime/src/main/java/dev/cel/runtime:cel_value_function_overload"],
240+
)

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

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ java_library(
130130
],
131131
deps = [
132132
":base",
133-
":function_binding",
134-
":function_overload",
133+
":cel_value_function_binding",
134+
":cel_value_function_overload",
135135
"//:auto_value",
136136
"//common/annotations",
137137
"@maven//:com_google_errorprone_error_prone_annotations",
@@ -1204,3 +1204,31 @@ cel_android_library(
12041204
"@maven//:com_google_errorprone_error_prone_annotations",
12051205
],
12061206
)
1207+
1208+
java_library(
1209+
name = "cel_value_function_binding",
1210+
srcs = ["CelValueFunctionBinding.java"],
1211+
tags = [
1212+
],
1213+
deps = [
1214+
":cel_value_function_overload",
1215+
"//common/values:cel_value",
1216+
"@maven//:com_google_errorprone_error_prone_annotations",
1217+
"@maven//:com_google_guava_guava",
1218+
],
1219+
)
1220+
1221+
java_library(
1222+
name = "cel_value_function_overload",
1223+
srcs = [
1224+
"CelValueFunctionOverload.java",
1225+
],
1226+
tags = [
1227+
],
1228+
deps = [
1229+
":evaluation_exception",
1230+
"//common/values:cel_value",
1231+
"@maven//:com_google_errorprone_error_prone_annotations",
1232+
"@maven//:com_google_guava_guava",
1233+
],
1234+
)

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

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,4 @@ static CelFunctionBinding from(
6666
String overloadId, Iterable<Class<?>> argTypes, CelFunctionOverload impl) {
6767
return new FunctionBindingImpl(overloadId, ImmutableList.copyOf(argTypes), impl);
6868
}
69-
70-
default boolean canHandle(Object[] arguments) {
71-
ImmutableList<Class<?>> parameterTypes = getArgTypes();
72-
if (parameterTypes.size() != arguments.length) {
73-
return false;
74-
}
75-
for (int i = 0; i < parameterTypes.size(); i++) {
76-
Class<?> paramType = parameterTypes.get(i);
77-
Object arg = arguments[i];
78-
if (arg == null) {
79-
// Reject nulls. CEL-Java in general is not designed to handle nullability of objects.
80-
return false;
81-
}
82-
if (!paramType.isAssignableFrom(arg.getClass())) {
83-
return false;
84-
}
85-
}
86-
return true;
87-
}
8869
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package dev.cel.runtime;
2+
3+
import com.google.common.collect.ImmutableList;
4+
import com.google.errorprone.annotations.Immutable;
5+
import dev.cel.common.values.CelValue;
6+
7+
@Immutable
8+
public final class CelValueFunctionBinding {
9+
10+
private final String overloadId;
11+
private final ImmutableList<Class<? extends CelValue>> argTypes;
12+
private final CelValueFunctionOverload definition;
13+
14+
public String overloadId() {
15+
return overloadId;
16+
}
17+
18+
public ImmutableList<Class<? extends CelValue>> argTypes() {
19+
return argTypes;
20+
}
21+
22+
public CelValueFunctionOverload definition() {
23+
return definition;
24+
}
25+
26+
public static CelValueFunctionBinding from(String overloadId, CelValueFunctionOverload.Nullary impl) {
27+
return from(overloadId, ImmutableList.of(), (args) -> impl.apply());
28+
}
29+
30+
public static <T extends CelValue> CelValueFunctionBinding from(
31+
String overloadId, Class<T> argType, CelValueFunctionOverload.Unary<T> impl) {
32+
return from(overloadId, ImmutableList.of(argType), (args) -> impl.apply((T) args[0]));
33+
}
34+
35+
public static <T1 extends CelValue, T2 extends CelValue> CelValueFunctionBinding from(String overloadId, Class<T1> argType1, Class<T2> argType2, CelValueFunctionOverload.Binary<T1, T2> impl) {
36+
return from(overloadId, ImmutableList.of(argType1, argType2), (args) -> impl.apply((T1) args[0], (T2) args[1]));
37+
}
38+
39+
public static <T1 extends CelValue, T2 extends CelValue, T3 extends CelValue> CelValueFunctionBinding from(String overloadId, Class<T1> argType1, Class<T2> argType2, Class<T3> argType3, CelValueFunctionOverload.Ternary<T1, T2, T3> impl) {
40+
return from(overloadId, ImmutableList.of(argType1, argType2, argType3), (args) -> impl.apply((T1) args[0], (T2) args[1], (T3) args[2]));
41+
}
42+
43+
public static CelValueFunctionBinding from(String overloadId, ImmutableList<Class<? extends CelValue>> argTypes, CelValueFunctionOverload impl) {
44+
return new CelValueFunctionBinding(overloadId, argTypes, impl);
45+
}
46+
47+
public boolean canHandle(CelValue[] arguments) {
48+
if (argTypes().size() != arguments.length) {
49+
return false;
50+
}
51+
52+
for (int i = 0; i < argTypes().size(); i++) {
53+
Class<? extends CelValue> paramType = argTypes().get(i);
54+
CelValue arg = arguments[i];
55+
if (!paramType.isInstance(arg)) {
56+
return false;
57+
}
58+
}
59+
return true;
60+
}
61+
62+
private CelValueFunctionBinding(String overloadId, ImmutableList<Class<? extends CelValue>> argTypes, CelValueFunctionOverload definition) {
63+
this.overloadId = overloadId;
64+
this.argTypes = argTypes;
65+
this.definition = definition;
66+
}
67+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dev.cel.runtime;
2+
3+
import com.google.errorprone.annotations.Immutable;
4+
import dev.cel.common.values.CelValue;
5+
6+
@Immutable
7+
@FunctionalInterface
8+
public interface CelValueFunctionOverload {
9+
10+
CelValue apply(CelValue... args) throws CelEvaluationException;
11+
12+
@Immutable
13+
interface Nullary {
14+
CelValue apply() throws CelEvaluationException;
15+
}
16+
17+
@Immutable
18+
interface Unary<T extends CelValue> {
19+
CelValue apply(T arg) throws CelEvaluationException;
20+
}
21+
22+
@Immutable
23+
interface Binary<T1 extends CelValue, T2 extends CelValue> {
24+
CelValue apply(T1 arg1, T2 arg2) throws CelEvaluationException;
25+
}
26+
27+
@Immutable
28+
interface Ternary<T1 extends CelValue, T2 extends CelValue, T3 extends CelValue> {
29+
CelValue apply(T1 arg1, T2 arg2, T3 arg3) throws CelEvaluationException;
30+
}
31+
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
@AutoValue
1414
public abstract class DefaultDispatcher {
1515

16-
abstract ImmutableMap<String, CelFunctionBinding> overloads();
16+
abstract ImmutableMap<String, CelValueFunctionBinding> overloads();
1717

18-
public Optional<CelFunctionBinding> findOverload(String overloadId) {
18+
public Optional<CelValueFunctionBinding> findOverload(String overloadId) {
1919
return Optional.ofNullable(overloads().get(overloadId));
2020
}
2121

@@ -25,20 +25,20 @@ public static Builder newBuilder() {
2525

2626
@AutoValue.Builder
2727
public abstract static class Builder {
28-
public abstract ImmutableMap.Builder<String, CelFunctionBinding> overloadsBuilder();
28+
public abstract ImmutableMap.Builder<String, CelValueFunctionBinding> overloadsBuilder();
2929

3030
@CanIgnoreReturnValue
31-
public Builder addOverload(CelFunctionBinding functionBinding) {
31+
public Builder addOverload(CelValueFunctionBinding functionBinding) {
3232
overloadsBuilder().put(
33-
functionBinding.getOverloadId(),
33+
functionBinding.overloadId(),
3434
functionBinding);
3535
return this;
3636
}
3737

3838
@CanIgnoreReturnValue
39-
public Builder addFunction(String functionName, CelFunctionOverload definition) {
39+
public Builder addDynamicDispatchOverload(String functionName, CelValueFunctionOverload definition) {
4040
overloadsBuilder().put(
41-
functionName, CelFunctionBinding.from(functionName, ImmutableList.of(), definition)
41+
functionName, CelValueFunctionBinding.from(functionName, ImmutableList.of(), definition)
4242
);
4343

4444
return this;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ java_library(
3434
"//common/values:cel_value",
3535
"//common/values:cel_value_provider",
3636
"//runtime:activation",
37+
"//runtime:cel_value_function_binding",
3738
"//runtime:default_dispatcher",
3839
"//runtime:evaluation_exception",
3940
"//runtime:function_binding",
@@ -140,6 +141,7 @@ java_library(
140141
":cel_value_interpretable",
141142
"//common/values",
142143
"//common/values:cel_value",
144+
"//runtime:cel_value_function_binding",
143145
"//runtime:evaluation_exception",
144146
"//runtime:function_binding",
145147
"//runtime:interpretable",
@@ -153,6 +155,7 @@ java_library(
153155
":cel_value_interpretable",
154156
"//common/values",
155157
"//common/values:cel_value",
158+
"//runtime:cel_value_function_binding",
156159
"//runtime:evaluation_exception",
157160
"//runtime:function_binding",
158161
"//runtime:interpretable",
@@ -166,6 +169,7 @@ java_library(
166169
":cel_value_interpretable",
167170
"//common/values",
168171
"//common/values:cel_value",
172+
"//runtime:cel_value_function_binding",
169173
"//runtime:evaluation_exception",
170174
"//runtime:function_binding",
171175
"//runtime:interpretable",

runtime/src/main/java/dev/cel/runtime/planner/EvalAnd.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static dev.cel.runtime.planner.EvalHelpers.evalNonstrictly;
44

55
import com.google.common.base.Preconditions;
6-
import com.google.common.collect.ImmutableList;
76
import dev.cel.common.values.BoolValue;
87
import dev.cel.common.values.CelValue;
98
import dev.cel.common.values.ErrorValue;
@@ -13,7 +12,8 @@
1312

1413
final class EvalAnd implements CelValueInterpretable {
1514

16-
private final ImmutableList<CelValueInterpretable> args;
15+
@SuppressWarnings("Immutable")
16+
private final CelValueInterpretable[] args;
1717

1818
@Override
1919
public CelValue eval(GlobalResolver resolver) throws CelEvaluationException {
@@ -37,12 +37,12 @@ public CelValue eval(GlobalResolver resolver) throws CelEvaluationException {
3737
return BoolValue.create(true);
3838
}
3939

40-
static EvalAnd create(ImmutableList<CelValueInterpretable> args) {
40+
static EvalAnd create(CelValueInterpretable[] args) {
4141
return new EvalAnd(args);
4242
}
4343

44-
private EvalAnd(ImmutableList<CelValueInterpretable> args) {
45-
Preconditions.checkArgument(args.size() == 2);
44+
private EvalAnd(CelValueInterpretable[] args) {
45+
Preconditions.checkArgument(args.length == 2);
4646
this.args = args;
4747
}
4848
}

runtime/src/main/java/dev/cel/runtime/planner/EvalOr.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static dev.cel.runtime.planner.EvalHelpers.evalNonstrictly;
44

55
import com.google.common.base.Preconditions;
6-
import com.google.common.collect.ImmutableList;
76
import dev.cel.common.values.BoolValue;
87
import dev.cel.common.values.CelValue;
98
import dev.cel.common.values.ErrorValue;
@@ -13,7 +12,8 @@
1312

1413
final class EvalOr implements CelValueInterpretable {
1514

16-
private final ImmutableList<CelValueInterpretable> args;
15+
@SuppressWarnings("Immutable")
16+
private final CelValueInterpretable[] args;
1717

1818
@Override
1919
public CelValue eval(GlobalResolver resolver) throws CelEvaluationException {
@@ -37,12 +37,12 @@ public CelValue eval(GlobalResolver resolver) throws CelEvaluationException {
3737
return BoolValue.create(false);
3838
}
3939

40-
static EvalOr create(ImmutableList<CelValueInterpretable> args) {
40+
static EvalOr create(CelValueInterpretable[] args) {
4141
return new EvalOr(args);
4242
}
4343

44-
private EvalOr(ImmutableList<CelValueInterpretable> args) {
45-
Preconditions.checkArgument(args.size() == 2);
44+
private EvalOr(CelValueInterpretable[] args) {
45+
Preconditions.checkArgument(args.length == 2);
4646
this.args = args;
4747
}
4848
}

0 commit comments

Comments
 (0)