// Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;

import com.android.tools.r8.androidapi.AndroidApiLevelCompute;
import com.android.tools.r8.androidapi.ComputedApiLevel;
import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.dex.MixedSectionCollection;
import com.android.tools.r8.graph.DexValue.DexValueAnnotation;
import com.android.tools.r8.graph.DexValue.DexValueArray;
import com.android.tools.r8.graph.DexValue.DexValueByte;
import com.android.tools.r8.graph.DexValue.DexValueInt;
import com.android.tools.r8.graph.DexValue.DexValueMethod;
import com.android.tools.r8.graph.DexValue.DexValueNull;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.DexValue.DexValueType;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.ir.desugar.CovariantReturnTypeAnnotationTransformer;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.synthesis.SyntheticItems;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

public class DexAnnotation extends DexItem implements StructuralItem<DexAnnotation> {

  public enum AnnotatedKind {
    FIELD,
    METHOD,
    TYPE,
    PARAMETER;

    public static AnnotatedKind from(DexDefinition definition) {
      return from(definition.getReference());
    }

    public static AnnotatedKind from(ProgramDefinition definition) {
      return from(definition.getReference());
    }

    public static AnnotatedKind from(DexReference reference) {
      return reference.apply(type -> TYPE, field -> FIELD, method -> METHOD);
    }

    public boolean isParameter() {
      return this == PARAMETER;
    }
  }

  public static final DexAnnotation[] EMPTY_ARRAY = {};
  public static final int VISIBILITY_BUILD = 0x00;
  public static final int VISIBILITY_RUNTIME = 0x01;
  public static final int VISIBILITY_SYSTEM = 0x02;
  public final int visibility;
  public final DexEncodedAnnotation annotation;

  private static final int UNKNOWN_API_LEVEL = -1;
  private static final int NOT_SET_API_LEVEL = -2;

  protected static void specify(StructuralSpecification<DexAnnotation, ?> spec) {
    spec.withItem(a -> a.annotation).withInt(a -> a.visibility);
  }

  public DexAnnotation(int visibility, DexEncodedAnnotation annotation) {
    this.visibility = visibility;
    this.annotation = annotation;
  }

  public boolean isTypeAnnotation() {
    return false;
  }

  public DexTypeAnnotation asTypeAnnotation() {
    return null;
  }

  @Override
  public DexAnnotation self() {
    return this;
  }

  @Override
  public StructuralMapping<DexAnnotation> getStructuralMapping() {
    return DexAnnotation::specify;
  }

  public DexType getAnnotationType() {
    return annotation.type;
  }

  @Override
  public int hashCode() {
    return visibility + annotation.hashCode() * 3;
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (other instanceof DexAnnotation) {
      DexAnnotation o = (DexAnnotation) other;
      return (visibility == o.visibility) && annotation.equals(o.annotation);
    }
    return false;
  }

  @Override
  public String toString() {
    return visibility + " " + annotation;
  }

  public int getVisibility() {
    return visibility;
  }

  public void collectIndexedItems(AppView<?> appView, IndexedItemCollection indexedItems) {
    annotation.collectIndexedItems(appView, indexedItems);
  }

  @Override
  void collectMixedSectionItems(MixedSectionCollection mixedItems) {
    mixedItems.add(this);
  }

  public static boolean retainCompileTimeAnnotation(DexType annotation, InternalOptions options) {
    if (options.retainCompileTimeAnnotations) {
      return true;
    }
    if (annotation == options.itemFactory.annotationSynthesizedClass
        || annotation
            .getDescriptor()
            .startsWith(options.itemFactory.dalvikAnnotationOptimizationPrefix)) {
      return true;
    }
    if (options.processCovariantReturnTypeAnnotations) {
      // @CovariantReturnType annotations are processed by CovariantReturnTypeAnnotationTransformer,
      // they thus need to be read here and will then be removed as part of the processing.
      return CovariantReturnTypeAnnotationTransformer.isCovariantReturnTypeAnnotation(
          annotation, options.itemFactory);
    }
    return false;
  }

  public static DexAnnotation createEnclosingClassAnnotation(DexType enclosingClass,
      DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationEnclosingClass, factory,
        new DexValueType(enclosingClass));
  }

  public static DexType getEnclosingClassFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationEnclosingClass, annotation);
    if (value == null) {
      return null;
    }
    return value.asDexValueType().value;
  }

  public static DexAnnotation createEnclosingMethodAnnotation(DexMethod enclosingMethod,
      DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationEnclosingMethod, factory,
        new DexValueMethod(enclosingMethod));
  }

  public static DexMethod getEnclosingMethodFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationEnclosingMethod, annotation);
    if (value == null) {
      return null;
    }
    return value.asDexValueMethod().value;
  }

  public static boolean isEnclosingClassAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationEnclosingClass;
  }

  public static boolean isEnclosingMethodAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationEnclosingMethod;
  }

  public static boolean isInnerClassAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationInnerClass;
  }

  public static boolean isMemberClassesAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationMemberClasses;
  }

  public static boolean isNestHostAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationNestHost;
  }

  public static boolean isNestMembersAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationNestMembers;
  }

  public static boolean isPermittedSubclassesAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationPermittedSubclasses;
  }

  public static boolean isRecordAnnotation(DexAnnotation annotation, DexItemFactory factory) {
    return annotation.getAnnotationType() == factory.annotationRecord;
  }

  public static DexAnnotation createInnerClassAnnotation(
      DexString clazz, int access, DexItemFactory factory) {
    return new DexAnnotation(
        VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(
            factory.annotationInnerClass,
            new DexAnnotationElement[] {
              new DexAnnotationElement(
                  factory.createString("accessFlags"), DexValueInt.create(access)),
              new DexAnnotationElement(
                  factory.createString("name"),
                  (clazz == null) ? DexValueNull.NULL : new DexValueString(clazz))
            }));
  }

  public static Pair<DexString, Integer> getInnerClassFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    assert isInnerClassAnnotation(annotation, factory);
    DexAnnotationElement[] elements = annotation.annotation.elements;
    Pair<DexString, Integer> result = new Pair<>();
    for (DexAnnotationElement element : elements) {
      if (element.name == factory.createString("name")) {
        if (element.value.isDexValueString()) {
          result.setFirst(element.value.asDexValueString().getValue());
        }
      } else {
        assert element.name == factory.createString("accessFlags");
        result.setSecond(element.value.asDexValueInt().getValue());
      }
    }
    return result;
  }

  public static DexAnnotation createMemberClassesAnnotation(List<DexType> classes,
      DexItemFactory factory) {
    DexValue[] values = new DexValue[classes.size()];
    for (int i = 0; i < classes.size(); i++) {
      values[i] = new DexValueType(classes.get(i));
    }
    return createSystemValueAnnotation(factory.annotationMemberClasses, factory,
        new DexValueArray(values));
  }

  public static List<DexType> getMemberClassesFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationMemberClasses, annotation);
    if (value == null) {
      return null;
    }
    DexValueArray membersArray = value.asDexValueArray();
    List<DexType> types = new ArrayList<>(membersArray.getValues().length);
    for (DexValue elementValue : membersArray.getValues()) {
      types.add(elementValue.asDexValueType().value);
    }
    return types;
  }

  public static DexType getNestHostFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    DexValue value = getSystemValueAnnotationValue(factory.annotationNestHost, annotation);
    if (value == null) {
      return null;
    }
    return value.asDexValueType().getValue();
  }

  private static List<DexType> getTypesFromAnnotation(
      DexType annotationType, DexAnnotation annotation) {
    DexValue value = getSystemValueAnnotationValue(annotationType, annotation);
    if (value == null) {
      return null;
    }
    DexValueArray membersArray = value.asDexValueArray();
    List<DexType> types = new ArrayList<>(membersArray.getValues().length);
    for (DexValue elementValue : membersArray.getValues()) {
      types.add(elementValue.asDexValueType().value);
    }
    return types;
  }

  public static List<DexType> getNestMembersFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return getTypesFromAnnotation(factory.annotationNestMembers, annotation);
  }

  public static List<DexType> getPermittedSubclassesFromAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return getTypesFromAnnotation(factory.annotationPermittedSubclasses, annotation);
  }

  /** See {@link #createRecordAnnotation(DexProgramClass, AppView)} for the representation. */
  public static List<RecordComponentInfo> getRecordComponentInfoFromAnnotation(
      DexType type, DexAnnotation annotation, DexItemFactory factory, Origin origin) {
    DexValue componentNamesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentNames);
    DexValue componentTypesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentTypes);
    DexValue componentSignaturesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentSignatures);
    DexValue componentAnnotationVisibilitiesValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord,
            annotation,
            factory.annotationRecordComponentAnnotationVisibilities);
    DexValue componentAnnotationsValue =
        getSystemValueAnnotationValueWithName(
            factory.annotationRecord, annotation, factory.annotationRecordComponentAnnotations);

    if (componentNamesValue == null
        || componentTypesValue == null
        || componentSignaturesValue == null
        || componentAnnotationVisibilitiesValue == null
        || componentAnnotationsValue == null) {
      return null;
    }
    if (!componentNamesValue.isDexValueArray()
        || !componentTypesValue.isDexValueArray()
        || !componentSignaturesValue.isDexValueArray()
        || !componentAnnotationVisibilitiesValue.isDexValueArray()
        || !componentAnnotationsValue.isDexValueArray()) {
      return null;
    }
    DexValueArray componentNamesValueArray = componentNamesValue.asDexValueArray();
    DexValueArray componentTypesValueArray = componentTypesValue.asDexValueArray();
    DexValueArray componentSignaturesValueArray = componentSignaturesValue.asDexValueArray();
    DexValueArray componentAnnotationVisibilitiesValueArray =
        componentAnnotationVisibilitiesValue.asDexValueArray();
    DexValueArray componentAnnotationsValueArray = componentAnnotationsValue.asDexValueArray();
    if (componentNamesValueArray.size() != componentTypesValueArray.size()
        || componentNamesValueArray.size() != componentSignaturesValueArray.size()
        || componentNamesValueArray.size() != componentAnnotationVisibilitiesValueArray.size()
        || componentNamesValueArray.size() != componentAnnotationsValueArray.size()) {
      return null;
    }
    List<RecordComponentInfo> result = new ArrayList<>(componentNamesValueArray.size());
    for (int componentIndex = 0;
        componentIndex < componentNamesValueArray.size();
        componentIndex++) {
      DexValue nameValue = componentNamesValueArray.getValue(componentIndex);
      DexValue typeValue = componentTypesValueArray.getValue(componentIndex);
      DexValue signatureValue = componentSignaturesValueArray.getValue(componentIndex);
      DexValue visibilitiesValue =
          componentAnnotationVisibilitiesValueArray.getValue(componentIndex);
      DexValue annotationsValue = componentAnnotationsValueArray.getValue(componentIndex);
      if (!nameValue.isDexValueString()
          || !typeValue.isDexValueType()
          || !(signatureValue.isDexValueAnnotation() || signatureValue.isDexValueNull())
          || !visibilitiesValue.isDexValueArray()
          || !annotationsValue.isDexValueArray()) {
        return null;
      }
      DexValueArray visibilitiesValueArray = visibilitiesValue.asDexValueArray();
      DexValueArray annotationsValueArray = annotationsValue.asDexValueArray();
      if (visibilitiesValueArray.size() != annotationsValueArray.size()) {
        return null;
      }
      List<DexAnnotation> componentAnnotations = Collections.emptyList();
      if (annotationsValueArray.size() > 0) {
        componentAnnotations = new ArrayList<>(annotationsValueArray.size());
        for (int annotationIndex = 0;
            annotationIndex < annotationsValueArray.size();
            annotationIndex++) {
          DexValue visibilityValue = visibilitiesValueArray.getValue(annotationIndex);
          DexValue annotationValue = annotationsValueArray.getValue(annotationIndex);
          if (!visibilityValue.isDexValueByte() || !annotationValue.isDexValueAnnotation()) {
            return null;
          }
          componentAnnotations.add(
              new DexAnnotation(
                  visibilityValue.asDexValueByte().getValue(),
                  annotationValue.asDexValueAnnotation().getValue()));
        }
      }
      FieldTypeSignature componentSignature =
          GenericSignature.parseFieldTypeSignature(
              nameValue.asDexValueString().getValue().toString(),
              signatureValue.isDexValueAnnotation()
                  ? getSignature(signatureValue.asDexValueAnnotation().getValue())
                  : null,
              origin,
              factory,
              null);

      DexType componentType = typeValue.asDexValueType().getValue();
      DexString componentName = nameValue.asDexValueString().getValue();
      DexField componentField = factory.createField(type, componentType, componentName);
      result.add(new RecordComponentInfo(componentField, componentSignature, componentAnnotations));
    }
    return result;
  }

  public static DexAnnotation createSourceDebugExtensionAnnotation(DexValue value,
      DexItemFactory factory) {
    return new DexAnnotation(VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(factory.annotationSourceDebugExtension,
            new DexAnnotationElement[] {
              new DexAnnotationElement(factory.createString("value"), value)
            }));
  }

  public static DexAnnotation createMethodParametersAnnotation(DexValue[] names,
      DexValue[] accessFlags, DexItemFactory factory) {
    assert names.length == accessFlags.length;
    return new DexAnnotation(VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(factory.annotationMethodParameters,
            new DexAnnotationElement[]{
                new DexAnnotationElement(
                    factory.createString("names"),
                    new DexValueArray(names)),
                new DexAnnotationElement(
                    factory.createString("accessFlags"),
                    new DexValueArray(accessFlags))
            }));
  }

  public static DexAnnotation createAnnotationDefaultAnnotation(DexType type,
      List<DexAnnotationElement> defaults, DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationDefault, factory,
        new DexValueAnnotation(
            new DexEncodedAnnotation(type,
                defaults.toArray(DexAnnotationElement.EMPTY_ARRAY)))
    );
  }

  public static DexAnnotation createSignatureAnnotation(String signature, DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationSignature, factory,
        compressSignature(signature, factory));
  }

  public static DexAnnotation createNestHostAnnotation(
      NestHostClassAttribute host, DexItemFactory factory) {
    return createSystemValueAnnotation(
        factory.annotationNestHost, factory, new DexValue.DexValueType(host.getNestHost()));
  }

  public static DexAnnotation createNestMembersAnnotation(
      List<NestMemberClassAttribute> members, DexItemFactory factory) {
    List<DexValueType> list = new ArrayList<>(members.size());
    for (NestMemberClassAttribute member : members) {
      list.add(new DexValue.DexValueType(member.getNestMember()));
    }
    return createSystemValueAnnotation(
        factory.annotationNestMembers,
        factory,
        new DexValue.DexValueArray(list.toArray(DexValue.EMPTY_ARRAY)));
  }

  public static DexAnnotation createPermittedSubclassesAnnotation(
      List<PermittedSubclassAttribute> permittedSubclasses, DexItemFactory factory) {
    List<DexValueType> list = new ArrayList<>(permittedSubclasses.size());
    for (PermittedSubclassAttribute permittedSubclass : permittedSubclasses) {
      list.add(new DexValue.DexValueType(permittedSubclass.getPermittedSubclass()));
    }
    return createSystemValueAnnotation(
        factory.annotationPermittedSubclasses,
        factory,
        new DexValue.DexValueArray(list.toArray(DexValue.EMPTY_ARRAY)));
  }

  /**
   * Record component information is written to DEX as a system annotation named <code>
   * dalvik.annotation.Record</code> with the following content:
   *
   * <pre>
   *   componentAnnotationVisibilities byte[][]
   *   componentAnnotations Annotation[][]
   *   componentNames String[]
   *   componentSignatures Annotation[]  // Annotation dalvik.annotation.Signature or NULL
   *   componentTypes String[]
   * </pre>
   *
   * Each of the arrays have one element for each component.
   *
   * <p>Example of a two component record with two annotations on the first component and one on the
   * second and with a signature on the first component.
   *
   * <pre>
   * .annotation system Ldalvik/annotation/Record;
   *   componentAnnotationVisibilities = {
   *     {
   *       0x1,
   *       0x1
   *     },
   *     {
   *       0x1
   *     }
   *   }
   *   componentAnnotations = {
   *     {
   *       .subannotation LAnnotation1;
   *         value = "a"
   *       .end subannotation,
   *       .subannotation LAnnotation2;
   *         value = "c"
   *       .end subannotation
   *     },
   *     {
   *       .subannotation LAnnotation3;
   *         value = "z"
   *       .end subannotation
   *     }
   *   }
   *   componentNames = {
   *      "name",
   *      "age"
   *   }
   *   componentSignatures = {
   *     .subannotation Ldalvik/annotation/Signature;
   *       value = {
   *         "TX;"
   *       }
   *     .end subannotation,
   *     NULL
   *   }
   *   componentTypes = {
   *     Ljava/lang/CharSequence;,
   *     Ljava/lang/Object;
   *   }
   * .end annotation
   * </pre>
   */
  public static DexAnnotation createRecordAnnotation(DexProgramClass clazz, AppView<?> appView) {
    DexItemFactory factory = appView.dexItemFactory();
    int componentCount = clazz.getRecordComponents().size();
    DexValueString[] componentNames = new DexValueString[componentCount];
    DexValueType[] componentTypes = new DexValueType[componentCount];
    DexValue[] componentSignatures = new DexValue[componentCount];
    DexValueArray[] componentAnnotationVisibilities = new DexValueArray[componentCount];
    DexValueArray[] componentAnnotations = new DexValueArray[componentCount];
    for (int componentIndex = 0; componentIndex < componentCount; componentIndex++) {
      RecordComponentInfo info = clazz.getRecordComponents().get(componentIndex);
      componentNames[componentIndex] =
          new DexValueString(appView.getNamingLens().lookupName(info.getField()));
      componentTypes[componentIndex] = new DexValueType(info.getType());
      if (info.getSignature().hasNoSignature()) {
        componentSignatures[componentIndex] = DexValueNull.NULL;
      } else {
        componentSignatures[componentIndex] =
            new DexValueAnnotation(
                createSignatureAnnotation(info.getSignature().toString(), factory).annotation);
      }
      int annotationsSize = info.getAnnotations().size();
      DexValueByte[] visibilities = new DexValueByte[annotationsSize];
      DexValueAnnotation[] annotations = new DexValueAnnotation[annotationsSize];
      componentAnnotationVisibilities[componentIndex] = new DexValueArray(visibilities);
      componentAnnotations[componentIndex] = new DexValueArray(annotations);
      for (int annotationIndex = 0; annotationIndex < annotationsSize; annotationIndex++) {
        DexAnnotation annotation = info.getAnnotations().get(annotationIndex);
        visibilities[annotationIndex] = DexValueByte.create((byte) annotation.getVisibility());
        annotations[annotationIndex] = new DexValueAnnotation(annotation.annotation);
      }
    }

    if (appView.options().emitRecordAnnotationsExInDex) {
      return new DexAnnotation(
          VISIBILITY_SYSTEM,
          new DexEncodedAnnotation(
              factory.annotationRecord,
              new DexAnnotationElement[] {
                new DexAnnotationElement(
                    factory.annotationRecordComponentNames, new DexValueArray(componentNames)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentTypes, new DexValueArray(componentTypes)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentSignatures,
                    new DexValueArray(componentSignatures)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentAnnotationVisibilities,
                    new DexValueArray(componentAnnotationVisibilities)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentAnnotations,
                    new DexValueArray(componentAnnotations))
              }));
    } else {
      return new DexAnnotation(
          VISIBILITY_SYSTEM,
          new DexEncodedAnnotation(
              factory.annotationRecord,
              new DexAnnotationElement[] {
                new DexAnnotationElement(
                    factory.annotationRecordComponentNames, new DexValueArray(componentNames)),
                new DexAnnotationElement(
                    factory.annotationRecordComponentTypes, new DexValueArray(componentTypes))
              }));
    }
  }

  public static String getSignature(DexAnnotation signatureAnnotation) {
    return getSignature(signatureAnnotation.annotation);
  }

  public static String getSignature(DexEncodedAnnotation signatureAnnotation) {
    return getSignature(signatureAnnotation.elements[0].value.asDexValueArray());
  }

  public static String getSignature(DexValueArray elements) {
    StringBuilder signature = new StringBuilder();
    for (DexValue element : elements.getValues()) {
      signature.append(element.asDexValueString().value.toString());
    }
    return signature.toString();
  }

  public static String getSignature(DexAnnotationSet signatureAnnotations, DexItemFactory factory) {
    DexAnnotation signature = signatureAnnotations.getFirstMatching(factory.annotationSignature);
    return signature == null ? null : getSignature(signature);
  }

  public static DexAnnotation createThrowsAnnotation(DexValue[] exceptions,
      DexItemFactory factory) {
    return createSystemValueAnnotation(factory.annotationThrows, factory,
        new DexValueArray(exceptions));
  }

  private static DexAnnotation createSystemValueAnnotation(DexType type, DexItemFactory factory,
      DexValue value) {
    return new DexAnnotation(VISIBILITY_SYSTEM,
        new DexEncodedAnnotation(type, new DexAnnotationElement[]{
            new DexAnnotationElement(factory.createString("value"), value)
        }));
  }

  private static DexValue getSystemValueAnnotationValue(DexType type, DexAnnotation annotation) {
    assert annotation.visibility == VISIBILITY_SYSTEM;
    assert annotation.annotation.type == type;
    return annotation.annotation.elements.length == 0
        ? null
        : annotation.annotation.elements[0].value;
  }

  private static DexValue getSystemValueAnnotationValueWithName(
      DexType type, DexAnnotation annotation, DexString name) {
    assert annotation.visibility == VISIBILITY_SYSTEM;
    assert annotation.getAnnotationType() == type;
    for (DexAnnotationElement element : annotation.annotation.elements) {
      if (element.name == name) {
        return element.value;
      }
    }
    return null;
  }

  public static boolean isThrowingAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationThrows;
  }

  public static boolean isSignatureAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationSignature;

  }

  public static boolean isAnnotationDefaultAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationDefault;
  }

  public static boolean isJavaLangRetentionAnnotation(
      DexAnnotation annotation, DexItemFactory factory) {
    return annotation.getAnnotationType() == factory.retentionType;
  }

  public static boolean isSourceDebugExtension(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationSourceDebugExtension;
  }

  public static boolean isParameterNameAnnotation(DexAnnotation annotation,
      DexItemFactory factory) {
    return annotation.annotation.type == factory.annotationMethodParameters;
  }

  /**
   * As a simple heuristic for compressing a signature by splitting on fully qualified class names
   * and make them individual part. All other parts of the signature are simply grouped and separate
   * the names.
   * For examples, "()Ljava/lang/List<Lfoo/bar/Baz;>;" splits into:
   * <pre>
   *   ["()", "Ljava/lang/List<", "Lfoo/bar/Baz;", ">;"]
   * </pre>
   */
  private static DexValue compressSignature(String signature, DexItemFactory factory) {
    final int length = signature.length();
    List<DexValue> parts = new ArrayList<>();

    for (int at = 0; at < length; /*at*/) {
      char c = signature.charAt(at);
      int endAt = at + 1;
      if (c == 'L') {
        // Scan to ';' or '<' and consume them.
        while (endAt < length) {
          c = signature.charAt(endAt);
          if (c == ';' || c == '<') {
            endAt++;
            break;
          }
          endAt++;
        }
      } else {
        // Scan to 'L' without consuming it.
        while (endAt < length) {
          c = signature.charAt(endAt);
          if (c == 'L') {
            break;
          }
          endAt++;
        }
      }

      parts.add(toDexValue(signature.substring(at, endAt), factory));
      at = endAt;
    }

    return new DexValueArray(parts.toArray(DexValue.EMPTY_ARRAY));
  }

  private static DexValue toDexValue(String string, DexItemFactory factory) {
    return new DexValueString(factory.createString(string));
  }

  public static DexAnnotation createAnnotationSynthesizedClass(
      SyntheticKind kind, DexItemFactory dexItemFactory, ComputedApiLevel computedApiLevel) {
    DexString versionHash =
        dexItemFactory.createString(dexItemFactory.getSyntheticNaming().getVersionHash());
    DexAnnotationElement kindElement =
        new DexAnnotationElement(dexItemFactory.kindString, DexValueInt.create(kind.getId()));
    DexAnnotationElement versionHashElement =
        new DexAnnotationElement(dexItemFactory.versionHashString, new DexValueString(versionHash));
    int apiLevel = getApiLevelForSerialization(computedApiLevel);
    DexAnnotationElement apiLevelElement =
        new DexAnnotationElement(dexItemFactory.apiLevelString, DexValueInt.create(apiLevel));
    DexAnnotationElement[] elements =
        new DexAnnotationElement[] {apiLevelElement, kindElement, versionHashElement};
    return new DexAnnotation(
        VISIBILITY_BUILD,
        new DexEncodedAnnotation(dexItemFactory.annotationSynthesizedClass, elements));
  }

  public static boolean hasSynthesizedClassAnnotation(
      DexAnnotationSet annotations,
      DexItemFactory factory,
      SyntheticItems synthetics,
      AndroidApiLevelCompute apiLevelCompute) {
    return getSynthesizedClassAnnotationInfo(annotations, factory, synthetics, apiLevelCompute)
        != null;
  }

  public static SynthesizedAnnotationClassInfo getSynthesizedClassAnnotationInfo(
      DexAnnotationSet annotations,
      DexItemFactory factory,
      SyntheticItems synthetics,
      AndroidApiLevelCompute apiLevelCompute) {
    if (annotations.size() != 1) {
      return null;
    }
    DexAnnotation annotation = annotations.annotations[0];
    if (annotation.annotation.type != factory.annotationSynthesizedClass) {
      return null;
    }
    int length = annotation.annotation.elements.length;
    if (length != 3) {
      return null;
    }
    assert factory.kindString.isLessThan(factory.versionHashString);
    DexAnnotationElement apiLevelElement = annotation.annotation.elements[0];
    DexAnnotationElement kindElement = annotation.annotation.elements[1];
    DexAnnotationElement versionHashElement = annotation.annotation.elements[2];
    if (kindElement.name != factory.kindString) {
      return null;
    }
    if (!kindElement.value.isDexValueInt()) {
      return null;
    }
    if (versionHashElement.name != factory.versionHashString) {
      return null;
    }
    if (!versionHashElement.value.isDexValueString()) {
      return null;
    }
    if (apiLevelElement.name != factory.apiLevelString || !apiLevelElement.value.isDexValueInt()) {
      return null;
    }
    String currentVersionHash = synthetics.getNaming().getVersionHash();
    String syntheticVersionHash = versionHashElement.value.asDexValueString().getValue().toString();
    if (!currentVersionHash.equals(syntheticVersionHash)) {
      return null;
    }
    int apiLevelValue = apiLevelElement.value.asDexValueInt().getValue();
    ComputedApiLevel computedApiLevel = getSerializedApiLevel(apiLevelCompute, apiLevelValue);
    SyntheticKind syntheticKind =
        synthetics.getNaming().fromId(kindElement.value.asDexValueInt().getValue());
    assert syntheticKind != synthetics.getNaming().API_MODEL_OUTLINE
        || computedApiLevel.isKnownApiLevel();
    return SynthesizedAnnotationClassInfo.create(syntheticKind, computedApiLevel);
  }

  private static int getApiLevelForSerialization(ComputedApiLevel computedApiLevel) {
    if (computedApiLevel.isNotSetApiLevel()) {
      return NOT_SET_API_LEVEL;
    } else if (computedApiLevel.isUnknownApiLevel()) {
      return UNKNOWN_API_LEVEL;
    } else {
      assert computedApiLevel.isKnownApiLevel();
      return computedApiLevel.asKnownApiLevel().getApiLevel().getLevel();
    }
  }

  private static ComputedApiLevel getSerializedApiLevel(
      AndroidApiLevelCompute apiLevelCompute, int apiLevelValue) {
    if (apiLevelValue == NOT_SET_API_LEVEL) {
      return ComputedApiLevel.notSet();
    } else if (apiLevelValue == UNKNOWN_API_LEVEL) {
      return ComputedApiLevel.unknown();
    } else {
      return apiLevelCompute.of(AndroidApiLevel.getAndroidApiLevel(apiLevelValue));
    }
  }

  public DexAnnotation rewrite(Function<DexEncodedAnnotation, DexEncodedAnnotation> rewriter) {
    DexEncodedAnnotation rewritten = rewriter.apply(annotation);
    if (rewritten == annotation) {
      return this;
    }
    if (rewritten == null) {
      return null;
    }
    return new DexAnnotation(visibility, rewritten);
  }

  public static class SynthesizedAnnotationClassInfo {

    private final SyntheticKind syntheticKind;
    private final ComputedApiLevel computedApiLevel;

    private SynthesizedAnnotationClassInfo(
        SyntheticKind syntheticKind, ComputedApiLevel computedApiLevel) {
      this.syntheticKind = syntheticKind;
      this.computedApiLevel = computedApiLevel;
    }

    private static SynthesizedAnnotationClassInfo create(
        SyntheticKind syntheticKind, ComputedApiLevel computedApiLevel) {
      return new SynthesizedAnnotationClassInfo(syntheticKind, computedApiLevel);
    }

    public SyntheticKind getSyntheticKind() {
      return syntheticKind;
    }

    public ComputedApiLevel getComputedApiLevel() {
      return computedApiLevel;
    }
  }
}
