diff --git a/bundle/BUILD.bazel b/bundle/BUILD.bazel index 1eaf0bec8..11e0b8a6d 100644 --- a/bundle/BUILD.bazel +++ b/bundle/BUILD.bazel @@ -13,6 +13,14 @@ java_library( ], ) +java_library( + name = "cel_experimental_factory", + visibility = ["//:internal"], + exports = [ + "//bundle/src/main/java/dev/cel/bundle:cel_experimental_factory", + ], +) + java_library( name = "environment", exports = ["//bundle/src/main/java/dev/cel/bundle:environment"], diff --git a/bundle/src/main/java/dev/cel/bundle/BUILD.bazel b/bundle/src/main/java/dev/cel/bundle/BUILD.bazel index 0a014ec73..822511e4c 100644 --- a/bundle/src/main/java/dev/cel/bundle/BUILD.bazel +++ b/bundle/src/main/java/dev/cel/bundle/BUILD.bazel @@ -57,6 +57,23 @@ java_library( ], ) +java_library( + name = "cel_experimental_factory", + srcs = ["CelExperimentalFactory.java"], + tags = [ + ], + deps = [ + ":cel", + ":cel_impl", + "//checker", + "//common:options", + "//common/annotations", + "//compiler", + "//parser", + "//runtime:runtime_planner_impl", + ], +) + java_library( name = "cel_impl", srcs = ["CelImpl.java"], @@ -73,7 +90,6 @@ java_library( "//common:compiler_common", "//common:container", "//common:options", - "//common/annotations", "//common/internal:env_visitor", "//common/internal:file_descriptor_converter", "//common/types:cel_proto_types", diff --git a/bundle/src/main/java/dev/cel/bundle/CelExperimentalFactory.java b/bundle/src/main/java/dev/cel/bundle/CelExperimentalFactory.java new file mode 100644 index 000000000..2275d1c56 --- /dev/null +++ b/bundle/src/main/java/dev/cel/bundle/CelExperimentalFactory.java @@ -0,0 +1,61 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.bundle; + +import dev.cel.checker.CelCheckerLegacyImpl; +import dev.cel.common.CelOptions; +import dev.cel.common.annotations.Beta; +import dev.cel.compiler.CelCompilerImpl; +import dev.cel.parser.CelParserImpl; +import dev.cel.runtime.CelRuntimeImpl; + +/** + * Experimental helper class to configure the entire CEL stack in a common interface, backed by the + * new {@code ProgramPlanner} architecture. + * + *
All APIs and behaviors surfaced here are subject to change. + */ +@Beta +public final class CelExperimentalFactory { + + /** + * Creates a builder for configuring CEL for the parsing, optional type-checking, and evaluation + * of expressions using the Program Planner. + * + *
The {@code ProgramPlanner} architecture provides key benefits over the legacy runtime: + * + *
Note, the underlying {@link CelCompiler} and {@link CelRuntime} values are constructed lazily. - * - *
CEL Library Internals. Do Not Use. Consumers should use {@code CelFactory} instead. - * - *
TODO: Restrict visibility once factory is introduced */ @Immutable -@Internal -public final class CelImpl implements Cel, EnvVisitable { +final class CelImpl implements Cel, EnvVisitable { // The lazily constructed compiler and runtime values are memoized and guaranteed to be // constructed only once without side effects, thus making them effectively immutable. @@ -151,11 +145,8 @@ static CelImpl combine(CelCompiler compiler, CelRuntime runtime) { *
By default, {@link CelOptions#DEFAULT} are enabled, as is the CEL standard environment. * *
CEL Library Internals. Do Not Use. Consumers should use {@code CelFactory} instead. - * - *
TODO: Restrict visibility once factory is introduced */ - @Internal - public static CelBuilder newBuilder( + static CelBuilder newBuilder( CelCompilerBuilder compilerBuilder, CelRuntimeBuilder celRuntimeBuilder) { return new CelImpl.Builder(compilerBuilder, celRuntimeBuilder); } diff --git a/extensions/src/test/java/dev/cel/extensions/BUILD.bazel b/extensions/src/test/java/dev/cel/extensions/BUILD.bazel index b441c33cf..48915fd02 100644 --- a/extensions/src/test/java/dev/cel/extensions/BUILD.bazel +++ b/extensions/src/test/java/dev/cel/extensions/BUILD.bazel @@ -10,8 +10,7 @@ java_library( deps = [ "//:java_truth", "//bundle:cel", - "//bundle:cel_impl", - "//checker", + "//bundle:cel_experimental_factory", "//common:cel_ast", "//common:compiler_common", "//common:container", @@ -32,7 +31,6 @@ java_library( "//extensions:sets", "//extensions:sets_function", "//extensions:strings", - "//parser", "//parser:macro", "//parser:unparser", "//runtime", @@ -40,7 +38,6 @@ java_library( "//runtime:interpreter_util", "//runtime:lite_runtime", "//runtime:lite_runtime_factory", - "//runtime:runtime_planner_impl", "@cel_spec//proto/cel/expr/conformance/proto2:test_all_types_java_proto", "@cel_spec//proto/cel/expr/conformance/proto3:test_all_types_java_proto", "@cel_spec//proto/cel/expr/conformance/test:simple_java_proto", diff --git a/extensions/src/test/java/dev/cel/extensions/CelOptionalLibraryTest.java b/extensions/src/test/java/dev/cel/extensions/CelOptionalLibraryTest.java index 0f0c649f8..24e9d6d86 100644 --- a/extensions/src/test/java/dev/cel/extensions/CelOptionalLibraryTest.java +++ b/extensions/src/test/java/dev/cel/extensions/CelOptionalLibraryTest.java @@ -26,9 +26,8 @@ import com.google.testing.junit.testparameterinjector.TestParameters; import dev.cel.bundle.Cel; import dev.cel.bundle.CelBuilder; +import dev.cel.bundle.CelExperimentalFactory; import dev.cel.bundle.CelFactory; -import dev.cel.bundle.CelImpl; -import dev.cel.checker.CelCheckerLegacyImpl; import dev.cel.common.CelAbstractSyntaxTree; import dev.cel.common.CelContainer; import dev.cel.common.CelFunctionDecl; @@ -46,16 +45,13 @@ import dev.cel.common.values.CelByteString; import dev.cel.common.values.NullValue; import dev.cel.compiler.CelCompiler; -import dev.cel.compiler.CelCompilerImpl; import dev.cel.expr.conformance.proto3.TestAllTypes; import dev.cel.expr.conformance.proto3.TestAllTypes.NestedMessage; import dev.cel.parser.CelMacro; -import dev.cel.parser.CelParserImpl; import dev.cel.parser.CelStandardMacro; import dev.cel.runtime.CelEvaluationException; import dev.cel.runtime.CelFunctionBinding; import dev.cel.runtime.CelRuntime; -import dev.cel.runtime.CelRuntimeImpl; import dev.cel.runtime.InterpreterUtil; import java.time.Duration; import java.time.Instant; @@ -106,17 +102,6 @@ private enum ConstantTestCases { } } - private static CelBuilder plannerCelBuilder() { - // TODO: Replace with factory once available. - return CelImpl.newBuilder( - CelCompilerImpl.newBuilder( - CelParserImpl.newBuilder(), - CelCheckerLegacyImpl.newBuilder().setStandardEnvironmentEnabled(true)), - CelRuntimeImpl.newBuilder()) - // CEL-Internal-2 - .setOptions(CelOptions.current().build()); - } - private CelBuilder newCelBuilder() { return newCelBuilder(Integer.MAX_VALUE); } @@ -126,7 +111,7 @@ private CelBuilder newCelBuilder(int version) { switch (testMode) { case PLANNER_PARSE_ONLY: case PLANNER_CHECKED: - celBuilder = plannerCelBuilder(); + celBuilder = CelExperimentalFactory.plannerCelBuilder(); break; case LEGACY_CHECKED: celBuilder = CelFactory.standardCelBuilder(); diff --git a/runtime/BUILD.bazel b/runtime/BUILD.bazel index 72ec02d12..55ee241a0 100644 --- a/runtime/BUILD.bazel +++ b/runtime/BUILD.bazel @@ -29,6 +29,14 @@ java_library( ], ) +java_library( + name = "runtime_experimental_factory", + visibility = ["//:internal"], + exports = [ + "//runtime/src/main/java/dev/cel/runtime:runtime_experimental_factory", + ], +) + java_library( name = "runtime_legacy_impl", visibility = ["//:internal"], diff --git a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel index 70568cd90..10dca9ece 100644 --- a/runtime/src/main/java/dev/cel/runtime/BUILD.bazel +++ b/runtime/src/main/java/dev/cel/runtime/BUILD.bazel @@ -912,6 +912,19 @@ java_library( ], ) +java_library( + name = "runtime_experimental_factory", + srcs = ["CelRuntimeExperimentalFactory.java"], + tags = [ + ], + deps = [ + ":runtime", + ":runtime_planner_impl", + "//common:options", + "//common/annotations", + ], +) + java_library( name = "runtime", srcs = RUNTIME_SOURCES, diff --git a/runtime/src/main/java/dev/cel/runtime/CelRuntimeExperimentalFactory.java b/runtime/src/main/java/dev/cel/runtime/CelRuntimeExperimentalFactory.java new file mode 100644 index 000000000..d0089e48d --- /dev/null +++ b/runtime/src/main/java/dev/cel/runtime/CelRuntimeExperimentalFactory.java @@ -0,0 +1,52 @@ +// Copyright 2026 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dev.cel.runtime; + +import dev.cel.common.CelOptions; +import dev.cel.common.annotations.Beta; + +/** + * Experimental helper class to construct new {@code CelRuntime} instances backed by the new {@code + * ProgramPlanner} architecture. + * + *
All APIs and behaviors surfaced here are subject to change. + */ +@Beta +public final class CelRuntimeExperimentalFactory { + + /** + * Create a new builder for constructing a {@code CelRuntime} instance. + * + *
The {@code ProgramPlanner} architecture provides key benefits over the legacy runtime: + * + *