This is an automated email from the ASF dual-hosted git repository. iemejia pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/avro.git
commit cff8d11d0de6b3cfe8941775abcf151a801de1e2 Author: prygunovx <[email protected]> AuthorDate: Mon Aug 17 11:30:17 2026 +0200 AVRO-4332: [java] Add support for enum default values in IDL serialization IdlUtils.writeSchema did not emit the enum default when serializing a schema to IDL, even though IdlReader parses it. As a result, an enum default was silently dropped when round-tripping a schema through IDL. Append "= <default>;" after the enum body when the schema has a default, matching the IDL grammar (RBrace defaultSymbol=enumDefault?), and add tests covering the with-default, without-default and write-then-parse round-trip cases. --- .../main/java/org/apache/avro/idl/IdlUtils.java | 7 ++- .../java/org/apache/avro/idl/IdlUtilsTest.java | 55 ++++++++++++++++++++++ .../avro/idl/idl_utils_test_enum_default.avdl | 10 ++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lang/java/idl/src/main/java/org/apache/avro/idl/IdlUtils.java b/lang/java/idl/src/main/java/org/apache/avro/idl/IdlUtils.java index 29c787c9e2..80499a2709 100644 --- a/lang/java/idl/src/main/java/org/apache/avro/idl/IdlUtils.java +++ b/lang/java/idl/src/main/java/org/apache/avro/idl/IdlUtils.java @@ -285,7 +285,12 @@ public final class IdlUtils { } else { throw new AvroRuntimeException("Enum schema must have at least a symbol " + schema); } - writer.append(NEWLINE).append(indent).append("}").append(NEWLINE); + writer.append(NEWLINE).append(indent).append("}"); + String enumDefault = schema.getEnumDefault(); + if (enumDefault != null) { + writer.append(" = ").append(enumDefault).append(";"); + } + writer.append(NEWLINE); } else /* (type == Schema.Type.FIXED) */ { writer.append(indent).append("fixed ").append(schemaName).append('(') .append(Integer.toString(schema.getFixedSize())).append(");").append(NEWLINE); diff --git a/lang/java/idl/src/test/java/org/apache/avro/idl/IdlUtilsTest.java b/lang/java/idl/src/test/java/org/apache/avro/idl/IdlUtilsTest.java index ef2a81d3ff..7b3f2fd91d 100644 --- a/lang/java/idl/src/test/java/org/apache/avro/idl/IdlUtilsTest.java +++ b/lang/java/idl/src/test/java/org/apache/avro/idl/IdlUtilsTest.java @@ -17,6 +17,7 @@ */ package org.apache.avro.idl; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -33,11 +34,15 @@ import org.apache.avro.Protocol; import org.apache.avro.Schema; import org.junit.jupiter.api.Test; +import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class IdlUtilsTest { @Test @@ -103,6 +108,56 @@ public class IdlUtilsTest { () -> IdlUtils.writeIdlProtocol(new StringWriter(), Schema.create(Schema.Type.STRING))); } + @Test + public void enumDefaultIsWrittenToIdl() throws IOException { + Schema withDefault = Schema.createEnum("Status", null, "naming", asList("ACTIVE", "INACTIVE"), "ACTIVE"); + Schema withoutDefault = Schema.createEnum("Status", null, "naming", asList("ACTIVE", "INACTIVE")); + + StringWriter withDefaultWriter = new StringWriter(); + IdlUtils.writeIdlProtocol(withDefaultWriter, withDefault); + StringWriter withoutDefaultWriter = new StringWriter(); + IdlUtils.writeIdlProtocol(withoutDefaultWriter, withoutDefault); + + assertTrue(withDefaultWriter.toString().contains("} = ACTIVE;"), + "Enum with default should serialize default value"); + assertFalse(withoutDefaultWriter.toString().contains("="), "Enum without default should not serialize a default"); + } + + @Test + public void enumDefaultSurvivesWriteThenParse() throws IOException { + Schema withDefault = Schema.createEnum("Status", null, "naming", asList("ACTIVE", "INACTIVE"), "ACTIVE"); + + StringWriter withDefaultWriter = new StringWriter(); + IdlUtils.writeIdlProtocol(withDefaultWriter, withDefault); + + // The written IDL must parse back into an equivalent schema: this is the bug + // that was reported. + IdlReader reader = new IdlReader(); + Schema roundTripped; + try (InputStream in = new ByteArrayInputStream(withDefaultWriter.toString().getBytes(StandardCharsets.UTF_8))) { + roundTripped = reader.parse(in).getNamedSchemas().get("naming.Status"); + } + assertEquals("ACTIVE", roundTripped.getEnumDefault()); + } + + @Test + public void enumDefaultIsReadFromIdlFile() throws IOException { + Protocol protocol = parseIdlResource("idl_utils_test_enum_default.avdl").getProtocol(); + + assertEquals("ACTIVE", protocol.getType("naming.Status").getEnumDefault()); + assertNull(protocol.getType("naming.Color").getEnumDefault()); + } + + @Test + public void idlFileWithEnumDefaultIsWrittenBackUnchanged() throws IOException { + Protocol protocol = parseIdlResource("idl_utils_test_enum_default.avdl").getProtocol(); + + StringWriter buffer = new StringWriter(); + IdlUtils.writeIdlProtocol(buffer, protocol); + + assertEquals(getResourceAsString("idl_utils_test_enum_default.avdl"), buffer.toString()); + } + @Test public void cannotWriteEmptyEnums() { assertThrows(AvroRuntimeException.class, diff --git a/lang/java/idl/src/test/resources/org/apache/avro/idl/idl_utils_test_enum_default.avdl b/lang/java/idl/src/test/resources/org/apache/avro/idl/idl_utils_test_enum_default.avdl new file mode 100644 index 0000000000..d2c2a0d5eb --- /dev/null +++ b/lang/java/idl/src/test/resources/org/apache/avro/idl/idl_utils_test_enum_default.avdl @@ -0,0 +1,10 @@ +@namespace("naming") +protocol EnumDefaults { + enum Status { + ACTIVE, INACTIVE + } = ACTIVE; + + enum Color { + RED, GREEN + } +}
