-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy pathCelResolvedOverload.java
More file actions
132 lines (116 loc) · 4.71 KB
/
Copy pathCelResolvedOverload.java
File metadata and controls
132 lines (116 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package dev.cel.runtime;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.Immutable;
import dev.cel.common.annotations.Internal;
import dev.cel.common.exceptions.CelOverloadNotFoundException;
import java.util.List;
/**
* Representation of a function overload which has been resolved to a specific set of argument types
* and a function definition.
*/
@AutoValue
@Immutable
@Internal
public abstract class CelResolvedOverload {
/** The base function name. */
public abstract String getFunctionName();
/** The overload id of the function. */
public abstract String getOverloadId();
/** The types of the function parameters. */
public abstract ImmutableList<Class<?>> getParameterTypes();
/* Denotes whether an overload is strict.
*
* <p>A strict function will not be invoked if any of its arguments are an error or unknown value.
* The runtime automatically propagates the error or unknown instead.
*
* <p>A non-strict function will be invoked even if its arguments contain errors or unknowns. The
* function's implementation is then responsible for handling these values. This is primarily used
* for short-circuiting logical operators (e.g., `||`, `&&`) and comprehension's
* internal @not_strictly_false function.
*
* <p>In a vast majority of cases, this should be set to true.
*/
public abstract boolean isStrict();
/** The function definition. */
public abstract CelFunctionOverload getDefinition();
abstract OptimizedFunctionOverload getOptimizedDefinition();
public Object invoke(Object[] args) throws CelEvaluationException {
// Note: canHandle check is handled separately in DynamicDispatchOverload
if (isDynamicDispatch()
|| CelFunctionOverload.canHandle(args, getParameterTypes(), isStrict())) {
return getDefinition().apply(args);
}
throw new CelOverloadNotFoundException(getFunctionName(), ImmutableList.of(getOverloadId()));
}
public Object invoke(Object arg) throws CelEvaluationException {
if (isDynamicDispatch()
|| CelFunctionOverload.canHandle(arg, getParameterTypes(), isStrict())) {
return getOptimizedDefinition().apply(arg);
}
throw new CelOverloadNotFoundException(getFunctionName(), ImmutableList.of(getOverloadId()));
}
public Object invoke(Object arg1, Object arg2) throws CelEvaluationException {
if (isDynamicDispatch()
|| CelFunctionOverload.canHandle(arg1, arg2, getParameterTypes(), isStrict())) {
return getOptimizedDefinition().apply(arg1, arg2);
}
throw new CelOverloadNotFoundException(getFunctionName(), ImmutableList.of(getOverloadId()));
}
/**
* Creates a new resolved overload from the given function name, overload id, parameter types, and
* definition.
*/
public static CelResolvedOverload of(
String functionName,
String overloadId,
CelFunctionOverload definition,
boolean isStrict,
Class<?>... parameterTypes) {
return of(functionName, overloadId, definition, isStrict, ImmutableList.copyOf(parameterTypes));
}
/**
* Creates a new resolved overload from the given function name, overload id, parameter types, and
* definition.
*/
public static CelResolvedOverload of(
String functionName,
String overloadId,
CelFunctionOverload definition,
boolean isStrict,
List<Class<?>> parameterTypes) {
OptimizedFunctionOverload optimizedDef =
(definition instanceof OptimizedFunctionOverload)
? (OptimizedFunctionOverload) definition
: definition::apply;
return new AutoValue_CelResolvedOverload(
functionName,
overloadId,
ImmutableList.copyOf(parameterTypes),
isStrict,
definition,
optimizedDef);
}
/**
* Returns true if the overload's expected argument types match the types of the given arguments.
*/
boolean canHandle(Object[] arguments) {
return CelFunctionOverload.canHandle(arguments, getParameterTypes(), isStrict());
}
private boolean isDynamicDispatch() {
return getDefinition() instanceof FunctionBindingImpl.DynamicDispatchOverload;
}
}