##
## Licensed to the Apache Software Foundation (ASF) under one
## or more contributor license agreements.  See the NOTICE file
## distributed with this work for additional information
## regarding copyright ownership.  The ASF licenses this file
## to you under the Apache License, Version 2.0 (the
## "License"); you may not use this file except in compliance
## with the License.  You may obtain a copy of the License at
##
##     http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
#if ($schema.getNamespace())
package $schema.getNamespace();
#end

import org.apache.avro.specific.SpecificData;
#if (!$schema.isError())
import org.apache.avro.message.BinaryMessageEncoder;
import org.apache.avro.message.BinaryMessageDecoder;
import org.apache.avro.message.SchemaStore;
#end

#if ($schema.getDoc())
/** $schema.getDoc() */
#end
#foreach ($annotation in $this.javaAnnotations($schema))
@$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 {
  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.javaSplit($schema.toString())});
  public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }

  private static SpecificData MODEL$ = new SpecificData();

#if (!$schema.isError())
  private static final BinaryMessageEncoder<${this.mangle($schema.getName())}> ENCODER =
      new BinaryMessageEncoder<${this.mangle($schema.getName())}>(MODEL$, SCHEMA$);

  private static final BinaryMessageDecoder<${this.mangle($schema.getName())}> DECODER =
      new BinaryMessageDecoder<${this.mangle($schema.getName())}>(MODEL$, SCHEMA$);

  /**
   * Return the BinaryMessageDecoder instance used by this class.
   * @return the message decoder used by this class
   */
  public static BinaryMessageDecoder<${this.mangle($schema.getName())}> getDecoder() {
    return DECODER;
  }

  /**
   * Create a new BinaryMessageDecoder instance for this class that uses the specified {@link SchemaStore}.
   * @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) {
    return new BinaryMessageDecoder<${this.mangle($schema.getName())}>(MODEL$, SCHEMA$, resolver);
  }

  /**
   * Serializes this ${schema.getName()} to a ByteBuffer.
   * @return a buffer holding the serialized data for this instance
   * @throws java.io.IOException if this instance could not be serialized
   */
  public java.nio.ByteBuffer toByteBuffer() throws java.io.IOException {
    return ENCODER.encode(this);
  }

  /**
   * Deserializes a ${schema.getName()} from a ByteBuffer.
   * @param b a byte buffer holding serialized data for an instance of this class
   * @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(
      java.nio.ByteBuffer b) throws java.io.IOException {
    return DECODER.decode(b);
  }
#end

#foreach ($field in $schema.getFields())
#if ($field.doc())
  /** $field.doc() */
#end
#foreach ($annotation in $this.javaAnnotations($field))
  @$annotation
#end
  #if (${this.deprecatedFields()})@Deprecated#end #if (${this.publicFields()})public#elseif (${this.privateFields()})private#end ${this.javaUnbox($field.schema())} ${this.mangle($field.name(), $schema.isError())};
#end
#if ($schema.isError())

  public ${this.mangle($schema.getName())}() {
    super();
  }

  public ${this.mangle($schema.getName())}(Object value) {
    super(value);
  }

  public ${this.mangle($schema.getName())}(Throwable cause) {
    super(cause);
  }

  public ${this.mangle($schema.getName())}(Object value, Throwable cause) {
    super(value, cause);
  }

#else
#if ($schema.getFields().size() > 0)

  /**
   * Default constructor.  Note that this does not initialize fields
   * to their default values from the schema.  If that is desired then
   * one should use <code>newBuilder()</code>.
   */
  public ${this.mangle($schema.getName())}() {}
#if ($this.isCreateAllArgsConstructor())

  /**
   * All-args constructor.
#foreach ($field in $schema.getFields())
#if ($field.doc())   * @param ${this.mangle($field.name())} $field.doc()
#else   * @param ${this.mangle($field.name())} The new value for ${field.name()}
#end
#end
   */
  public ${this.mangle($schema.getName())}(#foreach($field in $schema.getFields())${this.javaType($field.schema())} ${this.mangle($field.name())}#if($velocityCount < $schema.getFields().size()), #end#end) {
#foreach ($field in $schema.getFields())
    this.${this.mangle($field.name())} = ${this.mangle($field.name())};
#end
  }
#else
  /**
   * This schema contains more than 254 fields which exceeds the maximum number
   * of permitted constructor parameters in the JVM. An all-args constructor
   * will not be generated. Please use <code>newBuilder()</code> to instantiate
   * objects instead.
   */
#end
#end

#end
  public org.apache.avro.Schema getSchema() { return SCHEMA$; }
  // Used by DatumWriter.  Applications should not call.
  public java.lang.Object get(int field$) {
    switch (field$) {
#set ($i = 0)
#foreach ($field in $schema.getFields())
    case $i: return ${this.mangle($field.name(), $schema.isError())};
#set ($i = $i + 1)
#end
    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
    }
  }

#if ($this.hasLogicalTypeField($schema))
  protected static final org.apache.avro.data.TimeConversions.DateConversion DATE_CONVERSION = new org.apache.avro.data.TimeConversions.DateConversion();
  protected static final org.apache.avro.data.TimeConversions.TimeConversion TIME_CONVERSION = new org.apache.avro.data.TimeConversions.TimeConversion();
  protected static final org.apache.avro.data.TimeConversions.TimeMicrosConversion TIME_MICROS_CONVERSION = new org.apache.avro.data.TimeConversions.TimeMicrosConversion();
  protected static final org.apache.avro.data.TimeConversions.TimestampConversion TIMESTAMP_CONVERSION = new org.apache.avro.data.TimeConversions.TimestampConversion();
  protected static final org.apache.avro.data.TimeConversions.TimestampMicrosConversion TIMESTAMP_MICROS_CONVERSION = new org.apache.avro.data.TimeConversions.TimestampMicrosConversion();
  protected static final org.apache.avro.Conversions.DecimalConversion DECIMAL_CONVERSION = new org.apache.avro.Conversions.DecimalConversion();

  private static final org.apache.avro.Conversion<?>[] conversions =
      new org.apache.avro.Conversion<?>[] {
#foreach ($field in $schema.getFields())
      ${this.conversionInstance($field.schema())},
#end
      null
  };

  @Override
  public org.apache.avro.Conversion<?> getConversion(int field) {
    return conversions[field];
  }

#end
  // Used by DatumReader.  Applications should not call.
  @SuppressWarnings(value="unchecked")
  public void put(int field$, java.lang.Object value$) {
    switch (field$) {
#set ($i = 0)
#foreach ($field in $schema.getFields())
    case $i: ${this.mangle($field.name(), $schema.isError())} = #if(${this.javaType($field.schema())} != "java.lang.Object")(${this.javaType($field.schema())})#{end}value$; break;
#set ($i = $i + 1)
#end
    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
    }
  }

#foreach ($field in $schema.getFields())
  /**
   * Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc())   * @return $field.doc()
#else   * @return The value of the '${this.mangle($field.name(), $schema.isError())}' field.
#end
   */
  public ${this.javaType($field.schema())} ${this.generateGetMethod($schema, $field)}() {
    return ${this.mangle($field.name(), $schema.isError())};
  }

#if ($this.createSetters)
  /**
   * Sets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc())   * $field.doc()
#end
   * @param value the value to set.
   */
  public void ${this.generateSetMethod($schema, $field)}(${this.javaType($field.schema())} value) {
    this.${this.mangle($field.name(), $schema.isError())} = value;
  }
#end

#end
  /**
   * Creates a new ${this.mangle($schema.getName())} RecordBuilder.
   * @return A new ${this.mangle($schema.getName())} RecordBuilder
   */
  public static #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder newBuilder() {
    return new #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder();
  }

  /**
   * Creates a new ${this.mangle($schema.getName())} RecordBuilder by copying an existing Builder.
   * @param other The existing builder to copy.
   * @return A new ${this.mangle($schema.getName())} RecordBuilder
   */
  public static #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder newBuilder(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder other) {
    if (other == null) {
      return new #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder();
    } else {
      return new #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder(other);
    }
  }

  /**
   * Creates a new ${this.mangle($schema.getName())} RecordBuilder by copying an existing $this.mangle($schema.getName()) instance.
   * @param other The existing instance to copy.
   * @return A new ${this.mangle($schema.getName())} RecordBuilder
   */
  public static #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder newBuilder(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())} other) {
    if (other == null) {
      return new #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder();
    } else {
      return new #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder(other);
    }
  }

  /**
   * RecordBuilder for ${this.mangle($schema.getName())} instances.
   */
  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

    implements#if ($schema.isError()) org.apache.avro.data.ErrorBuilder<${this.mangle($schema.getName())}>#else org.apache.avro.data.RecordBuilder<${this.mangle($schema.getName())}>#end {

#foreach ($field in $schema.getFields())
#if ($field.doc())
    /** $field.doc() */
#end
    private ${this.javaUnbox($field.schema())} ${this.mangle($field.name(), $schema.isError())};
#if (${this.hasBuilder($field.schema())})
    private ${this.javaUnbox($field.schema())}.Builder ${this.mangle($field.name(), $schema.isError())}Builder;
#end
#end

    /** Creates a new Builder */
    private Builder() {
      super(SCHEMA$);
    }

    /**
     * Creates a Builder by copying an existing Builder.
     * @param other The existing Builder to copy.
     */
    private Builder(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder other) {
      super(other);
#foreach ($field in $schema.getFields())
      if (isValidValue(fields()[$field.pos()], other.${this.mangle($field.name(), $schema.isError())})) {
        this.${this.mangle($field.name(), $schema.isError())} = data().deepCopy(fields()[$field.pos()].schema(), other.${this.mangle($field.name(), $schema.isError())});
        fieldSetFlags()[$field.pos()] = other.fieldSetFlags()[$field.pos()];
      }
#if (${this.hasBuilder($field.schema())})
      if (other.${this.generateHasBuilderMethod($schema, $field)}()) {
        this.${this.mangle($field.name(), $schema.isError())}Builder = ${this.javaType($field.schema())}.newBuilder(other.${this.generateGetBuilderMethod($schema, $field)}());
      }
#end
#end
    }

    /**
     * Creates a Builder by copying an existing $this.mangle($schema.getName()) instance
     * @param other The existing instance to copy.
     */
    private Builder(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())} other) {
#if ($schema.isError())      super(other)#else
      super(SCHEMA$)#end;
#foreach ($field in $schema.getFields())
      if (isValidValue(fields()[$field.pos()], other.${this.mangle($field.name(), $schema.isError())})) {
        this.${this.mangle($field.name(), $schema.isError())} = data().deepCopy(fields()[$field.pos()].schema(), other.${this.mangle($field.name(), $schema.isError())});
        fieldSetFlags()[$field.pos()] = true;
      }
#if (${this.hasBuilder($field.schema())})
      this.${this.mangle($field.name(), $schema.isError())}Builder = null;
#end
#end
    }
#if ($schema.isError())

    @Override
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder setValue(Object value) {
      super.setValue(value);
      return this;
    }

    @Override
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder clearValue() {
      super.clearValue();
      return this;
    }

    @Override
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder setCause(Throwable cause) {
      super.setCause(cause);
      return this;
    }

    @Override
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder clearCause() {
      super.clearCause();
      return this;
    }
#end

#foreach ($field in $schema.getFields())
    /**
      * Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc())      * $field.doc()
#end
      * @return The value.
      */
    public ${this.javaType($field.schema())} ${this.generateGetMethod($schema, $field)}() {
      return ${this.mangle($field.name(), $schema.isError())};
    }

    /**
      * Sets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc())      * $field.doc()
#end
      * @param value The value of '${this.mangle($field.name(), $schema.isError())}'.
      * @return This builder.
      */
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder ${this.generateSetMethod($schema, $field)}(${this.javaUnbox($field.schema())} value) {
      validate(fields()[$field.pos()], value);
#if (${this.hasBuilder($field.schema())})
      this.${this.mangle($field.name(), $schema.isError())}Builder = null;
#end
      this.${this.mangle($field.name(), $schema.isError())} = value;
      fieldSetFlags()[$field.pos()] = true;
      return this;
    }

    /**
      * Checks whether the '${this.mangle($field.name(), $schema.isError())}' field has been set.
#if ($field.doc())      * $field.doc()
#end
      * @return True if the '${this.mangle($field.name(), $schema.isError())}' field has been set, false otherwise.
      */
    public boolean ${this.generateHasMethod($schema, $field)}() {
      return fieldSetFlags()[$field.pos()];
    }

#if (${this.hasBuilder($field.schema())})
    /**
     * Gets the Builder instance for the '${this.mangle($field.name(), $schema.isError())}' field and creates one if it doesn't exist yet.
#if ($field.doc())     * $field.doc()
#end
     * @return This builder.
     */
    public ${this.javaType($field.schema())}.Builder ${this.generateGetBuilderMethod($schema, $field)}() {
      if (${this.mangle($field.name(), $schema.isError())}Builder == null) {
        if (${this.generateHasMethod($schema, $field)}()) {
          ${this.generateSetBuilderMethod($schema, $field)}(${this.javaType($field.schema())}.newBuilder(${this.mangle($field.name(), $schema.isError())}));
        } else {
          ${this.generateSetBuilderMethod($schema, $field)}(${this.javaType($field.schema())}.newBuilder());
        }
      }
      return ${this.mangle($field.name(), $schema.isError())}Builder;
    }

    /**
     * Sets the Builder instance for the '${this.mangle($field.name(), $schema.isError())}' field
#if ($field.doc())     * $field.doc()
#end
     * @param value The builder instance that must be set.
     * @return This builder.
     */
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder ${this.generateSetBuilderMethod($schema, $field)}(${this.javaUnbox($field.schema())}.Builder value) {
      ${this.generateClearMethod($schema, $field)}();
      ${this.mangle($field.name(), $schema.isError())}Builder = value;
      return this;
    }

    /**
     * Checks whether the '${this.mangle($field.name(), $schema.isError())}' field has an active Builder instance
#if ($field.doc())     * $field.doc()
#end
     * @return True if the '${this.mangle($field.name(), $schema.isError())}' field has an active Builder instance
     */
    public boolean ${this.generateHasBuilderMethod($schema, $field)}() {
      return ${this.mangle($field.name(), $schema.isError())}Builder != null;
    }
#end

    /**
      * Clears the value of the '${this.mangle($field.name(), $schema.isError())}' field.
#if ($field.doc())      * $field.doc()
#end
      * @return This builder.
      */
    public #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder ${this.generateClearMethod($schema, $field)}() {
#if (${this.isUnboxedJavaTypeNullable($field.schema())})
      ${this.mangle($field.name(), $schema.isError())} = null;
#end
#if (${this.hasBuilder($field.schema())})
      ${this.mangle($field.name(), $schema.isError())}Builder = null;
#end
      fieldSetFlags()[$field.pos()] = false;
      return this;
    }

#end
    @Override
    @SuppressWarnings("unchecked")
    public ${this.mangle($schema.getName())} build() {
      try {
        ${this.mangle($schema.getName())} record = new ${this.mangle($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) {
          try {
            record.${this.mangle($field.name(), $schema.isError())} = this.${this.mangle($field.name(), $schema.isError())}Builder.build();
          } catch (org.apache.avro.AvroMissingFieldException e) {
            e.addParentField(record.getSchema().getField("${this.mangle($field.name(), $schema.isError())}"));
            throw e;
          }
        } else {
#if ($this.hasLogicalTypeField($schema))
          record.${this.mangle($field.name(), $schema.isError())} = fieldSetFlags()[$field.pos()] ? this.${this.mangle($field.name(), $schema.isError())} : #if(${this.javaType($field.schema())} != "java.lang.Object")(${this.javaType($field.schema())})#{end} defaultValue(fields()[$field.pos()], record.getConversion($field.pos()));
#else
          record.${this.mangle($field.name(), $schema.isError())} = fieldSetFlags()[$field.pos()] ? this.${this.mangle($field.name(), $schema.isError())} : #if(${this.javaType($field.schema())} != "java.lang.Object")(${this.javaType($field.schema())})#{end} defaultValue(fields()[$field.pos()]);
#end
        }
#else
#if ($this.hasLogicalTypeField($schema))
        record.${this.mangle($field.name(), $schema.isError())} = fieldSetFlags()[$field.pos()] ? this.${this.mangle($field.name(), $schema.isError())} : #if(${this.javaType($field.schema())} != "java.lang.Object")(${this.javaType($field.schema())})#{end} defaultValue(fields()[$field.pos()], record.getConversion($field.pos()));
#else
        record.${this.mangle($field.name(), $schema.isError())} = fieldSetFlags()[$field.pos()] ? this.${this.mangle($field.name(), $schema.isError())} : #if(${this.javaType($field.schema())} != "java.lang.Object")(${this.javaType($field.schema())})#{end} defaultValue(fields()[$field.pos()]);
#end
#end
#end
        return record;
      } catch (org.apache.avro.AvroMissingFieldException e) {
        throw e;
      } catch (java.lang.Exception e) {
        throw new org.apache.avro.AvroRuntimeException(e);
      }
    }
  }

  @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$);

  @Override public void writeExternal(java.io.ObjectOutput out)
    throws java.io.IOException {
    WRITER$.write(this, SpecificData.getEncoder(out));
  }

  @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$);

  @Override public void readExternal(java.io.ObjectInput in)
    throws java.io.IOException {
    READER$.read(this, SpecificData.getDecoder(in));
  }

}
