Skip to content

Commit 9452eab

Browse files
l46kokcopybara-github
authored andcommitted
Add optional.elide
PiperOrigin-RevId: 666904662
1 parent dae82c6 commit 9452eab

18 files changed

Lines changed: 880 additions & 1197 deletions

File tree

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static com.google.common.base.Preconditions.checkArgument;
1818
import static com.google.common.base.Preconditions.checkNotNull;
19+
import static com.google.common.collect.ImmutableList.toImmutableList;
1920

2021
import com.google.common.collect.ImmutableList;
2122
import com.google.common.primitives.UnsignedLong;
@@ -58,6 +59,7 @@ public enum Function {
5859
HAS_VALUE("hasValue"),
5960
OPTIONAL_NONE("optional.none"),
6061
OPTIONAL_OF("optional.of"),
62+
OPTIONAL_ELIDE("optional.elide"),
6163
OPTIONAL_OF_NON_ZERO_VALUE("optional.ofNonZeroValue"),
6264
OR("or"),
6365
OR_VALUE("orValue");
@@ -117,6 +119,10 @@ public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
117119
CelFunctionDecl.newFunctionDeclaration(
118120
Function.HAS_VALUE.getFunction(),
119121
CelOverloadDecl.newMemberOverload("optional_hasValue", SimpleType.BOOL, optionalTypeV)),
122+
CelFunctionDecl.newFunctionDeclaration(
123+
Function.OPTIONAL_ELIDE.getFunction(),
124+
CelOverloadDecl.newGlobalOverload(
125+
"optional_elide_list", listTypeV, ListType.create(optionalTypeV))),
120126
// Note: Implementation of "or" and "orValue" are special-cased inside the interpreter.
121127
// Hence, their bindings are not provided here.
122128
CelFunctionDecl.newFunctionDeclaration(
@@ -165,6 +171,7 @@ public void setCheckerOptions(CelCheckerBuilder checkerBuilder) {
165171
}
166172

167173
@Override
174+
@SuppressWarnings("unchecked")
168175
public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
169176
runtimeBuilder.addFunctionBindings(
170177
CelRuntime.CelFunctionBinding.from("optional_of", Object.class, Optional::of),
@@ -177,6 +184,8 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
177184
}
178185
return Optional.of(val);
179186
}),
187+
CelRuntime.CelFunctionBinding.from(
188+
"optional_elide_list", Collection.class, CelOptionalLibrary::elideOptionalCollection),
180189
CelRuntime.CelFunctionBinding.from(
181190
"optional_none", ImmutableList.of(), val -> Optional.empty()),
182191
CelRuntime.CelFunctionBinding.from(
@@ -185,6 +194,10 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
185194
"optional_hasValue", Object.class, val -> ((Optional<?>) val).isPresent()));
186195
}
187196

197+
private static ImmutableList<Object> elideOptionalCollection(Collection<Optional<Object>> list) {
198+
return list.stream().filter(Optional::isPresent).map(Optional::get).collect(toImmutableList());
199+
}
200+
188201
// TODO: This will need to be adapted to handle an intermediate CelValue instead,
189202
// akin to Zeroer interface in Go. Currently, it is unable to handle zero-values for a
190203
// user-defined custom type.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ RUNTIME_SOURCES = [
135135
"CelRuntimeLegacyImpl.java",
136136
"CelRuntimeLibrary.java",
137137
"CelVariableResolver.java",
138+
"HierarchicalVariableResolver.java",
138139
"UnknownContext.java",
139140
]
140141

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@ public interface CelVariableResolver {
5050
*/
5151
static CelVariableResolver hierarchicalVariableResolver(
5252
CelVariableResolver primary, CelVariableResolver secondary) {
53-
return (name) -> {
54-
Optional<Object> value = primary.find(name);
55-
return value.isPresent() ? value : secondary.find(name);
56-
};
53+
return HierarchicalVariableResolver.newInstance(primary, secondary);
5754
}
5855
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2024 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.runtime;
16+
17+
import java.util.Optional;
18+
19+
final class HierarchicalVariableResolver implements CelVariableResolver {
20+
21+
private final CelVariableResolver primary;
22+
private final CelVariableResolver secondary;
23+
24+
@Override
25+
public Optional<Object> find(String name) {
26+
Optional<Object> value = primary.find(name);
27+
return value.isPresent() ? value : secondary.find(name);
28+
}
29+
30+
@Override
31+
public String toString() {
32+
return secondary + " +> " + primary;
33+
}
34+
35+
static HierarchicalVariableResolver newInstance(
36+
CelVariableResolver primary, CelVariableResolver secondary) {
37+
return new HierarchicalVariableResolver(primary, secondary);
38+
}
39+
40+
private HierarchicalVariableResolver(CelVariableResolver primary, CelVariableResolver secondary) {
41+
this.primary = primary;
42+
this.secondary = secondary;
43+
}
44+
}

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,9 @@ java_library(
6262
],
6363
deps = [
6464
# "//java/com/google/testing/testsize:annotations",
65-
"//common:options",
6665
"//testing:base_interpreter_test",
67-
"//testing:eval",
68-
"//testing:sync",
6966
"@maven//:junit_junit",
67+
"@maven//:com_google_testparameterinjector_test_parameter_injector",
7068
],
7169
)
7270

@@ -78,11 +76,9 @@ java_library(
7876
],
7977
deps = [
8078
# "//java/com/google/testing/testsize:annotations",
81-
"//common:options",
8279
"//testing:base_interpreter_test",
83-
"//testing:cel_value_sync",
84-
"//testing:eval",
8580
"@maven//:junit_junit",
81+
"@maven//:com_google_testparameterinjector_test_parameter_injector",
8682
],
8783
)
8884

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

Lines changed: 7 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,60 +14,20 @@
1414

1515
package dev.cel.runtime;
1616

17+
import com.google.testing.junit.testparameterinjector.TestParameter;
18+
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
1719
// import com.google.testing.testsize.MediumTest;
18-
import dev.cel.common.CelOptions;
1920
import dev.cel.testing.BaseInterpreterTest;
20-
import dev.cel.testing.Eval;
21-
import dev.cel.testing.EvalCelValueSync;
22-
import java.util.ArrayList;
23-
import java.util.Arrays;
24-
import java.util.List;
2521
import org.junit.runner.RunWith;
26-
import org.junit.runners.Parameterized;
27-
import org.junit.runners.Parameterized.Parameters;
2822

2923
/** Tests for {@link Interpreter} and related functionality using {@code CelValue}. */
3024
// @MediumTest
31-
@RunWith(Parameterized.class)
25+
@RunWith(TestParameterInjector.class)
3226
public class CelValueInterpreterTest extends BaseInterpreterTest {
3327

34-
private static final CelOptions SIGNED_UINT_TEST_OPTIONS =
35-
CelOptions.current()
36-
.enableTimestampEpoch(true)
37-
.enableHeterogeneousNumericComparisons(true)
38-
.enableCelValue(true)
39-
.comprehensionMaxIterations(1_000)
40-
.build();
41-
42-
public CelValueInterpreterTest(boolean declareWithCelType, Eval eval) {
43-
super(declareWithCelType, eval);
44-
}
45-
46-
@Parameters
47-
public static List<Object[]> testData() {
48-
return new ArrayList<>(
49-
Arrays.asList(
50-
new Object[][] {
51-
// SYNC_PROTO_TYPE
52-
{
53-
/* declareWithCelType= */ false,
54-
new EvalCelValueSync(TEST_FILE_DESCRIPTORS, TEST_OPTIONS)
55-
},
56-
// SYNC_PROTO_TYPE_SIGNED_UINT
57-
{
58-
/* declareWithCelType= */ false,
59-
new EvalCelValueSync(TEST_FILE_DESCRIPTORS, SIGNED_UINT_TEST_OPTIONS)
60-
},
61-
// SYNC_CEL_TYPE
62-
{
63-
/* declareWithCelType= */ true,
64-
new EvalCelValueSync(TEST_FILE_DESCRIPTORS, TEST_OPTIONS)
65-
},
66-
// SYNC_CEL_TYPE_SIGNED_UINT
67-
{
68-
/* declareWithCelType= */ true,
69-
new EvalCelValueSync(TEST_FILE_DESCRIPTORS, SIGNED_UINT_TEST_OPTIONS)
70-
},
71-
}));
28+
public CelValueInterpreterTest(@TestParameter InterpreterTestOption testOption) {
29+
super(
30+
testOption.celOptions.toBuilder().enableCelValue(true).build(),
31+
testOption.useNativeCelType);
7232
}
7333
}

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

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,54 +14,18 @@
1414

1515
package dev.cel.runtime;
1616

17+
import com.google.testing.junit.testparameterinjector.TestParameter;
18+
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
1719
// import com.google.testing.testsize.MediumTest;
18-
import dev.cel.common.CelOptions;
1920
import dev.cel.testing.BaseInterpreterTest;
20-
import dev.cel.testing.Eval;
21-
import dev.cel.testing.EvalSync;
22-
import java.util.ArrayList;
23-
import java.util.Arrays;
24-
import java.util.List;
2521
import org.junit.runner.RunWith;
26-
import org.junit.runners.Parameterized;
27-
import org.junit.runners.Parameterized.Parameters;
2822

2923
/** Tests for {@link Interpreter} and related functionality. */
3024
// @MediumTest
31-
@RunWith(Parameterized.class)
25+
@RunWith(TestParameterInjector.class)
3226
public class InterpreterTest extends BaseInterpreterTest {
3327

34-
private static final CelOptions SIGNED_UINT_TEST_OPTIONS =
35-
CelOptions.current()
36-
.enableTimestampEpoch(true)
37-
.enableHeterogeneousNumericComparisons(true)
38-
.comprehensionMaxIterations(1_000)
39-
.build();
40-
41-
public InterpreterTest(boolean declareWithCelType, Eval eval) {
42-
super(declareWithCelType, eval);
43-
}
44-
45-
@Parameters
46-
public static List<Object[]> testData() {
47-
48-
return new ArrayList<>(
49-
Arrays.asList(
50-
new Object[][] {
51-
// SYNC_PROTO_TYPE
52-
{/* declareWithCelType= */ false, new EvalSync(TEST_FILE_DESCRIPTORS, TEST_OPTIONS)},
53-
// SYNC_PROTO_TYPE_SIGNED_UINT
54-
{
55-
/* declareWithCelType= */ false,
56-
new EvalSync(TEST_FILE_DESCRIPTORS, SIGNED_UINT_TEST_OPTIONS)
57-
},
58-
// SYNC_CEL_TYPE
59-
{/* declareWithCelType= */ true, new EvalSync(TEST_FILE_DESCRIPTORS, TEST_OPTIONS)},
60-
// SYNC_CEL_TYPE_SIGNED_UINT
61-
{
62-
/* declareWithCelType= */ true,
63-
new EvalSync(TEST_FILE_DESCRIPTORS, SIGNED_UINT_TEST_OPTIONS)
64-
},
65-
}));
28+
public InterpreterTest(@TestParameter InterpreterTestOption testOption) {
29+
super(testOption.celOptions, testOption.useNativeCelType);
6630
}
6731
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Source: optional.elide([])
2+
=====>
3+
bindings: {}
4+
result: []
5+
6+
Source: optional.elide([optional.none(), optional.of(1), optional.of(str)])
7+
declare str {
8+
value string
9+
}
10+
=====>
11+
bindings: {str=foo}
12+
result: [1, foo]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Source: optional.elide([dyn(1)])
2+
=====>
3+
bindings: {}
4+
error: evaluation error: Function 'optional_elide_list' failed with arg(s) '[1]'
5+
error_code: INTERNAL_ERROR

testing/BUILD.bazel

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,6 @@ java_library(
2929
exports = ["//testing/src/main/java/dev/cel/testing:cel_baseline_test_case"],
3030
)
3131

32-
java_library(
33-
name = "sync",
34-
exports = ["//testing/src/main/java/dev/cel/testing:sync"],
35-
)
36-
37-
java_library(
38-
name = "cel_value_sync",
39-
exports = ["//testing/src/main/java/dev/cel/testing:cel_value_sync"],
40-
)
41-
42-
java_library(
43-
name = "eval",
44-
exports = ["//testing/src/main/java/dev/cel/testing:eval"],
45-
)
46-
4732
java_library(
4833
name = "base_interpreter_test",
4934
exports = ["//testing/src/main/java/dev/cel/testing:base_interpreter_test"],

0 commit comments

Comments
 (0)