## Copyright 2014 Google LLC
##
## Licensed 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.

## Template for each generated AutoValue_Foo class.
## This template uses the Apache Velocity Template Language (VTL).
## The variables ($pkg, $props, and so on) are defined by the fields of AutoValueTemplateVars.
##
## Comments, like this one, begin with ##. The comment text extends up to and including the newline
## character at the end of the line. So comments also serve to join a line to the next one.
## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.
## That does mean that we sometimes need an extra blank line after such a directive.
##
## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.
## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to
## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.

## Get #equalsThatExpression($p) and #hashCodeExpression($p).
#parse("equalshashcode.vm")

#if (!$pkg.empty)
package $pkg;
#end

## The following line will be replaced by the required imports during post-processing.
`import`

${gwtCompatibleAnnotation}
#foreach ($a in $annotations)
$a
#end
#if (!$generated.empty)
@${generated}("com.google.auto.value.processor.AutoValueProcessor")
#else
// Generated by com.google.auto.value.processor.AutoValueProcessor
#end
${modifiers}class $subclass$formalTypes extends $origClass$actualTypes {

## Fields

#foreach ($p in $props)
  #foreach ($a in ${p.fieldAnnotations})

  ${a}##
  #end

  private final $p.type $p;
#end

## Constructor

#if ($isFinal && $builderTypeName != "")
  private ##
#end
  $subclass(
#foreach ($p in $props)

      ${p.nullableAnnotation}$p.type $p #if ($foreach.hasNext) , #end
#end ) {
#foreach ($p in $props)
  #if (!$p.kind.primitive && !$p.nullable && ($builderTypeName == "" || !$isFinal))
    ## We don't need a null check if the type is primitive or @Nullable. We also don't need it
    ## if there is a builder, since the build() method will check for us. However, if there is a
    ## builder but there are also extensions (!$isFinal) then we can't omit the null check because
    ## the constructor is called from the extension code.

    #if ($identifiers)

    if ($p == null) {
      throw new NullPointerException("Null $p.name");
    }
    #else
      ## Just throw NullPointerException with no message if it's null.
      ## The Object cast has no effect on the code but silences an ErrorProne warning.

    ((`java.lang.Object`) ${p}).getClass();
    #end

  #end

    this.$p = $p;
#end
  }

## Property getters

#foreach ($p in $props)

  #foreach ($a in ${p.methodAnnotations})

  ${a}##
  #end

  @`java.lang.Override`
  ${p.access}${p.type} ${p.getter}() {
    return $p;
  }

#end

#if ($toString)

  @`java.lang.Override`
  public `java.lang.String` toString() {
    return "#if ($identifiers)$simpleClassName#end{"

  #foreach ($p in $props)

        #if ($identifiers)+ "$p.name=" ##
        #end+ #if ($p.kind == "ARRAY") `java.util.Arrays`.toString($p) #else $p #end
        #if ($foreach.hasNext) + ", " #end

  #end

        + "}";
  }

#end

#if ($equals)

  @`java.lang.Override`
  public boolean equals($equalsParameterType o) {
    if (o == this) {
      return true;
    }
    if (o instanceof $origClass) {

  #if ($props.empty)

      return true;

  #else

      $origClass$wildcardTypes that = ($origClass$wildcardTypes) o;
      return ##
          #foreach ($p in $props)
          #equalsThatExpression ($p $subclass)##
            #if ($foreach.hasNext)

          && ##
            #end
          #end
          ;
  #end

    }
    return false;
  }

#end

#if ($hashCode)

  @`java.lang.Override`
  public int hashCode() {
    int h$ = 1;

  #foreach ($p in $props)

    h$ *= 1000003;
    h$ ^= #hashCodeExpression($p);

  #end

    return h$;
  }
#end

  $serialVersionUID

#if ($builderTypeName != "")

  #foreach ($m in $toBuilderMethods)

  @`java.lang.Override`
  ${m.access}${builderTypeName}${builderActualTypes} ${m.name}() {
    return new Builder${builderActualTypes}(this);
  }

  #end

  ## BUILDER CLASS

  #set($autoBuilder = false)
  #parse("builder.vm")
#end

}
