Skip to content

Commit 233430f

Browse files
l46kokcopybara-github
authored andcommitted
Group overloads to a single function to facilitate dynamic dispatch
PiperOrigin-RevId: 852961755
1 parent e966e90 commit 233430f

File tree

10 files changed

+346
-232
lines changed

10 files changed

+346
-232
lines changed

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ java_library(
122122
deps = [
123123
":evaluation_exception",
124124
":evaluation_exception_builder",
125+
":function_binding",
125126
":function_overload",
126127
":function_resolver",
127128
":resolved_overload",
@@ -141,6 +142,7 @@ cel_android_library(
141142
deps = [
142143
":evaluation_exception",
143144
":evaluation_exception_builder",
145+
":function_binding_android",
144146
":function_overload_android",
145147
":function_resolver_android",
146148
":resolved_overload_android",
@@ -609,6 +611,7 @@ java_library(
609611
deps = [
610612
":function_binding",
611613
":runtime_equality",
614+
"//common:operator",
612615
"//common:options",
613616
"//common/annotations",
614617
"//runtime/standard:add",
@@ -666,6 +669,7 @@ cel_android_library(
666669
deps = [
667670
":function_binding_android",
668671
":runtime_equality_android",
672+
"//common:operator_android",
669673
"//common:options",
670674
"//common/annotations",
671675
"//runtime/standard:add_android",
@@ -723,6 +727,7 @@ java_library(
723727
tags = [
724728
],
725729
deps = [
730+
":evaluation_exception",
726731
":function_overload",
727732
"@maven//:com_google_errorprone_error_prone_annotations",
728733
"@maven//:com_google_guava_guava",
@@ -735,6 +740,7 @@ cel_android_library(
735740
tags = [
736741
],
737742
deps = [
743+
":evaluation_exception",
738744
":function_overload_android",
739745
"@maven//:com_google_errorprone_error_prone_annotations",
740746
"@maven_android//:com_google_guava_guava",
@@ -774,7 +780,9 @@ java_library(
774780
],
775781
deps = [
776782
":evaluation_exception",
783+
"//runtime:unknown_attributes",
777784
"@maven//:com_google_errorprone_error_prone_annotations",
785+
"@maven//:com_google_guava_guava",
778786
],
779787
)
780788

@@ -785,7 +793,9 @@ cel_android_library(
785793
],
786794
deps = [
787795
":evaluation_exception",
796+
"//runtime:unknown_attributes_android",
788797
"@maven//:com_google_errorprone_error_prone_annotations",
798+
"@maven_android//:com_google_guava_guava",
789799
],
790800
)
791801

@@ -1173,7 +1183,6 @@ java_library(
11731183
],
11741184
deps = [
11751185
":function_overload",
1176-
":unknown_attributes",
11771186
"//:auto_value",
11781187
"//common/annotations",
11791188
"@maven//:com_google_errorprone_error_prone_annotations",
@@ -1188,7 +1197,6 @@ cel_android_library(
11881197
],
11891198
deps = [
11901199
":function_overload_android",
1191-
":unknown_attributes_android",
11921200
"//:auto_value",
11931201
"//common/annotations",
11941202
"@maven//:com_google_errorprone_error_prone_annotations",

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414

1515
package dev.cel.runtime;
1616

17+
import static com.google.common.base.Preconditions.checkArgument;
18+
19+
import com.google.common.base.Strings;
1720
import com.google.common.collect.ImmutableList;
21+
import com.google.common.collect.ImmutableSet;
1822
import com.google.errorprone.annotations.Immutable;
23+
import java.util.Collection;
1924

2025
/**
2126
* Binding consisting of an overload id, a Java-native argument signature, and an overload
@@ -35,7 +40,6 @@
3540
*
3641
* <p>Examples: string_startsWith_string, mathMax_list, lessThan_money_money
3742
*/
38-
3943
@Immutable
4044
public interface CelFunctionBinding {
4145
String getOverloadId();
@@ -70,4 +74,23 @@ static CelFunctionBinding from(
7074
return new FunctionBindingImpl(
7175
overloadId, ImmutableList.copyOf(argTypes), impl, /* isStrict= */ true);
7276
}
77+
78+
/** See {@link #fromOverloads(String, Collection)}. */
79+
static ImmutableSet<CelFunctionBinding> fromOverloads(
80+
String functionName, CelFunctionBinding... overloadBindings) {
81+
return fromOverloads(functionName, ImmutableList.copyOf(overloadBindings));
82+
}
83+
84+
/**
85+
* Creates a set of bindings for a function, enabling dynamic dispatch logic to select the correct
86+
* overload at runtime based on argument types.
87+
*/
88+
static ImmutableSet<CelFunctionBinding> fromOverloads(
89+
String functionName, Collection<CelFunctionBinding> overloadBindings) {
90+
checkArgument(!Strings.isNullOrEmpty(functionName), "Function name cannot be null or empty");
91+
checkArgument(!overloadBindings.isEmpty(), "You must provide at least one binding.");
92+
93+
return FunctionBindingImpl.groupOverloadsToFunction(
94+
functionName, ImmutableSet.copyOf(overloadBindings));
95+
}
7396
}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
package dev.cel.runtime;
1616

17+
import com.google.common.collect.ImmutableList;
1718
import com.google.errorprone.annotations.Immutable;
19+
import java.util.Map;
1820

1921
/** Interface describing the general signature of all CEL custom function implementations. */
2022
@Immutable
@@ -43,4 +45,39 @@ interface Unary<T> {
4345
interface Binary<T1, T2> {
4446
Object apply(T1 arg1, T2 arg2) throws CelEvaluationException;
4547
}
48+
49+
/**
50+
* Returns true if the overload's expected argument types match the types of the given arguments.
51+
*/
52+
static boolean canHandle(
53+
Object[] arguments, ImmutableList<Class<?>> parameterTypes, boolean isStrict) {
54+
if (parameterTypes.size() != arguments.length) {
55+
return false;
56+
}
57+
for (int i = 0; i < parameterTypes.size(); i++) {
58+
Class<?> paramType = parameterTypes.get(i);
59+
Object arg = arguments[i];
60+
if (arg == null) {
61+
// null can be assigned to messages, maps, and to objects.
62+
// TODO: Remove null special casing
63+
if (paramType != Object.class && !Map.class.isAssignableFrom(paramType)) {
64+
return false;
65+
}
66+
continue;
67+
}
68+
69+
if (arg instanceof Exception || arg instanceof CelUnknownSet) {
70+
// Only non-strict functions can accept errors/unknowns as arguments to a function
71+
if (!isStrict) {
72+
// Skip assignability check below, but continue to validate remaining args
73+
continue;
74+
}
75+
}
76+
77+
if (!paramType.isAssignableFrom(arg.getClass())) {
78+
return false;
79+
}
80+
}
81+
return true;
82+
}
4683
}

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

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.google.errorprone.annotations.Immutable;
2020
import dev.cel.common.annotations.Internal;
2121
import java.util.List;
22-
import java.util.Map;
2322

2423
/**
2524
* Representation of a function overload which has been resolved to a specific set of argument types
@@ -80,41 +79,6 @@ public static CelResolvedOverload of(
8079
* Returns true if the overload's expected argument types match the types of the given arguments.
8180
*/
8281
boolean canHandle(Object[] arguments) {
83-
return canHandle(arguments, getParameterTypes(), isStrict());
84-
}
85-
86-
/**
87-
* Returns true if the overload's expected argument types match the types of the given arguments.
88-
*/
89-
public static boolean canHandle(
90-
Object[] arguments, ImmutableList<Class<?>> parameterTypes, boolean isStrict) {
91-
if (parameterTypes.size() != arguments.length) {
92-
return false;
93-
}
94-
for (int i = 0; i < parameterTypes.size(); i++) {
95-
Class<?> paramType = parameterTypes.get(i);
96-
Object arg = arguments[i];
97-
if (arg == null) {
98-
// null can be assigned to messages, maps, and to objects.
99-
// TODO: Remove null special casing
100-
if (paramType != Object.class && !Map.class.isAssignableFrom(paramType)) {
101-
return false;
102-
}
103-
continue;
104-
}
105-
106-
if (arg instanceof Exception || arg instanceof CelUnknownSet) {
107-
// Only non-strict functions can accept errors/unknowns as arguments to a function
108-
if (!isStrict) {
109-
// Skip assignability check below, but continue to validate remaining args
110-
continue;
111-
}
112-
}
113-
114-
if (!paramType.isAssignableFrom(arg.getClass())) {
115-
return false;
116-
}
117-
}
118-
return true;
82+
return CelFunctionOverload.canHandle(arguments, getParameterTypes(), isStrict());
11983
}
12084
}

0 commit comments

Comments
 (0)