Skip to content

Commit 40ddec0

Browse files
committed
Support empty message creation
1 parent 438cd99 commit 40ddec0

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ java_library(
293293
":proto_message_lite_value",
294294
"//common:error_codes",
295295
"//common:runtime_exception",
296+
"//common/internal:cel_lite_descriptor_pool",
296297
"//common/internal:default_instance_message_lite_factory",
297298
"//common/internal:default_lite_descriptor_pool",
298299
"//common/internal:proto_lite_adapter",

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

+19-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
import com.google.common.collect.ImmutableSet;
1818
import com.google.errorprone.annotations.Immutable;
19+
import com.google.protobuf.MessageLite;
20+
import dev.cel.common.internal.CelLiteDescriptorPool;
1921
import dev.cel.common.internal.DefaultLiteDescriptorPool;
2022
import dev.cel.protobuf.CelLiteDescriptor;
23+
import dev.cel.protobuf.CelLiteDescriptor.MessageLiteDescriptor;
2124
import java.util.Map;
2225
import java.util.Optional;
2326
import java.util.Set;
@@ -30,6 +33,7 @@
3033
*/
3134
@Immutable
3235
public class ProtoMessageLiteValueProvider implements CelValueProvider {
36+
private final CelLiteDescriptorPool descriptorPool;
3337
private final ProtoLiteCelValueConverter protoLiteCelValueConverter;
3438

3539
public ProtoLiteCelValueConverter getProtoLiteCelValueConverter() {
@@ -38,7 +42,17 @@ public ProtoLiteCelValueConverter getProtoLiteCelValueConverter() {
3842

3943
@Override
4044
public Optional<CelValue> newValue(String structType, Map<String, Object> fields) {
41-
throw new UnsupportedOperationException("Message creation is not supported yet.");
45+
MessageLiteDescriptor descriptor = descriptorPool.findDescriptor(structType).orElse(null);
46+
if (descriptor == null) {
47+
return Optional.empty();
48+
}
49+
50+
if (!fields.isEmpty()) {
51+
throw new UnsupportedOperationException("Message creation with prepopulated fields is not supported yet.");
52+
}
53+
54+
MessageLite message = descriptor.newMessageBuilder().build();
55+
return Optional.of(protoLiteCelValueConverter.fromProtoMessageToCelValue(structType, message));
4256
}
4357

4458

@@ -51,11 +65,13 @@ public static ProtoMessageLiteValueProvider newInstance(Set<CelLiteDescriptor> d
5165
DefaultLiteDescriptorPool descriptorPool = DefaultLiteDescriptorPool.newInstance(ImmutableSet.copyOf(descriptors));
5266
ProtoLiteCelValueConverter protoLiteCelValueConverter =
5367
ProtoLiteCelValueConverter.newInstance(descriptorPool);
54-
return new ProtoMessageLiteValueProvider(protoLiteCelValueConverter);
68+
return new ProtoMessageLiteValueProvider(protoLiteCelValueConverter, descriptorPool);
5569
}
5670

5771
private ProtoMessageLiteValueProvider(
58-
ProtoLiteCelValueConverter protoLiteCelValueConverter) {
72+
ProtoLiteCelValueConverter protoLiteCelValueConverter,
73+
CelLiteDescriptorPool descriptorPool) {
5974
this.protoLiteCelValueConverter = protoLiteCelValueConverter;
75+
this.descriptorPool = descriptorPool;
6076
}
6177
}

runtime/src/test/java/dev/cel/runtime/CelLiteDescriptorEvaluationTest.java

+31-3
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,23 @@ public class CelLiteDescriptorEvaluationTest {
8181
.build();
8282

8383
@Test
84-
public void messageCreation_throws() throws Exception {
84+
public void messageCreation_emptyMessage() throws Exception {
8585
CelAbstractSyntaxTree ast = CEL_COMPILER.compile("TestAllTypes{}").getAst();
8686

87+
TestAllTypes simpleTest = (TestAllTypes) CEL_RUNTIME.createProgram(ast).eval();
88+
89+
assertThat(simpleTest).isEqualTo(TestAllTypes.getDefaultInstance());
90+
}
91+
92+
@Test
93+
public void messageCreation_fieldsPopulated() throws Exception {
94+
CelAbstractSyntaxTree ast = CEL_COMPILER.compile("TestAllTypes{single_int32: 4}").getAst();
95+
8796
CelEvaluationException e = assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval());
88-
assertThat(e).hasCauseThat().hasMessageThat().contains("Message creation is not supported yet.");
97+
98+
assertThat(e.getMessage()).contains("Message creation with prepopulated fields is not supported yet.");
8999
}
100+
90101
@Test
91102
@TestParameters("{expression: 'msg.single_int32 == 1'}")
92103
@TestParameters("{expression: 'msg.single_int64 == 2'}")
@@ -403,7 +414,7 @@ public void presenceTest_evaluatesToTrue(String expression) throws Exception {
403414
}
404415

405416
@Test
406-
public void nestedMessage() throws Exception {
417+
public void nestedMessage_traversalThroughSetField() throws Exception {
407418
CelAbstractSyntaxTree ast =
408419
CEL_COMPILER
409420
.compile("msg.single_nested_message.bb == 43 && has(msg.single_nested_message)")
@@ -419,6 +430,23 @@ public void nestedMessage() throws Exception {
419430
assertThat(result).isTrue();
420431
}
421432

433+
@Test
434+
public void nestedMessage_safeTraversal() throws Exception {
435+
CelAbstractSyntaxTree ast =
436+
CEL_COMPILER
437+
.compile("msg.single_nested_message.bb == 43")
438+
.getAst();
439+
TestAllTypes nestedMessage =
440+
TestAllTypes.newBuilder()
441+
.setSingleNestedMessage(NestedMessage.getDefaultInstance())
442+
.build();
443+
444+
boolean result =
445+
(boolean) CEL_RUNTIME.createProgram(ast).eval(ImmutableMap.of("msg", nestedMessage));
446+
447+
assertThat(result).isFalse();
448+
}
449+
422450
@Test
423451
public void enumSelection() throws Exception {
424452
CelAbstractSyntaxTree ast = CEL_COMPILER.compile("msg.single_nested_enum").getAst();

0 commit comments

Comments
 (0)