Skip to content

Commit

Permalink
Helper Methods in AnnotationValues
Browse files Browse the repository at this point in the history
RELNOTES=Adding helper methods for getting different types of annotation values with AnnotationValueVisitor.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=275921910
  • Loading branch information
mahsabadian authored and cgdecker committed Oct 22, 2019
1 parent 7dc5450 commit 6c2c1a3
Show file tree
Hide file tree
Showing 2 changed files with 712 additions and 0 deletions.
355 changes: 355 additions & 0 deletions common/src/main/java/com/google/auto/common/AnnotationValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@
*/
package com.google.auto.common;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.base.Equivalence;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.function.Function;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleAnnotationValueVisitor8;

Expand Down Expand Up @@ -130,5 +137,353 @@ public static Equivalence<AnnotationValue> equivalence() {
return ANNOTATION_VALUE_EQUIVALENCE;
}

private static class DefaultVisitor<T> extends SimpleAnnotationValueVisitor8<T, Void> {
final Class<T> clazz;

DefaultVisitor(Class<T> clazz) {
this.clazz = checkNotNull(clazz);
}

@Override
public T defaultAction(Object o, Void unused) {
throw new IllegalArgumentException(
"Expected a " + clazz.getSimpleName() + ", got instead: " + o);
}
}

private static final class TypeMirrorVisitor extends DefaultVisitor<DeclaredType> {
static final TypeMirrorVisitor INSTANCE = new TypeMirrorVisitor();

TypeMirrorVisitor() {
super(DeclaredType.class);
}

@Override
public DeclaredType visitType(TypeMirror value, Void unused) {
return MoreTypes.asDeclared(value);
}
}
;

/**
* Returns the value as a class.
*
* @throws IllegalArgumentException if the value is not a class.
*/
public static DeclaredType getTypeMirror(AnnotationValue value) {
return TypeMirrorVisitor.INSTANCE.visit(value);
}

private static final class AnnotationMirrorVisitor extends DefaultVisitor<AnnotationMirror> {
static final AnnotationMirrorVisitor INSTANCE = new AnnotationMirrorVisitor();

AnnotationMirrorVisitor() {
super(AnnotationMirror.class);
}

@Override
public AnnotationMirror visitAnnotation(AnnotationMirror value, Void unused) {
return value;
}
}
;

/**
* Returns the value as an AnnotationMirror.
*
* @throws IllegalArgumentException if the value is not an annotation.
*/
public static AnnotationMirror getAnnotationMirror(AnnotationValue value) {
return AnnotationMirrorVisitor.INSTANCE.visit(value);
}

private static final class EnumVisitor extends DefaultVisitor<VariableElement> {
static final EnumVisitor INSTANCE = new EnumVisitor();

EnumVisitor() {
super(VariableElement.class);
}

@Override
public VariableElement visitEnumConstant(VariableElement value, Void unused) {
return value;
}
}
;

/**
* Returns the value as a VariableElement.
*
* @throws IllegalArgumentException if the value is not an enum.
*/
public static VariableElement getEnum(AnnotationValue value) {
return EnumVisitor.INSTANCE.visit(value);
}

private static <T> T valueOfType(AnnotationValue annotationValue, Class<T> type) {
Object value = annotationValue.getValue();
if (!type.isInstance(value)) {
throw new IllegalArgumentException(
"Expected " + type.getSimpleName() + ", got instead: " + value);
}
return type.cast(value);
}

/**
* Returns the value as a string.
*
* @throws IllegalArgumentException if the value is not a string.
*/
public static String getString(AnnotationValue value) {
return valueOfType(value, String.class);
}

/**
* Returns the value as an int.
*
* @throws IllegalArgumentException if the value is not an int.
*/
public static int getInt(AnnotationValue value) {
return valueOfType(value, Integer.class);
}

/**
* Returns the value as a long.
*
* @throws IllegalArgumentException if the value is not a long.
*/
public static long getLong(AnnotationValue value) {
return valueOfType(value, Long.class);
}

/**
* Returns the value as a byte.
*
* @throws IllegalArgumentException if the value is not a byte.
*/
public static byte getByte(AnnotationValue value) {
return valueOfType(value, Byte.class);
}

/**
* Returns the value as a short.
*
* @throws IllegalArgumentException if the value is not a short.
*/
public static short getShort(AnnotationValue value) {
return valueOfType(value, Short.class);
}

/**
* Returns the value as a float.
*
* @throws IllegalArgumentException if the value is not a float.
*/
public static float getFloat(AnnotationValue value) {
return valueOfType(value, Float.class);
}

/**
* Returns the value as a double.
*
* @throws IllegalArgumentException if the value is not a double.
*/
public static double getDouble(AnnotationValue value) {
return valueOfType(value, Double.class);
}

/**
* Returns the value as a boolean.
*
* @throws IllegalArgumentException if the value is not a boolean.
*/
public static boolean getBoolean(AnnotationValue value) {
return valueOfType(value, Boolean.class);
}

/**
* Returns the value as a char.
*
* @throws IllegalArgumentException if the value is not a char.
*/
public static char getChar(AnnotationValue value) {
return valueOfType(value, Character.class);
}

private static final class ArrayVisitor<T>
extends SimpleAnnotationValueVisitor8<ImmutableList<T>, Void> {
final Function<AnnotationValue, T> visitT;

ArrayVisitor(Function<AnnotationValue, T> visitT) {
this.visitT = checkNotNull(visitT);
}

@Override
public ImmutableList<T> defaultAction(Object o, Void unused) {
throw new IllegalStateException("Expected an array, got instead: " + o);
}

@Override
public ImmutableList<T> visitArray(List<? extends AnnotationValue> values, Void unused) {
return values.stream().map(visitT).collect(toImmutableList());
}
}

private static final ArrayVisitor<DeclaredType> TYPE_MIRRORS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getTypeMirror);

/**
* Returns the value as a list of classes.
*
* @throws IllegalArgumentException if the value is not an array of classes.
*/
public static ImmutableList<DeclaredType> getTypeMirrors(AnnotationValue value) {
return TYPE_MIRRORS_VISITOR.visit(value);
}

private static final ArrayVisitor<AnnotationMirror> ANNOTATION_MIRRORS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getAnnotationMirror);

/**
* Returns the value as a list of annotations.
*
* @throws IllegalArgumentException if the value if not an array of annotations.
*/
public static ImmutableList<AnnotationMirror> getAnnotationMirrors(AnnotationValue value) {
return ANNOTATION_MIRRORS_VISITOR.visit(value);
}

private static final ArrayVisitor<VariableElement> ENUMS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getEnum);

/**
* Returns the value as a list of enums.
*
* @throws IllegalArgumentException if the value is not an array of enums.
*/
public static ImmutableList<VariableElement> getEnums(AnnotationValue value) {
return ENUMS_VISITOR.visit(value);
}

private static final ArrayVisitor<String> STRINGS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getString);

/**
* Returns the value as a list of strings.
*
* @throws IllegalArgumentException if the value is not an array of strings.
*/
public static ImmutableList<String> getStrings(AnnotationValue value) {
return STRINGS_VISITOR.visit(value);
}

private static final ArrayVisitor<Integer> INTS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getInt);

/**
* Returns the value as a list of integers.
*
* @throws IllegalArgumentException if the value is not an array of ints.
*/
public static ImmutableList<Integer> getInts(AnnotationValue value) {
return INTS_VISITOR.visit(value);
}

private static final ArrayVisitor<Long> LONGS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getLong);

/**
* Returns the value as a list of longs.
*
* @throws IllegalArgumentException if the value is not an array of longs.
*/
public static ImmutableList<Long> getLongs(AnnotationValue value) {
return LONGS_VISITOR.visit(value);
}

private static final ArrayVisitor<Byte> BYTES_VISITOR =
new ArrayVisitor<>(AnnotationValues::getByte);

/**
* Returns the value as a list of bytes.
*
* @throws IllegalArgumentException if the value is not an array of bytes.
*/
public static ImmutableList<Byte> getBytes(AnnotationValue value) {
return BYTES_VISITOR.visit(value);
}

private static final ArrayVisitor<Short> SHORTS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getShort);
/**
* Returns the value as a list of shorts.
*
* @throws IllegalArgumentException if the value is not an array of shorts.
*/
public static ImmutableList<Short> getShorts(AnnotationValue value) {
return SHORTS_VISITOR.visit(value);
}

private static final ArrayVisitor<Float> FLOATS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getFloat);

/**
* Returns the value as a list of floats.
*
* @throws IllegalArgumentException if the value is not an array of floats.
*/
public static ImmutableList<Float> getFloats(AnnotationValue value) {
return FLOATS_VISITOR.visit(value);
}

private static final ArrayVisitor<Double> DOUBLES_VISITOR =
new ArrayVisitor<>(AnnotationValues::getDouble);

/**
* Returns the value as a list of doubles.
*
* @throws IllegalArgumentException if the value is not an array of doubles.
*/
public static ImmutableList<Double> getDoubles(AnnotationValue value) {
return DOUBLES_VISITOR.visit(value);
}

private static final ArrayVisitor<Boolean> BOOLEANS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getBoolean);

/**
* Returns the value as a list of booleans.
*
* @throws IllegalArgumentException if the value is not an array of booleans.
*/
public static ImmutableList<Boolean> getBooleans(AnnotationValue value) {
return BOOLEANS_VISITOR.visit(value);
}

private static final ArrayVisitor<Character> CHARS_VISITOR =
new ArrayVisitor<>(AnnotationValues::getChar);

/**
* Returns the value as a list of characters.
*
* @throws IllegalArgumentException if the value is not an array of chars.
*/
public static ImmutableList<Character> getChars(AnnotationValue value) {
return CHARS_VISITOR.visit(value);
}

private static final ArrayVisitor<AnnotationValue> ANNOTATION_VALUES_VISITOR =
new ArrayVisitor<>(x -> x);

/**
* Returns the value as a list of {@link AnnotationValue}s.
*
* @throws IllegalArgumentException if the value is not an array.
*/
public static ImmutableList<AnnotationValue> getAnnotationValues(AnnotationValue value) {
return ANNOTATION_VALUES_VISITOR.visit(value);
}

private AnnotationValues() {}
}

0 comments on commit 6c2c1a3

Please sign in to comment.