com.google.auto.value.processor.autoannotation.vm Maven / Gradle / Ivy
## Template for each generated AutoAnnotation_Foo_bar class.
## This template uses the Apache Velocity Template Language (VTL).
## The variables ($pkg, $props, and so on) are defined by the fields of AutoAnnotationTemplateVars.
##
## 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.
##
## A post-processing step will remove unwanted spaces and blank lines, but will not join two lines.
#macro (cloneArray $a)
#if ($gwtCompatible)
${arrays}.copyOf($a, ${a}.length)
#else
${a}.clone()
#end
#end
#if (!$pkg.empty)
package $pkg;
#end
#foreach ($i in $imports)
import $i;
#end
@${generated}("com.google.auto.value.processor.AutoAnnotationProcessor")
final class $className implements $annotationName {
## Fields
#foreach ($m in $members)
#if ($params.containsKey($m.toString()))
private final $m.type $m;
#else
private static final $m.type $m = $m.defaultValue;
#end
#end
## Constructor
$className(
#foreach ($p in $params.keySet())
$params[$p].type $members[$p] #if ($foreach.hasNext) , #end
#end ) {
#foreach ($p in $params.keySet())
#if (!$members[$p].kind.primitive)
if ($p == null) {
throw new NullPointerException("Null $p");
}
#end
#if ($members[$p].kind == "ARRAY")
#if ($params[$p].kind == "ARRAY")
this.$p = #cloneArray(${p});
#elseif ($members[$p].typeMirror.componentType.kind.primitive)
this.$p = ${members[$p].typeMirror.componentType}ArrayFromCollection($p);
#else
this.$p = ${p}.toArray(new ${members[$p].componentType}[${p}.size()]);
#end
#else
this.$p = $p;
#end
#end
}
## annotationType method (defined by the Annotation interface)
@Override
public Class extends $annotationName> annotationType() {
return ${annotationName}.class;
}
## Member getters
#foreach ($m in $members)
@Override
public ${m.type} ${m}() {
#if ($m.kind == "ARRAY")
return #cloneArray(${m});
#else
return ${m};
#end
}
#end
## toString
#macro (appendMemberString $m)
#if ($m.type == "String" || $m.type == "java.lang.String")
#set ($appendQuotedStringMethod = "true")
appendQuoted(sb, $m) ##
#elseif ($m.type == "char")
#set ($appendQuotedCharMethod = "true")
appendQuoted(sb, $m) ##
#elseif ($m.type == "String[]" || $m.type == "java.lang.String[]")
#set ($appendQuotedStringArrayMethod = "true")
appendQuoted(sb, $m) ##
#elseif ($m.type == "char[]")
#set ($appendQuotedCharArrayMethod = "true")
appendQuoted(sb, $m) ##
#elseif ($m.kind == "ARRAY")
sb.append(${arrays}.toString($m)) ##
#else
sb.append($m) ##
#end
#end
@Override
public String toString() {
StringBuilder sb = new StringBuilder("@$annotationFullName(");
#foreach ($p in $params.keySet())
#if ($params.size() > 1 || $params.keySet().iterator().next() != "value")
sb.append("$p=");
#end
#appendMemberString($members[$p]);
#if ($foreach.hasNext)
sb.append(", ");
#end
#end
return sb.append(')').toString();
}
## equals
#macro (memberEqualsThatExpression $m)
#if ($m.kind == "FLOAT")
Float.floatToIntBits($m) == Float.floatToIntBits(that.${m}()) ##
#elseif ($m.kind == "DOUBLE")
Double.doubleToLongBits($m) == Double.doubleToLongBits(that.${m}()) ##
#elseif ($m.kind.primitive)
$m == that.${m}() ##
#elseif ($m.kind == "ARRAY")
#if ($params.containsKey($m.toString()))
${arrays}.equals($m,
(that instanceof $className)
? (($className) that).$m
: that.${m}()) ##
#else ## default value, so if |that| is also a $className then it has the same constant value
that instanceof $className || ${arrays}.equals($m, that.${m}())
#end
#else
${m}.equals(that.${m}()) ##
#end
#end
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof $annotationName) {
#if ($members.isEmpty())
return true;
#else
$annotationName that = ($annotationName) o;
return ##
#foreach ($m in $members)
(#memberEqualsThatExpression ($m))##
#if ($foreach.hasNext)
&& ##
#end
#end
;
#end
}
return false;
}
## hashCode
#macro (memberHashCodeExpression $m)
#if ($m.kind == "LONG")
(int) (($m >>> 32) ^ $m) ##
#elseif ($m.kind == "FLOAT")
Float.floatToIntBits($m) ##
#elseif ($m.kind == "DOUBLE")
(int) ((Double.doubleToLongBits($m) >>> 32) ^ Double.doubleToLongBits($m)) ##
#elseif ($m.kind == "BOOLEAN")
$m ? 1231 : 1237 ##
#elseif ($m.kind.primitive)
$m ##
#elseif ($m.kind == "ARRAY")
${arrays}.hashCode($m) ##
#else
${m}.hashCode() ##
#end
#end
@Override
public int hashCode() {
#if ($members.isEmpty())
return 0;
#else
return
#foreach ($m in $members)
((127 * ${m.toString().hashCode()}) ^ (#memberHashCodeExpression($m))) ##
#if ($foreach.hasNext) + #end
#end
;
#foreach ($m in $members)
// ${m.toString().hashCode()} is "${m}".hashCode()
#end
#end
}
## support functions
#foreach ($w in $wrapperTypesUsedInCollections)
#set ($prim = $w.getField("TYPE").get(""))
private static ${prim}[] ${prim}ArrayFromCollection(Collection<${w.simpleName}> c) {
${prim}[] a = new ${prim}[c.size()];
int i = 0;
for (${prim} x : c) {
a[i++] = x;
}
return a;
}
#end
#if ($appendQuotedStringArrayMethod)
#set ($appendQuotedStringMethod = "true")
private static void appendQuoted(StringBuilder sb, String[] strings) {
sb.append('[');
String sep = "";
for (String s : strings) {
sb.append(sep);
sep = ", ";
appendQuoted(sb, s);
}
sb.append(']');
}
#end
#if ($appendQuotedCharArrayMethod)
#set ($appendQuotedCharMethod = "true")
private static void appendQuoted(StringBuilder sb, char[] chars) {
sb.append('[');
String sep = "";
for (char c : chars) {
sb.append(sep);
sep = ", ";
appendQuoted(sb, c);
}
sb.append(']');
}
#end
#if ($appendQuotedStringMethod)
#set ($appendEscapedMethod = "true")
private static void appendQuoted(StringBuilder sb, String s) {
sb.append('"');
for (int i = 0; i < s.length(); i++) {
appendEscaped(sb, s.charAt(i));
}
sb.append('"');
}
#end
#if ($appendQuotedCharMethod)
#set ($appendEscapedMethod = "true")
private static void appendQuoted(StringBuilder sb, char c) {
sb.append('\'');
appendEscaped(sb, c);
sb.append('\'');
}
#end
#if ($appendEscapedMethod)
private static void appendEscaped(StringBuilder sb, char c) {
switch (c) {
case '\\':
case '"':
case '\'':
sb.append('\\').append(c);
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
if (c < 0x20) {
sb.append('\\');
appendWithZeroPadding(sb, Integer.toOctalString(c), 3);;
} else if (c < 0x7f || Character.isLetter(c)) {
sb.append(c);
} else {
sb.append("\\u");
appendWithZeroPadding(sb, Integer.toHexString(c), 4);
}
break;
}
}
## We use this rather than String.format because that doesn't exist on GWT.
private static void appendWithZeroPadding(StringBuilder sb, String s, int width) {
for (int i = width - s.length(); i > 0; i--) {
sb.append('0');
}
sb.append(s);
}
#end
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy