Skip to content

Commit c83194d

Browse files
l46kokcopybara-github
authored andcommitted
Internally accumulate unknowns to a mutable list
PiperOrigin-RevId: 784636492
1 parent a98f8ad commit c83194d

11 files changed

Lines changed: 207 additions & 80 deletions
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License aj
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.runtime;
16+
17+
import com.google.errorprone.annotations.CanIgnoreReturnValue;
18+
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.Collection;
21+
import java.util.List;
22+
23+
/**
24+
* An internal representation used for fast accumulation of unknown expr IDs and attributes. For
25+
* safety, this object should never be returned as an evaluated result and instead be adapted into
26+
* an immutable CelUnknownSet.
27+
*/
28+
final class AccumulatedUnknowns {
29+
30+
private final List<Long> exprIds;
31+
private final List<CelAttribute> attributes;
32+
33+
List<Long> exprIds() {
34+
return exprIds;
35+
}
36+
37+
List<CelAttribute> attributes() {
38+
return attributes;
39+
}
40+
41+
@CanIgnoreReturnValue
42+
AccumulatedUnknowns merge(AccumulatedUnknowns arg) {
43+
this.exprIds.addAll(arg.exprIds);
44+
this.attributes.addAll(arg.attributes);
45+
return this;
46+
}
47+
48+
static AccumulatedUnknowns create(Long... ids) {
49+
return create(Arrays.asList(ids));
50+
}
51+
52+
static AccumulatedUnknowns create(Collection<Long> ids) {
53+
return create(ids, new ArrayList<>());
54+
}
55+
56+
static AccumulatedUnknowns create(Collection<Long> exprIds, Collection<CelAttribute> attributes) {
57+
return new AccumulatedUnknowns(new ArrayList<>(exprIds), new ArrayList<>(attributes));
58+
}
59+
60+
private AccumulatedUnknowns(List<Long> exprIds, List<CelAttribute> attributes) {
61+
this.exprIds = exprIds;
62+
this.attributes = attributes;
63+
}
64+
}

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ java_library(
271271
],
272272
exports = [":base"],
273273
deps = [
274+
":accumulated_unknowns",
274275
":base",
275276
":concatenated_list_view",
276277
":dispatcher",
@@ -306,6 +307,7 @@ cel_android_library(
306307
srcs = INTERPRETER_SOURCES,
307308
visibility = ["//visibility:private"],
308309
deps = [
310+
":accumulated_unknowns_android",
309311
":base_android",
310312
":concatenated_list_view",
311313
":dispatcher_android",
@@ -849,15 +851,13 @@ java_library(
849851
":cel_value_runtime_type_provider",
850852
":dispatcher",
851853
":evaluation_exception",
852-
":evaluation_listener",
853854
":function_binding",
854855
":function_resolver",
855856
":interpretable",
856857
":interpreter",
857858
":lite_runtime",
858859
":runtime_equality",
859860
":runtime_helpers",
860-
":standard_functions",
861861
":type_resolver",
862862
"//:auto_value",
863863
"//common:cel_ast",
@@ -880,15 +880,13 @@ cel_android_library(
880880
":cel_value_runtime_type_provider_android",
881881
":dispatcher_android",
882882
":evaluation_exception",
883-
":evaluation_listener_android",
884883
":function_binding_android",
885884
":function_resolver",
886885
":interpretable_android",
887886
":interpreter_android",
888887
":lite_runtime_android",
889888
":runtime_equality_android",
890889
":runtime_helpers_android",
891-
":standard_functions_android",
892890
":type_resolver_android",
893891
"//:auto_value",
894892
"//common:cel_ast_android",
@@ -1034,6 +1032,7 @@ java_library(
10341032
tags = [
10351033
],
10361034
deps = [
1035+
":accumulated_unknowns",
10371036
":evaluation_exception",
10381037
":unknown_attributes",
10391038
"//common/annotations",
@@ -1047,6 +1046,7 @@ cel_android_library(
10471046
srcs = ["InterpreterUtil.java"],
10481047
visibility = ["//visibility:private"],
10491048
deps = [
1049+
":accumulated_unknowns_android",
10501050
":evaluation_exception",
10511051
":unknown_attributes_android",
10521052
"//common/annotations",
@@ -1105,3 +1105,23 @@ java_library(
11051105
# used_by_android
11061106
visibility = ["//visibility:private"],
11071107
)
1108+
1109+
java_library(
1110+
name = "accumulated_unknowns",
1111+
srcs = ["AccumulatedUnknowns.java"],
1112+
visibility = ["//visibility:private"],
1113+
deps = [
1114+
":unknown_attributes",
1115+
"@maven//:com_google_errorprone_error_prone_annotations",
1116+
],
1117+
)
1118+
1119+
cel_android_library(
1120+
name = "accumulated_unknowns_android",
1121+
srcs = ["AccumulatedUnknowns.java"],
1122+
visibility = ["//visibility:private"],
1123+
deps = [
1124+
":unknown_attributes_android",
1125+
"@maven//:com_google_errorprone_error_prone_annotations",
1126+
],
1127+
)

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class CallArgumentChecker {
3232
private final ArrayList<Long> exprIds;
3333
private final RuntimeUnknownResolver resolver;
3434
private final boolean acceptPartial;
35-
private Optional<CelUnknownSet> unknowns;
35+
private Optional<AccumulatedUnknowns> unknowns;
3636

3737
private CallArgumentChecker(RuntimeUnknownResolver resolver, boolean acceptPartial) {
3838
this.exprIds = new ArrayList<>();
@@ -61,29 +61,30 @@ static CallArgumentChecker createAcceptingPartial(RuntimeUnknownResolver resolve
6161
return new CallArgumentChecker(resolver, true);
6262
}
6363

64-
private static Optional<CelUnknownSet> mergeOptionalUnknowns(
65-
Optional<CelUnknownSet> lhs, Optional<CelUnknownSet> rhs) {
64+
private static Optional<AccumulatedUnknowns> mergeOptionalUnknowns(
65+
Optional<AccumulatedUnknowns> lhs, Optional<AccumulatedUnknowns> rhs) {
6666
return lhs.isPresent() ? rhs.isPresent() ? Optional.of(lhs.get().merge(rhs.get())) : lhs : rhs;
6767
}
6868

6969
/** Determine if the call argument is unknown and accumulate if so. */
7070
void checkArg(DefaultInterpreter.IntermediateResult arg) {
7171
// Handle attribute tracked unknowns.
72-
Optional<CelUnknownSet> argUnknowns = maybeUnknownFromArg(arg);
72+
Optional<AccumulatedUnknowns> argUnknowns = maybeUnknownFromArg(arg);
7373
unknowns = mergeOptionalUnknowns(unknowns, argUnknowns);
7474

7575
// support for ExprValue unknowns.
76-
if (InterpreterUtil.isUnknown(arg.value())) {
77-
CelUnknownSet unknownSet = (CelUnknownSet) arg.value();
78-
exprIds.addAll(unknownSet.unknownExprIds());
76+
if (InterpreterUtil.isAccumulatedUnknowns(arg.value())) {
77+
AccumulatedUnknowns unknownSet = (AccumulatedUnknowns) arg.value();
78+
exprIds.addAll(unknownSet.exprIds());
7979
}
8080
}
8181

82-
private Optional<CelUnknownSet> maybeUnknownFromArg(DefaultInterpreter.IntermediateResult arg) {
83-
if (arg.value() instanceof CelUnknownSet) {
84-
CelUnknownSet celUnknownSet = (CelUnknownSet) arg.value();
82+
private Optional<AccumulatedUnknowns> maybeUnknownFromArg(
83+
DefaultInterpreter.IntermediateResult arg) {
84+
if (arg.value() instanceof AccumulatedUnknowns) {
85+
AccumulatedUnknowns celUnknownSet = (AccumulatedUnknowns) arg.value();
8586
if (!celUnknownSet.attributes().isEmpty()) {
86-
return Optional.of((CelUnknownSet) arg.value());
87+
return Optional.of((AccumulatedUnknowns) arg.value());
8788
}
8889
}
8990
if (!acceptPartial) {
@@ -99,7 +100,7 @@ Optional<Object> maybeUnknowns() {
99100
}
100101

101102
if (!exprIds.isEmpty()) {
102-
return Optional.of(CelUnknownSet.create(exprIds));
103+
return Optional.of(AccumulatedUnknowns.create(exprIds));
103104
}
104105

105106
return Optional.empty();

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,4 @@ public interface CelEvaluationListener {
3333
* @param evaluatedResult Evaluated result.
3434
*/
3535
void callback(CelExpr expr, Object evaluatedResult);
36-
37-
/** Construct a listener that does nothing. */
38-
static CelEvaluationListener noOpListener() {
39-
return (arg1, arg2) -> {};
40-
}
4136
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ static CelUnknownSet create(Iterable<Long> unknownExprIds) {
5959
return create(ImmutableSet.of(), ImmutableSet.copyOf(unknownExprIds));
6060
}
6161

62-
private static CelUnknownSet create(
62+
static CelUnknownSet create(
6363
ImmutableSet<CelAttribute> attributes, ImmutableSet<Long> unknownExprIds) {
6464
return new AutoValue_CelUnknownSet(attributes, unknownExprIds);
6565
}

0 commit comments

Comments
 (0)