Skip to content

Commit a6f2930

Browse files
Merge pull request #1074 from andrewparmet:fix-fieldmask-celvalue
PiperOrigin-RevId: 927360423
2 parents 7452e0d + c5d86d9 commit a6f2930

5 files changed

Lines changed: 50 additions & 15 deletions

File tree

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
import static com.google.common.collect.ImmutableList.toImmutableList;
1818
import static com.google.common.collect.ImmutableMap.toImmutableMap;
1919

20-
import com.google.common.base.CaseFormat;
21-
import com.google.common.base.Joiner;
2220
import com.google.common.base.Preconditions;
2321
import com.google.common.collect.ImmutableList;
2422
import com.google.common.collect.ImmutableMap;
@@ -29,7 +27,6 @@
2927
import com.google.protobuf.BytesValue;
3028
import com.google.protobuf.DoubleValue;
3129
import com.google.protobuf.Duration;
32-
import com.google.protobuf.FieldMask;
3330
import com.google.protobuf.FloatValue;
3431
import com.google.protobuf.Int32Value;
3532
import com.google.protobuf.Int64Value;
@@ -44,8 +41,6 @@
4441
import dev.cel.common.annotations.Internal;
4542
import dev.cel.common.internal.ProtoTimeUtils;
4643
import dev.cel.common.internal.WellKnownProto;
47-
import java.util.ArrayList;
48-
import java.util.List;
4944

5045
/**
5146
* {@code BaseProtoCelValueConverter} contains the common logic for converting between native Java
@@ -103,15 +98,6 @@ protected Object fromWellKnownProto(MessageLiteOrBuilder message, WellKnownProto
10398
return UnsignedLong.valueOf(((UInt32Value) message).getValue());
10499
case UINT64_VALUE:
105100
return UnsignedLong.fromLongBits(((UInt64Value) message).getValue());
106-
case FIELD_MASK:
107-
FieldMask fieldMask = (FieldMask) message;
108-
List<String> paths = new ArrayList<>(fieldMask.getPathsCount());
109-
for (String path : fieldMask.getPathsList()) {
110-
if (!path.isEmpty()) {
111-
paths.add(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, path));
112-
}
113-
}
114-
return normalizePrimitive(Joiner.on(",").join(paths));
115101
case EMPTY:
116102
return ImmutableMap.of();
117103
default:

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ protected Object fromWellKnownProto(MessageLiteOrBuilder msg, WellKnownProto wel
7171
"Unpacking failed for message: " + message.getDescriptorForType().getFullName(), e);
7272
}
7373
return toRuntimeValue(unpackedMessage);
74+
case FIELD_MASK:
75+
return ProtoMessageValue.create(
76+
(Message) message, celDescriptorPool, this, celOptions.enableJsonFieldNames());
7477
default:
7578
return super.fromWellKnownProto(message, wellKnownProto);
7679
}

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import com.google.protobuf.CodedInputStream;
2929
import com.google.protobuf.ExtensionRegistryLite;
3030
import com.google.protobuf.MessageLite;
31+
import com.google.protobuf.MessageLiteOrBuilder;
3132
import com.google.protobuf.WireFormat;
3233
import dev.cel.common.annotations.Internal;
3334
import dev.cel.common.internal.CelLiteDescriptorPool;
@@ -178,12 +179,27 @@ public Object toRuntimeValue(Object value) {
178179
return ProtoMessageLiteValue.create(msg, descriptor.getProtoTypeName(), this);
179180
}
180181

181-
return super.fromWellKnownProto(msg, wellKnownProto);
182+
return fromWellKnownProto(msg, wellKnownProto);
182183
}
183184

184185
return super.toRuntimeValue(value);
185186
}
186187

188+
@Override
189+
protected Object fromWellKnownProto(MessageLiteOrBuilder msg, WellKnownProto wellKnownProto) {
190+
if (wellKnownProto == WellKnownProto.FIELD_MASK) {
191+
MessageLite message = (MessageLite) msg;
192+
MessageLiteDescriptor descriptor =
193+
descriptorPool
194+
.findDescriptor(message)
195+
.orElseThrow(
196+
() -> new NoSuchElementException("Could not find a descriptor for: " + message));
197+
return ProtoMessageLiteValue.create(message, descriptor.getProtoTypeName(), this);
198+
}
199+
200+
return super.fromWellKnownProto(msg, wellKnownProto);
201+
}
202+
187203
private Object getDefaultValue(FieldLiteDescriptor fieldDescriptor) {
188204
EncodingType encodingType = fieldDescriptor.getEncodingType();
189205
switch (encodingType) {

common/src/test/java/dev/cel/common/values/ProtoLiteCelValueConverterTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.protobuf.DoubleValue;
2828
import com.google.protobuf.Duration;
2929
import com.google.protobuf.ExtensionRegistryLite;
30+
import com.google.protobuf.FieldMask;
3031
import com.google.protobuf.FloatValue;
3132
import com.google.protobuf.Int32Value;
3233
import com.google.protobuf.Int64Value;
@@ -104,6 +105,17 @@ public void fromProtoMessageToCelValue_withWellKnownProto_convertsToPrimitivesFr
104105
assertThat(adaptedValue).isEqualTo(testCase.value);
105106
}
106107

108+
@Test
109+
public void fromProtoMessageToCelValue_fieldMask_returnsProtoMessageLiteValue() {
110+
FieldMask fieldMask = FieldMask.newBuilder().addPaths("foo").addPaths("bar").build();
111+
112+
Object adaptedValue = PROTO_LITE_CEL_VALUE_CONVERTER.toRuntimeValue(fieldMask);
113+
114+
assertThat(adaptedValue).isInstanceOf(ProtoMessageLiteValue.class);
115+
assertThat(((ProtoMessageLiteValue) adaptedValue).select("paths"))
116+
.isEqualTo(ImmutableList.of("foo", "bar"));
117+
}
118+
107119
/** Test cases for repeated_int64: 1L,2L,3L */
108120
@SuppressWarnings("ImmutableEnumChecker") // Test only
109121
private enum RepeatedFieldBytesTestCase {

common/src/test/java/dev/cel/common/values/ProtoMessageValueTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.protobuf.Any;
2424
import com.google.protobuf.ByteString;
2525
import com.google.protobuf.DynamicMessage;
26+
import com.google.protobuf.FieldMask;
2627
import com.google.protobuf.FloatValue;
2728
import com.google.protobuf.Int32Value;
2829
import com.google.protobuf.Int64Value;
@@ -303,6 +304,23 @@ public void selectField_durationOutOfRange_success(int seconds, int nanos) {
303304
.isEqualTo(Duration.ofSeconds(seconds, nanos));
304305
}
305306

307+
@Test
308+
public void selectField_fieldMask_returnsProtoMessageValue() {
309+
TestAllTypes testAllTypes =
310+
TestAllTypes.newBuilder()
311+
.setFieldMask(FieldMask.newBuilder().addPaths("foo").addPaths("bar"))
312+
.build();
313+
314+
ProtoMessageValue protoMessageValue =
315+
ProtoMessageValue.create(
316+
testAllTypes, DefaultDescriptorPool.INSTANCE, PROTO_CEL_VALUE_CONVERTER, false);
317+
318+
Object selected = protoMessageValue.select("field_mask");
319+
assertThat(selected).isInstanceOf(ProtoMessageValue.class);
320+
assertThat(((ProtoMessageValue) selected).select("paths"))
321+
.isEqualTo(ImmutableList.of("foo", "bar"));
322+
}
323+
306324
@Test
307325
public void selectField_fixed32_returnsUnsignedLong() {
308326
TestAllTypes testAllTypes = TestAllTypes.newBuilder().setSingleFixed32(1).build();

0 commit comments

Comments
 (0)