Skip to content

Commit a76a728

Browse files
zenfenansivaprasanna
authored andcommitted
AVRO-4133: Support default enum value in Protobuf to Avro (apache#3367)
* [AVRO-4133] Support default enum value in Protobuf to Avro * [AVRO-4133] Add unit test for proto schema enum default * [AVRO-4133] Exclude generated test proto code --------- Co-authored-by: sivaprasanna <sivaprasanna@sivaprasannas-MacBook-Air.local>
1 parent 4aa4e53 commit a76a728

7 files changed

Lines changed: 951 additions & 2 deletions

File tree

lang/java/protobuf/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
<arg value="--java_out=src/test/java/"/>
6666
<arg value="src/test/protobuf/test_multiple_files.proto"/>
6767
</exec>
68+
<exec executable="protoc">
69+
<arg value="--java_out=src/test/java/"/>
70+
<arg value="src/test/protobuf/test_proto3.proto"/>
71+
</exec>
6872
</target>
6973
</configuration>
7074
<goals>

lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ProtobufData.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ private Schema getNonRepeatedSchema(FieldDescriptor f) {
301301
case SFIXED64:
302302
return Schema.create(Schema.Type.LONG);
303303
case ENUM:
304-
return getSchema(f.getEnumType());
304+
return f.hasDefaultValue() ? getSchema(f.getEnumType(), ((EnumValueDescriptor) f.getDefaultValue()).getName())
305+
: getSchema(f.getEnumType());
305306
case MESSAGE:
306307
result = getSchema(f.getMessageType());
307308
if (f.isOptional())
@@ -315,11 +316,22 @@ private Schema getNonRepeatedSchema(FieldDescriptor f) {
315316
}
316317

317318
public Schema getSchema(EnumDescriptor d) {
319+
List<String> symbols = getEnumSymbols(d);
320+
String enumDefault = symbols.isEmpty() ? null : symbols.get(0);
321+
return Schema.createEnum(d.getName(), null, getNamespace(d.getFile(), d.getContainingType()), symbols, enumDefault);
322+
}
323+
324+
public Schema getSchema(EnumDescriptor d, String enumDefault) {
325+
List<String> symbols = getEnumSymbols(d);
326+
return Schema.createEnum(d.getName(), null, getNamespace(d.getFile(), d.getContainingType()), symbols, enumDefault);
327+
}
328+
329+
private List<String> getEnumSymbols(EnumDescriptor d) {
318330
List<String> symbols = new ArrayList<>(d.getValues().size());
319331
for (EnumValueDescriptor e : d.getValues()) {
320332
symbols.add(e.getName());
321333
}
322-
return Schema.createEnum(d.getName(), null, getNamespace(d.getFile(), d.getContainingType()), symbols);
334+
return symbols;
323335
}
324336

325337
private static final JsonFactory FACTORY = new JsonFactory();

lang/java/protobuf/src/test/java/org/apache/avro/protobuf/TestProtobuf.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.avro.io.DecoderFactory;
2525
import org.apache.avro.io.Encoder;
2626
import org.apache.avro.io.EncoderFactory;
27+
import org.apache.avro.protobuf.noopt.TestProto3;
2728
import org.apache.avro.specific.SpecificData;
2829
import org.apache.commons.compress.utils.Lists;
2930
import org.junit.jupiter.api.Test;
@@ -146,4 +147,17 @@ void getNonRepeatedSchemaWithLogicalType() throws Exception {
146147
Schema s2 = instance2.getSchema(com.google.protobuf.Timestamp.class);
147148
assertEquals(conversion.getRecommendedSchema(), s2);
148149
}
150+
151+
@Test
152+
void enumDefault() {
153+
Schema fooSchema = ProtobufData.get().getSchema(Foo.class);
154+
assertEquals("Z", fooSchema.getField("enum").schema().getEnumDefault());
155+
156+
Schema nSchema = ProtobufData.get().getSchema(N.class);
157+
assertEquals("A", nSchema.getEnumDefault());
158+
159+
Schema proto3Schema = ProtobufData.get().getSchema(TestProto3.User.class);
160+
assertEquals("STATUS_UNKNOWN", proto3Schema.getField("status").defaultVal());
161+
assertEquals("STATUS_UNKNOWN", proto3Schema.getField("status").schema().getEnumDefault());
162+
}
149163
}

0 commit comments

Comments
 (0)