package annotations.field;
/*>>>
import org.checkerframework.checker.nullness.qual.*;
*/
import java.util.HashMap;
import java.util.Map;
import com.google.common.escape.CharEscaperBuilder;
import com.google.common.escape.Escaper;
/**
* A BasicAFT
represents a primitive or {@link String} annotation
* field type. Get one using {@link #forType(Class)}.
*/
// should be an enum except they can't be generic and can't extend a class
public final class BasicAFT extends ScalarAFT {
static final Escaper charEscaper =
new CharEscaperBuilder()
.addEscape('\b', "\\b")
.addEscape('\f', "\\f")
.addEscape('\n', "\\n")
.addEscape('\r', "\\r")
.addEscape('\t', "\\t")
.addEscape('\"', "\\\"")
.addEscape('\\', "\\\\")
.addEscape('\'', "\\'")
.toEscaper();
/**
* The Java type backing this annotation field type.
*/
public final Class> type;
private BasicAFT(Class> type) {
this.type = type;
}
/**
* Returns the BasicAFT
for type
, which
* should be primitive (e.g., int.class) or String. Returns null if
* type
is not appropriate for a basic annotation field
* type.
*/
public static BasicAFT forType(Class> type) {
return bafts.get(type);
}
/**
* Maps from {@link #type} to BasicAFT
.
* Contains every BasicAFT.
*/
// Disgusting reason for being public; need to fix.
public static final Map, BasicAFT> bafts;
static {
Map, BasicAFT> tempBafts =
new HashMap, BasicAFT>(9);
tempBafts.put(byte.class, new BasicAFT(byte.class));
tempBafts.put(short.class, new BasicAFT(short.class));
tempBafts.put(int.class, new BasicAFT(int.class));
tempBafts.put(long.class, new BasicAFT(long.class));
tempBafts.put(float.class, new BasicAFT(float.class));
tempBafts.put(double.class, new BasicAFT(double.class));
tempBafts.put(char.class, new BasicAFT(char.class));
tempBafts.put(boolean.class, new BasicAFT(boolean.class));
tempBafts.put(String.class, new BasicAFT(String.class));
// bafts = Collections2., BasicAFT>unmodifiableKeyedSet(tempBafts);
// bafts = bafts2;
bafts = tempBafts;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isValidValue(Object o) {
return ( (type == byte.class && o instanceof Byte)
|| (type == short.class && o instanceof Short)
|| (type == int.class && o instanceof Integer)
|| (type == long.class && o instanceof Long)
|| (type == float.class && o instanceof Float)
|| (type == double.class && o instanceof Double)
|| (type == char.class && o instanceof Character)
|| (type == boolean.class && o instanceof Boolean)
|| (type == String.class && o instanceof String));
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
if (type == String.class) {
return "String";
} else {
return type.getName();
}
}
/**
* {@inheritDoc}
*/
@Override
public String format(Object o) {
return type != String.class ? o.toString()
: "\"" + charEscaper.escape((String) o) + "\"";
}
@Override
public R accept(AFTVisitor v, T arg) {
return v.visitBasicAFT(this, arg);
}
}