#!/usr/bin/env python

# Copyright (C) 2014 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.

"""
Enforces common Android public API design patterns.  It ignores lint messages from
a previous API level, if provided.

Usage: apilint.py current.txt
Usage: apilint.py current.txt previous.txt

You can also splice in blame details like this:
$ git blame api/current.txt -t -e > /tmp/currentblame.txt
$ apilint.py /tmp/currentblame.txt previous.txt --no-color
"""

import re, sys, collections, traceback, argparse, itertools


BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

ALLOW_GOOGLE = False
USE_COLOR = True

def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False):
    # manually derived from http://en.wikipedia.org/wiki/ANSI_escape_code#Codes
    if not USE_COLOR: return ""
    codes = []
    if reset: codes.append("0")
    else:
        if not fg is None: codes.append("3%d" % (fg))
        if not bg is None:
            if not bright: codes.append("4%d" % (bg))
            else: codes.append("10%d" % (bg))
        if bold: codes.append("1")
        elif dim: codes.append("2")
        else: codes.append("22")
    return "\033[%sm" % (";".join(codes))


class Field():
    def __init__(self, clazz, line, raw, blame, sig_format = 1):
        self.clazz = clazz
        self.line = line
        self.raw = raw.strip(" {;")
        self.blame = blame

        if sig_format == 2:
            V2LineParser(raw).parse_into_field(self)
        elif sig_format == 1:
            # drop generics for now; may need multiple passes
            raw = re.sub("<[^<]+?>", "", raw)
            raw = re.sub("<[^<]+?>", "", raw)

            raw = raw.split()
            self.split = list(raw)

            for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]:
                while r in raw: raw.remove(r)

            # ignore annotations for now
            raw = [ r for r in raw if not r.startswith("@") ]

            self.typ = raw[0]
            self.name = raw[1].strip(";")
            if len(raw) >= 4 and raw[2] == "=":
                self.value = raw[3].strip(';"')
            else:
                self.value = None
            self.annotations = []

        self.ident = "-".join((self.typ, self.name, self.value or ""))

    def __hash__(self):
        return hash(self.raw)

    def __repr__(self):
        return self.raw


class Argument(object):

    __slots__ = ["type", "annotations", "name", "default"]

    def __init__(self, type):
        self.type = type
        self.annotations = []
        self.name = None
        self.default = None


class Method():
    def __init__(self, clazz, line, raw, blame, sig_format = 1):
        self.clazz = clazz
        self.line = line
        self.raw = raw.strip(" {;")
        self.blame = blame

        if sig_format == 2:
            V2LineParser(raw).parse_into_method(self)
        elif sig_format == 1:
            # drop generics for now; may need multiple passes
            raw = re.sub("<[^<]+?>", "", raw)
            raw = re.sub("<[^<]+?>", "", raw)

            # handle each clause differently
            raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups()

            # parse prefixes
            raw = re.split("[\s]+", raw_prefix)
            for r in ["", ";"]:
                while r in raw: raw.remove(r)
            self.split = list(raw)

            for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator", "synchronized"]:
                while r in raw: raw.remove(r)

            self.typ = raw[0]
            self.name = raw[1]

            # parse args
            self.detailed_args = []
            for arg in re.split(",\s*", raw_args):
                arg = re.split("\s", arg)
                # ignore annotations for now
                arg = [ a for a in arg if not a.startswith("@") ]
                if len(arg[0]) > 0:
                    self.detailed_args.append(Argument(arg[0]))

            # parse throws
            self.throws = []
            for throw in re.split(",\s*", raw_throws):
                self.throws.append(throw)

            self.annotations = []
        else:
            raise ValueError("Unknown signature format: " + sig_format)

        self.args = map(lambda a: a.type, self.detailed_args)
        self.ident = "-".join((self.typ, self.name, "-".join(self.args)))

    def sig_matches(self, typ, name, args):
        return typ == self.typ and name == self.name and args == self.args

    def __hash__(self):
        return hash(self.raw)

    def __repr__(self):
        return self.raw


class Class():
    def __init__(self, pkg, line, raw, blame, sig_format = 1):
        self.pkg = pkg
        self.line = line
        self.raw = raw.strip(" {;")
        self.blame = blame
        self.ctors = []
        self.fields = []
        self.methods = []
        self.annotations = []

        if sig_format == 2:
            V2LineParser(raw).parse_into_class(self)
        elif sig_format == 1:
            # drop generics for now; may need multiple passes
            raw = re.sub("<[^<]+?>", "", raw)
            raw = re.sub("<[^<]+?>", "", raw)

            raw = raw.split()
            self.split = list(raw)
            if "class" in raw:
                self.fullname = raw[raw.index("class")+1]
            elif "interface" in raw:
                self.fullname = raw[raw.index("interface")+1]
            elif "@interface" in raw:
                self.fullname = raw[raw.index("@interface")+1]
            else:
                raise ValueError("Funky class type %s" % (self.raw))

            if "extends" in raw:
                self.extends = raw[raw.index("extends")+1]
            else:
                self.extends = None

            if "implements" in raw:
                self.implements = raw[raw.index("implements")+1]
                self.implements_all = [self.implements]
            else:
                self.implements = None
                self.implements_all = []
        else:
            raise ValueError("Unknown signature format: " + sig_format)

        self.fullname = self.pkg.name + "." + self.fullname
        self.fullname_path = self.fullname.split(".")

        if self.extends is not None:
            self.extends_path = self.extends.split(".")
        else:
            self.extends_path = []

        self.name = self.fullname[self.fullname.rindex(".")+1:]

    def merge_from(self, other):
        self.ctors.extend(other.ctors)
        self.fields.extend(other.fields)
        self.methods.extend(other.methods)

    def __hash__(self):
        return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods)))

    def __repr__(self):
        return self.raw


class Package():
    NAME = re.compile("package(?: .*)? ([A-Za-z0-9.]+)")

    def __init__(self, line, raw, blame):
        self.line = line
        self.raw = raw.strip(" {;")
        self.blame = blame

        self.name = Package.NAME.match(raw).group(1)
        self.name_path = self.name.split(".")

    def __repr__(self):
        return self.raw

class V2Tokenizer(object):
    __slots__ = ["raw"]

    SIGNATURE_PREFIX = "// Signature format: "
    DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.')
    STRING_SPECIAL = re.compile(r'["\\]')

    def __init__(self, raw):
        self.raw = raw

    def tokenize(self):
        tokens = []
        current = 0
        raw = self.raw
        length = len(raw)

        while current < length:
            while current < length:
                start = current
                match = V2Tokenizer.DELIMITER.search(raw, start)
                if match is not None:
                    match_start = match.start()
                    if match_start == current:
                        end = match.end()
                    else:
                        end = match_start
                else:
                    end = length

                token = raw[start:end]
                current = end

                if token == "" or token[0] == " ":
                    continue
                else:
                    break

            if token == "@":
                if raw[start:start+11] == "@interface ":
                    current = start + 11
                    tokens.append("@interface")
                    continue
            elif token == '/':
                if raw[start:start+2] == "//":
                    current = length
                    continue
            elif token == '"':
                current, string_token = self.tokenize_string(raw, length, current)
                tokens.append(token + string_token)
                continue

            tokens.append(token)

        return tokens

    def tokenize_string(self, raw, length, current):
        start = current
        end = length
        while start < end:
            match = V2Tokenizer.STRING_SPECIAL.search(raw, start)
            if match:
                if match.group() == '"':
                    end = match.end()
                    break
                elif match.group() == '\\':
                    # ignore whatever is after the slash
                    start += 2
                else:
                    raise ValueError("Unexpected match: `%s`" % (match.group()))
            else:
                raise ValueError("Unexpected EOF tokenizing string: `%s`" % (raw[current - 1:],))

        token = raw[current:end]
        return end, token

class V2LineParser(object):
    __slots__ = ["tokenized", "current", "len"]

    FIELD_KINDS = ("field", "property", "enum_constant")
    MODIFIERS = set("public protected internal private abstract default static final transient volatile synchronized native operator sealed strictfp infix inline suspend vararg".split())
    JAVA_LANG_TYPES = set("AbstractMethodError AbstractStringBuilder Appendable ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AssertionError AutoCloseable Boolean BootstrapMethodError Byte Character CharSequence Class ClassCastException ClassCircularityError ClassFormatError ClassLoader ClassNotFoundException Cloneable CloneNotSupportedException Comparable Compiler Deprecated Double Enum EnumConstantNotPresentException Error Exception ExceptionInInitializerError Float FunctionalInterface IllegalAccessError IllegalAccessException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IncompatibleClassChangeError IndexOutOfBoundsException InheritableThreadLocal InstantiationError InstantiationException Integer InternalError InterruptedException Iterable LinkageError Long Math NegativeArraySizeException NoClassDefFoundError NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NullPointerException Number NumberFormatException Object OutOfMemoryError Override Package package-info.java Process ProcessBuilder ProcessEnvironment ProcessImpl Readable ReflectiveOperationException Runnable Runtime RuntimeException RuntimePermission SafeVarargs SecurityException SecurityManager Short StackOverflowError StackTraceElement StrictMath String StringBuffer StringBuilder StringIndexOutOfBoundsException SuppressWarnings System Thread ThreadDeath ThreadGroup ThreadLocal Throwable TypeNotPresentException UNIXProcess UnknownError UnsatisfiedLinkError UnsupportedClassVersionError UnsupportedOperationException VerifyError VirtualMachineError Void".split())

    def __init__(self, raw):
        self.tokenized = V2Tokenizer(raw).tokenize()
        self.current = 0
        self.len = len(self.tokenized)

    def parse_into_method(self, method):
        method.split = []
        kind = self.parse_one_of("ctor", "method")
        method.split.append(kind)
        method.annotations = self.parse_annotations()
        method.split.extend(self.parse_modifiers())
        self.parse_matching_paren("<", ">")
        if "@Deprecated" in method.annotations:
            method.split.append("deprecated")
        if kind == "ctor":
            method.typ = "ctor"
        else:
            method.typ = self.parse_type()
            method.split.append(method.typ)
        method.name = self.parse_name()
        method.split.append(method.name)
        self.parse_token("(")
        method.detailed_args = self.parse_args()
        self.parse_token(")")
        method.throws = self.parse_throws()
        if "@interface" in method.clazz.split:
            self.parse_annotation_default()
        self.parse_token(";")
        self.parse_eof()

    def parse_into_class(self, clazz):
        clazz.split = []
        clazz.annotations = self.parse_annotations()
        if "@Deprecated" in clazz.annotations:
            clazz.split.append("deprecated")
        clazz.split.extend(self.parse_modifiers())
        kind = self.parse_one_of("class", "interface", "@interface", "enum")
        if kind == "enum":
            # enums are implicitly final
            clazz.split.append("final")
        clazz.split.append(kind)
        clazz.fullname = self.parse_name()
        self.parse_matching_paren("<", ">")
        extends = self.parse_extends()
        clazz.extends = extends[0] if extends else None
        clazz.implements_all = self.parse_implements()
        # The checks assume that interfaces are always found in implements, which isn't true for
        # subinterfaces.
        if not clazz.implements_all and "interface" in clazz.split:
            clazz.implements_all = [clazz.extends]
        clazz.implements = clazz.implements_all[0] if clazz.implements_all else None
        self.parse_token("{")
        self.parse_eof()

    def parse_into_field(self, field):
        kind = self.parse_one_of(*V2LineParser.FIELD_KINDS)
        field.split = [kind]
        field.annotations = self.parse_annotations()
        if "@Deprecated" in field.annotations:
            field.split.append("deprecated")
        field.split.extend(self.parse_modifiers())
        field.typ = self.parse_type()
        field.split.append(field.typ)
        field.name = self.parse_name()
        field.split.append(field.name)
        if self.parse_if("="):
            field.value = self.parse_value_stripped()
        else:
            field.value = None

        self.parse_token(";")
        self.parse_eof()

    def lookahead(self):
        return self.tokenized[self.current]

    def parse_one_of(self, *options):
        found = self.lookahead()
        if found not in options:
            raise ValueError("Parsing failed, expected one of `%s` but found `%s` in %s" % (options, found, repr(self.tokenized)))
        return self.parse_token()

    def parse_token(self, tok = None):
        found = self.lookahead()
        if tok is not None and found != tok:
            raise ValueError("Parsing failed, expected `%s` but found `%s` in %s" % (tok, found, repr(self.tokenized)))
        self.current += 1
        return found

    def eof(self):
        return self.current == self.len

    def parse_eof(self):
        if not self.eof():
            raise ValueError("Parsing failed, expected EOF, but %s has not been parsed in %s" % (self.tokenized[self.current:], self.tokenized))

    def parse_if(self, tok):
        if not self.eof() and self.lookahead() == tok:
            self.parse_token()
            return True
        return False

    def parse_annotations(self):
        ret = []
        while self.lookahead() == "@":
            ret.append(self.parse_annotation())
        return ret

    def parse_annotation(self):
        ret = self.parse_token("@") + self.parse_token()
        self.parse_matching_paren("(", ")")
        return ret

    def parse_matching_paren(self, open, close):
        start = self.current
        if not self.parse_if(open):
            return
        length = len(self.tokenized)
        count = 1
        while count > 0:
            if self.current == length:
                raise ValueError("Unexpected EOF looking for closing paren: `%s`" % (self.tokenized[start:],))
            t = self.parse_token()
            if t == open:
                count += 1
            elif t == close:
                count -= 1
        return self.tokenized[start:self.current]

    def parse_modifiers(self):
        ret = []
        while self.lookahead() in V2LineParser.MODIFIERS:
            ret.append(self.parse_token())
        return ret

    def parse_kotlin_nullability(self):
        t = self.lookahead()
        if t == "?" or t == "!":
            return self.parse_token()
        return None

    def parse_type(self):
        self.parse_annotations()
        type = self.parse_token()
        if type[-1] == '.':
            self.parse_annotations()
            type += self.parse_token()
        if type in V2LineParser.JAVA_LANG_TYPES:
            type = "java.lang." + type
        self.parse_matching_paren("<", ">")
        while True:
            t = self.lookahead()
            if t == "@":
                self.parse_annotation()
            elif t == "[]":
                type += self.parse_token()
            elif self.parse_kotlin_nullability() is not None:
                pass  # discard nullability for now
            else:
                break
        return type

    def parse_arg_type(self):
        type = self.parse_type()
        if self.parse_if("..."):
            type += "..."
        self.parse_kotlin_nullability() # discard nullability for now
        return type

    def parse_name(self):
        return self.parse_token()

    def parse_args(self):
        args = []
        if self.lookahead() == ")":
            return args

        while True:
            args.append(self.parse_arg())
            if self.lookahead() == ")":
                return args
            self.parse_token(",")

    def parse_arg(self):
        self.parse_if("vararg")  # kotlin vararg
        annotations = self.parse_annotations()
        arg = Argument(self.parse_arg_type())
        arg.annotations = annotations
        l = self.lookahead()
        if l != "," and l != ")":
            if self.lookahead() != '=':
                arg.name = self.parse_token()  # kotlin argument name
            if self.parse_if('='): # kotlin default value
                arg.default = self.parse_expression()
        return arg

    def parse_expression(self):
        while not self.lookahead() in [')', ',', ';']:
            (self.parse_matching_paren('(', ')') or
            self.parse_matching_paren('{', '}') or
            self.parse_token())

    def parse_throws(self):
        ret = []
        if self.parse_if("throws"):
            ret.append(self.parse_type())
            while self.parse_if(","):
                ret.append(self.parse_type())
        return ret

    def parse_extends(self):
        if self.parse_if("extends"):
            return self.parse_space_delimited_type_list()
        return []

    def parse_implements(self):
        if self.parse_if("implements"):
            return self.parse_space_delimited_type_list()
        return []

    def parse_space_delimited_type_list(self, terminals = ["implements", "{"]):
        types = []
        while True:
            types.append(self.parse_type())
            if self.lookahead() in terminals:
                return types

    def parse_annotation_default(self):
        if self.parse_if("default"):
            self.parse_expression()

    def parse_value(self):
        if self.lookahead() == "{":
            return " ".join(self.parse_matching_paren("{", "}"))
        elif self.lookahead() == "(":
            return " ".join(self.parse_matching_paren("(", ")"))
        else:
            return self.parse_token()

    def parse_value_stripped(self):
        value = self.parse_value()
        if value[0] == '"':
            return value[1:-1]
        return value


def _parse_stream(f, clazz_cb=None, base_f=None, out_classes_with_base=None,
                  in_classes_with_base=[]):
    api = {}
    in_classes_with_base = _retry_iterator(in_classes_with_base)

    if base_f:
        base_classes = _retry_iterator(_parse_stream_to_generator(base_f))
    else:
        base_classes = []

    def handle_class(clazz):
        if clazz_cb:
            clazz_cb(clazz)
        else: # In callback mode, don't keep track of the full API
            api[clazz.fullname] = clazz

    def handle_missed_classes_with_base(clazz):
        for c in _yield_until_matching_class(in_classes_with_base, clazz):
            base_class = _skip_to_matching_class(base_classes, c)
            if base_class:
                handle_class(base_class)

    for clazz in _parse_stream_to_generator(f):
        # Before looking at clazz, let's see if there's some classes that were not present, but
        # may have an entry in the base stream.
        handle_missed_classes_with_base(clazz)

        base_class = _skip_to_matching_class(base_classes, clazz)
        if base_class:
            clazz.merge_from(base_class)
            if out_classes_with_base is not None:
                out_classes_with_base.append(clazz)
        handle_class(clazz)

    handle_missed_classes_with_base(None)

    return api

def _parse_stream_to_generator(f):
    line = 0
    pkg = None
    clazz = None
    blame = None
    sig_format = 1

    re_blame = re.compile(r"^(\^?[a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$")

    field_prefixes = map(lambda kind: "    %s" % (kind,), V2LineParser.FIELD_KINDS)
    def startsWithFieldPrefix(raw):
        for prefix in field_prefixes:
            if raw.startswith(prefix):
                return True
        return False

    for raw in f:
        line += 1
        raw = raw.rstrip()
        match = re_blame.match(raw)
        if match is not None:
            blame = match.groups()[0:2]
            if blame[0].startswith("^"):  # Outside of blame range
              blame = None
            raw = match.groups()[2]
        else:
            blame = None

        if line == 1 and V2Tokenizer.SIGNATURE_PREFIX in raw:
            sig_format_string = raw[len(V2Tokenizer.SIGNATURE_PREFIX):]
            if sig_format_string in ["2.0", "3.0"]:
                sig_format = 2
            else:
                raise ValueError("Unknown format: %s" % (sig_format_string,))
        elif raw.startswith("package"):
            pkg = Package(line, raw, blame)
        elif raw.startswith("  ") and raw.endswith("{"):
            clazz = Class(pkg, line, raw, blame, sig_format=sig_format)
        elif raw.startswith("    ctor"):
            clazz.ctors.append(Method(clazz, line, raw, blame, sig_format=sig_format))
        elif raw.startswith("    method"):
            clazz.methods.append(Method(clazz, line, raw, blame, sig_format=sig_format))
        elif startsWithFieldPrefix(raw):
            clazz.fields.append(Field(clazz, line, raw, blame, sig_format=sig_format))
        elif raw.startswith("  }") and clazz:
            yield clazz

def _retry_iterator(it):
    """Wraps an iterator, such that calling send(True) on it will redeliver the same element"""
    for e in it:
        while True:
            retry = yield e
            if not retry:
                break
            # send() was called, asking us to redeliver clazz on next(). Still need to yield
            # a dummy value to the send() first though.
            if (yield "Returning clazz on next()"):
                raise TypeError("send() must be followed by next(), not send()")

def _skip_to_matching_class(classes, needle):
    """Takes a classes iterator and consumes entries until it returns the class we're looking for

    This relies on classes being sorted by package and class name."""

    for clazz in classes:
        if clazz.pkg.name < needle.pkg.name:
            # We haven't reached the right package yet
            continue
        if clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname:
            # We're in the right package, but not the right class yet
            continue
        if clazz.fullname == needle.fullname:
            return clazz
        # We ran past the right class. Send it back into the generator, then report failure.
        classes.send(clazz)
        return None

def _yield_until_matching_class(classes, needle):
    """Takes a class iterator and yields entries it until it reaches the class we're looking for.

    This relies on classes being sorted by package and class name."""

    for clazz in classes:
        if needle is None:
            yield clazz
        elif clazz.pkg.name < needle.pkg.name:
            # We haven't reached the right package yet
            yield clazz
        elif clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname:
            # We're in the right package, but not the right class yet
            yield clazz
        elif clazz.fullname == needle.fullname:
            # Class found, abort.
            return
        else:
            # We ran past the right class. Send it back into the iterator, then abort.
            classes.send(clazz)
            return

class Failure():
    def __init__(self, sig, clazz, detail, error, rule, msg):
        self.clazz = clazz
        self.sig = sig
        self.error = error
        self.rule = rule
        self.msg = msg

        if error:
            self.head = "Error %s" % (rule) if rule else "Error"
            dump = "%s%s:%s %s" % (format(fg=RED, bg=BLACK, bold=True), self.head, format(reset=True), msg)
        else:
            self.head = "Warning %s" % (rule) if rule else "Warning"
            dump = "%s%s:%s %s" % (format(fg=YELLOW, bg=BLACK, bold=True), self.head, format(reset=True), msg)

        self.line = clazz.line
        blame = clazz.blame
        if detail is not None:
            dump += "\n    in " + repr(detail)
            self.line = detail.line
            blame = detail.blame
        dump += "\n    in " + repr(clazz)
        dump += "\n    in " + repr(clazz.pkg)
        dump += "\n    at line " + repr(self.line)
        if blame is not None:
            dump += "\n    last modified by %s in %s" % (blame[1], blame[0])

        self.dump = dump

    def __repr__(self):
        return self.dump


failures = {}

def _fail(clazz, detail, error, rule, msg):
    """Records an API failure to be processed later."""
    global failures

    sig = "%s-%s-%s" % (clazz.fullname, detail.ident if detail else None, msg)
    sig = sig.replace(" deprecated ", " ")

    failures[sig] = Failure(sig, clazz, detail, error, rule, msg)


def warn(clazz, detail, rule, msg):
    _fail(clazz, detail, False, rule, msg)

def error(clazz, detail, rule, msg):
    _fail(clazz, detail, True, rule, msg)


noticed = {}

def notice(clazz):
    global noticed

    noticed[clazz.fullname] = hash(clazz)


verifiers = {}

def verifier(f):
    verifiers[f.__name__] = f
    return f


@verifier
def verify_constants(clazz):
    """All static final constants must be FOO_NAME style."""
    if re.match("android\.R\.[a-z]+", clazz.fullname): return
    if clazz.fullname.startswith("android.os.Build"): return
    if clazz.fullname == "android.system.OsConstants": return

    req = ["java.lang.String","byte","short","int","long","float","double","boolean","char"]
    for f in clazz.fields:
        if "static" in f.split and "final" in f.split:
            if re.match("[A-Z0-9_]+", f.name) is None:
                error(clazz, f, "C2", "Constant field names must be FOO_NAME")
            if f.typ != "java.lang.String":
                if f.name.startswith("MIN_") or f.name.startswith("MAX_"):
                    warn(clazz, f, "C8", "If min/max could change in future, make them dynamic methods")
            if f.typ in req and f.value is None:
                error(clazz, f, None, "All constants must be defined at compile time")

@verifier
def verify_enums(clazz):
    """Enums are bad, mmkay?"""
    if clazz.extends == "java.lang.Enum" or "enum" in clazz.split:
        error(clazz, None, "F5", "Enums are not allowed")

@verifier
def verify_class_names(clazz):
    """Try catching malformed class names like myMtp or MTPUser."""
    if clazz.fullname.startswith("android.opengl"): return
    if clazz.fullname.startswith("android.renderscript"): return
    if re.match("android\.R\.[a-z]+", clazz.fullname): return

    if re.search("[A-Z]{2,}", clazz.name) is not None:
        warn(clazz, None, "S1", "Class names with acronyms should be Mtp not MTP")
    if re.match("[^A-Z]", clazz.name):
        error(clazz, None, "S1", "Class must start with uppercase char")
    if clazz.name.endswith("Impl"):
        error(clazz, None, None, "Don't expose your implementation details")


@verifier
def verify_method_names(clazz):
    """Try catching malformed method names, like Foo() or getMTU()."""
    if clazz.fullname.startswith("android.opengl"): return
    if clazz.fullname.startswith("android.renderscript"): return
    if clazz.fullname == "android.system.OsConstants": return

    for m in clazz.methods:
        if re.search("[A-Z]{2,}", m.name) is not None:
            warn(clazz, m, "S1", "Method names with acronyms should be getMtu() instead of getMTU()")
        if re.match("[^a-z]", m.name):
            error(clazz, m, "S1", "Method name must start with lowercase char")


@verifier
def verify_callbacks(clazz):
    """Verify Callback classes.
    All methods must follow onFoo() naming style."""
    if clazz.fullname == "android.speech.tts.SynthesisCallback": return

    if clazz.name.endswith("Callbacks"):
        error(clazz, None, "L1", "Callback class names should be singular")
    if clazz.name.endswith("Observer"):
        warn(clazz, None, "L1", "Class should be named FooCallback")

    if clazz.name.endswith("Callback"):
        for m in clazz.methods:
            if not re.match("on[A-Z][a-z]*", m.name):
                error(clazz, m, "L1", "Callback method names must be onFoo() style")


@verifier
def verify_listeners(clazz):
    """Verify Listener classes.
    All Listener classes must be interface.
    All methods must follow onFoo() naming style.
    If only a single method, it must match class name:
        interface OnFooListener { void onFoo() }"""

    if clazz.name.endswith("Listener"):
        if "abstract" in clazz.split and "class" in clazz.split:
            error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback")

        for m in clazz.methods:
            if not re.match("on[A-Z][a-z]*", m.name):
                error(clazz, m, "L1", "Listener method names must be onFoo() style")

        if len(clazz.methods) == 1 and clazz.name.startswith("On"):
            m = clazz.methods[0]
            if (m.name + "Listener").lower() != clazz.name.lower():
                error(clazz, m, "L1", "Single listener method name must match class name")


@verifier
def verify_actions(clazz):
    """Verify intent actions.
    All action names must be named ACTION_FOO.
    All action values must be scoped by package and match name:
        package android.foo {
            String ACTION_BAR = "android.foo.action.BAR";
        }"""
    for f in clazz.fields:
        if f.value is None: continue
        if f.name.startswith("EXTRA_"): continue
        if f.name == "SERVICE_INTERFACE" or f.name == "PROVIDER_INTERFACE": continue
        if "INTERACTION" in f.name: continue

        if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
            if "_ACTION" in f.name or "ACTION_" in f.name or ".action." in f.value.lower():
                if not f.name.startswith("ACTION_"):
                    error(clazz, f, "C3", "Intent action constant name must be ACTION_FOO")
                else:
                    if clazz.fullname == "android.content.Intent":
                        prefix = "android.intent.action"
                    elif clazz.fullname == "android.provider.Settings":
                        prefix = "android.settings"
                    elif clazz.fullname == "android.app.admin.DevicePolicyManager" or clazz.fullname == "android.app.admin.DeviceAdminReceiver":
                        prefix = "android.app.action"
                    else:
                        prefix = clazz.pkg.name + ".action"
                    expected = prefix + "." + f.name[7:]
                    if f.value != expected:
                        error(clazz, f, "C4", "Inconsistent action value; expected '%s'" % (expected))


@verifier
def verify_extras(clazz):
    """Verify intent extras.
    All extra names must be named EXTRA_FOO.
    All extra values must be scoped by package and match name:
        package android.foo {
            String EXTRA_BAR = "android.foo.extra.BAR";
        }"""
    if clazz.fullname == "android.app.Notification": return
    if clazz.fullname == "android.appwidget.AppWidgetManager": return

    for f in clazz.fields:
        if f.value is None: continue
        if f.name.startswith("ACTION_"): continue

        if "static" in f.split and "final" in f.split and f.typ == "java.lang.String":
            if "_EXTRA" in f.name or "EXTRA_" in f.name or ".extra" in f.value.lower():
                if not f.name.startswith("EXTRA_"):
                    error(clazz, f, "C3", "Intent extra must be EXTRA_FOO")
                else:
                    if clazz.pkg.name == "android.content" and clazz.name == "Intent":
                        prefix = "android.intent.extra"
                    elif clazz.pkg.name == "android.app.admin":
                        prefix = "android.app.extra"
                    else:
                        prefix = clazz.pkg.name + ".extra"
                    expected = prefix + "." + f.name[6:]
                    if f.value != expected:
                        error(clazz, f, "C4", "Inconsistent extra value; expected '%s'" % (expected))


@verifier
def verify_equals(clazz):
    """Verify that equals() and hashCode() must be overridden together."""
    eq = False
    hc = False
    for m in clazz.methods:
        if "static" in m.split: continue
        if m.sig_matches("boolean", "equals", ["java.lang.Object"]): eq = True
        if m.sig_matches("int", "hashCode", []): hc = True
    if eq != hc:
        error(clazz, None, "M8", "Must override both equals and hashCode; missing one")


@verifier
def verify_parcelable(clazz):
    """Verify that Parcelable objects aren't hiding required bits."""
    if clazz.implements == "android.os.Parcelable":
        creator = [ i for i in clazz.fields if i.name == "CREATOR" ]
        write = [ i for i in clazz.methods if i.name == "writeToParcel" ]
        describe = [ i for i in clazz.methods if i.name == "describeContents" ]

        if len(creator) == 0 or len(write) == 0 or len(describe) == 0:
            error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one")

        if "final" not in clazz.split:
            error(clazz, None, "FW8", "Parcelable classes must be final")

        for c in clazz.ctors:
            if c.args == ["android.os.Parcel"]:
                error(clazz, c, "FW3", "Parcelable inflation is exposed through CREATOR, not raw constructors")


@verifier
def verify_protected(clazz):
    """Verify that no protected methods or fields are allowed."""
    for m in clazz.methods:
        if m.name == "finalize": continue
        if "protected" in m.split:
            error(clazz, m, "M7", "Protected methods not allowed; must be public")
    for f in clazz.fields:
        if "protected" in f.split:
            error(clazz, f, "M7", "Protected fields not allowed; must be public")


@verifier
def verify_fields(clazz):
    """Verify that all exposed fields are final.
    Exposed fields must follow myName style.
    Catch internal mFoo objects being exposed."""

    IGNORE_BARE_FIELDS = [
        "android.app.ActivityManager.RecentTaskInfo",
        "android.app.Notification",
        "android.content.pm.ActivityInfo",
        "android.content.pm.ApplicationInfo",
        "android.content.pm.ComponentInfo",
        "android.content.pm.ResolveInfo",
        "android.content.pm.FeatureGroupInfo",
        "android.content.pm.InstrumentationInfo",
        "android.content.pm.PackageInfo",
        "android.content.pm.PackageItemInfo",
        "android.content.res.Configuration",
        "android.graphics.BitmapFactory.Options",
        "android.os.Message",
        "android.system.StructPollfd",
    ]

    for f in clazz.fields:
        if not "final" in f.split:
            if clazz.fullname in IGNORE_BARE_FIELDS:
                pass
            elif clazz.fullname.endswith("LayoutParams"):
                pass
            elif clazz.fullname.startswith("android.util.Mutable"):
                pass
            else:
                error(clazz, f, "F2", "Bare fields must be marked final, or add accessors if mutable")

        if "static" not in f.split and "property" not in f.split:
            if not re.match("[a-z]([a-zA-Z]+)?", f.name):
                error(clazz, f, "S1", "Non-static fields must be named using myField style")

        if re.match("[ms][A-Z]", f.name):
            error(clazz, f, "F1", "Internal objects must not be exposed")

        if re.match("[A-Z_]+", f.name):
            if "static" not in f.split or "final" not in f.split:
                error(clazz, f, "C2", "Constants must be marked static final")


@verifier
def verify_register(clazz):
    """Verify parity of registration methods.
    Callback objects use register/unregister methods.
    Listener objects use add/remove methods."""
    methods = [ m.name for m in clazz.methods ]
    for m in clazz.methods:
        if "Callback" in m.raw:
            if m.name.startswith("register"):
                other = "unregister" + m.name[8:]
                if other not in methods:
                    error(clazz, m, "L2", "Missing unregister method")
            if m.name.startswith("unregister"):
                other = "register" + m.name[10:]
                if other not in methods:
                    error(clazz, m, "L2", "Missing register method")

            if m.name.startswith("add") or m.name.startswith("remove"):
                error(clazz, m, "L3", "Callback methods should be named register/unregister")

        if "Listener" in m.raw:
            if m.name.startswith("add"):
                other = "remove" + m.name[3:]
                if other not in methods:
                    error(clazz, m, "L2", "Missing remove method")
            if m.name.startswith("remove") and not m.name.startswith("removeAll"):
                other = "add" + m.name[6:]
                if other not in methods:
                    error(clazz, m, "L2", "Missing add method")

            if m.name.startswith("register") or m.name.startswith("unregister"):
                error(clazz, m, "L3", "Listener methods should be named add/remove")


@verifier
def verify_sync(clazz):
    """Verify synchronized methods aren't exposed."""
    for m in clazz.methods:
        if "synchronized" in m.split:
            error(clazz, m, "M5", "Internal locks must not be exposed")


@verifier
def verify_intent_builder(clazz):
    """Verify that Intent builders are createFooIntent() style."""
    if clazz.name == "Intent": return

    for m in clazz.methods:
        if m.typ == "android.content.Intent":
            if m.name.startswith("create") and m.name.endswith("Intent"):
                pass
            else:
                warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")


@verifier
def verify_helper_classes(clazz):
    """Verify that helper classes are named consistently with what they extend.
    All developer extendable methods should be named onFoo()."""
    test_methods = False
    if clazz.extends == "android.app.Service":
        test_methods = True
        if not clazz.name.endswith("Service"):
            error(clazz, None, "CL4", "Inconsistent class name; should be FooService")

        found = False
        for f in clazz.fields:
            if f.name == "SERVICE_INTERFACE":
                found = True
                if f.value != clazz.fullname:
                    error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname))

    if clazz.extends == "android.content.ContentProvider":
        test_methods = True
        if not clazz.name.endswith("Provider"):
            error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider")

        found = False
        for f in clazz.fields:
            if f.name == "PROVIDER_INTERFACE":
                found = True
                if f.value != clazz.fullname:
                    error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname))

    if clazz.extends == "android.content.BroadcastReceiver":
        test_methods = True
        if not clazz.name.endswith("Receiver"):
            error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver")

    if clazz.extends == "android.app.Activity":
        test_methods = True
        if not clazz.name.endswith("Activity"):
            error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity")

    if test_methods:
        for m in clazz.methods:
            if "final" in m.split: continue
            if not re.match("on[A-Z]", m.name):
                if "abstract" in m.split:
                    warn(clazz, m, None, "Methods implemented by developers should be named onFoo()")
                else:
                    warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")


@verifier
def verify_builder(clazz):
    """Verify builder classes.
    Methods should return the builder to enable chaining."""
    if clazz.extends: return
    if not clazz.name.endswith("Builder"): return

    if clazz.name != "Builder":
        warn(clazz, None, None, "Builder should be defined as inner class")

    has_build = False
    for m in clazz.methods:
        if m.name == "build":
            has_build = True
            continue

        if m.name.startswith("get"): continue
        if m.name.startswith("clear"): continue

        if m.name.startswith("with"):
            warn(clazz, m, None, "Builder methods names should use setFoo() style")

        if m.name.startswith("set"):
            if not m.typ.endswith(clazz.fullname):
                warn(clazz, m, "M4", "Methods must return the builder object")

    if not has_build:
        warn(clazz, None, None, "Missing build() method")

    if "final" not in clazz.split:
        error(clazz, None, None, "Builder should be final")


@verifier
def verify_aidl(clazz):
    """Catch people exposing raw AIDL."""
    if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface":
        error(clazz, None, None, "Raw AIDL interfaces must not be exposed")


@verifier
def verify_internal(clazz):
    """Catch people exposing internal classes."""
    if clazz.pkg.name.startswith("com.android"):
        error(clazz, None, None, "Internal classes must not be exposed")

def layering_build_ranking(ranking_list):
    r = {}
    for rank, ps in enumerate(ranking_list):
        if not isinstance(ps, list):
            ps = [ps]
        for p in ps:
            rs = r
            for n in p.split('.'):
                if n not in rs:
                    rs[n] = {}
                rs = rs[n]
            rs['-rank'] = rank
    return r

LAYERING_PACKAGE_RANKING = layering_build_ranking([
    ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"],
    "android.app",
    "android.widget",
    "android.view",
    "android.animation",
    "android.provider",
    ["android.content","android.graphics.drawable"],
    "android.database",
    "android.text",
    "android.graphics",
    "android.os",
    "android.util"
])

@verifier
def verify_layering(clazz):
    """Catch package layering violations.
    For example, something in android.os depending on android.app."""

    def rank(p):
        r = None
        l = LAYERING_PACKAGE_RANKING
        for n in p.split('.'):
            if n in l:
                l = l[n]
                if '-rank' in l:
                    r = l['-rank']
            else:
                break
        return r

    cr = rank(clazz.pkg.name)
    if cr is None: return

    for f in clazz.fields:
        ir = rank(f.typ)
        if ir is not None and ir < cr:
            warn(clazz, f, "FW6", "Field type violates package layering")

    for m in itertools.chain(clazz.methods, clazz.ctors):
        ir = rank(m.typ)
        if ir is not None and ir < cr:
            warn(clazz, m, "FW6", "Method return type violates package layering")
        for arg in m.args:
            ir = rank(arg)
            if ir is not None and ir < cr:
                warn(clazz, m, "FW6", "Method argument type violates package layering")


@verifier
def verify_boolean(clazz):
    """Verifies that boolean accessors are named correctly.
    For example, hasFoo() and setHasFoo()."""

    def is_get(m): return len(m.args) == 0 and m.typ == "boolean"
    def is_set(m): return len(m.args) == 1 and m.args[0] == "boolean"

    gets = [ m for m in clazz.methods if is_get(m) ]
    sets = [ m for m in clazz.methods if is_set(m) ]

    def error_if_exists(methods, trigger, expected, actual):
        for m in methods:
            if m.name == actual:
                error(clazz, m, "M6", "Symmetric method for %s must be named %s" % (trigger, expected))

    for m in clazz.methods:
        if is_get(m):
            if re.match("is[A-Z]", m.name):
                target = m.name[2:]
                expected = "setIs" + target
                error_if_exists(sets, m.name, expected, "setHas" + target)
            elif re.match("has[A-Z]", m.name):
                target = m.name[3:]
                expected = "setHas" + target
                error_if_exists(sets, m.name, expected, "setIs" + target)
                error_if_exists(sets, m.name, expected, "set" + target)
            elif re.match("get[A-Z]", m.name):
                target = m.name[3:]
                expected = "set" + target
                error_if_exists(sets, m.name, expected, "setIs" + target)
                error_if_exists(sets, m.name, expected, "setHas" + target)

        if is_set(m):
            if re.match("set[A-Z]", m.name):
                target = m.name[3:]
                expected = "get" + target
                error_if_exists(sets, m.name, expected, "is" + target)
                error_if_exists(sets, m.name, expected, "has" + target)


@verifier
def verify_collections(clazz):
    """Verifies that collection types are interfaces."""
    if clazz.fullname == "android.os.Bundle": return
    if clazz.fullname == "android.os.Parcel": return

    bad = ["java.util.Vector", "java.util.LinkedList", "java.util.ArrayList", "java.util.Stack",
           "java.util.HashMap", "java.util.HashSet", "android.util.ArraySet", "android.util.ArrayMap"]
    for m in clazz.methods:
        if m.typ in bad:
            error(clazz, m, "CL2", "Return type is concrete collection; must be higher-level interface")
        for arg in m.args:
            if arg in bad:
                error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")


@verifier
def verify_uris(clazz):
    bad = ["java.net.URL", "java.net.URI", "android.net.URL"]

    for f in clazz.fields:
        if f.typ in bad:
            error(clazz, f, None, "Field must be android.net.Uri instead of " + f.typ)

    for m in clazz.methods + clazz.ctors:
        if m.typ in bad:
            error(clazz, m, None, "Must return android.net.Uri instead of " + m.typ)
        for arg in m.args:
            if arg in bad:
                error(clazz, m, None, "Argument must take android.net.Uri instead of " + arg)


@verifier
def verify_flags(clazz):
    """Verifies that flags are non-overlapping."""
    known = collections.defaultdict(int)
    for f in clazz.fields:
        if "FLAG_" in f.name:
            try:
                val = int(f.value)
            except:
                continue

            scope = f.name[0:f.name.index("FLAG_")]
            if val & known[scope]:
                warn(clazz, f, "C1", "Found overlapping flag constant value")
            known[scope] |= val


@verifier
def verify_exception(clazz):
    """Verifies that methods don't throw generic exceptions."""
    for m in clazz.methods:
        for t in m.throws:
            if t in ["java.lang.Exception", "java.lang.Throwable", "java.lang.Error"]:
                error(clazz, m, "S1", "Methods must not throw generic exceptions")

            if t in ["android.os.RemoteException"]:
                if clazz.fullname == "android.content.ContentProviderClient": continue
                if clazz.fullname == "android.os.Binder": continue
                if clazz.fullname == "android.os.IBinder": continue

                error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")

            if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]:
                warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException")


GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE)

# Not marked as @verifier, because it is only conditionally applied.
def verify_google(clazz):
    """Verifies that APIs never reference Google."""

    if GOOGLE_IGNORECASE.search(clazz.raw) is not None:
        error(clazz, None, None, "Must never reference Google")

    for test in clazz.ctors, clazz.fields, clazz.methods:
        for t in test:
            if GOOGLE_IGNORECASE.search(t.raw) is not None:
                error(clazz, t, None, "Must never reference Google")


@verifier
def verify_bitset(clazz):
    """Verifies that we avoid using heavy BitSet."""

    for f in clazz.fields:
        if f.typ == "java.util.BitSet":
            error(clazz, f, None, "Field type must not be heavy BitSet")

    for m in clazz.methods:
        if m.typ == "java.util.BitSet":
            error(clazz, m, None, "Return type must not be heavy BitSet")
        for arg in m.args:
            if arg == "java.util.BitSet":
                error(clazz, m, None, "Argument type must not be heavy BitSet")


@verifier
def verify_manager(clazz):
    """Verifies that FooManager is only obtained from Context."""

    if not clazz.name.endswith("Manager"): return

    for c in clazz.ctors:
        error(clazz, c, None, "Managers must always be obtained from Context; no direct constructors")

    for m in clazz.methods:
        if m.typ == clazz.fullname:
            error(clazz, m, None, "Managers must always be obtained from Context")


@verifier
def verify_boxed(clazz):
    """Verifies that methods avoid boxed primitives."""

    boxed = ["java.lang.Number","java.lang.Byte","java.lang.Double","java.lang.Float","java.lang.Integer","java.lang.Long","java.lang.Short"]

    for c in clazz.ctors:
        for arg in c.args:
            if arg in boxed:
                error(clazz, c, "M11", "Must avoid boxed primitives")

    for f in clazz.fields:
        if f.typ in boxed:
            error(clazz, f, "M11", "Must avoid boxed primitives")

    for m in clazz.methods:
        if m.typ in boxed:
            error(clazz, m, "M11", "Must avoid boxed primitives")
        for arg in m.args:
            if arg in boxed:
                error(clazz, m, "M11", "Must avoid boxed primitives")


@verifier
def verify_static_utils(clazz):
    """Verifies that helper classes can't be constructed."""
    if clazz.fullname.startswith("android.opengl"): return
    if clazz.fullname.startswith("android.R"): return

    # Only care about classes with default constructors
    if len(clazz.ctors) == 1 and len(clazz.ctors[0].args) == 0:
        test = []
        test.extend(clazz.fields)
        test.extend(clazz.methods)

        if len(test) == 0: return
        for t in test:
            if "static" not in t.split:
                return

        error(clazz, None, None, "Fully-static utility classes must not have constructor")


# @verifier  # Disabled for now
def verify_overload_args(clazz):
    """Verifies that method overloads add new arguments at the end."""
    if clazz.fullname.startswith("android.opengl"): return

    overloads = collections.defaultdict(list)
    for m in clazz.methods:
        if "deprecated" in m.split: continue
        overloads[m.name].append(m)

    for name, methods in overloads.items():
        if len(methods) <= 1: continue

        # Look for arguments common across all overloads
        def cluster(args):
            count = collections.defaultdict(int)
            res = set()
            for i in range(len(args)):
                a = args[i]
                res.add("%s#%d" % (a, count[a]))
                count[a] += 1
            return res

        common_args = cluster(methods[0].args)
        for m in methods:
            common_args = common_args & cluster(m.args)

        if len(common_args) == 0: continue

        # Require that all common arguments are present at start of signature
        locked_sig = None
        for m in methods:
            sig = m.args[0:len(common_args)]
            if not common_args.issubset(cluster(sig)):
                warn(clazz, m, "M2", "Expected common arguments [%s] at beginning of overloaded method" % (", ".join(common_args)))
            elif not locked_sig:
                locked_sig = sig
            elif locked_sig != sig:
                error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))


@verifier
def verify_callback_handlers(clazz):
    """Verifies that methods adding listener/callback have overload
    for specifying delivery thread."""

    # Ignore UI packages which assume main thread
    skip = [
        "animation",
        "view",
        "graphics",
        "transition",
        "widget",
        "webkit",
    ]
    for s in skip:
        if s in clazz.pkg.name_path: return
        if s in clazz.extends_path: return

    # Ignore UI classes which assume main thread
    if "app" in clazz.pkg.name_path or "app" in clazz.extends_path:
        for s in ["ActionBar","Dialog","Application","Activity","Fragment","Loader"]:
            if s in clazz.fullname: return
    if "content" in clazz.pkg.name_path or "content" in clazz.extends_path:
        for s in ["Loader"]:
            if s in clazz.fullname: return

    found = {}
    by_name = collections.defaultdict(list)
    examine = clazz.ctors + clazz.methods
    for m in examine:
        if m.name.startswith("unregister"): continue
        if m.name.startswith("remove"): continue
        if re.match("on[A-Z]+", m.name): continue

        by_name[m.name].append(m)

        for a in m.args:
            if a.endswith("Listener") or a.endswith("Callback") or a.endswith("Callbacks"):
                found[m.name] = m

    for f in found.values():
        takes_handler = False
        takes_exec = False
        for m in by_name[f.name]:
            if "android.os.Handler" in m.args:
                takes_handler = True
            if "java.util.concurrent.Executor" in m.args:
                takes_exec = True
        if not takes_exec:
            warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Executor")


@verifier
def verify_context_first(clazz):
    """Verifies that methods accepting a Context keep it the first argument."""
    examine = clazz.ctors + clazz.methods
    for m in examine:
        if len(m.args) > 1 and m.args[0] != "android.content.Context":
            if "android.content.Context" in m.args[1:]:
                error(clazz, m, "M3", "Context is distinct, so it must be the first argument")
        if len(m.args) > 1 and m.args[0] != "android.content.ContentResolver":
            if "android.content.ContentResolver" in m.args[1:]:
                error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")


@verifier
def verify_listener_last(clazz):
    """Verifies that methods accepting a Listener or Callback keep them as last arguments."""
    examine = clazz.ctors + clazz.methods
    for m in examine:
        if "Listener" in m.name or "Callback" in m.name: continue
        found = False
        for a in m.args:
            if a.endswith("Callback") or a.endswith("Callbacks") or a.endswith("Listener"):
                found = True
            elif found:
                warn(clazz, m, "M3", "Listeners should always be at end of argument list")


@verifier
def verify_resource_names(clazz):
    """Verifies that resource names have consistent case."""
    if not re.match("android\.R\.[a-z]+", clazz.fullname): return

    # Resources defined by files are foo_bar_baz
    if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]:
        for f in clazz.fields:
            if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
            if f.name.startswith("config_"):
                error(clazz, f, None, "Expected config name to be config_fooBarBaz style")

            if re.match("[a-z1-9_]+$", f.name): continue
            error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style")

    # Resources defined inside files are fooBarBaz
    if clazz.name in ["array","attr","id","bool","fraction","integer"]:
        for f in clazz.fields:
            if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue
            if re.match("layout_[a-z][a-zA-Z1-9]*$", f.name): continue
            if re.match("state_[a-z_]*$", f.name): continue

            if re.match("[a-z][a-zA-Z1-9]*$", f.name): continue
            error(clazz, f, "C7", "Expected resource name in this class to be fooBarBaz style")

    # Styles are FooBar_Baz
    if clazz.name in ["style"]:
        for f in clazz.fields:
            if re.match("[A-Z][A-Za-z1-9]+(_[A-Z][A-Za-z1-9]+?)*$", f.name): continue
            error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")


@verifier
def verify_files(clazz):
    """Verifies that methods accepting File also accept streams."""

    has_file = set()
    has_stream = set()

    test = []
    test.extend(clazz.ctors)
    test.extend(clazz.methods)

    for m in test:
        if "java.io.File" in m.args:
            has_file.add(m)
        if "java.io.FileDescriptor" in m.args or "android.os.ParcelFileDescriptor" in m.args or "java.io.InputStream" in m.args or "java.io.OutputStream" in m.args:
            has_stream.add(m.name)

    for m in has_file:
        if m.name not in has_stream:
            warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")


@verifier
def verify_manager_list(clazz):
    """Verifies that managers return List<? extends Parcelable> instead of arrays."""

    if not clazz.name.endswith("Manager"): return

    for m in clazz.methods:
        if m.typ.startswith("android.") and m.typ.endswith("[]"):
            warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")


@verifier
def verify_abstract_inner(clazz):
    """Verifies that abstract inner classes are static."""

    if re.match(".+?\.[A-Z][^\.]+\.[A-Z]", clazz.fullname):
        if "abstract" in clazz.split and "static" not in clazz.split:
            warn(clazz, None, None, "Abstract inner classes should be static to improve testability")


@verifier
def verify_runtime_exceptions(clazz):
    """Verifies that runtime exceptions aren't listed in throws."""

    banned = [
        "java.lang.NullPointerException",
        "java.lang.ClassCastException",
        "java.lang.IndexOutOfBoundsException",
        "java.lang.reflect.UndeclaredThrowableException",
        "java.lang.reflect.MalformedParametersException",
        "java.lang.reflect.MalformedParameterizedTypeException",
        "java.lang.invoke.WrongMethodTypeException",
        "java.lang.EnumConstantNotPresentException",
        "java.lang.IllegalMonitorStateException",
        "java.lang.SecurityException",
        "java.lang.UnsupportedOperationException",
        "java.lang.annotation.AnnotationTypeMismatchException",
        "java.lang.annotation.IncompleteAnnotationException",
        "java.lang.TypeNotPresentException",
        "java.lang.IllegalStateException",
        "java.lang.ArithmeticException",
        "java.lang.IllegalArgumentException",
        "java.lang.ArrayStoreException",
        "java.lang.NegativeArraySizeException",
        "java.util.MissingResourceException",
        "java.util.EmptyStackException",
        "java.util.concurrent.CompletionException",
        "java.util.concurrent.RejectedExecutionException",
        "java.util.IllformedLocaleException",
        "java.util.ConcurrentModificationException",
        "java.util.NoSuchElementException",
        "java.io.UncheckedIOException",
        "java.time.DateTimeException",
        "java.security.ProviderException",
        "java.nio.BufferUnderflowException",
        "java.nio.BufferOverflowException",
    ]

    examine = clazz.ctors + clazz.methods
    for m in examine:
        for t in m.throws:
            if t in banned:
                error(clazz, m, None, "Methods must not mention RuntimeException subclasses in throws clauses")


@verifier
def verify_error(clazz):
    """Verifies that we always use Exception instead of Error."""
    if not clazz.extends: return
    if clazz.extends.endswith("Error"):
        error(clazz, None, None, "Trouble must be reported through an Exception, not Error")
    if clazz.extends.endswith("Exception") and not clazz.name.endswith("Exception"):
        error(clazz, None, None, "Exceptions must be named FooException")


@verifier
def verify_units(clazz):
    """Verifies that we use consistent naming for units."""

    # If we find K, recommend replacing with V
    bad = {
        "Ns": "Nanos",
        "Ms": "Millis or Micros",
        "Sec": "Seconds", "Secs": "Seconds",
        "Hr": "Hours", "Hrs": "Hours",
        "Mo": "Months", "Mos": "Months",
        "Yr": "Years", "Yrs": "Years",
        "Byte": "Bytes", "Space": "Bytes",
    }

    for m in clazz.methods:
        if m.typ not in ["short","int","long"]: continue
        for k, v in bad.iteritems():
            if m.name.endswith(k):
                error(clazz, m, None, "Expected method name units to be " + v)
        if m.name.endswith("Nanos") or m.name.endswith("Micros"):
            warn(clazz, m, None, "Returned time values are strongly encouraged to be in milliseconds unless you need the extra precision")
        if m.name.endswith("Seconds"):
            error(clazz, m, None, "Returned time values must be in milliseconds")

    for m in clazz.methods:
        typ = m.typ
        if typ == "void":
            if len(m.args) != 1: continue
            typ = m.args[0]

        if m.name.endswith("Fraction") and typ != "float":
            error(clazz, m, None, "Fractions must use floats")
        if m.name.endswith("Percentage") and typ != "int":
            error(clazz, m, None, "Percentage must use ints")


@verifier
def verify_closable(clazz):
    """Verifies that classes are AutoClosable."""
    if "java.lang.AutoCloseable" in clazz.implements_all: return
    if "java.io.Closeable" in clazz.implements_all: return

    for m in clazz.methods:
        if len(m.args) > 0: continue
        if m.name in ["close","release","destroy","finish","finalize","disconnect","shutdown","stop","free","quit"]:
            warn(clazz, m, None, "Classes that release resources should implement AutoClosable and CloseGuard")
            return


@verifier
def verify_member_name_not_kotlin_keyword(clazz):
    """Prevent method names which are keywords in Kotlin."""

    # https://kotlinlang.org/docs/reference/keyword-reference.html#hard-keywords
    # This list does not include Java keywords as those are already impossible to use.
    keywords = [
        'as',
        'fun',
        'in',
        'is',
        'object',
        'typealias',
        'val',
        'var',
        'when',
    ]

    for m in clazz.methods:
        if m.name in keywords:
            error(clazz, m, None, "Method name must not be a Kotlin keyword")
    for f in clazz.fields:
        if f.name in keywords:
            error(clazz, f, None, "Field name must not be a Kotlin keyword")


@verifier
def verify_method_name_not_kotlin_operator(clazz):
    """Warn about method names which become operators in Kotlin."""

    binary = set()

    def unique_binary_op(m, op):
        if op in binary:
            error(clazz, m, None, "Only one of '{0}' and '{0}Assign' methods should be present for Kotlin".format(op))
        binary.add(op)

    for m in clazz.methods:
        if 'static' in m.split or 'operator' in m.split:
            continue

        # https://kotlinlang.org/docs/reference/operator-overloading.html#unary-prefix-operators
        if m.name in ['unaryPlus', 'unaryMinus', 'not'] and len(m.args) == 0:
            warn(clazz, m, None, "Method can be invoked as a unary operator from Kotlin")

        # https://kotlinlang.org/docs/reference/operator-overloading.html#increments-and-decrements
        if m.name in ['inc', 'dec'] and len(m.args) == 0 and m.typ != 'void':
            # This only applies if the return type is the same or a subtype of the enclosing class, but we have no
            # practical way of checking that relationship here.
            warn(clazz, m, None, "Method can be invoked as a pre/postfix inc/decrement operator from Kotlin")

        # https://kotlinlang.org/docs/reference/operator-overloading.html#arithmetic
        if m.name in ['plus', 'minus', 'times', 'div', 'rem', 'mod', 'rangeTo'] and len(m.args) == 1:
            warn(clazz, m, None, "Method can be invoked as a binary operator from Kotlin")
            unique_binary_op(m, m.name)

        # https://kotlinlang.org/docs/reference/operator-overloading.html#in
        if m.name == 'contains' and len(m.args) == 1 and m.typ == 'boolean':
            warn(clazz, m, None, "Method can be invoked as a 'in' operator from Kotlin")

        # https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
        if (m.name == 'get' and len(m.args) > 0) or (m.name == 'set' and len(m.args) > 1):
            warn(clazz, m, None, "Method can be invoked with an indexing operator from Kotlin")

        # https://kotlinlang.org/docs/reference/operator-overloading.html#invoke
        if m.name == 'invoke':
            warn(clazz, m, None, "Method can be invoked with function call syntax from Kotlin")

        # https://kotlinlang.org/docs/reference/operator-overloading.html#assignments
        if m.name in ['plusAssign', 'minusAssign', 'timesAssign', 'divAssign', 'remAssign', 'modAssign'] \
                and len(m.args) == 1 \
                and m.typ == 'void':
            warn(clazz, m, None, "Method can be invoked as a compound assignment operator from Kotlin")
            unique_binary_op(m, m.name[:-6])  # Remove 'Assign' suffix


@verifier
def verify_collections_over_arrays(clazz):
    """Warn that [] should be Collections."""

    if "@interface" in clazz.split:
        return

    safe = ["java.lang.String[]","byte[]","short[]","int[]","long[]","float[]","double[]","boolean[]","char[]"]
    for m in clazz.methods:
        if m.typ.endswith("[]") and m.typ not in safe:
            warn(clazz, m, None, "Method should return Collection<> (or subclass) instead of raw array")
        for arg in m.args:
            if arg.endswith("[]") and arg not in safe:
                warn(clazz, m, None, "Method argument should be Collection<> (or subclass) instead of raw array")


@verifier
def verify_user_handle(clazz):
    """Methods taking UserHandle should be ForUser or AsUser."""
    if clazz.name.endswith("Listener") or clazz.name.endswith("Callback") or clazz.name.endswith("Callbacks"): return
    if clazz.fullname == "android.app.admin.DeviceAdminReceiver": return
    if clazz.fullname == "android.content.pm.LauncherApps": return
    if clazz.fullname == "android.os.UserHandle": return
    if clazz.fullname == "android.os.UserManager": return

    for m in clazz.methods:
        if re.match("on[A-Z]+", m.name): continue

        has_arg = "android.os.UserHandle" in m.args
        has_name = m.name.endswith("AsUser") or m.name.endswith("ForUser")

        if clazz.fullname.endswith("Manager") and has_arg:
            warn(clazz, m, None, "When a method overload is needed to target a specific "
                 "UserHandle, callers should be directed to use "
                 "Context.createPackageContextAsUser() and re-obtain the relevant "
                 "Manager, and no new API should be added")
        elif has_arg and not has_name:
            warn(clazz, m, None, "Method taking UserHandle should be named 'doFooAsUser' "
                 "or 'queryFooForUser'")


@verifier
def verify_params(clazz):
    """Parameter classes should be 'Params'."""
    if clazz.name.endswith("Params"): return
    if clazz.fullname == "android.app.ActivityOptions": return
    if clazz.fullname == "android.app.BroadcastOptions": return
    if clazz.fullname == "android.os.Bundle": return
    if clazz.fullname == "android.os.BaseBundle": return
    if clazz.fullname == "android.os.PersistableBundle": return

    bad = ["Param","Parameter","Parameters","Args","Arg","Argument","Arguments","Options","Bundle"]
    for b in bad:
        if clazz.name.endswith(b):
            error(clazz, None, None, "Classes holding a set of parameters should be called 'FooParams'")


@verifier
def verify_services(clazz):
    """Service name should be FOO_BAR_SERVICE = 'foo_bar'."""
    if clazz.fullname != "android.content.Context": return

    for f in clazz.fields:
        if f.typ != "java.lang.String": continue
        found = re.match(r"([A-Z_]+)_SERVICE", f.name)
        if found:
            expected = found.group(1).lower()
            if f.value != expected:
                error(clazz, f, "C4", "Inconsistent service value; expected '%s'" % (expected))


@verifier
def verify_tense(clazz):
    """Verify tenses of method names."""
    if clazz.fullname.startswith("android.opengl"): return

    for m in clazz.methods:
        if m.name.endswith("Enable"):
            warn(clazz, m, None, "Unexpected tense; probably meant 'enabled'")


@verifier
def verify_icu(clazz):
    """Verifies that richer ICU replacements are used."""
    better = {
        "java.util.TimeZone": "android.icu.util.TimeZone",
        "java.util.Calendar": "android.icu.util.Calendar",
        "java.util.Locale": "android.icu.util.ULocale",
        "java.util.ResourceBundle": "android.icu.util.UResourceBundle",
        "java.util.SimpleTimeZone": "android.icu.util.SimpleTimeZone",
        "java.util.StringTokenizer": "android.icu.util.StringTokenizer",
        "java.util.GregorianCalendar": "android.icu.util.GregorianCalendar",
        "java.lang.Character": "android.icu.lang.UCharacter",
        "java.text.BreakIterator": "android.icu.text.BreakIterator",
        "java.text.Collator": "android.icu.text.Collator",
        "java.text.DecimalFormatSymbols": "android.icu.text.DecimalFormatSymbols",
        "java.text.NumberFormat": "android.icu.text.NumberFormat",
        "java.text.DateFormatSymbols": "android.icu.text.DateFormatSymbols",
        "java.text.DateFormat": "android.icu.text.DateFormat",
        "java.text.SimpleDateFormat": "android.icu.text.SimpleDateFormat",
        "java.text.MessageFormat": "android.icu.text.MessageFormat",
        "java.text.DecimalFormat": "android.icu.text.DecimalFormat",
    }

    for m in clazz.ctors + clazz.methods:
        types = []
        types.extend(m.typ)
        types.extend(m.args)
        for arg in types:
            if arg in better:
                warn(clazz, m, None, "Type %s should be replaced with richer ICU type %s" % (arg, better[arg]))


@verifier
def verify_clone(clazz):
    """Verify that clone() isn't implemented; see EJ page 61."""
    for m in clazz.methods:
        if m.name == "clone":
            error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()")


@verifier
def verify_pfd(clazz):
    """Verify that android APIs use PFD over FD."""
    if clazz.fullname == "android.os.FileUtils" or clazz.fullname == "android.system.Os":
        return

    examine = clazz.ctors + clazz.methods
    for m in examine:
        if m.typ == "java.io.FileDescriptor":
            error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
        if m.typ == "int":
            if "Fd" in m.name or "FD" in m.name or "FileDescriptor" in m.name:
                error(clazz, m, "FW11", "Must use ParcelFileDescriptor")
        for arg in m.args:
            if arg == "java.io.FileDescriptor":
                error(clazz, m, "FW11", "Must use ParcelFileDescriptor")

    for f in clazz.fields:
        if f.typ == "java.io.FileDescriptor":
            error(clazz, f, "FW11", "Must use ParcelFileDescriptor")


@verifier
def verify_numbers(clazz):
    """Discourage small numbers types like short and byte."""

    discouraged = ["short","byte"]

    for c in clazz.ctors:
        for arg in c.args:
            if arg in discouraged:
                warn(clazz, c, "FW12", "Should avoid odd sized primitives; use int instead")

    for f in clazz.fields:
        if f.typ in discouraged:
            warn(clazz, f, "FW12", "Should avoid odd sized primitives; use int instead")

    for m in clazz.methods:
        if m.typ in discouraged:
            warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
        for arg in m.args:
            if arg in discouraged:
                warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")


PRIMITIVES = {"void", "int", "float", "boolean", "short", "char", "byte", "long", "double"}

@verifier
def verify_nullability(clazz):
    """Catches missing nullability annotations"""

    for f in clazz.fields:
        if f.value is not None and 'static' in f.split and 'final' in f.split:
            continue  # Nullability of constants can be inferred.
        if f.typ not in PRIMITIVES and not has_nullability(f.annotations):
            error(clazz, f, "M12", "Field must be marked either @NonNull or @Nullable")

    for c in clazz.ctors:
        verify_nullability_args(clazz, c)

    for m in clazz.methods:
        if m.name == "writeToParcel" or m.name == "onReceive":
            continue  # Parcelable.writeToParcel() and BroadcastReceiver.onReceive() are not yet annotated

        if m.typ not in PRIMITIVES and not has_nullability(m.annotations):
            error(clazz, m, "M12", "Return value must be marked either @NonNull or @Nullable")
        verify_nullability_args(clazz, m)

def verify_nullability_args(clazz, m):
    for i, arg in enumerate(m.detailed_args):
        if arg.type not in PRIMITIVES and not has_nullability(arg.annotations):
            error(clazz, m, "M12", "Argument %d must be marked either @NonNull or @Nullable" % (i+1,))

def has_nullability(annotations):
    return "@NonNull" in annotations or "@Nullable" in annotations


@verifier
def verify_intdef(clazz):
    """intdefs must be @hide, because the constant names cannot be stored in
       the stubs (only the values are, which is not useful)"""
    if "@interface" not in clazz.split:
        return
    if "@IntDef" in clazz.annotations or "@LongDef" in clazz.annotations:
        error(clazz, None, None, "@IntDef and @LongDef annotations must be @hide")


@verifier
def verify_singleton(clazz):
    """Catch singleton objects with constructors."""

    singleton = False
    for m in clazz.methods:
        if m.name.startswith("get") and m.name.endswith("Instance") and " static " in m.raw:
            singleton = True

    if singleton:
        for c in clazz.ctors:
            error(clazz, c, None, "Singleton classes should use getInstance() methods")



def is_interesting(clazz):
    """Test if given class is interesting from an Android PoV."""

    if clazz.pkg.name.startswith("java"): return False
    if clazz.pkg.name.startswith("junit"): return False
    if clazz.pkg.name.startswith("org.apache"): return False
    if clazz.pkg.name.startswith("org.xml"): return False
    if clazz.pkg.name.startswith("org.json"): return False
    if clazz.pkg.name.startswith("org.w3c"): return False
    if clazz.pkg.name.startswith("android.icu."): return False
    return True


def examine_clazz(clazz):
    """Find all style issues in the given class."""

    notice(clazz)

    if not is_interesting(clazz): return

    for v in verifiers.itervalues():
        v(clazz)

    if not ALLOW_GOOGLE: verify_google(clazz)


def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None):
    """Find all style issues in the given API stream."""
    global failures, noticed
    failures = {}
    noticed = {}
    _parse_stream(stream, examine_clazz, base_f=base_stream,
                  in_classes_with_base=in_classes_with_base,
                  out_classes_with_base=out_classes_with_base)
    return (failures, noticed)


def examine_api(api):
    """Find all style issues in the given parsed API."""
    global failures
    failures = {}
    for key in sorted(api.keys()):
        examine_clazz(api[key])
    return failures


def verify_compat(cur, prev):
    """Find any incompatible API changes between two levels."""
    global failures

    def class_exists(api, test):
        return test.fullname in api

    def ctor_exists(api, clazz, test):
        for m in clazz.ctors:
            if m.ident == test.ident: return True
        return False

    def all_methods(api, clazz):
        methods = list(clazz.methods)
        if clazz.extends is not None:
            methods.extend(all_methods(api, api[clazz.extends]))
        return methods

    def method_exists(api, clazz, test):
        methods = all_methods(api, clazz)
        for m in methods:
            if m.ident == test.ident: return True
        return False

    def field_exists(api, clazz, test):
        for f in clazz.fields:
            if f.ident == test.ident: return True
        return False

    failures = {}
    for key in sorted(prev.keys()):
        prev_clazz = prev[key]

        if not class_exists(cur, prev_clazz):
            error(prev_clazz, None, None, "Class removed or incompatible change")
            continue

        cur_clazz = cur[key]

        for test in prev_clazz.ctors:
            if not ctor_exists(cur, cur_clazz, test):
                error(prev_clazz, prev_ctor, None, "Constructor removed or incompatible change")

        methods = all_methods(prev, prev_clazz)
        for test in methods:
            if not method_exists(cur, cur_clazz, test):
                error(prev_clazz, test, None, "Method removed or incompatible change")

        for test in prev_clazz.fields:
            if not field_exists(cur, cur_clazz, test):
                error(prev_clazz, test, None, "Field removed or incompatible change")

    return failures


def match_filter(filters, fullname):
    for f in filters:
        if fullname == f:
            return True
        if fullname.startswith(f + '.'):
            return True
    return False


def show_deprecations_at_birth(cur, prev):
    """Show API deprecations at birth."""
    global failures

    # Remove all existing things so we're left with new
    for prev_clazz in prev.values():
        if prev_clazz.fullname not in cur:
            # The class was removed this release; we can safely ignore it.
            continue

        cur_clazz = cur[prev_clazz.fullname]
        if not is_interesting(cur_clazz): continue

        sigs = { i.ident: i for i in prev_clazz.ctors }
        cur_clazz.ctors = [ i for i in cur_clazz.ctors if i.ident not in sigs ]
        sigs = { i.ident: i for i in prev_clazz.methods }
        cur_clazz.methods = [ i for i in cur_clazz.methods if i.ident not in sigs ]
        sigs = { i.ident: i for i in prev_clazz.fields }
        cur_clazz.fields = [ i for i in cur_clazz.fields if i.ident not in sigs ]

        # Forget about class entirely when nothing new
        if len(cur_clazz.ctors) == 0 and len(cur_clazz.methods) == 0 and len(cur_clazz.fields) == 0:
            del cur[prev_clazz.fullname]

    for clazz in cur.values():
        if not is_interesting(clazz): continue

        if "deprecated" in clazz.split and not clazz.fullname in prev:
            error(clazz, None, None, "Found API deprecation at birth")

        for i in clazz.ctors + clazz.methods + clazz.fields:
            if "deprecated" in i.split:
                error(clazz, i, None, "Found API deprecation at birth")

    print "%s Deprecated at birth %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True),
                                            format(reset=True)))
    for f in sorted(failures):
        print failures[f]
        print


def show_stats(cur, prev):
    """Show API stats."""

    stats = collections.defaultdict(int)
    for cur_clazz in cur.values():
        if not is_interesting(cur_clazz): continue

        if cur_clazz.fullname not in prev:
            stats['new_classes'] += 1
            stats['new_ctors'] += len(cur_clazz.ctors)
            stats['new_methods'] += len(cur_clazz.methods)
            stats['new_fields'] += len(cur_clazz.fields)
        else:
            prev_clazz = prev[cur_clazz.fullname]

            sigs = { i.ident: i for i in prev_clazz.ctors }
            ctors = len([ i for i in cur_clazz.ctors if i.ident not in sigs ])
            sigs = { i.ident: i for i in prev_clazz.methods }
            methods = len([ i for i in cur_clazz.methods if i.ident not in sigs ])
            sigs = { i.ident: i for i in prev_clazz.fields }
            fields = len([ i for i in cur_clazz.fields if i.ident not in sigs ])

            if ctors + methods + fields > 0:
                stats['extend_classes'] += 1
                stats['extend_ctors'] += ctors
                stats['extend_methods'] += methods
                stats['extend_fields'] += fields

    print "#", "".join([ k.ljust(20) for k in sorted(stats.keys()) ])
    print " ", "".join([ str(stats[k]).ljust(20) for k in sorted(stats.keys()) ])


def main():
    parser = argparse.ArgumentParser(description="Enforces common Android public API design \
            patterns. It ignores lint messages from a previous API level, if provided.")
    parser.add_argument("--base-current", nargs='?', type=argparse.FileType('r'), default=None,
            help="The base current.txt to use when examining system-current.txt or"
                 " test-current.txt")
    parser.add_argument("--base-previous", nargs='?', type=argparse.FileType('r'), default=None,
            help="The base previous.txt to use when examining system-previous.txt or"
                 " test-previous.txt")
    parser.add_argument("--no-color", action='store_const', const=True,
            help="Disable terminal colors")
    parser.add_argument("--color", action='store_const', const=True,
            help="Use terminal colors")
    parser.add_argument("--allow-google", action='store_const', const=True,
            help="Allow references to Google")
    parser.add_argument("--show-noticed", action='store_const', const=True,
            help="Show API changes noticed")
    parser.add_argument("--show-deprecations-at-birth", action='store_const', const=True,
            help="Show API deprecations at birth")
    parser.add_argument("--show-stats", action='store_const', const=True,
            help="Show API stats")
    parser.add_argument("--title", action='store', default=None,
            help="Title to put in for display purposes")
    parser.add_argument("--filter", action="append",
            help="If provided, only show lint for the given packages or classes.")
    parser.add_argument("current.txt", type=argparse.FileType('r'), help="current.txt")
    parser.add_argument("previous.txt", nargs='?', type=argparse.FileType('r'), default=None,
            help="previous.txt")
    args = vars(parser.parse_args())

    if args['no_color']:
        USE_COLOR = False
    elif args['color']:
        USE_COLOR = True
    else:
        USE_COLOR = sys.stdout.isatty()

    if args['allow_google']:
        ALLOW_GOOGLE = True

    current_file = args['current.txt']
    base_current_file = args['base_current']
    previous_file = args['previous.txt']
    base_previous_file = args['base_previous']
    filters = args['filter']
    if not filters:
        filters = []
    title = args['title']
    if not title:
        title = current_file.name

    if args['show_deprecations_at_birth']:
        with current_file as f:
            cur = _parse_stream(f)
        with previous_file as f:
            prev = _parse_stream(f)
        show_deprecations_at_birth(cur, prev)
        sys.exit()

    if args['show_stats']:
        with current_file as f:
            cur = _parse_stream(f)
        with previous_file as f:
            prev = _parse_stream(f)
        show_stats(cur, prev)
        sys.exit()

    classes_with_base = []

    with current_file as f:
        if base_current_file:
            with base_current_file as base_f:
                cur_fail, cur_noticed = examine_stream(f, base_f,
                                                       out_classes_with_base=classes_with_base)
        else:
            cur_fail, cur_noticed = examine_stream(f, out_classes_with_base=classes_with_base)

    if not previous_file is None:
        with previous_file as f:
            if base_previous_file:
                with base_previous_file as base_f:
                    prev_fail, prev_noticed = examine_stream(f, base_f,
                                                             in_classes_with_base=classes_with_base)
            else:
                prev_fail, prev_noticed = examine_stream(f, in_classes_with_base=classes_with_base)

        # ignore errors from previous API level
        for p in prev_fail:
            if p in cur_fail:
                del cur_fail[p]

        # ignore classes unchanged from previous API level
        for k, v in prev_noticed.iteritems():
            if k in cur_noticed and v == cur_noticed[k]:
                del cur_noticed[k]

        """
        # NOTE: disabled because of memory pressure
        # look for compatibility issues
        compat_fail = verify_compat(cur, prev)

        print "%s API compatibility issues %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
        for f in sorted(compat_fail):
            print compat_fail[f]
            print
        """

    # ignore everything but the given filters, if provided
    if filters:
        cur_fail = dict([(key, failure) for key, failure in cur_fail.iteritems()
                if match_filter(filters, failure.clazz.fullname)])

    if args['show_noticed'] and len(cur_noticed) != 0:
        print "%s API changes noticed %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), format(reset=True)))
        for f in sorted(cur_noticed.keys()):
            print f
        print

    if len(cur_fail) != 0:
        print "%s API style issues: %s %s" % ((format(fg=WHITE, bg=BLUE, bold=True),
                    title, format(reset=True)))
        for f in filters:
            print "%s   filter: %s %s" % ((format(fg=WHITE, bg=BLUE, bold=True),
                        f, format(reset=True)))
        print
        for f in sorted(cur_fail):
            print cur_fail[f]
            print
        print "%d errors" % len(cur_fail)
        sys.exit(77)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        sys.exit(1)
