Skip to content

Commit 1344489

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

21 files changed

Lines changed: 1346 additions & 169 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);

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: 19 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,20 @@ 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_provider",
336+
"//runtime",
337+
"@maven//:com_google_guava_guava",
338+
],
339+
)

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.google.errorprone.annotations.InlineMe;
2323
import dev.cel.common.CelOptions;
2424
import dev.cel.extensions.CelMathExtensions.Function;
25+
import dev.cel.runtime.CelRuntimeLibrary;
2526
import java.util.Set;
2627

2728
/**
@@ -350,6 +351,67 @@ public static CelComprehensionsExtensions comprehensions() {
350351
return COMPREHENSIONS_EXTENSIONS;
351352
}
352353

354+
/**
355+
* Creates a {@link CelRuntimeLibrary} that registers the given POJO classes.
356+
*
357+
* <p>All POJO classes are exposed to CEL using their fully qualified canonical name. For example,
358+
* if you have a class `com.example.Account`:
359+
*
360+
* <pre>{@code
361+
* package com.example;
362+
* public class Account {
363+
* public int id;
364+
* }
365+
* }</pre>
366+
*
367+
* The type `com.example.Account` would be exported to CEL using its full name. If you set the
368+
* container to `com.example` on the compiler, you can use it simply as `Account`: `Account{id:
369+
* 1234}` would create a new `Account` instance with the `id` field populated.
370+
*
371+
* <p>Properties are discovered by scanning public fields and public getter methods. For field
372+
* selection (reading) and object creation (writing), resolution happens in the following order of
373+
* precedence:
374+
*
375+
* <ol>
376+
* <li>Standard JavaBeans getter (e.g., `getFoo()`) or setter (e.g., `setFoo(...)`)
377+
* <li>Boolean getter (e.g., `isFoo()`) for boolean properties
378+
* <li>Prefix-less getter (e.g., `foo()`) matching a declared field name
379+
* <li>Public field directly (e.g., `public String foo`)
380+
* </ol>
381+
*
382+
* <p>The type-mapping between Java and CEL is as follows:
383+
*
384+
* <table>
385+
* <tr><th>Java type</th><th>CEL type</th></tr>
386+
* <tr><td>boolean, Boolean</td><td>bool</td></tr>
387+
* <tr><td>byte[]</td><td>bytes</td></tr>
388+
* <tr><td>float, Float, double, Double</td><td>double</td></tr>
389+
* <tr><td>int, Integer, long, Long</td><td>int</td></tr>
390+
* <tr><td>com.google.common.primitives.UnsignedLong</td><td>uint</td></tr>
391+
* <tr><td>String</td><td>string</td></tr>
392+
* <tr><td>java.time.Duration</td><td>duration</td></tr>
393+
* <tr><td>java.time.Instant</td><td>timestamp</td></tr>
394+
* <tr><td>java.util.List</td><td>list</td></tr>
395+
* <tr><td>java.util.Map</td><td>map</td></tr>
396+
* <tr><td>java.util.Optional</td><td>optional_type</td></tr>
397+
* </table>
398+
*
399+
* <p>Note: This is only supported for the planner runtime (e.g., {@code
400+
* CelRuntimeFactory.plannerRuntimeBuilder()}).
401+
*
402+
* <p>Note: Native Java arrays (except `byte[]`) are not supported. Use {@link java.util.List}
403+
* instead.
404+
*
405+
* <p>Note: If there is a name collision with a Protocol Buffer type, the protobuf type will take
406+
* precedence.
407+
*
408+
* @throws IllegalArgumentException if a class contains any fields or getters with types that
409+
* cannot be mapped to CEL, or if an anonymous or local class is passed.
410+
*/
411+
public static CelRuntimeLibrary nativeTypes(Class<?>... classes) {
412+
return CelNativeExtensions.nativeTypes(classes);
413+
}
414+
353415
/**
354416
* Retrieves all function names used by every extension libraries.
355417
*

0 commit comments

Comments
 (0)