/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.tools.lint.checks;

import static com.android.SdkConstants.ATTR_VALUE;
import static com.android.SdkConstants.FQCN_SUPPRESS_LINT;
import static com.android.SdkConstants.INT_DEF_ANNOTATION;
import static com.android.SdkConstants.LONG_DEF_ANNOTATION;
import static com.android.SdkConstants.STRING_DEF_ANNOTATION;
import static com.android.SdkConstants.SUPPORT_ANNOTATIONS_PREFIX;
import static com.android.SdkConstants.TYPE_DEF_FLAG_ATTRIBUTE;
import static com.android.tools.lint.client.api.JavaEvaluatorKt.TYPE_DOUBLE;
import static com.android.tools.lint.client.api.JavaEvaluatorKt.TYPE_FLOAT;
import static com.android.tools.lint.client.api.JavaEvaluatorKt.TYPE_INT;
import static com.android.tools.lint.client.api.JavaEvaluatorKt.TYPE_LONG;
import static com.android.tools.lint.client.api.JavaEvaluatorKt.TYPE_SHORT;
import static com.android.tools.lint.client.api.JavaEvaluatorKt.TYPE_STRING;
import static com.android.tools.lint.detector.api.Lint.getAutoBoxedType;
import static com.android.tools.lint.detector.api.ResourceEvaluator.COLOR_INT_ANNOTATION;
import static com.android.tools.lint.detector.api.ResourceEvaluator.DIMENSION_ANNOTATION;
import static com.android.tools.lint.detector.api.ResourceEvaluator.PX_ANNOTATION;
import static com.android.tools.lint.detector.api.ResourceEvaluator.RES_SUFFIX;
import static com.android.tools.lint.detector.api.UastLintUtils.getAnnotationBooleanValue;
import static com.android.tools.lint.detector.api.UastLintUtils.getAnnotationStringValue;
import static com.android.tools.lint.detector.api.UastLintUtils.getAnnotationStringValues;
import static com.android.tools.lint.detector.api.UastLintUtils.getDoubleAttribute;
import static com.android.tools.lint.detector.api.UastLintUtils.getLongAttribute;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.support.AndroidxName;
import com.android.tools.lint.client.api.IssueRegistry;
import com.android.tools.lint.client.api.JavaEvaluator;
import com.android.tools.lint.client.api.UElementHandler;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.ConstantEvaluator;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.ExternalReferenceExpression;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.LintFix;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.SourceCodeScanner;
import com.android.tools.lint.detector.api.UastLintUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiArrayType;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiCompiledElement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiLiteral;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import kotlin.collections.CollectionsKt;
import org.jetbrains.uast.UAnnotation;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UDeclaration;
import org.jetbrains.uast.UDeclarationsExpression;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UIdentifier;
import org.jetbrains.uast.UIfExpression;
import org.jetbrains.uast.ULiteralExpression;
import org.jetbrains.uast.ULocalVariable;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UNamedExpression;
import org.jetbrains.uast.UParameter;
import org.jetbrains.uast.UParenthesizedExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.USwitchClauseExpression;
import org.jetbrains.uast.USwitchExpression;
import org.jetbrains.uast.UVariable;
import org.jetbrains.uast.UastFacade;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.java.JavaUAnnotation;
import org.jetbrains.uast.java.JavaUTypeCastExpression;
import org.jetbrains.uast.kotlin.KotlinUSwitchExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;

/** Checks annotations to make sure they are valid */
public class AnnotationDetector extends Detector implements SourceCodeScanner {
    public static final String GMS_HIDE_ANNOTATION = "com.google.android.gms.common.internal.Hide";
    public static final AndroidxName CHECK_RESULT_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "CheckResult");
    public static final AndroidxName INT_RANGE_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "IntRange");
    public static final AndroidxName FLOAT_RANGE_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "FloatRange");
    public static final AndroidxName SIZE_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "Size");
    public static final AndroidxName PERMISSION_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX.oldName(), "RequiresPermission");
    public static final AndroidxName UI_THREAD_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "UiThread");
    public static final AndroidxName MAIN_THREAD_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "MainThread");
    public static final AndroidxName WORKER_THREAD_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "WorkerThread");
    public static final AndroidxName BINDER_THREAD_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "BinderThread");
    public static final AndroidxName ANY_THREAD_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "AnyThread");
    public static final AndroidxName RESTRICT_TO_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "RestrictTo");
    public static final AndroidxName VISIBLE_FOR_TESTING_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "VisibleForTesting");
    public static final AndroidxName PERMISSION_ANNOTATION_READ =
            AndroidxName.of(PERMISSION_ANNOTATION, "Read");
    public static final AndroidxName PERMISSION_ANNOTATION_WRITE =
            AndroidxName.of(PERMISSION_ANNOTATION, "Write");

    // TODO: Add analysis to enforce this annotation:
    public static final AndroidxName HALF_FLOAT_ANNOTATION =
            AndroidxName.of(SUPPORT_ANNOTATIONS_PREFIX, "HalfFloat");

    public static final String THREAD_SUFFIX = "Thread";
    public static final String ATTR_SUGGEST = "suggest";
    public static final String ATTR_TO = "to";
    public static final String ATTR_FROM = "from";
    public static final String ATTR_FROM_INCLUSIVE = "fromInclusive";
    public static final String ATTR_TO_INCLUSIVE = "toInclusive";
    public static final String ATTR_MULTIPLE = "multiple";
    public static final String ATTR_MIN = "min";
    public static final String ATTR_MAX = "max";
    public static final String ATTR_ALL_OF = "allOf";
    public static final String ATTR_ANY_OF = "anyOf";
    public static final String ATTR_CONDITIONAL = "conditional";

    public static final String SECURITY_EXCEPTION = "java.lang.SecurityException";

    public static final String FINDBUGS_ANNOTATIONS_CHECK_RETURN_VALUE =
            "edu.umd.cs.findbugs.annotations.CheckReturnValue";
    public static final String JAVAX_ANNOTATION_CHECK_RETURN_VALUE =
            "javax.annotation.CheckReturnValue";
    public static final String ERRORPRONE_CAN_IGNORE_RETURN_VALUE =
            "com.google.errorprone.annotations.CanIgnoreReturnValue";
    public static final String GUAVA_VISIBLE_FOR_TESTING =
            "com.google.common.annotations.VisibleForTesting";

    public static final Implementation IMPLEMENTATION =
            new Implementation(AnnotationDetector.class, Scope.JAVA_FILE_SCOPE);

    /** Placing SuppressLint on a local variable doesn't work for class-file based checks */
    public static final Issue INSIDE_METHOD =
            Issue.create(
                    "LocalSuppress",
                    "@SuppressLint on invalid element",
                    "The `@SuppressAnnotation` is used to suppress Lint warnings in Java files. However, "
                            + "while many lint checks analyzes the Java source code, where they can find "
                            + "annotations on (for example) local variables, some checks are analyzing the "
                            + "`.class` files. And in class files, annotations only appear on classes, fields "
                            + "and methods. Annotations placed on local variables disappear. If you attempt "
                            + "to suppress a lint error for a class-file based lint check, the suppress "
                            + "annotation not work. You must move the annotation out to the surrounding method.",
                    Category.CORRECTNESS,
                    3,
                    Severity.ERROR,
                    IMPLEMENTATION);

    /** Incorrectly using a support annotation */
    @SuppressWarnings("WeakerAccess")
    public static final Issue ANNOTATION_USAGE =
            Issue.create(
                    "SupportAnnotationUsage",
                    "Incorrect support annotation usage",
                    "This lint check makes sure that the support annotations (such as "
                            + "`@IntDef` and `@ColorInt`) are used correctly. For example, it's an "
                            + "error to specify an `@IntRange` where the `from` value is higher than "
                            + "the `to` value.",
                    Category.CORRECTNESS,
                    2,
                    Severity.ERROR,
                    IMPLEMENTATION);

    /** IntDef annotations should be unique */
    public static final Issue UNIQUE =
            Issue.create(
                            "UniqueConstants",
                            "Overlapping Enumeration Constants",
                            "The `@IntDef` annotation allows you to "
                                    + "create a light-weight \"enum\" or type definition. However, it's possible to "
                                    + "accidentally specify the same value for two or more of the values, which can "
                                    + "lead to hard-to-detect bugs. This check looks for this scenario and flags any "
                                    + "repeated constants.\n"
                                    + "\n"
                                    + "In some cases, the repeated constant is intentional (for example, renaming a "
                                    + "constant to a more intuitive name, and leaving the old name in place for "
                                    + "compatibility purposes).  In that case, simply suppress this check by adding a "
                                    + "`@SuppressLint(\"UniqueConstants\")` annotation.",
                            Category.CORRECTNESS,
                            3,
                            Severity.ERROR,
                            IMPLEMENTATION)
                    .setAndroidSpecific(true);

    /** Flags should typically be specified as bit shifts */
    public static final Issue FLAG_STYLE =
            Issue.create(
                    "ShiftFlags",
                    "Dangerous Flag Constant Declaration",
                    "When defining multiple constants for use in flags, the recommended style is "
                            + "to use the form `1 << 2`, `1 << 3`, `1 << 4` and so on to ensure that the "
                            + "constants are unique and non-overlapping.",
                    Category.CORRECTNESS,
                    3,
                    Severity.WARNING,
                    IMPLEMENTATION);

    /** All IntDef constants should be included in switch */
    public static final Issue SWITCH_TYPE_DEF =
            Issue.create(
                            "SwitchIntDef",
                            "Missing @IntDef in Switch",
                            "This check warns if a `switch` statement does not explicitly include all "
                                    + "the values declared by the typedef `@IntDef` declaration.",
                            Category.CORRECTNESS,
                            3,
                            Severity.WARNING,
                            IMPLEMENTATION)
                    .setAndroidSpecific(true);

    /** Constructs a new {@link AnnotationDetector} check */
    public AnnotationDetector() {}

    // ---- implements SourceCodeScanner ----

    /**
     * Set of fields we've already warned about {@link #FLAG_STYLE} for; these can be referenced
     * multiple times, so we should only flag them once
     */
    private Set<PsiElement> mWarnedFlags;

    @Override
    public List<Class<? extends UElement>> getApplicableUastTypes() {
        List<Class<? extends UElement>> types = new ArrayList<>(2);
        types.add(UAnnotation.class);
        types.add(USwitchExpression.class);
        return types;
    }

    @Nullable
    @Override
    public UElementHandler createUastHandler(@NonNull JavaContext context) {
        return new AnnotationChecker(context);
    }

    private class AnnotationChecker extends UElementHandler {
        private final JavaContext mContext;

        public AnnotationChecker(JavaContext context) {
            mContext = context;
        }

        @Override
        public void visitAnnotation(@NonNull UAnnotation annotation) {
            String type = annotation.getQualifiedName();
            if (type == null || type.startsWith("java.lang.")) {
                return;
            }

            if (FQCN_SUPPRESS_LINT.equals(type)) {
                UElement parent = annotation.getUastParent();
                if (parent == null) {
                    return;
                }
                // Only flag local variables and parameters (not classes, fields and methods)
                if (!(parent instanceof UDeclarationsExpression
                        || parent instanceof ULocalVariable
                        || parent instanceof UParameter)) {
                    return;
                }
                List<UNamedExpression> attributes = annotation.getAttributeValues();
                if (attributes.size() == 1) {
                    UNamedExpression attribute = attributes.get(0);
                    UExpression value = attribute.getExpression();
                    if (value instanceof ULiteralExpression) {
                        Object v = ((ULiteralExpression) value).getValue();
                        if (v instanceof String) {
                            String id = (String) v;
                            checkSuppressLint(annotation, id);
                        }
                    } else if (UastExpressionUtils.isArrayInitializer(value)) {
                        for (UExpression ex : ((UCallExpression) value).getValueArguments()) {
                            if (ex instanceof ULiteralExpression) {
                                Object v = ((ULiteralExpression) ex).getValue();
                                if (v instanceof String) {
                                    String id = (String) v;
                                    if (!checkSuppressLint(annotation, id)) {
                                        return;
                                    }
                                }
                            }
                        }
                    }
                }
            } else if (SUPPORT_ANNOTATIONS_PREFIX.isPrefix(type)) {
                if (CHECK_RESULT_ANNOTATION.isEquals(type)) {
                    // Check that the return type of this method is not void!
                    if (annotation.getUastParent() instanceof UMethod) {
                        UMethod method = (UMethod) annotation.getUastParent();
                        if (!method.isConstructor()
                                && PsiType.VOID.equals(method.getReturnType())) {
                            mContext.report(
                                    ANNOTATION_USAGE,
                                    annotation,
                                    mContext.getLocation(annotation),
                                    "@CheckResult should not be specified on `void` methods");
                        }
                    }
                } else if (INT_RANGE_ANNOTATION.isEquals(type)
                        || FLOAT_RANGE_ANNOTATION.isEquals(type)) {
                    // Check that the annotated element's type is int or long.
                    // Also make sure that from <= to.
                    boolean invalid;
                    if (INT_RANGE_ANNOTATION.isEquals(type)) {
                        checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);

                        long from =
                                getLongAttribute(mContext, annotation, ATTR_FROM, Long.MIN_VALUE);
                        long to = getLongAttribute(mContext, annotation, ATTR_TO, Long.MAX_VALUE);
                        invalid = from > to;
                    } else {
                        checkTargetType(annotation, TYPE_FLOAT, TYPE_DOUBLE, true);

                        double from =
                                getDoubleAttribute(
                                        mContext, annotation, ATTR_FROM, Double.NEGATIVE_INFINITY);
                        double to =
                                getDoubleAttribute(
                                        mContext, annotation, ATTR_TO, Double.POSITIVE_INFINITY);
                        invalid = from > to;
                    }
                    if (invalid) {
                        mContext.report(
                                ANNOTATION_USAGE,
                                annotation,
                                mContext.getLocation(annotation),
                                "Invalid range: the `from` attribute must be less than "
                                        + "the `to` attribute");
                    }
                } else if (SIZE_ANNOTATION.isEquals(type)) {
                    // Check that the annotated element's type is an array, or a collection
                    // (or at least not an int or long; if so, suggest IntRange)
                    // Make sure the size and the modulo is not negative.
                    int unset = -42;
                    long exact = getLongAttribute(mContext, annotation, ATTR_VALUE, unset);
                    long min = getLongAttribute(mContext, annotation, ATTR_MIN, Long.MIN_VALUE);
                    long max = getLongAttribute(mContext, annotation, ATTR_MAX, Long.MAX_VALUE);
                    long multiple = getLongAttribute(mContext, annotation, ATTR_MULTIPLE, 1);
                    if (min > max) {
                        mContext.report(
                                ANNOTATION_USAGE,
                                annotation,
                                mContext.getLocation(annotation),
                                "Invalid size range: the `min` attribute must be less than "
                                        + "the `max` attribute");
                    } else if (multiple < 1) {
                        mContext.report(
                                ANNOTATION_USAGE,
                                annotation,
                                mContext.getLocation(annotation),
                                "The size multiple must be at least 1");

                    } else if (exact < 0 && exact != unset || min < 0 && min != Long.MIN_VALUE) {
                        mContext.report(
                                ANNOTATION_USAGE,
                                annotation,
                                mContext.getLocation(annotation),
                                "The size can't be negative");
                    }
                } else if (COLOR_INT_ANNOTATION.isEquals(type)) {
                    // Check that ColorInt applies to the right type
                    checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
                } else if (DIMENSION_ANNOTATION.isEquals(type) || (PX_ANNOTATION.isEquals(type))) {
                    // Check that @Dimension and @Px applies to the right type
                    checkTargetType(annotation, TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, true);
                } else if (INT_DEF_ANNOTATION.isEquals(type)
                        || LONG_DEF_ANNOTATION.isEquals(type)) {
                    // Make sure IntDef constants are unique
                    ensureUniqueValues(annotation);
                } else if (PERMISSION_ANNOTATION.isEquals(type)
                        || PERMISSION_ANNOTATION_READ.isEquals(type)
                        || PERMISSION_ANNOTATION_WRITE.isEquals(type)) {
                    // Check that if there are no arguments, this is specified on a parameter,
                    // and conversely, on methods and fields there is a valid argument.
                    if (annotation.getUastParent() instanceof UMethod) {
                        String value = getAnnotationStringValue(annotation, ATTR_VALUE);
                        String[] anyOf = getAnnotationStringValues(annotation, ATTR_ANY_OF);
                        String[] allOf = getAnnotationStringValues(annotation, ATTR_ALL_OF);

                        int set = 0;
                        //noinspection VariableNotUsedInsideIf
                        if (value != null) {
                            set++;
                        }
                        //noinspection VariableNotUsedInsideIf
                        if (allOf != null) {
                            set++;
                        }
                        //noinspection VariableNotUsedInsideIf
                        if (anyOf != null) {
                            set++;
                        }

                        if (set == 0) {
                            mContext.report(
                                    ANNOTATION_USAGE,
                                    annotation,
                                    mContext.getLocation(annotation),
                                    "For methods, permission annotation should specify one "
                                            + "of `value`, `anyOf` or `allOf`");
                        } else if (set > 1) {
                            mContext.report(
                                    ANNOTATION_USAGE,
                                    annotation,
                                    mContext.getLocation(annotation),
                                    "Only specify one of `value`, `anyOf` or `allOf`");
                        }
                    }
                } else if (HALF_FLOAT_ANNOTATION.isEquals(type)) {
                    // Check that half floats are on shorts
                    checkTargetType(annotation, TYPE_SHORT, null, true);
                } else if (type.endsWith(RES_SUFFIX)) {
                    // Check that resource type annotations are on ints
                    checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
                } else if (RESTRICT_TO_ANNOTATION.isEquals(type)) {
                    UExpression attributeValue = annotation.findDeclaredAttributeValue(ATTR_VALUE);
                    if (attributeValue == null) {
                        attributeValue = annotation.findDeclaredAttributeValue(null);
                    }
                    if (attributeValue == null) {
                        mContext.report(
                                ANNOTATION_USAGE,
                                annotation,
                                mContext.getLocation(annotation),
                                "Restrict to what? Expected at least one `RestrictTo.Scope` arguments.");
                    } else {
                        String values = attributeValue.asSourceString();
                        if (values.contains("SUBCLASSES")
                                && annotation.getUastParent() instanceof UClass) {
                            mContext.report(
                                    ANNOTATION_USAGE,
                                    annotation,
                                    mContext.getLocation(annotation),
                                    "`RestrictTo.Scope.SUBCLASSES` should only be specified on methods and fields");
                        }
                    }
                }
            } else {
                // Look for typedefs (and make sure they're specified on the right type)
                PsiElement resolved = annotation.resolve();
                if (resolved != null) {
                    PsiClass cls = (PsiClass) resolved;
                    if (cls.isAnnotationType() && cls.getModifierList() != null) {
                        for (PsiAnnotation a :
                                mContext.getEvaluator().getAllAnnotations(cls, false)) {
                            String name = a.getQualifiedName();
                            if (INT_DEF_ANNOTATION.isEquals(name)) {
                                checkTargetType(annotation, TYPE_INT, TYPE_LONG, true);
                            } else if (LONG_DEF_ANNOTATION.isEquals(name)) {
                                checkTargetType(annotation, TYPE_LONG, null, true);
                            } else if (STRING_DEF_ANNOTATION.isEquals(type)) {
                                checkTargetType(annotation, TYPE_STRING, null, true);
                            }
                        }
                    }
                }
            }
        }

        private void checkTargetType(
                @NonNull UAnnotation node, @NonNull String type, boolean allowCollection) {
            checkTargetType(node, type, null, null, null, allowCollection);
        }

        private void checkTargetType(
                @NonNull UAnnotation node,
                @NonNull String type1,
                @Nullable String type2,
                boolean allowCollection) {
            checkTargetType(node, type1, type2, null, null, allowCollection);
        }

        private void checkTargetType(
                @NonNull UAnnotation node,
                @NonNull String type1,
                @Nullable String type2,
                @Nullable String type3,
                @Nullable String type4,
                boolean allowCollection) {
            UElement parent = node.getUastParent();
            PsiType type;

            if (parent instanceof UDeclarationsExpression) {
                List<UDeclaration> elements = ((UDeclarationsExpression) parent).getDeclarations();
                if (!elements.isEmpty()) {
                    UDeclaration element = elements.get(0);
                    if (element instanceof ULocalVariable) {
                        type = ((ULocalVariable) element).getType();
                    } else {
                        return;
                    }
                } else {
                    return;
                }
            } else if (parent instanceof UMethod) {
                UMethod method = (UMethod) parent;
                type =
                        method.isConstructor()
                                ? mContext.getEvaluator()
                                        .getClassType(UastUtils.getContainingUClass(method))
                                : method.getReturnType();
            } else if (parent instanceof UVariable) {
                // Field or local variable or parameter
                UVariable variable = (UVariable) parent;
                if (variable.getTypeReference() == null) {
                    // Uh oh.
                    // https://youtrack.jetbrains.com/issue/KT-20172
                    return;
                }
                type = variable.getType();
            } else {
                return;
            }
            if (type == null) {
                return;
            }

            if (allowCollection) {
                if (type instanceof PsiArrayType) {
                    // For example, int[]
                    type = type.getDeepComponentType();
                } else if (type instanceof PsiClassType) {
                    // For example, List<Integer>
                    PsiClassType classType = (PsiClassType) type;
                    if (classType.getParameters().length == 1) {
                        PsiClass resolved = classType.resolve();
                        if (resolved != null
                                && mContext.getEvaluator()
                                        .implementsInterface(
                                                resolved, "java.util.Collection", false)) {
                            type = classType.getParameters()[0];
                        }
                    }
                }
            }

            if (!type.isValid()) {
                return;
            }

            String typeName = type.getCanonicalText();
            if (typeName.equals("error.NonExistentClass")) {
                // Type not found. Not awesome.
                // https://youtrack.jetbrains.com/issue/KT-20172
                return;
            }

            if (!(typeName.equals(type1)
                    || typeName.equals(type2)
                    || typeName.equals(type3)
                    || typeName.equals(type4))) {
                // Autoboxing? You can put @DrawableRes on a java.lang.Integer for example
                if (typeName.equals(getAutoBoxedType(type1))
                        || type2 != null && typeName.equals(getAutoBoxedType(type2))
                        || type3 != null && typeName.equals(getAutoBoxedType(type3))
                        || type4 != null && typeName.equals(getAutoBoxedType(type4))) {
                    return;
                }

                String expectedTypes;
                if (type4 != null) {
                    expectedTypes = type1 + ", " + type2 + ", " + type3 + ", or " + type4;
                } else if (type3 != null) {
                    expectedTypes = type1 + ", " + type2 + ", or " + type3;
                } else if (type2 != null) {
                    expectedTypes = type1 + " or " + type2;
                } else {
                    expectedTypes = type1;
                }
                if (typeName.equals(TYPE_STRING)) {
                    typeName = "String";
                }
                String message =
                        String.format(
                                "This annotation does not apply for type %1$s; expected %2$s",
                                typeName, expectedTypes);
                Location location = mContext.getLocation(node);
                mContext.report(ANNOTATION_USAGE, node, location, message);
            }
        }

        @Override
        public void visitSwitchExpression(@NonNull USwitchExpression switchExpression) {
            UExpression condition = switchExpression.getExpression();
            if (condition != null && PsiType.INT.equals(condition.getExpressionType())) {
                UAnnotation annotation = findIntDefAnnotation(condition);
                if (annotation != null) {
                    UExpression value = annotation.findAttributeValue(ATTR_VALUE);
                    if (value == null) {
                        value = annotation.findAttributeValue(null);
                    }

                    if (value != null && UastExpressionUtils.isArrayInitializer(value)) {
                        List<UExpression> allowedValues =
                                ((UCallExpression) value).getValueArguments();
                        switchExpression.accept(new SwitchChecker(switchExpression, allowedValues));
                    }
                }
            }
        }

        /**
         * Searches for the corresponding @IntDef annotation definition associated with a given node
         */
        @Nullable
        private UAnnotation findIntDefAnnotation(@NonNull UExpression expression) {
            if (expression instanceof UReferenceExpression) {
                PsiElement resolved = ((UReferenceExpression) expression).resolve();

                if (resolved instanceof PsiModifierListOwner) {
                    PsiAnnotation[] annotations =
                            mContext.getEvaluator()
                                    .getAllAnnotations((PsiModifierListOwner) resolved, true);
                    PsiAnnotation[] relevantAnnotations =
                            filterRelevantAnnotations(mContext.getEvaluator(), annotations);
                    UAnnotation annotation =
                            TypedefDetector.Companion.findIntDef(
                                    JavaUAnnotation.wrap(relevantAnnotations));
                    if (annotation != null) {
                        return annotation;
                    }
                }

                if (resolved instanceof PsiLocalVariable) {
                    PsiLocalVariable variable = (PsiLocalVariable) resolved;
                    UExpression lastAssignment =
                            UastLintUtils.findLastAssignment(variable, expression);

                    if (lastAssignment != null) {
                        return findIntDefAnnotation(lastAssignment);
                    }
                }
            } else if (expression instanceof UCallExpression) {
                PsiMethod method = ((UCallExpression) expression).resolve();
                if (method != null) {
                    PsiAnnotation[] annotations =
                            mContext.getEvaluator().getAllAnnotations(method, true);
                    PsiAnnotation[] relevantAnnotations =
                            filterRelevantAnnotations(mContext.getEvaluator(), annotations);
                    List<UAnnotation> uAnnotations = JavaUAnnotation.wrap(relevantAnnotations);
                    UAnnotation annotation = TypedefDetector.Companion.findIntDef(uAnnotations);
                    if (annotation != null) {
                        return annotation;
                    }
                }
            } else if (expression instanceof UIfExpression) {
                UIfExpression ifExpression = (UIfExpression) expression;
                if (ifExpression.getThenExpression() != null) {
                    UAnnotation result = findIntDefAnnotation(ifExpression.getThenExpression());
                    if (result != null) {
                        return result;
                    }
                }
                if (ifExpression.getElseExpression() != null) {
                    UAnnotation result = findIntDefAnnotation(ifExpression.getElseExpression());
                    if (result != null) {
                        return result;
                    }
                }
            } else if (expression instanceof JavaUTypeCastExpression) {
                return findIntDefAnnotation(((JavaUTypeCastExpression) expression).getOperand());

            } else if (expression instanceof UParenthesizedExpression) {
                return findIntDefAnnotation(
                        ((UParenthesizedExpression) expression).getExpression());
            }

            return null;
        }

        @Nullable
        private Integer getConstantValue(@NonNull PsiField intDefConstantRef) {
            Object constant = intDefConstantRef.computeConstantValue();
            if (constant instanceof Number) {
                return ((Number) constant).intValue();
            }

            return null;
        }

        private void ensureUniqueValues(@NonNull UAnnotation node) {
            UExpression value = node.findDeclaredAttributeValue(ATTR_VALUE);
            if (value == null) {
                value = node.findDeclaredAttributeValue(null);
            }
            if (value == null) {
                return;
            }

            if (!(UastExpressionUtils.isArrayInitializer(value))) {
                return;
            }

            List<UExpression> initializers = ((UCallExpression) value).getValueArguments();
            Map<Number, Integer> valueToIndex =
                    Maps.newHashMapWithExpectedSize(initializers.size());

            boolean flag = getAnnotationBooleanValue(node, TYPE_DEF_FLAG_ATTRIBUTE) == Boolean.TRUE;
            if (flag) {
                ensureUsingFlagStyle(initializers);
            }

            ConstantEvaluator constantEvaluator = new ConstantEvaluator();
            for (int index = 0; index < initializers.size(); index++) {
                UExpression expression = initializers.get(index);
                Object o = constantEvaluator.evaluate(expression);
                if (o instanceof Number) {
                    Number number = (Number) o;
                    if (valueToIndex.containsKey(number)) {
                        @SuppressWarnings("UnnecessaryLocalVariable")
                        Number repeatedValue = number;

                        Location location;
                        String message;
                        int prevIndex = valueToIndex.get(number);
                        UExpression prevConstant = initializers.get(prevIndex);
                        message =
                                String.format(
                                        "Constants `%1$s` and `%2$s` specify the same exact "
                                                + "value (%3$s); this is usually a cut & paste or "
                                                + "merge error",
                                        expression.asSourceString(),
                                        prevConstant.asSourceString(),
                                        repeatedValue.toString());
                        location = mContext.getLocation(expression);
                        Location secondary = mContext.getLocation(prevConstant);
                        secondary.setMessage("Previous same value");
                        location.setSecondary(secondary);
                        UElement scope = getAnnotationScope(node);
                        mContext.report(UNIQUE, scope, location, message);
                        break;
                    }
                    valueToIndex.put(number, index);
                }
            }
        }

        private void ensureUsingFlagStyle(@NonNull List<UExpression> constants) {
            if (constants.size() < 3) {
                return;
            }

            for (UExpression constant : constants) {
                if (constant instanceof UReferenceExpression) {
                    PsiElement resolved = ((UReferenceExpression) constant).resolve();
                    // Don't try to check complied code.
                    if (!(resolved instanceof PsiCompiledElement) && resolved instanceof PsiField) {
                        UExpression initializer =
                                UastFacade.INSTANCE.getInitializerBody((PsiField) resolved);
                        if (initializer instanceof ULiteralExpression) {
                            ULiteralExpression literal = (ULiteralExpression) initializer;
                            Object o = literal.getValue();
                            if (!(o instanceof Number)) {
                                continue;
                            }
                            long value = ((Number) o).longValue();
                            // Allow -1, 0 and 1. You can write 1 as "1 << 0" but IntelliJ for
                            // example warns that that's a redundant shift.
                            if (Math.abs(value) <= 1) {
                                continue;
                            }
                            // Only warn if we're setting a specific bit
                            if (Long.bitCount(value) != 1) {
                                continue;
                            }
                            int shift = Long.numberOfTrailingZeros(value);
                            if (mWarnedFlags == null) {
                                mWarnedFlags = Sets.newHashSet();
                            }
                            if (!mWarnedFlags.add(resolved)) {
                                return;
                            }
                            String message =
                                    String.format(
                                            Locale.US,
                                            "Consider declaring this constant using 1 << %1$d instead",
                                            shift);
                            String replace =
                                    String.format(
                                            Locale.ROOT,
                                            "1%s << %d",
                                            o instanceof Long ? "L" : "",
                                            shift);
                            LintFix fix =
                                    fix().replace()
                                            .sharedName("Change declaration to <<")
                                            .with(replace)
                                            .autoFix()
                                            .build();
                            Location location = mContext.getLocation(initializer);
                            mContext.report(FLAG_STYLE, initializer, location, message, fix);
                        }
                    }
                }
            }
        }

        private boolean checkSuppressLint(@NonNull UAnnotation node, @NonNull String id) {
            IssueRegistry registry = mContext.getDriver().getRegistry();
            Issue issue = registry.getIssue(id);
            // Special-case the ApiDetector issue, since it does both source file analysis
            // only on field references, and class file analysis on the rest, so we allow
            // annotations outside of methods only on fields
            if (issue != null && !issue.getImplementation().getScope().contains(Scope.JAVA_FILE)
                    || issue == ApiDetector.UNSUPPORTED) {
                // This issue doesn't have AST access: annotations are not
                // available for local variables or parameters
                UElement scope = getAnnotationScope(node);
                mContext.report(
                        INSIDE_METHOD,
                        scope,
                        mContext.getLocation(node),
                        String.format(
                                "The `@SuppressLint` annotation cannot be used on a local "
                                        + "variable with the lint check '%1$s': move out to the "
                                        + "surrounding method",
                                id));
                return false;
            }

            return true;
        }

        private class SwitchChecker extends AbstractUastVisitor {

            private final USwitchExpression mSwitchExpression;
            private final List<UExpression> mAllowedValues;
            private final List<Object> mFields;
            private final List<Integer> mSeenValues;

            private boolean mReported = false;

            private SwitchChecker(
                    USwitchExpression switchExpression, List<UExpression> allowedValues) {
                mSwitchExpression = switchExpression;
                mAllowedValues = allowedValues;

                mFields = Lists.newArrayListWithCapacity(allowedValues.size());
                for (UExpression allowedValue : allowedValues) {
                    if (allowedValue instanceof ExternalReferenceExpression) {
                        ExternalReferenceExpression externalRef =
                                (ExternalReferenceExpression) allowedValue;

                        PsiElement resolved = UastLintUtils.resolve(externalRef, switchExpression);

                        if (resolved instanceof PsiField) {
                            mFields.add(resolved);
                        }
                    } else if (allowedValue instanceof UReferenceExpression) {
                        PsiElement resolved = ((UReferenceExpression) allowedValue).resolve();
                        if (resolved != null) {
                            mFields.add(resolved);
                        }
                    } else if (allowedValue instanceof ULiteralExpression) {
                        mFields.add(allowedValue);
                    }
                }

                mSeenValues = Lists.newArrayListWithCapacity(allowedValues.size());
            }

            @Override
            public boolean visitSwitchClauseExpression(USwitchClauseExpression node) {
                if (mReported) {
                    return true;
                }

                if (mAllowedValues == null) {
                    return true;
                }

                List<UExpression> caseValues = node.getCaseValues();
                if (caseValues.isEmpty()) {
                    // We had an else clause: don't report any as missing
                    mFields.clear();
                    return true;
                }

                for (UExpression caseValue : caseValues) {
                    if (caseValue instanceof ULiteralExpression) {
                        // Report warnings if you specify hardcoded constants.
                        // It's the wrong thing to do.
                        List<String> list = computeFieldNames(mSwitchExpression, mAllowedValues);
                        // Keep error message in sync with {@link #getMissingCases}
                        String message =
                                "Don't use a constant here; expected one of: "
                                        + displayConstants(list);
                        mContext.report(
                                SWITCH_TYPE_DEF,
                                caseValue,
                                mContext.getLocation(caseValue),
                                message);
                        // Don't look for other missing typedef constants since you might
                        // have aliased with value
                        mReported = true;
                    } else if (caseValue
                            instanceof
                            UReferenceExpression) { // default case can have null expression
                        PsiElement resolved = ((UReferenceExpression) caseValue).resolve();
                        if (resolved == null) {
                            // If there are compilation issues (e.g. user is editing code) we
                            // can't be certain, so don't flag anything.
                            return true;
                        }
                        if (resolved instanceof PsiField) {
                            // We can't just do
                            //    fields.remove(resolved);
                            // since the fields list contains instances of potentially
                            // different types with different hash codes (due to the
                            // external annotations, which are not of the same type as
                            // for example the ECJ based ones.
                            //
                            // The equals method on external field class deliberately handles
                            // this (but it can't make its hash code match what
                            // the ECJ fields do, which is tied to the ECJ binding hash code.)
                            // So instead, manually check for equals. These lists tend to
                            // be very short anyway.
                            PsiField resolvedField = (PsiField) resolved;
                            boolean found = removeFieldFromList(mFields, resolvedField);
                            if (!found) {
                                // Look for local alias
                                UExpression initializer =
                                        UastFacade.INSTANCE.getInitializerBody(
                                                ((PsiField) resolved));
                                if (initializer instanceof UReferenceExpression) {
                                    resolved = ((UReferenceExpression) initializer).resolve();
                                    if (resolved instanceof PsiField) {
                                        found = removeFieldFromList(mFields, (PsiField) resolved);
                                    }
                                }
                            }

                            if (found) {
                                Integer cv = getConstantValue((PsiField) resolved);
                                if (cv != null) {
                                    mSeenValues.add(cv);
                                }
                            } else {
                                List<String> list =
                                        computeFieldNames(mSwitchExpression, mAllowedValues);
                                // Keep error message in sync with {@link #getMissingCases}
                                String message =
                                        "Unexpected constant; expected one of: "
                                                + displayConstants(list);
                                LintFix fix = fix().data(list);
                                Location location = mContext.getNameLocation(caseValue);
                                mContext.report(SWITCH_TYPE_DEF, caseValue, location, message, fix);
                            }
                        }
                    }
                }
                return true;
            }

            @Override
            public void afterVisitSwitchExpression(USwitchExpression node) {
                reportMissingSwitchCases();
                super.afterVisitSwitchExpression(node);
            }

            private void reportMissingSwitchCases() {
                if (mReported) {
                    return;
                }

                if (mAllowedValues == null) {
                    return;
                }

                // Any missing switch constants? Before we flag them, look to see if any
                // of them have the same values: those can be omitted
                if (!mFields.isEmpty()) {
                    ListIterator<Object> iterator = mFields.listIterator();
                    while (iterator.hasNext()) {
                        Object next = iterator.next();
                        if (next instanceof PsiField) {
                            Integer cv = getConstantValue((PsiField) next);
                            if (mSeenValues.contains(cv)) {
                                iterator.remove();
                            }
                        }
                    }
                }

                if (!mFields.isEmpty()) {
                    List<String> list = computeFieldNames(mSwitchExpression, mFields);
                    // Keep error message in sync with {@link #getMissingCases}
                    LintFix fix = fix().data(list);
                    UIdentifier identifier = mSwitchExpression.getSwitchIdentifier();
                    Location location = mContext.getLocation(identifier);
                    // Workaround Kotlin UAST passing <error> instead of PsiKeyword as in Java
                    if (mSwitchExpression instanceof KotlinUSwitchExpression
                            && !"when".equals(identifier.getName())) {
                        PsiElement sourcePsi = mSwitchExpression.getSourcePsi();
                        if (sourcePsi != null) {
                            PsiElement keyword = sourcePsi.getFirstChild();
                            if (keyword != null) {
                                location = mContext.getLocation(keyword);
                            }
                        }
                    }
                    String message =
                            "Switch statement on an `int` with known associated constant "
                                    + "missing case "
                                    + displayConstants(list);
                    mContext.report(SWITCH_TYPE_DEF, mSwitchExpression, location, message, fix);
                }
            }
        }
    }

    @NonNull
    private static String displayConstants(List<String> list) {
        return CollectionsKt.joinToString(
                list,
                ", ", // separator
                "", // prefix
                "", // postfix
                -1, // limited
                "", // truncated
                s -> {
                    int index = s.lastIndexOf('.');
                    if (index != -1) {
                        int classIndex = s.lastIndexOf('.', index - 1);
                        if (classIndex != -1) {
                            return "`" + s.substring(classIndex + 1) + "`";
                        }
                    }
                    return "`" + s + "`";
                });
    }

    private static List<String> computeFieldNames(
            @NonNull USwitchExpression node, Iterable<?> allowedValues) {

        List<String> list = Lists.newArrayList();
        for (Object o : allowedValues) {
            if (o instanceof ExternalReferenceExpression) {
                ExternalReferenceExpression externalRef = (ExternalReferenceExpression) o;
                PsiElement resolved = UastLintUtils.resolve(externalRef, node);
                if (resolved != null) {
                    o = resolved;
                }
            } else if (o instanceof PsiReferenceExpression) {
                PsiReferenceExpression ref = (PsiReferenceExpression) o;
                PsiElement resolved = ref.resolve();
                if (resolved != null) {
                    o = resolved;
                } else {
                    String referenceName = ref.getReferenceName();
                    if (referenceName != null) {
                        list.add(referenceName);
                    }
                    continue;
                }
            } else if (o instanceof PsiLiteral) {
                list.add((String) ((PsiLiteral) o).getValue());
                continue;
            } else if (o instanceof UReferenceExpression) {
                UReferenceExpression ref = (UReferenceExpression) o;
                PsiElement resolved = ref.resolve();
                if (resolved == null) {
                    String resolvedName = ref.getResolvedName();
                    if (resolvedName != null) {
                        list.add(resolvedName);
                    }
                    continue;
                }
                o = resolved;
            }

            if (o instanceof PsiField) {
                PsiField field = (PsiField) o;
                // Only include class name if necessary
                String name = field.getName();
                UClass clz = UastUtils.getParentOfType(node, UClass.class, true);
                if (clz != null) {
                    PsiClass containingClass = field.getContainingClass();
                    if (containingClass != null && !containingClass.isEquivalentTo(clz.getPsi())) {
                        name = containingClass.getQualifiedName() + '.' + field.getName();
                    }
                }
                list.add(name);
            }
        }
        Collections.sort(list);
        return list;
    }

    /**
     * Returns the node to use as the scope for the given annotation node. You can't annotate an
     * annotation itself (with {@code @SuppressLint}), but you should be able to place an annotation
     * next to it, as a sibling, to only suppress the error on this annotated element, not the whole
     * surrounding class.
     */
    @NonNull
    private static UElement getAnnotationScope(@NonNull UAnnotation node) {
        UElement scope = UastUtils.getParentOfType(node, UAnnotation.class, true);
        if (scope == null) {
            scope = node;
        }
        return scope;
    }

    private static boolean removeFieldFromList(
            @NonNull List<Object> fields, @NonNull PsiField resolvedField) {
        for (Object field : fields) {
            // We can't just call .equals here because the annotation
            // we are comparing against may be either a PsiFieldImpl
            // (for a local annotation) or a ClsFieldImpl (for an annotation
            // read from storage) or maybe even other PSI internal classes.
            // So compare by name and class instead.

            if (!(field instanceof PsiField)) {
                continue;
            }
            PsiField candidateField = (PsiField) field;
            if (candidateField.isEquivalentTo(resolvedField)) {
                return true;
            }
        }

        return false;
    }

    // Like JavaEvaluator#filterRelevantAnnotations, but hardcoded for the IntRange and
    // IntDef annotations since this check isn't a generalized annotation checker like the
    // others.
    @NonNull
    static PsiAnnotation[] filterRelevantAnnotations(
            @NonNull JavaEvaluator evaluator, @NonNull PsiAnnotation[] annotations) {
        List<PsiAnnotation> result = null;
        int length = annotations.length;
        if (length == 0) {
            return annotations;
        }
        for (PsiAnnotation annotation : annotations) {
            String signature = annotation.getQualifiedName();
            if (signature == null || signature.startsWith("java.")) {
                // @Override, @SuppressWarnings etc. Ignore
                continue;
            }

            if (SUPPORT_ANNOTATIONS_PREFIX.isPrefix(signature)
                    || signature.equals(GMS_HIDE_ANNOTATION)) {
                // Bail on the nullness annotations early since they're the most commonly
                // defined ones. They're not analyzed in lint yet.
                if (signature.endsWith(".Nullable") || signature.endsWith(".NonNull")) {
                    continue;
                }

                // Common case: there's just one annotation; no need to create a list copy
                if (length == 1) {
                    return annotations;
                }
                if (result == null) {
                    result = new ArrayList<>(2);
                }
                result.add(annotation);
            }

            // Special case @IntDef and @StringDef: These are used on annotations
            // themselves. For example, you create a new annotation named @foo.bar.Baz,
            // annotate it with @IntDef, and then use @foo.bar.Baz in your signatures.
            // Here we want to map from @foo.bar.Baz to the corresponding int def.
            // Don't need to compute this if performing @IntDef or @StringDef lookup
            PsiClass cls = null;
            PsiJavaCodeReferenceElement ref = annotation.getNameReferenceElement();
            if (ref != null) {
                PsiElement resolved = ref.resolve();
                if (resolved instanceof PsiClass) {
                    cls = (PsiClass) resolved;
                }
            } else {
                Project project = annotation.getProject();
                GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
                cls = JavaPsiFacade.getInstance(project).findClass(signature, scope);
            }
            if (cls == null || !cls.isAnnotationType()) {
                continue;
            }
            PsiAnnotation[] innerAnnotations = evaluator.getAllAnnotations(cls, false);
            for (int j = 0; j < innerAnnotations.length; j++) {
                PsiAnnotation inner = innerAnnotations[j];
                String a = inner.getQualifiedName();
                if (a == null || a.startsWith("java.")) {
                    // @Override, @SuppressWarnings etc. Ignore
                    continue;
                }
                if (INT_DEF_ANNOTATION.isEquals(a)
                        || LONG_DEF_ANNOTATION.isEquals(a)
                        || PERMISSION_ANNOTATION.isEquals(a)
                        || INT_RANGE_ANNOTATION.isEquals(a)
                        || STRING_DEF_ANNOTATION.isEquals(a)) {
                    if (length == 1 && j == innerAnnotations.length - 1 && result == null) {
                        return innerAnnotations;
                    }
                    if (result == null) {
                        result = new ArrayList<>(2);
                    }
                    result.add(inner);
                }
            }
        }

        return result != null
                ? result.toArray(PsiAnnotation.EMPTY_ARRAY)
                : PsiAnnotation.EMPTY_ARRAY;
    }
}
