This is an automated email from the ASF dual-hosted git repository.

rskraba pushed a commit to branch branch-1.11
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/branch-1.11 by this push:
     new ceaf649  AVRO-3305: Only mangle type identifier keywords when used as 
types  (#1457)
ceaf649 is described below

commit ceaf64952e2297964e82f400f426fc0490bf7fea
Author: Kyle Carter <[email protected]>
AuthorDate: Tue Feb 1 11:32:12 2022 -0700

    AVRO-3305: Only mangle type identifier keywords when used as types  (#1457)
    
    * AVRO-3305: Only mangle type identifier keywords when types
    
    Instead of treating all Java keywords identically, only mangles what
    the JLS terms as "contextual keywords" when used in the context they
    are reserved. Specifically, only mangle reserved type identifiers
    when used as type identifiers.
    
    * AVRO-3305: Extend tests to test mangling of all types of keywords
    
    Previously tests only tested with a subset of the keywords accounted for
    in the Avro compiler. This commit extends those tests to test against all
    known keywords.
---
 .../org/apache/avro/specific/SpecificData.java     |  2 -
 .../avro/compiler/specific/SpecificCompiler.java   | 48 +++++++++--
 .../specific/templates/java/classic/enum.vm        |  2 +-
 .../specific/templates/java/classic/fixed.vm       | 20 ++---
 .../specific/templates/java/classic/protocol.vm    |  6 +-
 .../specific/templates/java/classic/record.vm      | 92 +++++++++++-----------
 .../compiler/specific/TestSpecificCompiler.java    |  9 ++-
 7 files changed, 111 insertions(+), 68 deletions(-)

diff --git 
a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java 
b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
index 8efd904..f392868 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/specific/SpecificData.java
@@ -103,8 +103,6 @@ public class SpecificData extends GenericData {
       "throw", "throws", "transient", "try", "void", "volatile", "while",
       // Literals from Section 3.10 can't be used as identifiers.
       "true", "false", "null",
-      // Some keywords from Section 3.8 can't be used as type identifiers.
-      "var", "yield", "record",
       // Note that module-related restricted keywords can still be used.
       // Class names used internally by the avro code generator
       "Builder"));
diff --git 
a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
 
b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
index b517cbc..7e6a9c7 100644
--- 
a/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
+++ 
b/lang/java/compiler/src/main/java/org/apache/avro/compiler/specific/SpecificCompiler.java
@@ -135,7 +135,7 @@ public class SpecificCompiler {
   }
 
   /* Reserved words for accessor/mutator methods */
-  private static final Set<String> ACCESSOR_MUTATOR_RESERVED_WORDS = new 
HashSet<>(
+  protected static final Set<String> ACCESSOR_MUTATOR_RESERVED_WORDS = new 
HashSet<>(
       Arrays.asList("class", "schema", "classSchema"));
 
   static {
@@ -143,8 +143,17 @@ public class SpecificCompiler {
     ACCESSOR_MUTATOR_RESERVED_WORDS.addAll(RESERVED_WORDS);
   }
 
+  /* Reserved words for type identifiers */
+  protected static final Set<String> TYPE_IDENTIFIER_RESERVED_WORDS = new 
HashSet<>(
+      Arrays.asList("var", "yield", "record"));
+
+  static {
+    // Add reserved words to type identifier reserved words
+    TYPE_IDENTIFIER_RESERVED_WORDS.addAll(RESERVED_WORDS);
+  }
+
   /* Reserved words for error types */
-  private static final Set<String> ERROR_RESERVED_WORDS = new 
HashSet<>(Arrays.asList("message", "cause"));
+  protected static final Set<String> ERROR_RESERVED_WORDS = new 
HashSet<>(Arrays.asList("message", "cause"));
 
   static {
     // Add accessor/mutator reserved words to error reserved words
@@ -558,7 +567,7 @@ public class SpecificCompiler {
     String out = renderTemplate(templateDir + "protocol.vm", context);
 
     OutputFile outputFile = new OutputFile();
-    String mangledName = mangle(protocol.getName());
+    String mangledName = mangleTypeIdentifier(protocol.getName());
     outputFile.path = makePath(mangledName, mangle(protocol.getNamespace()));
     outputFile.contents = out;
     outputFile.outputCharacterEncoding = outputCharacterEncoding;
@@ -630,7 +639,7 @@ public class SpecificCompiler {
     }
 
     OutputFile outputFile = new OutputFile();
-    String name = mangle(schema.getName());
+    String name = mangleTypeIdentifier(schema.getName());
     outputFile.path = makePath(name, mangle(schema.getNamespace()));
     outputFile.contents = output;
     outputFile.outputCharacterEncoding = outputCharacterEncoding;
@@ -796,7 +805,7 @@ public class SpecificCompiler {
     case RECORD:
     case ENUM:
     case FIXED:
-      return mangle(schema.getFullName());
+      return mangleFullyQualified(schema.getFullName());
     case ARRAY:
       return "java.util.List<" + javaType(schema.getElementType()) + ">";
     case MAP:
@@ -828,6 +837,19 @@ public class SpecificCompiler {
     }
   }
 
+  private String mangleFullyQualified(String fullName) {
+    int lastDot = fullName.lastIndexOf('.');
+
+    if (lastDot < 0) {
+      return mangleTypeIdentifier(fullName);
+    } else {
+      String namespace = fullName.substring(0, lastDot);
+      String typeName = fullName.substring(lastDot + 1);
+
+      return mangle(namespace) + "." + mangleTypeIdentifier(typeName);
+    }
+  }
+
   private LogicalType getLogicalType(Schema schema) {
     if (enableDecimalLogicalType || !(schema.getLogicalType() instanceof 
LogicalTypes.Decimal)) {
       return schema.getLogicalType();
@@ -1061,6 +1083,22 @@ public class SpecificCompiler {
   }
 
   /**
+   * Utility for template use. Adds a dollar sign to reserved words in type
+   * identifiers.
+   */
+  public static String mangleTypeIdentifier(String word) {
+    return mangleTypeIdentifier(word, false);
+  }
+
+  /**
+   * Utility for template use. Adds a dollar sign to reserved words in type
+   * identifiers.
+   */
+  public static String mangleTypeIdentifier(String word, boolean isError) {
+    return mangle(word, isError ? ERROR_RESERVED_WORDS : 
TYPE_IDENTIFIER_RESERVED_WORDS);
+  }
+
+  /**
    * Utility for template use. Adds a dollar sign to reserved words.
    */
   public static String mangle(String word, Set<String> reservedWords) {
diff --git 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/enum.vm
 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/enum.vm
index c3feab9..fa5aa3f 100644
--- 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/enum.vm
+++ 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/enum.vm
@@ -25,7 +25,7 @@ package $this.mangle($schema.getNamespace());
 @$annotation
 #end
 @org.apache.avro.specific.AvroGenerated
-public enum ${this.mangle($schema.getName())} implements 
org.apache.avro.generic.GenericEnumSymbol<${this.mangle($schema.getName())}> {
+public enum ${this.mangleTypeIdentifier($schema.getName())} implements 
org.apache.avro.generic.GenericEnumSymbol<${this.mangleTypeIdentifier($schema.getName())}>
 {
   #foreach ($symbol in ${schema.getEnumSymbols()})${this.mangle($symbol)}#if 
($foreach.hasNext), #end#end
   ;
   public static final org.apache.avro.Schema SCHEMA$ = new 
org.apache.avro.Schema.Parser().parse("${this.javaEscape($schema.toString())}");
diff --git 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/fixed.vm
 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/fixed.vm
index f4c935a..dbbef6f 100644
--- 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/fixed.vm
+++ 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/fixed.vm
@@ -26,35 +26,35 @@ package $this.mangle($schema.getNamespace());
 #end
 @org.apache.avro.specific.FixedSize($schema.getFixedSize())
 @org.apache.avro.specific.AvroGenerated
-public class ${this.mangle($schema.getName())} extends 
org.apache.avro.specific.SpecificFixed {
+public class ${this.mangleTypeIdentifier($schema.getName())} extends 
org.apache.avro.specific.SpecificFixed {
   private static final long serialVersionUID = ${this.fingerprint64($schema)}L;
   public static final org.apache.avro.Schema SCHEMA$ = new 
org.apache.avro.Schema.Parser().parse("${this.javaEscape($schema.toString())}");
   public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
   public org.apache.avro.Schema getSchema() { return SCHEMA$; }
 
-  /** Creates a new ${this.mangle($schema.getName())} */
-  public ${this.mangle($schema.getName())}() {
+  /** Creates a new ${this.mangleTypeIdentifier($schema.getName())} */
+  public ${this.mangleTypeIdentifier($schema.getName())}() {
     super();
   }
 
   /**
-   * Creates a new ${this.mangle($schema.getName())} with the given bytes.
-   * @param bytes The bytes to create the new 
${this.mangle($schema.getName())}.
+   * Creates a new ${this.mangleTypeIdentifier($schema.getName())} with the 
given bytes.
+   * @param bytes The bytes to create the new 
${this.mangleTypeIdentifier($schema.getName())}.
    */
-  public ${this.mangle($schema.getName())}(byte[] bytes) {
+  public ${this.mangleTypeIdentifier($schema.getName())}(byte[] bytes) {
     super(bytes);
   }
 
-  private static final 
org.apache.avro.io.DatumWriter<${this.mangle($schema.getName())}>
-    WRITER$ = new 
org.apache.avro.specific.SpecificDatumWriter<${this.mangle($schema.getName())}>(SCHEMA$);
+  private static final 
org.apache.avro.io.DatumWriter<${this.mangleTypeIdentifier($schema.getName())}>
+    WRITER$ = new 
org.apache.avro.specific.SpecificDatumWriter<${this.mangleTypeIdentifier($schema.getName())}>(SCHEMA$);
 
   @Override public void writeExternal(java.io.ObjectOutput out)
     throws java.io.IOException {
     WRITER$.write(this, org.apache.avro.specific.SpecificData.getEncoder(out));
   }
 
-  private static final 
org.apache.avro.io.DatumReader<${this.mangle($schema.getName())}>
-    READER$ = new 
org.apache.avro.specific.SpecificDatumReader<${this.mangle($schema.getName())}>(SCHEMA$);
+  private static final 
org.apache.avro.io.DatumReader<${this.mangleTypeIdentifier($schema.getName())}>
+    READER$ = new 
org.apache.avro.specific.SpecificDatumReader<${this.mangleTypeIdentifier($schema.getName())}>(SCHEMA$);
 
   @Override public void readExternal(java.io.ObjectInput in)
     throws java.io.IOException {
diff --git 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/protocol.vm
 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/protocol.vm
index 055cf8e..f9a4d1a 100644
--- 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/protocol.vm
+++ 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/protocol.vm
@@ -26,7 +26,7 @@ package $this.mangle($protocol.getNamespace());
 @$annotation
 #end
 @org.apache.avro.specific.AvroGenerated
-public interface $this.mangle($protocol.getName()) {
+public interface $this.mangleTypeIdentifier($protocol.getName()) {
   public static final org.apache.avro.Protocol PROTOCOL = 
org.apache.avro.Protocol.parse(${this.javaSplit($protocol.toString())});
 #foreach ($e in $protocol.getMessages().entrySet())
 #set ($name = $e.getKey())
@@ -65,8 +65,8 @@ ${this.mangle($error.getFullName())}##
   /** $protocol.getDoc() */
 #end
   @org.apache.avro.specific.AvroGenerated
-  public interface Callback extends $this.mangle($protocol.getName()) {
-    public static final org.apache.avro.Protocol PROTOCOL = #if 
($this.mangle($protocol.getNamespace()))$this.mangle($protocol.getNamespace()).#end${this.mangle($protocol.getName())}.PROTOCOL;
+  public interface Callback extends 
$this.mangleTypeIdentifier($protocol.getName()) {
+    public static final org.apache.avro.Protocol PROTOCOL = #if 
($this.mangle($protocol.getNamespace()))$this.mangle($protocol.getNamespace()).#end${this.mangleTypeIdentifier($protocol.getName())}.PROTOCOL;
 #foreach ($e in $protocol.getMessages().entrySet())
 #set ($name = $e.getKey())
 #set ($message = $e.getValue())
diff --git 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
index 563cd86..4415521 100755
--- 
a/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
+++ 
b/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/record.vm
@@ -36,7 +36,7 @@ import org.apache.avro.message.SchemaStore;
 @$annotation
 #end
 @org.apache.avro.specific.AvroGenerated
-public class ${this.mangle($schema.getName())}#if ($schema.isError()) extends 
org.apache.avro.specific.SpecificExceptionBase#else extends 
org.apache.avro.specific.SpecificRecordBase#end implements 
org.apache.avro.specific.SpecificRecord {
+public class ${this.mangleTypeIdentifier($schema.getName())}#if 
($schema.isError()) extends org.apache.avro.specific.SpecificExceptionBase#else 
extends org.apache.avro.specific.SpecificRecordBase#end implements 
org.apache.avro.specific.SpecificRecord {
   private static final long serialVersionUID = ${this.fingerprint64($schema)}L;
 
 #set ($schemaString = $this.javaSplit($schema.toString()))
@@ -63,17 +63,17 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 #end
 
 #if (!$schema.isError())
-  private static final BinaryMessageEncoder<${this.mangle($schema.getName())}> 
ENCODER =
+  private static final 
BinaryMessageEncoder<${this.mangleTypeIdentifier($schema.getName())}> ENCODER =
       new BinaryMessageEncoder<>(MODEL$, SCHEMA$);
 
-  private static final BinaryMessageDecoder<${this.mangle($schema.getName())}> 
DECODER =
+  private static final 
BinaryMessageDecoder<${this.mangleTypeIdentifier($schema.getName())}> DECODER =
       new BinaryMessageDecoder<>(MODEL$, SCHEMA$);
 
   /**
    * Return the BinaryMessageEncoder instance used by this class.
    * @return the message encoder used by this class
    */
-  public static BinaryMessageEncoder<${this.mangle($schema.getName())}> 
getEncoder() {
+  public static 
BinaryMessageEncoder<${this.mangleTypeIdentifier($schema.getName())}> 
getEncoder() {
     return ENCODER;
   }
 
@@ -81,7 +81,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
    * Return the BinaryMessageDecoder instance used by this class.
    * @return the message decoder used by this class
    */
-  public static BinaryMessageDecoder<${this.mangle($schema.getName())}> 
getDecoder() {
+  public static 
BinaryMessageDecoder<${this.mangleTypeIdentifier($schema.getName())}> 
getDecoder() {
     return DECODER;
   }
 
@@ -90,7 +90,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
    * @param resolver a {@link SchemaStore} used to find schemas by fingerprint
    * @return a BinaryMessageDecoder instance for this class backed by the 
given SchemaStore
    */
-  public static BinaryMessageDecoder<${this.mangle($schema.getName())}> 
createDecoder(SchemaStore resolver) {
+  public static 
BinaryMessageDecoder<${this.mangleTypeIdentifier($schema.getName())}> 
createDecoder(SchemaStore resolver) {
     return new BinaryMessageDecoder<>(MODEL$, SCHEMA$, resolver);
   }
 
@@ -109,7 +109,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
    * @return a ${schema.getName()} instance decoded from the given buffer
    * @throws java.io.IOException if the given bytes could not be deserialized 
into an instance of this class
    */
-  public static ${this.mangle($schema.getName())} fromByteBuffer(
+  public static ${this.mangleTypeIdentifier($schema.getName())} fromByteBuffer(
       java.nio.ByteBuffer b) throws java.io.IOException {
     return DECODER.decode(b);
   }
@@ -126,19 +126,19 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 #end
 #if ($schema.isError())
 
-  public ${this.mangle($schema.getName())}() {
+  public ${this.mangleTypeIdentifier($schema.getName())}() {
     super();
   }
 
-  public ${this.mangle($schema.getName())}(Object value) {
+  public ${this.mangleTypeIdentifier($schema.getName())}(Object value) {
     super(value);
   }
 
-  public ${this.mangle($schema.getName())}(Throwable cause) {
+  public ${this.mangleTypeIdentifier($schema.getName())}(Throwable cause) {
     super(cause);
   }
 
-  public ${this.mangle($schema.getName())}(Object value, Throwable cause) {
+  public ${this.mangleTypeIdentifier($schema.getName())}(Object value, 
Throwable cause) {
     super(value, cause);
   }
 
@@ -150,7 +150,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
    * to their default values from the schema.  If that is desired then
    * one should use <code>newBuilder()</code>.
    */
-  public ${this.mangle($schema.getName())}() {}
+  public ${this.mangleTypeIdentifier($schema.getName())}() {}
 #if ($this.isCreateAllArgsConstructor())
 
   /**
@@ -161,7 +161,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 #end
 #end
    */
-  public ${this.mangle($schema.getName())}(#foreach($field in 
$schema.getFields())${this.javaType($field.schema())} 
${this.mangle($field.name())}#if($foreach.count < $schema.getFields().size()), 
#end#end) {
+  public ${this.mangleTypeIdentifier($schema.getName())}(#foreach($field in 
$schema.getFields())${this.javaType($field.schema())} 
${this.mangle($field.name())}#if($foreach.count < $schema.getFields().size()), 
#end#end) {
 #foreach ($field in $schema.getFields())
     ${this.generateSetterCode($field.schema(), ${this.mangle($field.name())}, 
${this.mangle($field.name())})}
 #end
@@ -268,46 +268,46 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 
 #end
   /**
-   * Creates a new ${this.mangle($schema.getName())} RecordBuilder.
-   * @return A new ${this.mangle($schema.getName())} RecordBuilder
+   * Creates a new ${this.mangleTypeIdentifier($schema.getName())} 
RecordBuilder.
+   * @return A new ${this.mangleTypeIdentifier($schema.getName())} 
RecordBuilder
    */
-  public static #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 newBuilder() {
-    return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder();
+  public static #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 newBuilder() {
+    return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder();
   }
 
   /**
-   * Creates a new ${this.mangle($schema.getName())} RecordBuilder by copying 
an existing Builder.
+   * Creates a new ${this.mangleTypeIdentifier($schema.getName())} 
RecordBuilder by copying an existing Builder.
    * @param other The existing builder to copy.
-   * @return A new ${this.mangle($schema.getName())} RecordBuilder
+   * @return A new ${this.mangleTypeIdentifier($schema.getName())} 
RecordBuilder
    */
-  public static #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 newBuilder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 other) {
+  public static #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 newBuilder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 other) {
     if (other == null) {
-      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder();
+      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder();
     } else {
-      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder(other);
+      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder(other);
     }
   }
 
   /**
-   * Creates a new ${this.mangle($schema.getName())} RecordBuilder by copying 
an existing $this.mangle($schema.getName()) instance.
+   * Creates a new ${this.mangleTypeIdentifier($schema.getName())} 
RecordBuilder by copying an existing 
$this.mangleTypeIdentifier($schema.getName()) instance.
    * @param other The existing instance to copy.
-   * @return A new ${this.mangle($schema.getName())} RecordBuilder
+   * @return A new ${this.mangleTypeIdentifier($schema.getName())} 
RecordBuilder
    */
-  public static #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 newBuilder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}
 other) {
+  public static #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 newBuilder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}
 other) {
     if (other == null) {
-      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder();
+      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder();
     } else {
-      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder(other);
+      return new #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder(other);
     }
   }
 
   /**
-   * RecordBuilder for ${this.mangle($schema.getName())} instances.
+   * RecordBuilder for ${this.mangleTypeIdentifier($schema.getName())} 
instances.
    */
   @org.apache.avro.specific.AvroGenerated
-  public static class Builder extends#if ($schema.isError()) 
org.apache.avro.specific.SpecificErrorBuilderBase<${this.mangle($schema.getName())}>#else
 
org.apache.avro.specific.SpecificRecordBuilderBase<${this.mangle($schema.getName())}>#end
+  public static class Builder extends#if ($schema.isError()) 
org.apache.avro.specific.SpecificErrorBuilderBase<${this.mangleTypeIdentifier($schema.getName())}>#else
 
org.apache.avro.specific.SpecificRecordBuilderBase<${this.mangleTypeIdentifier($schema.getName())}>#end
 
-    implements#if ($schema.isError()) 
org.apache.avro.data.ErrorBuilder<${this.mangle($schema.getName())}>#else 
org.apache.avro.data.RecordBuilder<${this.mangle($schema.getName())}>#end {
+    implements#if ($schema.isError()) 
org.apache.avro.data.ErrorBuilder<${this.mangleTypeIdentifier($schema.getName())}>#else
 
org.apache.avro.data.RecordBuilder<${this.mangleTypeIdentifier($schema.getName())}>#end
 {
 
 #foreach ($field in $schema.getFields())
 #if ($field.doc())
@@ -328,7 +328,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
      * Creates a Builder by copying an existing Builder.
      * @param other The existing Builder to copy.
      */
-    private Builder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 other) {
+    private Builder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 other) {
       super(other);
 #foreach ($field in $schema.getFields())
       if (isValidValue(fields()[$field.pos()], 
other.${this.mangle($field.name(), $schema.isError())})) {
@@ -344,10 +344,10 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
     }
 
     /**
-     * Creates a Builder by copying an existing 
$this.mangle($schema.getName()) instance
+     * Creates a Builder by copying an existing 
$this.mangleTypeIdentifier($schema.getName()) instance
      * @param other The existing instance to copy.
      */
-    private Builder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}
 other) {
+    private Builder(#if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}
 other) {
 #if ($schema.isError())      super(other)#else
       super(SCHEMA$, MODEL$)#end;
 #foreach ($field in $schema.getFields())
@@ -363,25 +363,25 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 #if ($schema.isError())
 
     @Override
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 setValue(Object value) {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 setValue(Object value) {
       super.setValue(value);
       return this;
     }
 
     @Override
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 clearValue() {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 clearValue() {
       super.clearValue();
       return this;
     }
 
     @Override
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 setCause(Throwable cause) {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 setCause(Throwable cause) {
       super.setCause(cause);
       return this;
     }
 
     @Override
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 clearCause() {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 clearCause() {
       super.clearCause();
       return this;
     }
@@ -417,7 +417,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
       * @param value The value of '${this.mangle($field.name(), 
$schema.isError())}'.
       * @return This builder.
       */
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 ${this.generateSetMethod($schema, $field)}(${this.javaUnbox($field.schema(), 
false)} value) {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 ${this.generateSetMethod($schema, $field)}(${this.javaUnbox($field.schema(), 
false)} value) {
       validate(fields()[$field.pos()], value);
 #if (${this.hasBuilder($field.schema())})
       this.${this.mangle($field.name(), $schema.isError())}Builder = null;
@@ -463,7 +463,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
      * @return This builder.
      */
 
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 ${this.generateSetBuilderMethod($schema, 
$field)}(${this.javaUnbox($field.schema(), false)}.Builder value) {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 ${this.generateSetBuilderMethod($schema, 
$field)}(${this.javaUnbox($field.schema(), false)}.Builder value) {
       ${this.generateClearMethod($schema, $field)}();
       ${this.mangle($field.name(), $schema.isError())}Builder = value;
       return this;
@@ -486,7 +486,7 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 #end
       * @return This builder.
       */
-    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangle($schema.getName())}.Builder
 ${this.generateClearMethod($schema, $field)}() {
+    public #if 
($schema.getNamespace())$this.mangle($schema.getNamespace()).#end${this.mangleTypeIdentifier($schema.getName())}.Builder
 ${this.generateClearMethod($schema, $field)}() {
 #if (${this.isUnboxedJavaTypeNullable($field.schema())})
       ${this.mangle($field.name(), $schema.isError())} = null;
 #end
@@ -500,9 +500,9 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
 #end
     @Override
     @SuppressWarnings("unchecked")
-    public ${this.mangle($schema.getName())} build() {
+    public ${this.mangleTypeIdentifier($schema.getName())} build() {
       try {
-        ${this.mangle($schema.getName())} record = new 
${this.mangle($schema.getName())}(#if ($schema.isError())getValue(), 
getCause()#end);
+        ${this.mangleTypeIdentifier($schema.getName())} record = new 
${this.mangleTypeIdentifier($schema.getName())}(#if 
($schema.isError())getValue(), getCause()#end);
 #foreach ($field in $schema.getFields())
 #if (${this.hasBuilder($field.schema())})
         if (${this.mangle($field.name(), $schema.isError())}Builder != null) {
@@ -529,8 +529,8 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
   }
 
   @SuppressWarnings("unchecked")
-  private static final 
org.apache.avro.io.DatumWriter<${this.mangle($schema.getName())}>
-    WRITER$ = 
(org.apache.avro.io.DatumWriter<${this.mangle($schema.getName())}>)MODEL$.createDatumWriter(SCHEMA$);
+  private static final 
org.apache.avro.io.DatumWriter<${this.mangleTypeIdentifier($schema.getName())}>
+    WRITER$ = 
(org.apache.avro.io.DatumWriter<${this.mangleTypeIdentifier($schema.getName())}>)MODEL$.createDatumWriter(SCHEMA$);
 
   @Override public void writeExternal(java.io.ObjectOutput out)
     throws java.io.IOException {
@@ -538,8 +538,8 @@ public class ${this.mangle($schema.getName())}#if 
($schema.isError()) extends or
   }
 
   @SuppressWarnings("unchecked")
-  private static final 
org.apache.avro.io.DatumReader<${this.mangle($schema.getName())}>
-    READER$ = 
(org.apache.avro.io.DatumReader<${this.mangle($schema.getName())}>)MODEL$.createDatumReader(SCHEMA$);
+  private static final 
org.apache.avro.io.DatumReader<${this.mangleTypeIdentifier($schema.getName())}>
+    READER$ = 
(org.apache.avro.io.DatumReader<${this.mangleTypeIdentifier($schema.getName())}>)MODEL$.createDatumReader(SCHEMA$);
 
   @Override public void readExternal(java.io.ObjectInput in)
     throws java.io.IOException {
diff --git 
a/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
 
b/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
index 89d773e..1d075bd 100644
--- 
a/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
+++ 
b/lang/java/compiler/src/test/java/org/apache/avro/compiler/specific/TestSpecificCompiler.java
@@ -34,6 +34,7 @@ import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
@@ -45,6 +46,7 @@ import org.apache.avro.AvroTypeException;
 
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.avro.LogicalType;
 import org.apache.avro.LogicalTypes;
@@ -684,7 +686,12 @@ public class TestSpecificCompiler {
    */
   public void testManglingReservedIdentifiers(String schema, boolean 
throwsTypeExceptionOnPrimitive,
       String dstDirPrefix) throws IOException {
-    for (String reserved : SpecificData.RESERVED_WORDS) {
+    Set<String> reservedIdentifiers = new HashSet<>();
+    reservedIdentifiers.addAll(SpecificData.RESERVED_WORDS);
+    
reservedIdentifiers.addAll(SpecificCompiler.TYPE_IDENTIFIER_RESERVED_WORDS);
+    
reservedIdentifiers.addAll(SpecificCompiler.ACCESSOR_MUTATOR_RESERVED_WORDS);
+    reservedIdentifiers.addAll(SpecificCompiler.ERROR_RESERVED_WORDS);
+    for (String reserved : reservedIdentifiers) {
       try {
         Schema s = new Schema.Parser().parse(schema.replace("__test__", 
reserved));
         assertCompilesWithJavaCompiler(new File(OUTPUT_DIR.getRoot(), 
dstDirPrefix + "_" + reserved),

Reply via email to