Skip to content

Commit 4cf2b79

Browse files
l46kokcopybara-github
authored andcommitted
Fixed parsed-only evaluation for non-special cased optional functions
PiperOrigin-RevId: 873122213
1 parent a729a20 commit 4cf2b79

2 files changed

Lines changed: 62 additions & 42 deletions

File tree

extensions/src/main/java/dev/cel/extensions/CelOptionalLibrary.java

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717
import static com.google.common.base.Preconditions.checkArgument;
1818
import static com.google.common.base.Preconditions.checkNotNull;
1919
import static com.google.common.collect.ImmutableList.toImmutableList;
20+
import static dev.cel.extensions.CelOptionalLibrary.Function.FIRST;
21+
import static dev.cel.extensions.CelOptionalLibrary.Function.HAS_VALUE;
22+
import static dev.cel.extensions.CelOptionalLibrary.Function.LAST;
23+
import static dev.cel.extensions.CelOptionalLibrary.Function.OPTIONAL_NONE;
24+
import static dev.cel.extensions.CelOptionalLibrary.Function.OPTIONAL_OF;
25+
import static dev.cel.extensions.CelOptionalLibrary.Function.OPTIONAL_OF_NON_ZERO_VALUE;
26+
import static dev.cel.extensions.CelOptionalLibrary.Function.OPTIONAL_UNWRAP;
27+
import static dev.cel.extensions.CelOptionalLibrary.Function.VALUE;
28+
import static dev.cel.runtime.CelFunctionBinding.fromOverloads;
2029

2130
import com.google.common.collect.ImmutableList;
2231
import com.google.common.collect.ImmutableSet;
@@ -97,26 +106,26 @@ public String getFunction() {
97106
0,
98107
ImmutableSet.of(
99108
CelFunctionDecl.newFunctionDeclaration(
100-
Function.OPTIONAL_OF.getFunction(),
109+
OPTIONAL_OF.getFunction(),
101110
CelOverloadDecl.newGlobalOverload(
102111
"optional_of", optionalTypeV, paramTypeV)),
103112
CelFunctionDecl.newFunctionDeclaration(
104-
Function.OPTIONAL_OF_NON_ZERO_VALUE.getFunction(),
113+
OPTIONAL_OF_NON_ZERO_VALUE.getFunction(),
105114
CelOverloadDecl.newGlobalOverload(
106115
"optional_ofNonZeroValue", optionalTypeV, paramTypeV)),
107116
CelFunctionDecl.newFunctionDeclaration(
108-
Function.OPTIONAL_NONE.getFunction(),
117+
OPTIONAL_NONE.getFunction(),
109118
CelOverloadDecl.newGlobalOverload("optional_none", optionalTypeV)),
110119
CelFunctionDecl.newFunctionDeclaration(
111-
Function.VALUE.getFunction(),
120+
VALUE.getFunction(),
112121
CelOverloadDecl.newMemberOverload(
113122
"optional_value", paramTypeV, optionalTypeV)),
114123
CelFunctionDecl.newFunctionDeclaration(
115-
Function.HAS_VALUE.getFunction(),
124+
HAS_VALUE.getFunction(),
116125
CelOverloadDecl.newMemberOverload(
117126
"optional_hasValue", SimpleType.BOOL, optionalTypeV)),
118127
CelFunctionDecl.newFunctionDeclaration(
119-
Function.OPTIONAL_UNWRAP.getFunction(),
128+
OPTIONAL_UNWRAP.getFunction(),
120129
CelOverloadDecl.newGlobalOverload(
121130
"optional_unwrap_list", listTypeV, ListType.create(optionalTypeV))),
122131
// Note: Implementation of "or" and "orValue" are special-cased inside the
@@ -193,15 +202,15 @@ public String getFunction() {
193202
.addAll(version1.functions)
194203
.add(
195204
CelFunctionDecl.newFunctionDeclaration(
196-
Function.FIRST.functionName,
205+
FIRST.functionName,
197206
CelOverloadDecl.newMemberOverload(
198207
"optional_list_first",
199208
"Return the first value in a list if present, otherwise"
200209
+ " optional.none()",
201210
optionalTypeV,
202211
listTypeV)),
203212
CelFunctionDecl.newFunctionDeclaration(
204-
Function.LAST.functionName,
213+
LAST.functionName,
205214
CelOverloadDecl.newMemberOverload(
206215
"optional_list_last",
207216
"Return the last value in a list if present, otherwise"
@@ -295,22 +304,44 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
295304
public void setRuntimeOptions(
296305
CelRuntimeBuilder runtimeBuilder, RuntimeEquality runtimeEquality, CelOptions celOptions) {
297306
runtimeBuilder.addFunctionBindings(
298-
CelFunctionBinding.from("optional_of", Object.class, Optional::of),
299-
CelFunctionBinding.from(
300-
"optional_ofNonZeroValue",
301-
Object.class,
302-
val -> {
303-
if (isZeroValue(val)) {
304-
return Optional.empty();
305-
}
306-
return Optional.of(val);
307-
}),
308-
CelFunctionBinding.from(
309-
"optional_unwrap_list", Collection.class, CelOptionalLibrary::elideOptionalCollection),
310-
CelFunctionBinding.from("optional_none", ImmutableList.of(), val -> Optional.empty()),
311-
CelFunctionBinding.from("optional_value", Object.class, val -> ((Optional<?>) val).get()),
312-
CelFunctionBinding.from(
313-
"optional_hasValue", Object.class, val -> ((Optional<?>) val).isPresent()),
307+
fromOverloads(
308+
OPTIONAL_OF.getFunction(),
309+
CelFunctionBinding.from("optional_of", Object.class, Optional::of)));
310+
runtimeBuilder.addFunctionBindings(
311+
fromOverloads(
312+
OPTIONAL_OF_NON_ZERO_VALUE.getFunction(),
313+
CelFunctionBinding.from(
314+
"optional_ofNonZeroValue",
315+
Object.class,
316+
val -> {
317+
if (isZeroValue(val)) {
318+
return Optional.empty();
319+
}
320+
return Optional.of(val);
321+
})));
322+
runtimeBuilder.addFunctionBindings(
323+
fromOverloads(
324+
OPTIONAL_UNWRAP.getFunction(),
325+
CelFunctionBinding.from(
326+
"optional_unwrap_list",
327+
Collection.class,
328+
CelOptionalLibrary::elideOptionalCollection)));
329+
runtimeBuilder.addFunctionBindings(
330+
fromOverloads(
331+
OPTIONAL_NONE.getFunction(),
332+
CelFunctionBinding.from("optional_none", ImmutableList.of(), val -> Optional.empty())));
333+
runtimeBuilder.addFunctionBindings(
334+
fromOverloads(
335+
VALUE.getFunction(),
336+
CelFunctionBinding.from(
337+
"optional_value", Object.class, val -> ((Optional<?>) val).get())));
338+
runtimeBuilder.addFunctionBindings(
339+
fromOverloads(
340+
HAS_VALUE.getFunction(),
341+
CelFunctionBinding.from(
342+
"optional_hasValue", Object.class, val -> ((Optional<?>) val).isPresent())));
343+
344+
runtimeBuilder.addFunctionBindings(
314345
CelFunctionBinding.from(
315346
"select_optional_field", // This only handles map selection. Proto selection is
316347
// special cased inside the interpreter.
@@ -425,19 +456,18 @@ private static Optional<CelExpr> expandOptMap(
425456
return Optional.of(
426457
exprFactory.newGlobalCall(
427458
Operator.CONDITIONAL.getFunction(),
428-
exprFactory.newReceiverCall(Function.HAS_VALUE.getFunction(), target),
459+
exprFactory.newReceiverCall(HAS_VALUE.getFunction(), target),
429460
exprFactory.newGlobalCall(
430-
Function.OPTIONAL_OF.getFunction(),
461+
OPTIONAL_OF.getFunction(),
431462
exprFactory.fold(
432463
UNUSED_ITER_VAR,
433464
exprFactory.newList(),
434465
varName,
435-
exprFactory.newReceiverCall(
436-
Function.VALUE.getFunction(), exprFactory.copy(target)),
466+
exprFactory.newReceiverCall(VALUE.getFunction(), exprFactory.copy(target)),
437467
exprFactory.newBoolLiteral(true),
438468
exprFactory.newIdentifier(varName),
439469
mapExpr)),
440-
exprFactory.newGlobalCall(Function.OPTIONAL_NONE.getFunction())));
470+
exprFactory.newGlobalCall(OPTIONAL_NONE.getFunction())));
441471
}
442472

443473
private static Optional<CelExpr> expandOptFlatMap(
@@ -460,16 +490,16 @@ private static Optional<CelExpr> expandOptFlatMap(
460490
return Optional.of(
461491
exprFactory.newGlobalCall(
462492
Operator.CONDITIONAL.getFunction(),
463-
exprFactory.newReceiverCall(Function.HAS_VALUE.getFunction(), target),
493+
exprFactory.newReceiverCall(HAS_VALUE.getFunction(), target),
464494
exprFactory.fold(
465495
UNUSED_ITER_VAR,
466496
exprFactory.newList(),
467497
varName,
468-
exprFactory.newReceiverCall(Function.VALUE.getFunction(), exprFactory.copy(target)),
498+
exprFactory.newReceiverCall(VALUE.getFunction(), exprFactory.copy(target)),
469499
exprFactory.newBoolLiteral(true),
470500
exprFactory.newIdentifier(varName),
471501
mapExpr),
472-
exprFactory.newGlobalCall(Function.OPTIONAL_NONE.getFunction())));
502+
exprFactory.newGlobalCall(OPTIONAL_NONE.getFunction())));
473503
}
474504

475505
private static Object indexOptionalMap(

runtime/src/test/java/dev/cel/runtime/PlannerInterpreterTest.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,6 @@ public void unknownResultSet() {
8383
skipBaselineVerification();
8484
}
8585

86-
@Override
87-
public void optional() {
88-
if (isParseOnly) {
89-
// TODO: Fix for parsed-only mode.
90-
skipBaselineVerification();
91-
} else {
92-
super.optional();
93-
}
94-
}
95-
9686
@Override
9787
public void optional_errors() {
9888
if (isParseOnly) {

0 commit comments

Comments
 (0)