package org.checkerframework.common.value;

import com.sun.source.tree.ConditionalExpressionTree;
import com.sun.source.tree.ExpressionTree;
import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.LiteralTree;
import com.sun.source.tree.MemberSelectTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.NewArrayTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.TypeCastTree;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import org.checkerframework.checker.signature.qual.BinaryName;
import org.checkerframework.checker.signature.qual.Identifier;
import org.checkerframework.common.value.qual.ArrayLen;
import org.checkerframework.common.value.qual.ArrayLenRange;
import org.checkerframework.common.value.qual.StaticallyExecutable;
import org.checkerframework.common.value.util.NumberUtils;
import org.checkerframework.common.value.util.Range;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.treeannotator.TreeAnnotator;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.ElementUtils;
import org.checkerframework.javacutil.TreeUtils;
import org.checkerframework.javacutil.TypesUtils;

/** The TreeAnnotator for this AnnotatedTypeFactory. It adds/replaces annotations. */
class ValueTreeAnnotator extends TreeAnnotator {

  /** The type factory to use. Shadows the field from the superclass with a more specific type. */
  @SuppressWarnings("HidingField")
  protected final ValueAnnotatedTypeFactory atypeFactory;

  /** The domain of the Constant Value Checker: the types for which it estimates possible values. */
  protected static final Set<String> COVERED_CLASS_STRINGS =
      Collections.unmodifiableSet(
          new HashSet<>(
              Arrays.asList(
                  "int",
                  "java.lang.Integer",
                  "double",
                  "java.lang.Double",
                  "byte",
                  "java.lang.Byte",
                  "java.lang.String",
                  "char",
                  "java.lang.Character",
                  "float",
                  "java.lang.Float",
                  "boolean",
                  "java.lang.Boolean",
                  "long",
                  "java.lang.Long",
                  "short",
                  "java.lang.Short",
                  "char[]")));

  /**
   * Create a ValueTreeAnnotator.
   *
   * @param atypeFactory the ValueAnnotatedTypeFactory to use
   */
  public ValueTreeAnnotator(ValueAnnotatedTypeFactory atypeFactory) {
    super(atypeFactory);
    this.atypeFactory = atypeFactory;
  }

  @Override
  public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) {

    List<? extends ExpressionTree> dimensions = tree.getDimensions();
    List<? extends ExpressionTree> initializers = tree.getInitializers();

    // Array construction can provide dimensions or use an initializer.

    // Dimensions provided
    if (!dimensions.isEmpty()) {
      handleDimensions(dimensions, (AnnotatedTypeMirror.AnnotatedArrayType) type);
    } else {
      // Initializer used
      handleInitializers(initializers, (AnnotatedTypeMirror.AnnotatedArrayType) type);

      AnnotationMirror newQual;
      Class<?> clazz = TypesUtils.getClassFromType(type.getUnderlyingType());
      String stringVal = null;
      if (clazz == char[].class) {
        stringVal = getCharArrayStringVal(initializers);
      }

      if (stringVal != null) {
        newQual = atypeFactory.createStringAnnotation(Collections.singletonList(stringVal));
        type.replaceAnnotation(newQual);
      }
    }

    return null;
  }

  /**
   * Recursive method to handle array initializations. Recursively descends the initializer to find
   * each dimension's size and create the appropriate annotation for it.
   *
   * <p>If the annotation of the dimension is {@code @IntVal}, create an {@code @ArrayLen} with the
   * same set of possible values. If the annotation is {@code @IntRange}, create an
   * {@code @ArrayLenRange}. If the annotation is {@code @BottomVal}, create an {@code @BottomVal}
   * instead. In other cases, no annotations are created.
   *
   * @param dimensions a list of ExpressionTrees where each ExpressionTree is a specifier of the
   *     size of that dimension
   * @param type the AnnotatedTypeMirror of the array
   */
  private void handleDimensions(
      List<? extends ExpressionTree> dimensions, AnnotatedTypeMirror.AnnotatedArrayType type) {
    if (dimensions.size() > 1) {
      handleDimensions(
          dimensions.subList(1, dimensions.size()),
          (AnnotatedTypeMirror.AnnotatedArrayType) type.getComponentType());
    }
    AnnotationMirror dimType =
        atypeFactory
            .getAnnotatedType(dimensions.get(0))
            .getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);

    if (AnnotationUtils.areSameByName(dimType, atypeFactory.BOTTOMVAL)) {
      type.replaceAnnotation(atypeFactory.BOTTOMVAL);
    } else {
      RangeOrListOfValues rolv = null;
      if (atypeFactory.isIntRange(dimType)) {
        rolv = new RangeOrListOfValues(atypeFactory.getRange(dimType));
      } else if (AnnotationUtils.areSameByName(dimType, ValueAnnotatedTypeFactory.INTVAL_NAME)) {
        rolv =
            new RangeOrListOfValues(
                RangeOrListOfValues.convertLongsToInts(atypeFactory.getIntValues(dimType)));
      }
      if (rolv != null) {
        AnnotationMirror newQual = rolv.createAnnotation(atypeFactory);
        type.replaceAnnotation(newQual);
      }
    }
  }

  /**
   * Adds the ArrayLen/ArrayLenRange annotation from the array initializers to {@code type}.
   *
   * <p>If type is a multi-dimensional array, the initializers might also contain arrays, so this
   * method adds the annotations for those initializers, too.
   *
   * @param initializers initializer trees
   * @param type array type to which annotations are added
   */
  private void handleInitializers(
      List<? extends ExpressionTree> initializers, AnnotatedTypeMirror.AnnotatedArrayType type) {

    type.replaceAnnotation(
        atypeFactory.createArrayLenAnnotation(Collections.singletonList(initializers.size())));

    if (type.getComponentType().getKind() != TypeKind.ARRAY) {
      return;
    }

    // A list of arrayLens.  arrayLenOfDimensions.get(i) is the array lengths for the ith dimension.
    List<RangeOrListOfValues> arrayLenOfDimensions = new ArrayList<>();
    for (ExpressionTree init : initializers) {
      AnnotatedTypeMirror componentType = atypeFactory.getAnnotatedType(init);
      int dimension = 0;
      while (componentType.getKind() == TypeKind.ARRAY) {
        RangeOrListOfValues rolv = null;
        if (dimension < arrayLenOfDimensions.size()) {
          rolv = arrayLenOfDimensions.get(dimension);
        }
        AnnotationMirror arrayLen = componentType.getAnnotation(ArrayLen.class);
        if (arrayLen != null) {
          List<Integer> currentLengths = atypeFactory.getArrayLength(arrayLen);
          if (rolv != null) {
            rolv.addAll(currentLengths);
          } else {
            arrayLenOfDimensions.add(new RangeOrListOfValues(currentLengths));
          }
        } else {
          // Check for an arrayLenRange annotation
          AnnotationMirror arrayLenRangeAnno = componentType.getAnnotation(ArrayLenRange.class);
          Range range;
          if (arrayLenRangeAnno != null) {
            range = atypeFactory.getRange(arrayLenRangeAnno);
          } else {
            range = Range.EVERYTHING;
          }
          if (rolv != null) {
            rolv.add(range);
          } else {
            arrayLenOfDimensions.add(new RangeOrListOfValues(range));
          }
        }

        dimension++;
        componentType = ((AnnotatedTypeMirror.AnnotatedArrayType) componentType).getComponentType();
      }
    }

    AnnotatedTypeMirror componentType = type.getComponentType();
    int i = 0;
    while (componentType.getKind() == TypeKind.ARRAY && i < arrayLenOfDimensions.size()) {
      RangeOrListOfValues rolv = arrayLenOfDimensions.get(i);
      componentType.addAnnotation(rolv.createAnnotation(atypeFactory));
      componentType = ((AnnotatedTypeMirror.AnnotatedArrayType) componentType).getComponentType();
      i++;
    }
  }

  /** Convert a char array to a String. Return null if unable to convert. */
  private String getCharArrayStringVal(List<? extends ExpressionTree> initializers) {
    boolean allLiterals = true;
    StringBuilder stringVal = new StringBuilder();
    for (ExpressionTree e : initializers) {
      Range range =
          atypeFactory.getRange(
              atypeFactory.getAnnotatedType(e).getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL));
      if (range != null && range.from == range.to) {
        char charVal = (char) range.from;
        stringVal.append(charVal);
      } else {
        allLiterals = false;
        break;
      }
    }
    if (allLiterals) {
      return stringVal.toString();
    }
    // If any part of the initializer isn't known,
    // the stringval isn't known.
    return null;
  }

  @Override
  public Void visitTypeCast(TypeCastTree tree, AnnotatedTypeMirror atm) {
    if (handledByValueChecker(atm)) {
      AnnotationMirror oldAnno =
          atypeFactory
              .getAnnotatedType(tree.getExpression())
              .getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);
      if (oldAnno == null) {
        return null;
      }
      TypeMirror newType = atm.getUnderlyingType();
      AnnotationMirror newAnno;
      Range range;

      if (TypesUtils.isString(newType) || newType.getKind() == TypeKind.ARRAY) {
        // Strings and arrays do not allow conversions
        newAnno = oldAnno;
      } else if (atypeFactory.isIntRange(oldAnno)
          && (range = atypeFactory.getRange(oldAnno))
              .isWiderThan(ValueAnnotatedTypeFactory.MAX_VALUES)) {
        Class<?> newClass = TypesUtils.getClassFromType(newType);
        if (newClass == String.class) {
          newAnno = atypeFactory.UNKNOWNVAL;
        } else if (newClass == Boolean.class || newClass == boolean.class) {
          throw new UnsupportedOperationException(
              "ValueAnnotatedTypeFactory: can't convert int to boolean");
        } else {
          newAnno = atypeFactory.createIntRangeAnnotation(NumberUtils.castRange(newType, range));
        }
      } else {
        List<?> values = ValueCheckerUtils.getValuesCastedToType(oldAnno, newType, atypeFactory);
        newAnno = atypeFactory.createResultingAnnotation(atm.getUnderlyingType(), values);
      }
      atm.addMissingAnnotations(Collections.singleton(newAnno));
    } else if (atm.getKind() == TypeKind.ARRAY) {
      if (tree.getExpression().getKind() == Tree.Kind.NULL_LITERAL) {
        atm.addMissingAnnotations(Collections.singleton(atypeFactory.BOTTOMVAL));
      }
    }
    return null;
  }

  /**
   * Get the "value" field of the given annotation, casted to the given type. Empty list means no
   * value is possible (dead code). Null means no information is known -- any value is possible.
   */
  private List<?> getValues(AnnotatedTypeMirror type, TypeMirror castTo) {
    AnnotationMirror anno = type.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL);
    if (anno == null) {
      // If type is an AnnotatedTypeVariable (or other type without a primary annotation)
      // then anno will be null. It would be safe to use the annotation on the upper
      // bound; however, unless the upper bound was explicitly annotated, it will be
      // unknown.  AnnotatedTypes.findEffectiveAnnotationInHierarchy(, toSearch, top)
      return null;
    }
    return ValueCheckerUtils.getValuesCastedToType(anno, castTo, atypeFactory);
  }

  @Override
  public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) {
    if (!handledByValueChecker(type)) {
      return null;
    }
    Object value = tree.getValue();
    switch (tree.getKind()) {
      case BOOLEAN_LITERAL:
        AnnotationMirror boolAnno =
            atypeFactory.createBooleanAnnotation(Collections.singletonList((Boolean) value));
        type.replaceAnnotation(boolAnno);
        return null;

      case CHAR_LITERAL:
        AnnotationMirror charAnno =
            atypeFactory.createCharAnnotation(Collections.singletonList((Character) value));
        type.replaceAnnotation(charAnno);
        return null;

      case DOUBLE_LITERAL:
      case FLOAT_LITERAL:
      case INT_LITERAL:
      case LONG_LITERAL:
        AnnotationMirror numberAnno =
            atypeFactory.createNumberAnnotationMirror(Collections.singletonList((Number) value));
        type.replaceAnnotation(numberAnno);
        return null;
      case STRING_LITERAL:
        AnnotationMirror stringAnno =
            atypeFactory.createStringAnnotation(Collections.singletonList((String) value));
        type.replaceAnnotation(stringAnno);
        return null;
      default:
        return null;
    }
  }

  /**
   * Given a MemberSelectTree representing a method call, return true if the method's declaration is
   * annotated with {@code @StaticallyExecutable}.
   */
  private boolean methodIsStaticallyExecutable(Element method) {
    return atypeFactory.getDeclAnnotation(method, StaticallyExecutable.class) != null;
  }

  /**
   * Returns the Range of the Math.min or Math.max method, or null if the argument is none of these
   * methods or their arguments are not annotated in ValueChecker hierarchy.
   *
   * @return the Range of the Math.min or Math.max method, or null if the argument is none of these
   *     methods or their arguments are not annotated in ValueChecker hierarchy
   */
  private Range getRangeForMathMinMax(MethodInvocationTree tree) {
    if (atypeFactory.getMethodIdentifier().isMathMin(tree, atypeFactory.getProcessingEnv())) {
      AnnotatedTypeMirror arg1 = atypeFactory.getAnnotatedType(tree.getArguments().get(0));
      AnnotatedTypeMirror arg2 = atypeFactory.getAnnotatedType(tree.getArguments().get(1));
      Range rangeArg1 =
          atypeFactory.getRange(arg1.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL));
      Range rangeArg2 =
          atypeFactory.getRange(arg2.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL));
      if (rangeArg1 != null && rangeArg2 != null) {
        return rangeArg1.min(rangeArg2);
      }
    } else if (atypeFactory
        .getMethodIdentifier()
        .isMathMax(tree, atypeFactory.getProcessingEnv())) {
      AnnotatedTypeMirror arg1 = atypeFactory.getAnnotatedType(tree.getArguments().get(0));
      AnnotatedTypeMirror arg2 = atypeFactory.getAnnotatedType(tree.getArguments().get(1));
      Range rangeArg1 =
          atypeFactory.getRange(arg1.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL));
      Range rangeArg2 =
          atypeFactory.getRange(arg2.getAnnotationInHierarchy(atypeFactory.UNKNOWNVAL));
      if (rangeArg1 != null && rangeArg2 != null) {
        return rangeArg1.max(rangeArg2);
      }
    }
    return null;
  }

  @Override
  public Void visitMethodInvocation(MethodInvocationTree tree, AnnotatedTypeMirror type) {
    if (type.hasAnnotation(atypeFactory.UNKNOWNVAL)) {
      Range range = getRangeForMathMinMax(tree);
      if (range != null) {
        type.replaceAnnotation(atypeFactory.createIntRangeAnnotation(range));
      }
    }

    if (atypeFactory
        .getMethodIdentifier()
        .isArraysCopyOfInvocation(tree, atypeFactory.getProcessingEnv())) {
      List<? extends ExpressionTree> args = tree.getArguments();
      Range range =
          ValueCheckerUtils.getPossibleValues(
              atypeFactory.getAnnotatedType(args.get(1)), atypeFactory);
      if (range != null) {
        type.replaceAnnotation(atypeFactory.createArrayLenRangeAnnotation(range));
      }
    }

    if (!methodIsStaticallyExecutable(TreeUtils.elementFromUse(tree))
        || !handledByValueChecker(type)) {
      return null;
    }

    if (atypeFactory
        .getMethodIdentifier()
        .isStringLengthInvocation(tree, atypeFactory.getProcessingEnv())) {
      AnnotatedTypeMirror receiverType = atypeFactory.getReceiverType(tree);
      AnnotationMirror resultAnno = atypeFactory.createArrayLengthResultAnnotation(receiverType);
      if (resultAnno != null) {
        type.replaceAnnotation(resultAnno);
      }
      return null;
    }

    if (atypeFactory
        .getMethodIdentifier()
        .isArrayGetLengthInvocation(tree, atypeFactory.getProcessingEnv())) {
      List<? extends ExpressionTree> args = tree.getArguments();
      AnnotatedTypeMirror argType = atypeFactory.getAnnotatedType(args.get(0));
      AnnotationMirror resultAnno = atypeFactory.createArrayLengthResultAnnotation(argType);
      if (resultAnno != null) {
        type.replaceAnnotation(resultAnno);
      }
      return null;
    }

    // Get argument values
    List<? extends ExpressionTree> arguments = tree.getArguments();
    ArrayList<List<?>> argValues;
    if (arguments.isEmpty()) {
      argValues = null;
    } else {
      argValues = new ArrayList<>(arguments.size());
      for (ExpressionTree argument : arguments) {
        AnnotatedTypeMirror argType = atypeFactory.getAnnotatedType(argument);
        List<?> values = getValues(argType, argType.getUnderlyingType());
        if (values == null || values.isEmpty()) {
          // Values aren't known, so don't try to evaluate the method.
          return null;
        }
        argValues.add(values);
      }
    }

    // Get receiver values
    AnnotatedTypeMirror receiver = atypeFactory.getReceiverType(tree);
    List<?> receiverValues;

    if (receiver != null && !ElementUtils.isStatic(TreeUtils.elementFromUse(tree))) {
      receiverValues = getValues(receiver, receiver.getUnderlyingType());
      if (receiverValues == null || receiverValues.isEmpty()) {
        // Values aren't known, so don't try to evaluate the method.
        return null;
      }
    } else {
      receiverValues = null;
    }

    // Evaluate method
    List<?> returnValues =
        atypeFactory.evaluator.evaluateMethodCall(argValues, receiverValues, tree);
    if (returnValues == null) {
      return null;
    }
    AnnotationMirror returnType =
        atypeFactory.createResultingAnnotation(type.getUnderlyingType(), returnValues);
    type.replaceAnnotation(returnType);

    return null;
  }

  @Override
  public Void visitNewClass(NewClassTree tree, AnnotatedTypeMirror type) {
    if (!methodIsStaticallyExecutable(TreeUtils.elementFromUse(tree))
        || !handledByValueChecker(type)) {
      return null;
    }

    // get argument values
    List<? extends ExpressionTree> arguments = tree.getArguments();
    ArrayList<List<?>> argValues;
    if (arguments.isEmpty()) {
      argValues = null;
    } else {
      argValues = new ArrayList<>(arguments.size());
      for (ExpressionTree argument : arguments) {
        AnnotatedTypeMirror argType = atypeFactory.getAnnotatedType(argument);
        List<?> values = getValues(argType, argType.getUnderlyingType());
        if (values == null || values.isEmpty()) {
          // Values aren't known, so don't try to evaluate the method.
          return null;
        }
        argValues.add(values);
      }
    }

    // Evaluate method
    List<?> returnValues =
        atypeFactory.evaluator.evaluteConstructorCall(argValues, tree, type.getUnderlyingType());
    if (returnValues == null) {
      return null;
    }
    AnnotationMirror returnType =
        atypeFactory.createResultingAnnotation(type.getUnderlyingType(), returnValues);
    type.replaceAnnotation(returnType);

    return null;
  }

  @Override
  public Void visitMemberSelect(MemberSelectTree tree, AnnotatedTypeMirror type) {
    visitFieldAccess(tree, type);
    visitEnumConstant(tree, type);

    if (TreeUtils.isArrayLengthAccess(tree)) {
      // The field access is to the length field, as in "someArrayExpression.length"
      AnnotatedTypeMirror receiverType = atypeFactory.getAnnotatedType(tree.getExpression());
      if (receiverType.getKind() == TypeKind.ARRAY) {
        AnnotationMirror resultAnno = atypeFactory.createArrayLengthResultAnnotation(receiverType);
        if (resultAnno != null) {
          type.replaceAnnotation(resultAnno);
        }
      }
    }
    return null;
  }

  /**
   * Visit a tree that might be a field access.
   *
   * @param tree a tree that might be a field access. It is either a MemberSelectTree or an
   *     IdentifierTree (if the programmer omitted the leading `this.`).
   * @param type its type
   */
  private void visitFieldAccess(ExpressionTree tree, AnnotatedTypeMirror type) {
    if (!TreeUtils.isFieldAccess(tree) || !handledByValueChecker(type)) {
      return;
    }

    VariableElement fieldElement = (VariableElement) TreeUtils.elementFromTree(tree);
    Object value = fieldElement.getConstantValue();
    if (value != null) {
      // The field is a compile-time constant.
      type.replaceAnnotation(
          atypeFactory.createResultingAnnotation(type.getUnderlyingType(), value));
      return;
    }
    if (ElementUtils.isStatic(fieldElement) && ElementUtils.isFinal(fieldElement)) {
      // The field is static and final, but its declaration does not initialize it to a
      // compile-time constant.  Obtain its value reflectively.
      Element classElement = fieldElement.getEnclosingElement();
      if (classElement != null) {
        @SuppressWarnings("signature" // TODO: bug in ValueAnnotatedTypeFactory.
        // evaluateStaticFieldAccess requires a @ClassGetName but this passes a
        // @FullyQualifiedName.  They differ for inner classes.
        )
        @BinaryName String classname = ElementUtils.getQualifiedClassName(classElement).toString();
        @SuppressWarnings("signature") // https://tinyurl.com/cfissue/658 for Name.toString()
        @Identifier String fieldName = fieldElement.getSimpleName().toString();
        value = atypeFactory.evaluator.evaluateStaticFieldAccess(classname, fieldName, tree);
        if (value != null) {
          type.replaceAnnotation(
              atypeFactory.createResultingAnnotation(type.getUnderlyingType(), value));
        }
        return;
      }
    }

    return;
  }

  /** Returns true iff the given type is in the domain of the Constant Value Checker. */
  private boolean handledByValueChecker(AnnotatedTypeMirror type) {
    TypeMirror tm = type.getUnderlyingType();
    /* TODO: compare performance to the more readable.
    return TypesUtils.isPrimitive(tm)
            || TypesUtils.isBoxedPrimitive(tm)
            || TypesUtils.isString(tm)
            || tm.toString().equals("char[]"); // Why?
    */
    return COVERED_CLASS_STRINGS.contains(tm.toString());
  }

  @Override
  public Void visitConditionalExpression(
      ConditionalExpressionTree node, AnnotatedTypeMirror annotatedTypeMirror) {
    // Work around for https://github.com/typetools/checker-framework/issues/602.
    annotatedTypeMirror.replaceAnnotation(atypeFactory.UNKNOWNVAL);
    return null;
  }

  // An IdentifierTree can be a local variable (including formals, exception parameters, etc.) or
  // an implicit field access (where `this.` is omitted).
  // A field access is always an IdentifierTree or MemberSelectTree.
  @Override
  public Void visitIdentifier(IdentifierTree tree, AnnotatedTypeMirror type) {
    visitFieldAccess(tree, type);
    visitEnumConstant(tree, type);
    return null;
  }

  /**
   * Default the type of an enum constant {@code E.V} to {@code @StringVal("V")}. Does nothing if
   * the argument is not an enum constant.
   *
   * @param tree an Identifier or MemberSelect tree that might be an enum
   * @param type the type of that tree
   */
  private void visitEnumConstant(ExpressionTree tree, AnnotatedTypeMirror type) {
    Element decl = TreeUtils.elementFromTree(tree);
    if (decl.getKind() != ElementKind.ENUM_CONSTANT) {
      return;
    }

    Name id;
    switch (tree.getKind()) {
      case MEMBER_SELECT:
        id = ((MemberSelectTree) tree).getIdentifier();
        break;
      case IDENTIFIER:
        id = ((IdentifierTree) tree).getName();
        break;
      default:
        throw new BugInCF("unexpected kind of enum constant use tree: " + tree.getKind());
    }
    AnnotationMirror stringVal =
        atypeFactory.createStringAnnotation(Collections.singletonList(id.toString()));
    type.replaceAnnotation(stringVal);
  }
}
