Skip to content

Commit f7db0e1

Browse files
l46kokcopybara-github
authored andcommitted
Store associated java class in WellKnownProto instead of its name
PiperOrigin-RevId: 747645852
1 parent c3cbda8 commit f7db0e1

File tree

4 files changed

+61
-53
lines changed

4 files changed

+61
-53
lines changed

common/src/main/java/dev/cel/common/internal/ProtoAdapter.java

+3-4
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public Object adaptProtoToValue(MessageOrBuilder proto) {
139139
// If the proto is not a well-known type, then the input Message is what's expected as the
140140
// output return value.
141141
WellKnownProto wellKnownProto =
142-
WellKnownProto.getByTypeName(typeName(proto.getDescriptorForType()));
142+
WellKnownProto.getByTypeName(typeName(proto.getDescriptorForType())).orElse(null);
143143
if (wellKnownProto == null) {
144144
return proto;
145145
}
@@ -280,7 +280,7 @@ private BidiConverter fieldToValueConverter(FieldDescriptor fieldDescriptor) {
280280
* considered, such as a packing an {@code google.protobuf.StringValue} into a {@code Any} value.
281281
*/
282282
public Message adaptValueToProto(Object value, String protoTypeName) {
283-
WellKnownProto wellKnownProto = WellKnownProto.getByTypeName(protoTypeName);
283+
WellKnownProto wellKnownProto = WellKnownProto.getByTypeName(protoTypeName).orElse(null);
284284
if (wellKnownProto == null) {
285285
if (value instanceof Message) {
286286
return (Message) value;
@@ -326,8 +326,7 @@ private static boolean isWrapperType(FieldDescriptor fieldDescriptor) {
326326
return false;
327327
}
328328
String fieldTypeName = fieldDescriptor.getMessageType().getFullName();
329-
WellKnownProto wellKnownProto = WellKnownProto.getByTypeName(fieldTypeName);
330-
return wellKnownProto != null && wellKnownProto.isWrapperType();
329+
return WellKnownProto.isWrapperType(fieldTypeName);
331330
}
332331

333332
private static int intCheckedCast(long value) {

common/src/main/java/dev/cel/common/internal/WellKnownProto.java

+48-46
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
import com.google.protobuf.UInt64Value;
3737
import com.google.protobuf.Value;
3838
import dev.cel.common.annotations.Internal;
39+
import java.util.Optional;
3940
import java.util.function.Function;
40-
import org.jspecify.annotations.Nullable;
4141

4242
/**
4343
* WellKnownProto types used throughout CEL. These types are specially handled to ensure that
@@ -46,77 +46,79 @@
4646
*/
4747
@Internal
4848
public enum WellKnownProto {
49-
ANY_VALUE("google.protobuf.Any", Any.class.getName()),
50-
DURATION("google.protobuf.Duration", Duration.class.getName()),
51-
JSON_LIST_VALUE("google.protobuf.ListValue", ListValue.class.getName()),
52-
JSON_STRUCT_VALUE("google.protobuf.Struct", Struct.class.getName()),
53-
JSON_VALUE("google.protobuf.Value", Value.class.getName()),
54-
TIMESTAMP("google.protobuf.Timestamp", Timestamp.class.getName()),
49+
ANY_VALUE("google.protobuf.Any", Any.class),
50+
DURATION("google.protobuf.Duration", Duration.class),
51+
JSON_LIST_VALUE("google.protobuf.ListValue", ListValue.class),
52+
JSON_STRUCT_VALUE("google.protobuf.Struct", Struct.class),
53+
JSON_VALUE("google.protobuf.Value", Value.class),
54+
TIMESTAMP("google.protobuf.Timestamp", Timestamp.class),
5555
// Wrapper types
56-
FLOAT_VALUE("google.protobuf.FloatValue", FloatValue.class.getName(), /* isWrapperType= */ true),
57-
INT32_VALUE("google.protobuf.Int32Value", Int32Value.class.getName(), /* isWrapperType= */ true),
58-
INT64_VALUE("google.protobuf.Int64Value", Int64Value.class.getName(), /* isWrapperType= */ true),
59-
STRING_VALUE(
60-
"google.protobuf.StringValue", StringValue.class.getName(), /* isWrapperType= */ true),
61-
BOOL_VALUE("google.protobuf.BoolValue", BoolValue.class.getName(), /* isWrapperType= */ true),
62-
BYTES_VALUE("google.protobuf.BytesValue", BytesValue.class.getName(), /* isWrapperType= */ true),
63-
DOUBLE_VALUE(
64-
"google.protobuf.DoubleValue", DoubleValue.class.getName(), /* isWrapperType= */ true),
65-
UINT32_VALUE(
66-
"google.protobuf.UInt32Value", UInt32Value.class.getName(), /* isWrapperType= */ true),
67-
UINT64_VALUE(
68-
"google.protobuf.UInt64Value", UInt64Value.class.getName(), /* isWrapperType= */ true),
56+
FLOAT_VALUE("google.protobuf.FloatValue", FloatValue.class, /* isWrapperType= */ true),
57+
INT32_VALUE("google.protobuf.Int32Value", Int32Value.class, /* isWrapperType= */ true),
58+
INT64_VALUE("google.protobuf.Int64Value", Int64Value.class, /* isWrapperType= */ true),
59+
STRING_VALUE("google.protobuf.StringValue", StringValue.class, /* isWrapperType= */ true),
60+
BOOL_VALUE("google.protobuf.BoolValue", BoolValue.class, /* isWrapperType= */ true),
61+
BYTES_VALUE("google.protobuf.BytesValue", BytesValue.class, /* isWrapperType= */ true),
62+
DOUBLE_VALUE("google.protobuf.DoubleValue", DoubleValue.class, /* isWrapperType= */ true),
63+
UINT32_VALUE("google.protobuf.UInt32Value", UInt32Value.class, /* isWrapperType= */ true),
64+
UINT64_VALUE("google.protobuf.UInt64Value", UInt64Value.class, /* isWrapperType= */ true),
6965
// These aren't explicitly called out as wrapper types in the spec, but behave like one, because
7066
// they are still converted into an equivalent primitive type.
7167

72-
EMPTY("google.protobuf.Empty", Empty.class.getName(), /* isWrapperType= */ true),
73-
FIELD_MASK("google.protobuf.FieldMask", FieldMask.class.getName(), /* isWrapperType= */ true),
68+
EMPTY("google.protobuf.Empty", Empty.class, /* isWrapperType= */ true),
69+
FIELD_MASK("google.protobuf.FieldMask", FieldMask.class, /* isWrapperType= */ true),
7470
;
7571

76-
private static final ImmutableMap<String, WellKnownProto> WELL_KNOWN_PROTO_MAP;
72+
private static final ImmutableMap<String, WellKnownProto> TYPE_NAME_TO_WELL_KNOWN_PROTO_MAP =
73+
stream(WellKnownProto.values())
74+
.collect(toImmutableMap(WellKnownProto::typeName, Function.identity()));
7775

78-
static {
79-
WELL_KNOWN_PROTO_MAP =
80-
stream(WellKnownProto.values())
81-
.collect(toImmutableMap(WellKnownProto::typeName, Function.identity()));
82-
}
76+
private static final ImmutableMap<Class<?>, WellKnownProto>
77+
CLASS_TO_NAME_TO_WELL_KNOWN_PROTO_MAP =
78+
stream(WellKnownProto.values())
79+
.collect(toImmutableMap(WellKnownProto::messageClass, Function.identity()));
8380

84-
private final String wellKnownProtoFullName;
85-
private final String javaClassName;
81+
private final String wellKnownProtoTypeName;
82+
private final Class<?> clazz;
8683
private final boolean isWrapperType;
8784

85+
/** Gets the fully qualified prototype name (ex: google.protobuf.FloatValue) */
8886
public String typeName() {
89-
return wellKnownProtoFullName;
87+
return wellKnownProtoTypeName;
9088
}
9189

92-
public String javaClassName() {
93-
return this.javaClassName;
90+
/** Gets the underlying java class for this WellKnownProto. */
91+
public Class<?> messageClass() {
92+
return clazz;
9493
}
9594

96-
public static @Nullable WellKnownProto getByTypeName(String typeName) {
97-
return WELL_KNOWN_PROTO_MAP.get(typeName);
95+
public static Optional<WellKnownProto> getByTypeName(String typeName) {
96+
return Optional.ofNullable(TYPE_NAME_TO_WELL_KNOWN_PROTO_MAP.get(typeName));
9897
}
9998

100-
public static boolean isWrapperType(String typeName) {
101-
WellKnownProto wellKnownProto = getByTypeName(typeName);
102-
if (wellKnownProto == null) {
103-
return false;
104-
}
99+
public static Optional<WellKnownProto> getByClass(Class<?> clazz) {
100+
return Optional.ofNullable(CLASS_TO_NAME_TO_WELL_KNOWN_PROTO_MAP.get(clazz));
101+
}
105102

106-
return wellKnownProto.isWrapperType();
103+
/**
104+
* Returns true if the provided {@code typeName} is a well known type, and it's a wrapper. False
105+
* otherwise.
106+
*/
107+
public static boolean isWrapperType(String typeName) {
108+
return getByTypeName(typeName).map(WellKnownProto::isWrapperType).orElse(false);
107109
}
108110

109111
public boolean isWrapperType() {
110112
return isWrapperType;
111113
}
112114

113-
WellKnownProto(String wellKnownProtoFullName, String javaClassName) {
114-
this(wellKnownProtoFullName, javaClassName, /* isWrapperType= */ false);
115+
WellKnownProto(String wellKnownProtoTypeName, Class<?> clazz) {
116+
this(wellKnownProtoTypeName, clazz, /* isWrapperType= */ false);
115117
}
116118

117-
WellKnownProto(String wellKnownProtoFullName, String javaClassName, boolean isWrapperType) {
118-
this.wellKnownProtoFullName = wellKnownProtoFullName;
119-
this.javaClassName = javaClassName;
119+
WellKnownProto(String wellKnownProtoFullName, Class<?> clazz, boolean isWrapperType) {
120+
this.wellKnownProtoTypeName = wellKnownProtoFullName;
121+
this.clazz = clazz;
120122
this.isWrapperType = isWrapperType;
121123
}
122124
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public CelValue fromProtoMessageToCelValue(MessageOrBuilder message) {
107107
}
108108

109109
WellKnownProto wellKnownProto =
110-
WellKnownProto.getByTypeName(message.getDescriptorForType().getFullName());
110+
WellKnownProto.getByTypeName(message.getDescriptorForType().getFullName()).orElse(null);
111111
if (wellKnownProto == null) {
112112
return ProtoMessageValue.create((Message) message, celDescriptorPool, this);
113113
}

common/src/test/java/dev/cel/common/internal/WellKnownProtoTest.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
import static com.google.common.truth.Truth.assertThat;
1818

19+
import com.google.protobuf.FloatValue;
1920
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
2021
import com.google.testing.junit.testparameterinjector.TestParameters;
22+
import java.util.List;
2123
import org.junit.Test;
2224
import org.junit.runner.RunWith;
2325

@@ -53,7 +55,12 @@ public void isWrapperType_withTypeName_false(String typeName) {
5355
}
5456

5557
@Test
56-
public void getJavaClassName() {
57-
assertThat(WellKnownProto.ANY_VALUE.javaClassName()).isEqualTo("com.google.protobuf.Any");
58+
public void getByClass_success() {
59+
assertThat(WellKnownProto.getByClass(FloatValue.class)).hasValue(WellKnownProto.FLOAT_VALUE);
60+
}
61+
62+
@Test
63+
public void getByClass_unknownClass_returnsEmpty() {
64+
assertThat(WellKnownProto.getByClass(List.class)).isEmpty();
5865
}
5966
}

0 commit comments

Comments
 (0)