Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
18 changes: 17 additions & 1 deletion bundle/src/main/java/dev/cel/bundle/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand All @@ -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",
Expand Down
61 changes: 61 additions & 0 deletions bundle/src/main/java/dev/cel/bundle/CelExperimentalFactory.java
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>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.
*
* <p>The {@code ProgramPlanner} architecture provides key benefits over the legacy runtime:
*
* <ul>
* <li><b>Performance:</b> Programs can be cached for improving evaluation speed.
* <li><b>Parsed-only expression evaluation:</b> Unlike the traditional stack which required
* supplying type-checked expressions, this architecture handles both parsed-only and
* type-checked expressions.
* </ul>
*/
public static CelBuilder plannerCelBuilder() {
return CelImpl.newBuilder(
CelCompilerImpl.newBuilder(
CelParserImpl.newBuilder(),
CelCheckerLegacyImpl.newBuilder().setStandardEnvironmentEnabled(true)),
CelRuntimeImpl.newBuilder())
// CEL-Internal-2
.setOptions(
CelOptions.current()
.enableHeterogeneousNumericComparisons(true)
.enableTimestampEpoch(true)
.build());
}

private CelExperimentalFactory() {}
}
13 changes: 2 additions & 11 deletions bundle/src/main/java/dev/cel/bundle/CelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import dev.cel.common.CelSource;
import dev.cel.common.CelValidationResult;
import dev.cel.common.CelVarDecl;
import dev.cel.common.annotations.Internal;
import dev.cel.common.internal.EnvVisitable;
import dev.cel.common.internal.EnvVisitor;
import dev.cel.common.internal.FileDescriptorSetConverter;
Expand All @@ -65,14 +64,9 @@
* Implementation of the synchronous CEL stack.
*
* <p>Note, the underlying {@link CelCompiler} and {@link CelRuntime} values are constructed lazily.
*
* <p>CEL Library Internals. Do Not Use. Consumers should use {@code CelFactory} instead.
*
* <p>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.
Expand Down Expand Up @@ -151,11 +145,8 @@ static CelImpl combine(CelCompiler compiler, CelRuntime runtime) {
* <p>By default, {@link CelOptions#DEFAULT} are enabled, as is the CEL standard environment.
*
* <p>CEL Library Internals. Do Not Use. Consumers should use {@code CelFactory} instead.
*
* <p>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);
}
Expand Down
5 changes: 1 addition & 4 deletions extensions/src/test/java/dev/cel/extensions/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -32,15 +31,13 @@ java_library(
"//extensions:sets",
"//extensions:sets_function",
"//extensions:strings",
"//parser",
"//parser:macro",
"//parser:unparser",
"//runtime",
"//runtime:function_binding",
"//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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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();
Expand Down
8 changes: 8 additions & 0 deletions runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
13 changes: 13 additions & 0 deletions runtime/src/main/java/dev/cel/runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>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.
*
* <p>The {@code ProgramPlanner} architecture provides key benefits over the legacy runtime:
*
* <ul>
* <li><b>Performance:</b> Programs can be cached for improving evaluation speed.
* <li><b>Parsed-only expression evaluation:</b> Unlike the traditional legacy runtime, which
* only supported evaluating type-checked expressions, this architecture handles both
* parsed-only and type-checked expressions.
* </ul>
*/
public static CelRuntimeBuilder plannerRuntimeBuilder() {
return CelRuntimeImpl.newBuilder()
// CEL-Internal-2
.setOptions(
CelOptions.current()
.enableTimestampEpoch(true)
.enableHeterogeneousNumericComparisons(true)
.build());
}

private CelRuntimeExperimentalFactory() {}
}
2 changes: 1 addition & 1 deletion runtime/src/test/java/dev/cel/runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ java_library(
"//common/types:type_providers",
"//extensions",
"//runtime",
"//runtime:runtime_planner_impl",
"//runtime:runtime_experimental_factory",
"//testing:base_interpreter_test",
"@maven//:com_google_testparameterinjector_test_parameter_injector",
"@maven//:junit_junit",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ public class PlannerInterpreterTest extends BaseInterpreterTest {

@Override
protected CelRuntimeBuilder newBaseRuntimeBuilder(CelOptions celOptions) {
return CelRuntimeImpl.newBuilder()
return CelRuntimeExperimentalFactory.plannerRuntimeBuilder()
.addLateBoundFunctions("record")
// CEL-Internal-2
.setOptions(celOptions)
.addLibraries(CelExtensions.optional())
.addFileTypes(TEST_FILE_DESCRIPTORS);
Expand Down
Loading