Skip to content

Commit b32918c

Browse files
l46kokcopybara-github
authored andcommitted
Add iteration limit control to planned comprehensions
PiperOrigin-RevId: 845589739
1 parent 40d81de commit b32918c

36 files changed

Lines changed: 726 additions & 350 deletions

common/exceptions/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,9 @@ java_library(
4040
# used_by_android
4141
exports = ["//common/src/main/java/dev/cel/common/exceptions:invalid_argument"],
4242
)
43+
44+
java_library(
45+
name = "iteration_budget_exceeded",
46+
# used_by_android
47+
exports = ["//common/src/main/java/dev/cel/common/exceptions:iteration_budget_exceeded"],
48+
)

common/src/main/java/dev/cel/common/exceptions/BUILD.bazel

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,16 @@ java_library(
8585
"//common/annotations",
8686
],
8787
)
88+
89+
java_library(
90+
name = "iteration_budget_exceeded",
91+
srcs = ["CelIterationLimitExceededException.java"],
92+
# used_by_android
93+
tags = [
94+
],
95+
deps = [
96+
"//common:error_codes",
97+
"//common:runtime_exception",
98+
"//common/annotations",
99+
],
100+
)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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 at
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.common.exceptions;
16+
17+
import dev.cel.common.CelErrorCode;
18+
import dev.cel.common.CelRuntimeException;
19+
import dev.cel.common.annotations.Internal;
20+
import java.util.Locale;
21+
22+
/** Indicates that the iteration budget for a comprehension has been exceeded. */
23+
@Internal
24+
public final class CelIterationLimitExceededException extends CelRuntimeException {
25+
26+
public CelIterationLimitExceededException(int budget) {
27+
super(
28+
String.format(Locale.US, "Iteration budget exceeded: %d", budget),
29+
CelErrorCode.ITERATION_BUDGET_EXCEEDED);
30+
}
31+
}

runtime/BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,11 @@ java_library(
255255
visibility = ["//:internal"],
256256
exports = ["//runtime/src/main/java/dev/cel/runtime:metadata"],
257257
)
258+
259+
java_library(
260+
name = "concatenated_list_view",
261+
visibility = ["//:internal"],
262+
exports = [
263+
"//runtime/src/main/java/dev/cel/runtime:concatenated_list_view",
264+
],
265+
)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
5-
// You may obtain a copy of the License aj
5+
// You may obtain a copy of the License at
66
//
77
// https://www.apache.org/licenses/LICENSE-2.0
88
//

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,9 @@ java_library(
11421142
name = "concatenated_list_view",
11431143
srcs = ["ConcatenatedListView.java"],
11441144
# used_by_android
1145-
visibility = ["//visibility:private"],
1145+
tags = [
1146+
],
1147+
deps = ["//common/annotations"],
11461148
)
11471149

11481150
java_library(

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// Licensed under the Apache License, Version 2.0 (the "License");
44
// you may not use this file except in compliance with the License.
5-
// You may obtain a copy of the License aj
5+
// You may obtain a copy of the License at
66
//
77
// https://www.apache.org/licenses/LICENSE-2.0
88
//
@@ -14,6 +14,7 @@
1414

1515
package dev.cel.runtime;
1616

17+
import dev.cel.common.annotations.Internal;
1718
import java.util.AbstractList;
1819
import java.util.ArrayList;
1920
import java.util.Collection;
@@ -27,16 +28,20 @@
2728
* comprehensions that dispatch `add_list` to concat N lists together).
2829
*
2930
* <p>This does not support any of the standard list operations from {@link java.util.List}.
31+
*
32+
33+
* <p>CEL Library Internals. Do Not Use.
3034
*/
31-
final class ConcatenatedListView<E> extends AbstractList<E> {
35+
@Internal
36+
public final class ConcatenatedListView<E> extends AbstractList<E> {
3237
private final List<List<? extends E>> sourceLists;
3338
private int totalSize = 0;
3439

3540
ConcatenatedListView() {
3641
this.sourceLists = new ArrayList<>();
3742
}
3843

39-
ConcatenatedListView(Collection<? extends E> collection) {
44+
public ConcatenatedListView(Collection<? extends E> collection) {
4045
this();
4146
addAll(collection);
4247
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
/** Represents a resolvable symbol or path (such as a variable or a field selection). */
2121
@Immutable
2222
interface Attribute {
23-
Object resolve(GlobalResolver ctx);
23+
Object resolve(GlobalResolver ctx, ExecutionFrame frame);
2424

2525
Attribute addQualifier(Qualifier qualifier);
2626
}

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

Lines changed: 71 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ java_library(
2222
":eval_create_list",
2323
":eval_create_map",
2424
":eval_create_struct",
25+
":eval_fold",
2526
":eval_or",
27+
":eval_test_only",
2628
":eval_unary",
2729
":eval_var_args_call",
2830
":eval_zero_arity",
@@ -35,6 +37,7 @@ java_library(
3537
"//common:cel_ast",
3638
"//common:container",
3739
"//common:operator",
40+
"//common:options",
3841
"//common/annotations",
3942
"//common/ast",
4043
"//common/types",
@@ -57,11 +60,14 @@ java_library(
5760
srcs = ["PlannedProgram.java"],
5861
deps = [
5962
":error_metadata",
63+
":execution_frame",
6064
":planned_interpretable",
6165
":strict_error_exception",
6266
"//:auto_value",
67+
"//common:options",
6368
"//common:runtime_exception",
6469
"//common/values",
70+
"//runtime",
6571
"//runtime:activation",
6672
"//runtime:evaluation_exception",
6773
"//runtime:evaluation_exception_builder",
@@ -76,11 +82,10 @@ java_library(
7682
name = "eval_const",
7783
srcs = ["EvalConstant.java"],
7884
deps = [
85+
":execution_frame",
7986
":planned_interpretable",
8087
"//common/values",
8188
"//common/values:cel_byte_string",
82-
"//runtime:evaluation_listener",
83-
"//runtime:function_resolver",
8489
"//runtime:interpretable",
8590
"@maven//:com_google_errorprone_error_prone_annotations",
8691
"@maven//:com_google_guava_guava",
@@ -109,6 +114,7 @@ java_library(
109114
],
110115
deps = [
111116
":eval_helpers",
117+
":execution_frame",
112118
":planned_interpretable",
113119
":qualifier",
114120
"//common:container",
@@ -131,6 +137,16 @@ java_library(
131137
],
132138
)
133139

140+
java_library(
141+
name = "presence_test_qualifier",
142+
srcs = ["PresenceTestQualifier.java"],
143+
deps = [
144+
":attribute",
145+
":qualifier",
146+
"//common/values",
147+
],
148+
)
149+
134150
java_library(
135151
name = "string_qualifier",
136152
srcs = ["StringQualifier.java"],
@@ -146,24 +162,36 @@ java_library(
146162
srcs = ["EvalAttribute.java"],
147163
deps = [
148164
":attribute",
165+
":execution_frame",
149166
":interpretable_attribute",
150167
":qualifier",
151-
"//runtime:evaluation_listener",
152-
"//runtime:function_resolver",
153168
"//runtime:interpretable",
154169
"@maven//:com_google_errorprone_error_prone_annotations",
155170
"@maven//:com_google_guava_guava",
156171
],
157172
)
158173

174+
java_library(
175+
name = "eval_test_only",
176+
srcs = ["EvalTestOnly.java"],
177+
deps = [
178+
":execution_frame",
179+
":interpretable_attribute",
180+
":presence_test_qualifier",
181+
":qualifier",
182+
"//runtime:evaluation_exception",
183+
"//runtime:interpretable",
184+
"@maven//:com_google_errorprone_error_prone_annotations",
185+
],
186+
)
187+
159188
java_library(
160189
name = "eval_zero_arity",
161190
srcs = ["EvalZeroArity.java"],
162191
deps = [
192+
":execution_frame",
163193
":planned_interpretable",
164194
"//runtime:evaluation_exception",
165-
"//runtime:evaluation_listener",
166-
"//runtime:function_resolver",
167195
"//runtime:interpretable",
168196
"//runtime:resolved_overload",
169197
],
@@ -174,10 +202,9 @@ java_library(
174202
srcs = ["EvalUnary.java"],
175203
deps = [
176204
":eval_helpers",
205+
":execution_frame",
177206
":planned_interpretable",
178207
"//runtime:evaluation_exception",
179-
"//runtime:evaluation_listener",
180-
"//runtime:function_resolver",
181208
"//runtime:interpretable",
182209
"//runtime:resolved_overload",
183210
],
@@ -188,10 +215,9 @@ java_library(
188215
srcs = ["EvalVarArgsCall.java"],
189216
deps = [
190217
":eval_helpers",
218+
":execution_frame",
191219
":planned_interpretable",
192220
"//runtime:evaluation_exception",
193-
"//runtime:evaluation_listener",
194-
"//runtime:function_resolver",
195221
"//runtime:interpretable",
196222
"//runtime:resolved_overload",
197223
],
@@ -202,10 +228,9 @@ java_library(
202228
srcs = ["EvalOr.java"],
203229
deps = [
204230
":eval_helpers",
231+
":execution_frame",
205232
":planned_interpretable",
206233
"//common/values",
207-
"//runtime:evaluation_listener",
208-
"//runtime:function_resolver",
209234
"//runtime:interpretable",
210235
"@maven//:com_google_guava_guava",
211236
],
@@ -216,10 +241,9 @@ java_library(
216241
srcs = ["EvalAnd.java"],
217242
deps = [
218243
":eval_helpers",
244+
":execution_frame",
219245
":planned_interpretable",
220246
"//common/values",
221-
"//runtime:evaluation_listener",
222-
"//runtime:function_resolver",
223247
"//runtime:interpretable",
224248
"@maven//:com_google_guava_guava",
225249
],
@@ -229,10 +253,9 @@ java_library(
229253
name = "eval_conditional",
230254
srcs = ["EvalConditional.java"],
231255
deps = [
256+
":execution_frame",
232257
":planned_interpretable",
233258
"//runtime:evaluation_exception",
234-
"//runtime:evaluation_listener",
235-
"//runtime:function_resolver",
236259
"//runtime:interpretable",
237260
"@maven//:com_google_guava_guava",
238261
],
@@ -242,13 +265,12 @@ java_library(
242265
name = "eval_create_struct",
243266
srcs = ["EvalCreateStruct.java"],
244267
deps = [
268+
":execution_frame",
245269
":planned_interpretable",
246270
"//common/types",
247271
"//common/values",
248272
"//common/values:cel_value_provider",
249273
"//runtime:evaluation_exception",
250-
"//runtime:evaluation_listener",
251-
"//runtime:function_resolver",
252274
"//runtime:interpretable",
253275
"@maven//:com_google_errorprone_error_prone_annotations",
254276
"@maven//:com_google_guava_guava",
@@ -259,10 +281,9 @@ java_library(
259281
name = "eval_create_list",
260282
srcs = ["EvalCreateList.java"],
261283
deps = [
284+
":execution_frame",
262285
":planned_interpretable",
263286
"//runtime:evaluation_exception",
264-
"//runtime:evaluation_listener",
265-
"//runtime:function_resolver",
266287
"//runtime:interpretable",
267288
"@maven//:com_google_errorprone_error_prone_annotations",
268289
"@maven//:com_google_guava_guava",
@@ -273,20 +294,46 @@ java_library(
273294
name = "eval_create_map",
274295
srcs = ["EvalCreateMap.java"],
275296
deps = [
297+
":execution_frame",
276298
":planned_interpretable",
277299
"//runtime:evaluation_exception",
278-
"//runtime:evaluation_listener",
279-
"//runtime:function_resolver",
280300
"//runtime:interpretable",
281301
"@maven//:com_google_errorprone_error_prone_annotations",
282302
"@maven//:com_google_guava_guava",
283303
],
284304
)
285305

306+
java_library(
307+
name = "eval_fold",
308+
srcs = ["EvalFold.java"],
309+
deps = [
310+
":execution_frame",
311+
":planned_interpretable",
312+
"//runtime:concatenated_list_view",
313+
"//runtime:evaluation_exception",
314+
"//runtime:interpretable",
315+
"@maven//:com_google_errorprone_error_prone_annotations",
316+
"@maven//:com_google_guava_guava",
317+
"@maven//:org_jspecify_jspecify",
318+
],
319+
)
320+
321+
java_library(
322+
name = "execution_frame",
323+
srcs = ["ExecutionFrame.java"],
324+
deps = [
325+
"//common:options",
326+
"//common/exceptions:iteration_budget_exceeded",
327+
"//runtime:interpretable",
328+
"@maven//:org_jspecify_jspecify",
329+
],
330+
)
331+
286332
java_library(
287333
name = "eval_helpers",
288334
srcs = ["EvalHelpers.java"],
289335
deps = [
336+
":execution_frame",
290337
":planned_interpretable",
291338
":strict_error_exception",
292339
"//common:error_codes",
@@ -319,6 +366,8 @@ java_library(
319366
name = "planned_interpretable",
320367
srcs = ["PlannedInterpretable.java"],
321368
deps = [
369+
":execution_frame",
370+
"//runtime:evaluation_exception",
322371
"//runtime:interpretable",
323372
"@maven//:com_google_errorprone_error_prone_annotations",
324373
],

0 commit comments

Comments
 (0)