Skip to content

Commit d6c550a

Browse files
l46kokcopybara-github
authored andcommitted
Add ProtoMessageLiteValueProvider
PiperOrigin-RevId: 751526691
1 parent c75eb39 commit d6c550a

File tree

5 files changed

+153
-0
lines changed

5 files changed

+153
-0
lines changed

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,3 +184,21 @@ java_library(
184184
"@maven_android//:com_google_protobuf_protobuf_javalite",
185185
],
186186
)
187+
188+
java_library(
189+
name = "proto_message_lite_value_provider",
190+
srcs = ["ProtoMessageLiteValueProvider.java"],
191+
tags = [
192+
],
193+
deps = [
194+
":cel_value",
195+
":cel_value_provider",
196+
":proto_message_lite_value",
197+
"//common/internal:cel_lite_descriptor_pool",
198+
"//common/internal:default_lite_descriptor_pool",
199+
"//protobuf:cel_lite_descriptor",
200+
"@maven//:com_google_errorprone_error_prone_annotations",
201+
"@maven//:com_google_guava_guava",
202+
"@maven_android//:com_google_protobuf_protobuf_javalite",
203+
],
204+
)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.values;
16+
17+
import com.google.common.collect.ImmutableSet;
18+
import com.google.errorprone.annotations.Immutable;
19+
import com.google.protobuf.MessageLite;
20+
import dev.cel.common.internal.CelLiteDescriptorPool;
21+
import dev.cel.common.internal.DefaultLiteDescriptorPool;
22+
import dev.cel.protobuf.CelLiteDescriptor;
23+
import dev.cel.protobuf.CelLiteDescriptor.MessageLiteDescriptor;
24+
import java.util.Map;
25+
import java.util.Optional;
26+
import java.util.Set;
27+
28+
/**
29+
* {@code ProtoMessageValueProvider} constructs new instances of protobuf lite-message given its
30+
* fully qualified name and its fields to populate.
31+
*/
32+
@Immutable
33+
public class ProtoMessageLiteValueProvider implements CelValueProvider {
34+
private final CelLiteDescriptorPool descriptorPool;
35+
private final ProtoLiteCelValueConverter protoLiteCelValueConverter;
36+
37+
public ProtoLiteCelValueConverter getProtoLiteCelValueConverter() {
38+
return protoLiteCelValueConverter;
39+
}
40+
41+
@Override
42+
public Optional<CelValue> newValue(String structType, Map<String, Object> fields) {
43+
MessageLiteDescriptor descriptor = descriptorPool.findDescriptor(structType).orElse(null);
44+
if (descriptor == null) {
45+
return Optional.empty();
46+
}
47+
48+
if (!fields.isEmpty()) {
49+
// TODO: Add support for this
50+
throw new UnsupportedOperationException(
51+
"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));
56+
}
57+
58+
public static ProtoMessageLiteValueProvider newInstance(CelLiteDescriptor... descriptors) {
59+
return newInstance(ImmutableSet.copyOf(descriptors));
60+
}
61+
62+
public static ProtoMessageLiteValueProvider newInstance(Set<CelLiteDescriptor> descriptors) {
63+
DefaultLiteDescriptorPool descriptorPool =
64+
DefaultLiteDescriptorPool.newInstance(ImmutableSet.copyOf(descriptors));
65+
ProtoLiteCelValueConverter protoLiteCelValueConverter =
66+
ProtoLiteCelValueConverter.newInstance(descriptorPool);
67+
return new ProtoMessageLiteValueProvider(protoLiteCelValueConverter, descriptorPool);
68+
}
69+
70+
private ProtoMessageLiteValueProvider(
71+
ProtoLiteCelValueConverter protoLiteCelValueConverter, CelLiteDescriptorPool descriptorPool) {
72+
this.protoLiteCelValueConverter = protoLiteCelValueConverter;
73+
this.descriptorPool = descriptorPool;
74+
}
75+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ java_library(
2828
"//common/values:cel_value",
2929
"//common/values:cel_value_provider",
3030
"//common/values:proto_message_lite_value",
31+
"//common/values:proto_message_lite_value_provider",
3132
"//common/values:proto_message_value",
3233
"//common/values:proto_message_value_provider",
3334
"//testing:test_all_types_cel_java_proto3",
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.common.values;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
19+
import com.google.common.collect.ImmutableMap;
20+
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
21+
import dev.cel.common.types.StructTypeReference;
22+
import dev.cel.expr.conformance.proto3.TestAllTypes;
23+
import dev.cel.expr.conformance.proto3.TestAllTypesCelDescriptor;
24+
import java.util.Optional;
25+
import org.junit.Test;
26+
import org.junit.runner.RunWith;
27+
28+
@RunWith(TestParameterInjector.class)
29+
public class ProtoMessageLiteValueProviderTest {
30+
private static final ProtoMessageLiteValueProvider VALUE_PROVIDER =
31+
ProtoMessageLiteValueProvider.newInstance(TestAllTypesCelDescriptor.getDescriptor());
32+
33+
@Test
34+
public void newValue_unknownType_returnsEmpty() {
35+
assertThat(VALUE_PROVIDER.newValue("unknownType", ImmutableMap.of())).isEmpty();
36+
}
37+
38+
@Test
39+
public void newValue_emptyFields_success() {
40+
Optional<CelValue> value =
41+
VALUE_PROVIDER.newValue("cel.expr.conformance.proto3.TestAllTypes", ImmutableMap.of());
42+
ProtoMessageLiteValue protoMessageLiteValue = (ProtoMessageLiteValue) value.get();
43+
44+
assertThat(protoMessageLiteValue.value()).isEqualTo(TestAllTypes.getDefaultInstance());
45+
assertThat(protoMessageLiteValue.isZeroValue()).isTrue();
46+
assertThat(protoMessageLiteValue.celType())
47+
.isEqualTo(StructTypeReference.create("cel.expr.conformance.proto3.TestAllTypes"));
48+
}
49+
50+
@Test
51+
public void getProtoLiteCelValueConverter() {
52+
assertThat(VALUE_PROVIDER.getProtoLiteCelValueConverter()).isNotNull();
53+
}
54+
}

common/values/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ java_library(
4545
name = "proto_message_lite_value",
4646
exports = ["//common/src/main/java/dev/cel/common/values:proto_message_lite_value"],
4747
)
48+
49+
java_library(
50+
name = "proto_message_lite_value_provider",
51+
exports = ["//common/src/main/java/dev/cel/common/values:proto_message_lite_value_provider"],
52+
)

0 commit comments

Comments
 (0)