Skip to content
Open
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
6 changes: 4 additions & 2 deletions common/src/main/java/dev/cel/common/values/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ java_library(
tags = [
],
deps = [
"//common/values",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_guava_guava",
],
Expand All @@ -68,6 +69,7 @@ cel_android_library(
tags = [
],
deps = [
"//common/values:values_android",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven_android//:com_google_guava_guava",
],
Expand Down Expand Up @@ -207,13 +209,13 @@ java_library(
tags = [
],
deps = [
":base_proto_message_value_provider",
":proto_message_value",
"//common:options",
"//common/annotations",
"//common/internal:dynamic_proto",
"//common/internal:proto_message_factory",
"//common/values:base_proto_cel_value_converter",
"//common/values",
"//common/values:cel_value_provider",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_protobuf_protobuf_java",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@
@SuppressWarnings("unchecked") // Unchecked cast of generics due to type-erasure (ex: MapValue).
@Internal
@Immutable
public abstract class CelValueConverter {
public class CelValueConverter {

private static final CelValueConverter DEFAULT_INSTANCE = new CelValueConverter();

public static CelValueConverter getDefaultInstance() {
return DEFAULT_INSTANCE;
}

/** Adapts a {@link CelValue} to a plain old Java Object. */
public Object unwrap(CelValue celValue) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ public interface CelValueProvider {
* a wrapper.
*/
Optional<Object> newValue(String structType, Map<String, Object> fields);

default CelValueConverter celValueConverter() {
return CelValueConverter.getDefaultInstance();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,13 @@ public Object toRuntimeValue(Object value) {
}

if (value instanceof MessageOrBuilder) {
MessageOrBuilder message = (MessageOrBuilder) value;
Message message;
if (value instanceof Message.Builder) {
message = ((Message.Builder) value).build();
} else {
message = (Message) value;
}

// Attempt to convert the proto from a dynamic message into a concrete message if possible.
if (message instanceof DynamicMessage) {
message = dynamicProto.maybeAdaptDynamicMessage((DynamicMessage) message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
*/
@Immutable
@Internal
public class ProtoMessageValueProvider extends BaseProtoMessageValueProvider {
public class ProtoMessageValueProvider implements CelValueProvider {
private final ProtoAdapter protoAdapter;
private final ProtoMessageFactory protoMessageFactory;
private final ProtoCelValueConverter protoCelValueConverter;

@Override
public BaseProtoCelValueConverter protoCelValueConverter() {
public CelValueConverter celValueConverter() {
return protoCelValueConverter;
}

Expand Down
35 changes: 3 additions & 32 deletions common/src/test/java/dev/cel/common/values/StructValueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import dev.cel.common.types.CelTypeProvider;
import dev.cel.common.types.SimpleType;
import dev.cel.common.types.StructType;
import dev.cel.expr.conformance.proto3.TestAllTypes;
import java.util.Map;
import java.util.Optional;
import org.junit.Test;
Expand Down Expand Up @@ -185,7 +184,7 @@ public void evaluate_usingMultipleProviders_selectFieldFromCustomClass() throws
.setValueProvider(
CombinedCelValueProvider.combine(
ProtoMessageValueProvider.newInstance(
CelOptions.DEFAULT, DynamicProto.create(typeName -> Optional.empty())),
CelOptions.DEFAULT, DynamicProto.create(unused -> Optional.empty())),
CUSTOM_STRUCT_VALUE_PROVIDER))
.build();
CelAbstractSyntaxTree ast = cel.compile("custom_struct{data: 5}.data").getAst();
Expand All @@ -195,36 +194,8 @@ public void evaluate_usingMultipleProviders_selectFieldFromCustomClass() throws
assertThat(result).isEqualTo(5L);
}

@Test
public void evaluate_usingMultipleProviders_selectFieldFromProtobufMessage() throws Exception {
Cel cel =
CelFactory.standardCelBuilder()
.setOptions(CelOptions.current().enableCelValue(true).build())
.addMessageTypes(TestAllTypes.getDescriptor())
.setTypeProvider(CUSTOM_STRUCT_TYPE_PROVIDER)
.setValueProvider(
CombinedCelValueProvider.combine(
ProtoMessageValueProvider.newInstance(
CelOptions.DEFAULT,
// Note: this is unideal. Future iterations should make DynamicProto
// completely an internal concern, and not expose it at all.
DynamicProto.create(
typeName -> {
if (typeName.equals(TestAllTypes.getDescriptor().getFullName())) {
return Optional.of(TestAllTypes.newBuilder());
}
return Optional.empty();
})),
CUSTOM_STRUCT_VALUE_PROVIDER))
.build();
CelAbstractSyntaxTree ast =
cel.compile("cel.expr.conformance.proto3.TestAllTypes{single_string: 'foo'}.single_string")
.getAst();

String result = (String) cel.createProgram(ast).eval();

assertThat(result).isEqualTo("foo");
}
// TODO: Bring back evaluate_usingMultipleProviders_selectFieldFromProtobufMessage
// once planner is exposed from factory

@SuppressWarnings("Immutable") // Test only
private static class CelCustomStructValue extends StructValue<String> {
Expand Down
9 changes: 9 additions & 0 deletions runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,12 @@ java_library(
"//runtime/src/main/java/dev/cel/runtime:variable_resolver",
],
)

java_library(
name = "runtime_planner_impl",
testonly = 1, # TODO: Move to factory when ready for exposure
visibility = ["//:internal"],
exports = [
"//runtime/src/main/java/dev/cel/runtime:runtime_planner_impl",
],
)
44 changes: 44 additions & 0 deletions runtime/src/main/java/dev/cel/runtime/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,48 @@ cel_android_library(
],
)

java_library(
name = "runtime_planner_impl",
testonly = 1,
srcs = ["CelRuntimeImpl.java"],
tags = [
],
deps = [
"//:auto_value",
"//common:cel_ast",
"//common:cel_descriptor_util",
"//common:cel_descriptors",
"//common:container",
"//common:options",
"//common/annotations",
"//common/internal:cel_descriptor_pools",
"//common/internal:default_message_factory",
"//common/internal:dynamic_proto",
"//common/types:default_type_provider",
"//common/types:message_type_provider",
"//common/types:type_providers",
"//common/values",
"//common/values:cel_value_provider",
"//common/values:combined_cel_value_provider",
"//common/values:proto_message_value_provider",
"//runtime",
"//runtime:dispatcher",
"//runtime:evaluation_listener",
"//runtime:function_binding",
"//runtime:function_resolver",
"//runtime:program",
"//runtime:proto_message_runtime_helpers",
"//runtime:runtime_equality",
"//runtime:standard_functions",
"//runtime:variable_resolver",
"//runtime/planner:program_planner",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_guava_guava",
"@maven//:com_google_protobuf_protobuf_java",
"@maven//:org_jspecify_jspecify",
],
)

java_library(
name = "runtime",
srcs = RUNTIME_SOURCES,
Expand Down Expand Up @@ -829,13 +871,15 @@ java_library(
"//common:cel_ast",
"//common:cel_descriptor_util",
"//common:cel_descriptors",
"//common:container",
"//common:options",
"//common/annotations",
"//common/internal:cel_descriptor_pools",
"//common/internal:default_message_factory",
"//common/internal:dynamic_proto",
"//common/internal:proto_message_factory",
"//common/types:cel_types",
"//common/types:type_providers",
"//common/values:cel_value_provider",
"//common/values:proto_message_value_provider",
"//runtime:variable_resolver",
Expand Down
28 changes: 27 additions & 1 deletion runtime/src/main/java/dev/cel/runtime/CelRuntimeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.Message;
import dev.cel.common.CelContainer;
import dev.cel.common.CelOptions;
import dev.cel.common.types.CelTypeProvider;
import dev.cel.common.values.CelValueProvider;
import java.util.function.Function;

Expand All @@ -48,6 +50,14 @@ public interface CelRuntimeBuilder {
@CanIgnoreReturnValue
CelRuntimeBuilder addFunctionBindings(Iterable<CelFunctionBinding> bindings);

/** Adds bindings for functions that are allowed to be late-bound (resolved at execution time). */
@CanIgnoreReturnValue
CelRuntimeBuilder addLateBoundFunctions(String... lateBoundFunctionNames);

/** Adds bindings for functions that are allowed to be late-bound (resolved at execution time). */
@CanIgnoreReturnValue
CelRuntimeBuilder addLateBoundFunctions(Iterable<String> lateBoundFunctionNames);

/**
* Add message {@link Descriptor}s to the builder for type-checking and object creation at
* interpretation time.
Expand Down Expand Up @@ -123,6 +133,13 @@ public interface CelRuntimeBuilder {
@CanIgnoreReturnValue
CelRuntimeBuilder addFileTypes(FileDescriptorSet fileDescriptorSet);

/**
* Sets the {@link CelTypeProvider} for resolving CEL types during evaluation, such as a fully
* qualified type name to a struct or an enum value.
*/
@CanIgnoreReturnValue
CelRuntimeBuilder setTypeProvider(CelTypeProvider celTypeProvider);

/**
* Set a custom type factory for the runtime.
*
Expand All @@ -145,7 +162,7 @@ public interface CelRuntimeBuilder {
* support proto messages in addition to custom struct values, protobuf value provider must be
* configured first before the custom value provider.
*
* <p>Note {@link CelOptions#enableCelValue()} must be enabled or this method will be a no-op.
* <p>Note that this option is only supported for planner-based runtime.
*/
@CanIgnoreReturnValue
CelRuntimeBuilder setValueProvider(CelValueProvider celValueProvider);
Expand Down Expand Up @@ -179,6 +196,15 @@ public interface CelRuntimeBuilder {
@CanIgnoreReturnValue
CelRuntimeBuilder setExtensionRegistry(ExtensionRegistry extensionRegistry);


/**
* Set the {@link CelContainer} to use as the namespace for resolving CEL expression variables and
* functions.
*/
@CanIgnoreReturnValue
CelRuntimeBuilder setContainer(CelContainer container);


/** Build a new instance of the {@code CelRuntime}. */
@CheckReturnValue
CelRuntime build();
Expand Down
Loading
Loading