Skip to content

Commit e6c1dce

Browse files
l46kokcopybara-github
authored andcommitted
Implement Native extension
PiperOrigin-RevId: 904195105
1 parent 1e1d8ea commit e6c1dce

26 files changed

Lines changed: 1555 additions & 172 deletions

File tree

bundle/BUILD.bazel

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,6 @@ java_library(
1313
],
1414
)
1515

16-
java_library(
17-
name = "cel_experimental_factory",
18-
visibility = ["//:internal"],
19-
exports = [
20-
"//bundle/src/main/java/dev/cel/bundle:cel_experimental_factory",
21-
],
22-
)
23-
2416
java_library(
2517
name = "environment",
2618
exports = ["//bundle/src/main/java/dev/cel/bundle:environment"],

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

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ java_library(
3535
"@cel_spec//proto/cel/expr:checked_java_proto",
3636
"@maven//:com_google_code_findbugs_annotations",
3737
"@maven//:com_google_errorprone_error_prone_annotations",
38-
"@maven//:com_google_guava_guava",
3938
"@maven//:com_google_protobuf_protobuf_java",
4039
],
4140
)
@@ -54,22 +53,6 @@ java_library(
5453
"//compiler:compiler_builder",
5554
"//parser",
5655
"//runtime",
57-
],
58-
)
59-
60-
java_library(
61-
name = "cel_experimental_factory",
62-
srcs = ["CelExperimentalFactory.java"],
63-
tags = [
64-
],
65-
deps = [
66-
":cel",
67-
":cel_impl",
68-
"//checker",
69-
"//common:options",
70-
"//common/annotations",
71-
"//compiler",
72-
"//parser",
7356
"//runtime:runtime_planner_impl",
7457
],
7558
)
@@ -117,7 +100,6 @@ java_library(
117100
tags = [
118101
],
119102
deps = [
120-
":cel_factory",
121103
":environment_exception",
122104
":required_fields_checker",
123105
"//:auto_value",
@@ -190,7 +172,6 @@ java_library(
190172
"//common:options",
191173
"//common/internal:env_visitor",
192174
"//common/types:cel_proto_types",
193-
"//common/types:cel_types",
194175
"//common/types:type_providers",
195176
"//compiler:compiler_builder",
196177
"//extensions",

bundle/src/main/java/dev/cel/bundle/CelExperimentalFactory.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

bundle/src/main/java/dev/cel/bundle/CelFactory.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import dev.cel.compiler.CelCompilerImpl;
2121
import dev.cel.parser.CelParserImpl;
2222
import dev.cel.runtime.CelRuntime;
23+
import dev.cel.runtime.CelRuntimeImpl;
2324
import dev.cel.runtime.CelRuntimeLegacyImpl;
2425

2526
/** Helper class to configure the entire CEL stack in a common interface. */
@@ -44,6 +45,30 @@ public static CelBuilder standardCelBuilder() {
4445
.setStandardEnvironmentEnabled(true);
4546
}
4647

48+
/**
49+
* Creates a builder for configuring CEL for the parsing, optional type-checking, and evaluation
50+
* of expressions using the Program Planner.
51+
*
52+
* <p>The {@code ProgramPlanner} architecture provides key benefits over the {@link
53+
* #standardCelBuilder()}:
54+
*
55+
* <ul>
56+
* <li><b>Performance:</b> Programs can be cached for improving evaluation speed.
57+
* <li><b>Parsed-only expression evaluation:</b> Unlike the traditional stack which required
58+
* supplying type-checked expressions, this architecture handles both parsed-only and
59+
* type-checked expressions.
60+
* </ul>
61+
*/
62+
public static CelBuilder plannerCelBuilder() {
63+
return CelImpl.newBuilder(
64+
CelCompilerImpl.newBuilder(
65+
CelParserImpl.newBuilder(),
66+
CelCheckerLegacyImpl.newBuilder().setStandardEnvironmentEnabled(true)),
67+
CelRuntimeImpl.newBuilder())
68+
// CEL-Internal-2
69+
.setOptions(CelOptions.current().enableHeterogeneousNumericComparisons(true).build());
70+
}
71+
4772
/** Combines a prebuilt {@link CelCompiler} and {@link CelRuntime} into {@link Cel}. */
4873
public static Cel combine(CelCompiler celCompiler, CelRuntime celRuntime) {
4974
return CelImpl.combine(celCompiler, celRuntime);

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,15 @@ cel_android_library(
7878

7979
java_library(
8080
name = "combined_cel_value_provider",
81-
srcs = ["CombinedCelValueProvider.java"],
81+
srcs = [
82+
"CombinedCelValueConverter.java",
83+
"CombinedCelValueProvider.java",
84+
],
8285
tags = [
8386
],
8487
deps = [
88+
":values",
89+
"//common/values:cel_value",
8590
"//common/values:cel_value_provider",
8691
"@maven//:com_google_errorprone_error_prone_annotations",
8792
"@maven//:com_google_guava_guava",
@@ -90,10 +95,15 @@ java_library(
9095

9196
cel_android_library(
9297
name = "combined_cel_value_provider_android",
93-
srcs = ["CombinedCelValueProvider.java"],
98+
srcs = [
99+
"CombinedCelValueConverter.java",
100+
"CombinedCelValueProvider.java",
101+
],
94102
tags = [
95103
],
96104
deps = [
105+
":cel_value_android",
106+
":values_android",
97107
"//common/values:cel_value_provider_android",
98108
"@maven//:com_google_errorprone_error_prone_annotations",
99109
"@maven_android//:com_google_guava_guava",
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright 2026 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.values;
16+
17+
import com.google.common.base.Preconditions;
18+
import com.google.common.collect.ImmutableList;
19+
import com.google.common.collect.ImmutableMap;
20+
import java.util.Collection;
21+
import java.util.Map;
22+
import java.util.Optional;
23+
24+
/**
25+
* {@code CombinedCelValueConverter} delegates value conversion to a list of underlying {@link
26+
* CelValueConverter}s.
27+
*/
28+
@SuppressWarnings("unchecked")
29+
public final class CombinedCelValueConverter extends CelValueConverter {
30+
private final ImmutableList<CelValueConverter> converters;
31+
32+
/** Creates a new instance of {@code CombinedCelValueConverter}. */
33+
public static CombinedCelValueConverter combine(ImmutableList<CelValueConverter> converters) {
34+
return new CombinedCelValueConverter(converters);
35+
}
36+
37+
private CombinedCelValueConverter(ImmutableList<CelValueConverter> converters) {
38+
this.converters = Preconditions.checkNotNull(converters);
39+
}
40+
41+
@Override
42+
public Object toRuntimeValue(Object value) {
43+
Preconditions.checkNotNull(value);
44+
45+
if (value instanceof CelValue) {
46+
return value;
47+
}
48+
49+
if (value instanceof Collection) {
50+
Collection<Object> collection = (Collection<Object>) value;
51+
ImmutableList.Builder<Object> listBuilder =
52+
ImmutableList.builderWithExpectedSize(collection.size());
53+
for (Object entry : collection) {
54+
listBuilder.add(toRuntimeValue(entry));
55+
}
56+
return listBuilder.build();
57+
}
58+
59+
if (value instanceof Map) {
60+
Map<Object, Object> map = (Map<Object, Object>) value;
61+
ImmutableMap.Builder<Object, Object> mapBuilder =
62+
ImmutableMap.builderWithExpectedSize(map.size());
63+
for (Map.Entry<Object, Object> entry : map.entrySet()) {
64+
mapBuilder.put(toRuntimeValue(entry.getKey()), toRuntimeValue(entry.getValue()));
65+
}
66+
return mapBuilder.buildOrThrow();
67+
}
68+
69+
if (value instanceof Optional) {
70+
Optional<Object> optionalValue = (Optional<Object>) value;
71+
return optionalValue
72+
.map(this::toRuntimeValue)
73+
.map(OptionalValue::create)
74+
.orElse(OptionalValue.EMPTY);
75+
}
76+
77+
// For non-container types, try each converter
78+
for (CelValueConverter converter : converters) {
79+
Object result = converter.toRuntimeValue(value);
80+
if (result != value) {
81+
return result;
82+
}
83+
}
84+
85+
return normalizePrimitive(value);
86+
}
87+
}

common/src/main/java/dev/cel/common/values/CombinedCelValueProvider.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ public Optional<Object> newValue(String structType, Map<String, Object> fields)
4949
return Optional.empty();
5050
}
5151

52+
@Override
53+
public CelValueConverter celValueConverter() {
54+
return CombinedCelValueConverter.combine(
55+
celValueProviders.stream()
56+
.map(CelValueProvider::celValueConverter)
57+
.collect(ImmutableList.toImmutableList()));
58+
}
59+
5260
/** Returns the underlying {@link CelValueProvider}s in order. */
5361
public ImmutableList<CelValueProvider> valueProviders() {
5462
return celValueProviders;

extensions/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,8 @@ java_library(
5656
name = "comprehensions",
5757
exports = ["//extensions/src/main/java/dev/cel/extensions:comprehensions"],
5858
)
59+
60+
java_library(
61+
name = "native",
62+
exports = ["//extensions/src/main/java/dev/cel/extensions:native"],
63+
)

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ java_library(
3434
":encoders",
3535
":lists",
3636
":math",
37+
":native",
3738
":optional_library",
3839
":protos",
3940
":regex",
@@ -42,6 +43,7 @@ java_library(
4243
":strings",
4344
"//common:options",
4445
"//extensions:extension_library",
46+
"//runtime",
4547
"@maven//:com_google_errorprone_error_prone_annotations",
4648
"@maven//:com_google_guava_guava",
4749
],
@@ -318,3 +320,21 @@ java_library(
318320
"@maven//:com_google_guava_guava",
319321
],
320322
)
323+
324+
java_library(
325+
name = "native",
326+
srcs = ["CelNativeExtensions.java"],
327+
tags = [
328+
],
329+
deps = [
330+
"//common/exceptions:attribute_not_found",
331+
"//common/types",
332+
"//common/types:type_providers",
333+
"//common/values",
334+
"//common/values:cel_byte_string",
335+
"//common/values:cel_value",
336+
"//common/values:cel_value_provider",
337+
"//runtime",
338+
"@maven//:com_google_guava_guava",
339+
],
340+
)

0 commit comments

Comments
 (0)