##
## 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
@SuppressWarnings("all")
#if ($schema.getDoc())
/** $schema.getDoc() */
#end
public class ${this.mangle($schema.getName())}#if ($schema.isError()) extends org.apache.avro.specific.SpecificExceptionBase#else extends org.apache.gora.persistency.impl.PersistentBase#end implements org.apache.avro.specific.SpecificRecord, org.apache.gora.persistency.Persistent {
  public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("${this.javaEscape($schema.toString())}");

  /** Enum containing all data bean's fields. */
  public static enum Field {
#set ($i = 0)
#foreach ($field in $schema.getFields())
    ${this.toUpperCase($field.name())}($i, "${this.mangle($field.name(), $schema.isError())}"),
#set ($i = $i + 1)
#end
    ;
    /**
     * Field's index.
     */
    private int index;

    /**
     * Field's name.
     */
    private String name;

    /**
     * Field's constructor
     * @param index field's index.
     * @param name field's name.
     */
    Field(int index, String name) {this.index=index;this.name=name;}

    /**
     * Gets field's index.
     * @return int field's index.
     */
    public int getIndex() {return index;}

    /**
     * Gets field's name.
     * @return String field's name.
     */
    public String getName() {return name;}

    /**
     * Gets field's attributes to string.
     * @return String field's attributes to string.
     */
    public String toString() {return name;}
  };

  public static final String[] _ALL_FIELDS = {
#foreach ($field in $schema.getFields())
  "${this.mangle($field.name(), $schema.isError())}",
#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.isNotHiddenField($field.name()) ) = ${this.generateDefaultValueString($schema,$field.name())}#end;
#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);
  }

#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");
    }
  }
  
  // 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())} = (${this.javaType($field.schema())})(${this.generateAppropriateWrapperOrValueForPut($field.schema())}); break;
#set ($i = $i + 1)
#end
    default: throw new org.apache.avro.AvroRuntimeException("Bad index");
    }
  }

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

  /**
   * 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())} = ${this.generateAppropriateWrapperOrValue($field.schema())};
    setDirty(${field.pos()});
  }
  
  /**
   * Checks the dirty status of the '${this.mangle($field.name(), $schema.isError())}' field. A field is dirty if it represents a change that has not yet been written to the database.
#if ($field.doc())   * $field.doc()#end
   * @param value the value to set.
   */
  public boolean ${this.generateDirtyMethod($schema, $field)}(${this.javaType($field.schema())} value) {
    return isDirty(${field.pos()});
  }

#end
#end
  /** Creates 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 */
  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) {
    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 */
  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) {
    return new #if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder(other);
  }
  
  private static java.nio.ByteBuffer deepCopyToWriteOnlyBuffer(
      java.nio.ByteBuffer input) {
    java.nio.ByteBuffer copy = java.nio.ByteBuffer.allocate(input.capacity());
    int position = input.position();
    input.reset();
    int mark = input.position();
    int limit = input.limit();
    input.rewind();
    input.limit(input.capacity());
    copy.put(input);
    input.rewind();
    copy.rewind();
    input.position(mark);
    input.mark();
    copy.position(mark);
    copy.mark();
    input.position(position);
    copy.position(position);
    input.limit(limit);
    copy.limit(limit);
    return copy.asReadOnlyBuffer();
  }
  
  /**
   * 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())
    private ${this.javaUnbox($field.schema())} ${this.mangle($field.name(), $schema.isError())};
#end

    /** Creates a new Builder */
    private Builder() {
      super(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.SCHEMA$);
    }
    
    /** Creates a Builder by copying an existing Builder */
    private Builder(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.Builder other) {
      super(other);
    }
    
    /** Creates a Builder by copying an existing $this.mangle($schema.getName()) instance */
    private Builder(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())} other) {
      #if ($schema.isError())super(other)#else
      super(#if ($schema.getNamespace())$schema.getNamespace().#end${this.mangle($schema.getName())}.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())} = (${this.javaType($field.schema())}) data().deepCopy(fields()[$field.pos()].schema(), other.${this.mangle($field.name(), $schema.isError())});
        fieldSetFlags()[$field.pos()] = true;
      }
#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())
#if ($this.isNotHiddenField($field.name()))
    /** Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field */
    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 */
    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);
      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 */
    public boolean ${this.generateHasMethod($schema, $field)}() {
      return fieldSetFlags()[$field.pos()];
    }
    
    /** Clears the value of the '${this.mangle($field.name(), $schema.isError())}' field */
    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
      fieldSetFlags()[$field.pos()] = false;
      return this;
    }
    
#end
#end
    @Override
    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())
        record.${this.mangle($field.name(), $schema.isError())} = fieldSetFlags()[$field.pos()] ? this.${this.mangle($field.name(), $schema.isError())} : (${this.javaType($field.schema())}) ${this.generateAppropriateWrapper($schema,$field)};
#end
        return record;
      } catch (Exception e) {
        throw new org.apache.avro.AvroRuntimeException(e);
      }
    }
  }
  
  public ${this.mangle($schema.getName())}.Tombstone getTombstone(){
  	return TOMBSTONE;
  }

  public ${this.mangle($schema.getName())} newInstance(){
    return newBuilder().build();
  }

  private static final Tombstone TOMBSTONE = new Tombstone();
  
  public static final class Tombstone extends ${this.mangle($schema.getName())} implements org.apache.gora.persistency.Tombstone {
  
      private Tombstone() { }
  
	  #foreach ($field in $schema.getFields())
	#if ($this.isNotHiddenField($field.name()))
	  /**
	   * Gets the value of the '${this.mangle($field.name(), $schema.isError())}' field.
	#if ($field.doc())   * $field.doc()#end
	   */
	  public ${this.javaType($field.schema())} ${this.generateGetMethod($schema, $field)}() {
	    throw new java.lang.UnsupportedOperationException("Get is not supported on tombstones");
	  }
	
	  /**
	   * 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) {
	    throw new java.lang.UnsupportedOperationException("Set is not supported on tombstones");
	  }
	  
	  /**
	   * Checks the dirty status of the '${this.mangle($field.name(), $schema.isError())}' field. A field is dirty if it represents a change that has not yet been written to the database.
	#if ($field.doc())   * $field.doc()#end
	   * @param value the value to set.
	   */
	  public boolean ${this.generateDirtyMethod($schema, $field)}(${this.javaType($field.schema())} value) {
	    throw new java.lang.UnsupportedOperationException("IsDirty is not supported on tombstones");
	  }
	
	#end
	#end
  
  }
  
}