diff --git a/protobuf/src/main/java/dev/cel/protobuf/CelLiteDescriptor.java b/protobuf/src/main/java/dev/cel/protobuf/CelLiteDescriptor.java index 305da6bc7..e2b299445 100644 --- a/protobuf/src/main/java/dev/cel/protobuf/CelLiteDescriptor.java +++ b/protobuf/src/main/java/dev/cel/protobuf/CelLiteDescriptor.java @@ -397,6 +397,27 @@ public FieldLiteDescriptor( return defaultScalarValues.contains(value) ? null : value; } + /** Describes map entry type {@code fullName}, whose key and value are fields 1 and 2. */ + protected static MessageLiteDescriptor mapEntry( + String fullName, + FieldLiteDescriptor.Type keyType, + FieldLiteDescriptor.Type valueType, + String valueTypeName) { + return new MessageLiteDescriptor( + fullName, + Arrays.asList( + new FieldLiteDescriptor( + 1, "key", FieldLiteDescriptor.EncodingType.SINGULAR, keyType, false, ""), + new FieldLiteDescriptor( + 2, + "value", + FieldLiteDescriptor.EncodingType.SINGULAR, + valueType, + false, + valueTypeName)), + () -> null); + } + protected CelLiteDescriptor(String version, List messageInfoList) { Map protoFqnMap = new HashMap<>(getMapInitialCapacity(messageInfoList.size())); diff --git a/protobuf/src/main/java/dev/cel/protobuf/templates/cel_lite_descriptor_template.txt b/protobuf/src/main/java/dev/cel/protobuf/templates/cel_lite_descriptor_template.txt index 512b0564d..35d7b8401 100644 --- a/protobuf/src/main/java/dev/cel/protobuf/templates/cel_lite_descriptor_template.txt +++ b/protobuf/src/main/java/dev/cel/protobuf/templates/cel_lite_descriptor_template.txt @@ -40,6 +40,7 @@ public final class ${descriptor_class_name} extends CelLiteDescriptor { List descriptors = new ArrayList<>(${descriptor_metadata_list?size}); List fieldDescriptors; <#list descriptor_metadata_list as descriptor_metadata> + <#if descriptor_metadata.javaClassName??> fieldDescriptors = new ArrayList<>(${descriptor_metadata.fieldDescriptors?size}); <#list descriptor_metadata.fieldDescriptors as field_descriptor> @@ -57,13 +58,17 @@ public final class ${descriptor_class_name} extends CelLiteDescriptor { new MessageLiteDescriptor( "${descriptor_metadata.protoTypeName}", fieldDescriptors, - <#if descriptor_metadata.javaClassName??> ${descriptor_metadata.javaClassName}::newBuilder - <#else> - () -> null - ) ); + <#else> + + descriptors.add(mapEntry( + "${descriptor_metadata.protoTypeName}", + ${descriptor_metadata.fieldDescriptors[0].protoFieldTypeEnumName}, + ${descriptor_metadata.fieldDescriptors[1].protoFieldTypeEnumName}, + "${descriptor_metadata.fieldDescriptors[1].fieldProtoTypeName}")); + return Collections.unmodifiableList(descriptors); diff --git a/protobuf/src/test/java/dev/cel/protobuf/CelLiteDescriptorTest.java b/protobuf/src/test/java/dev/cel/protobuf/CelLiteDescriptorTest.java index 98434273d..1eb53da65 100644 --- a/protobuf/src/test/java/dev/cel/protobuf/CelLiteDescriptorTest.java +++ b/protobuf/src/test/java/dev/cel/protobuf/CelLiteDescriptorTest.java @@ -178,6 +178,30 @@ public void fieldDescriptor_nestedMessage_fullyQualifiedNames() { .isEqualTo("cel.expr.conformance.proto3.TestAllTypes.NestedMessage"); } + @Test + public void mapEntryDescriptor_describesKeyAndValue() { + MessageLiteDescriptor mapEntryDescriptor = + TEST_ALL_TYPES_CEL_LITE_DESCRIPTOR + .getProtoTypeNamesToDescriptors() + .get("cel.expr.conformance.proto3.TestAllTypes.MapInt64NestedTypeEntry"); + + FieldLiteDescriptor key = mapEntryDescriptor.getByFieldNumberOrThrow(1); + FieldLiteDescriptor value = mapEntryDescriptor.getByFieldNumberOrThrow(2); + + assertThat(mapEntryDescriptor.newMessageBuilder()).isNull(); + assertThat(key.getFieldName()).isEqualTo("key"); + assertThat(key.getEncodingType()).isEqualTo(EncodingType.SINGULAR); + assertThat(key.getProtoFieldType()).isEqualTo(FieldLiteDescriptor.Type.INT64); + assertThat(key.getIsPacked()).isFalse(); + assertThat(key.getFieldProtoTypeName()).isEmpty(); + assertThat(value.getFieldName()).isEqualTo("value"); + assertThat(value.getEncodingType()).isEqualTo(EncodingType.SINGULAR); + assertThat(value.getProtoFieldType()).isEqualTo(FieldLiteDescriptor.Type.MESSAGE); + assertThat(value.getIsPacked()).isFalse(); + assertThat(value.getFieldProtoTypeName()) + .isEqualTo("cel.expr.conformance.proto3.NestedTestAllTypes"); + } + private enum ProtoFieldTypeTestCase { DOUBLE(FieldLiteDescriptor.Type.DOUBLE, 1, WireFormat.FieldType.DOUBLE), FLOAT(FieldLiteDescriptor.Type.FLOAT, 2, WireFormat.FieldType.FLOAT),