#!/usr/bin/env python3
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import os
import sys

import idl_definitions
from generator import MultitypeSortKey
from idl_types import IdlType, IdlNullableType, IdlUnionType, IdlArrayOrSequenceType
import dependency

new_asts = {}

# Report of union types mapped to any.
_unions_to_any = []


def report_unions_to_any():
    global _unions_to_any

    warnings = []
    for union_id in sorted(_unions_to_any):
        warnings.append('Union type %s is mapped to \'any\'' % union_id)

    return warnings


# Ugly but Chrome IDLs can reference typedefs in any IDL w/o an include.  So we
# need to remember any typedef seen then alias any reference to a typedef.
_typeDefsFixup = []


def _addTypedef(typedef):
    _typeDefsFixup.append(typedef)


def resolveTypedef(type):
    """ Given a type if it's a known typedef (only typedef's that aren't union)
      are remembered for fixup.  typedefs that are union type are mapped to
      any so those we don't need to alias.  typedefs referenced in the file
      where the typedef was defined are automatically aliased to the real type.
      This resolves typedef where the declaration is in another IDL file.
  """
    for typedef in _typeDefsFixup:
        if typedef.id == type.id:
            return typedef.type

    return type


_operation_suffix_map = {
    '__getter__': "Getter",
    '__setter__': "Setter",
    '__delete__': "Deleter",
}

class IDLNode(object):
    """Base class for all IDL elements.
  IDLNode may contain various child nodes, and have properties. Examples
  of IDLNode are interfaces, interface members, function arguments,
  etc.
  """

    def __init__(self, ast, id=None):
        """Initializes an IDLNode from a PegParser AST output."""
        if ast:
            self.id = self._find_first(ast, 'Id') if ast is not None else None
        else:
            # Support synthesized IDLNode created w/o an AST (e.g., setlike support).
            self.id = id

    def __repr__(self):
        """Generates string of the form <class id extra extra ... 0x12345678>."""
        extras = self._extra_repr()
        if isinstance(extras, list):
            extras = ' '.join([str(e) for e in extras])
        try:
            if self.id:
                return '<%s %s 0x%x>' % (type(self).__name__,
                                         ('%s %s' % (self.id, extras)).strip(),
                                         hash(self))
            return '<%s %s 0x%x>' % (type(self).__name__, extras, hash(self))
        except Exception as e:
            return "can't convert to string: %s" % e

    def _extra_repr(self):
        """Returns string of extra info for __repr__()."""
        return ''

    def __eq__(self, other):
        """Override default equals operation.
    IDLNodes are equal if all their properties are equal."""
        if other is None or not isinstance(other, IDLNode):
            return 1
        return self.__dict__.__eq__(other.__dict__)

    def __hash__(self):
        """Define default hashing behavior.
    In order to comply with a == b => hash(a) == hash(b), we recursively iterate
    self.__dict__ and convert all objects to hashable objects."""
        return self.to_hash()

    def reset_id(self, newId):
        """Reset the id of the Node.  This is typically done during a normalization
    phase (e.g., "DOMWindow" -> "Window")."""
        self.id = newId

    def all(self, type_filter=None):
        """Returns a list containing this node and all it child nodes
    (recursive).

    Args:
      type_filter -- can be used to limit the results to a specific
        node type (e.g. IDLOperation).
    """
        res = []
        if type_filter is None or isinstance(self, type_filter):
            res.append(self)
        for v in self._all_subnodes():
            if isinstance(v, IDLNode):
                res.extend(v.all(type_filter))
            elif isinstance(v, list):
                for item in v:
                    if isinstance(item, IDLNode):
                        res.extend(item.all(type_filter))
        return res

    def _all_subnodes(self):
        """Accessor used by all() to find subnodes."""
        return self.__dict__.values()

    def to_dict(self):
        """Converts the IDLNode and its children into a dictionary.
    This method is useful mostly for debugging and pretty printing.
    """
        res = {}
        for (k, v) in self.__dict__.items():
            if v == None or v == False or v == [] or v == {}:
                # Skip empty/false members.
                continue
            elif isinstance(v, IDLDictNode) and not len(v):
                # Skip empty dict sub-nodes.
                continue
            elif isinstance(v, list):
                # Convert lists:
                new_v = []
                for sub_node in v:
                    if isinstance(sub_node, IDLNode):
                        # Convert sub-node:
                        new_v.append(sub_node.to_dict())
                    else:
                        new_v.append(sub_node)
                v = new_v
            elif isinstance(v, IDLNode):
                # Convert sub-node:
                v = v.to_dict()
            res[k] = v
        return res

    def to_hash(self):
        return hash(self._to_hashable(self))

    def _to_hashable(self, obj):
        # By default, lists and dicts are not hashable, and user-defined objects
        # are unordered. In order to make a consistent hash for a given object,
        # this converts unhashable types and sorts properties.
        if isinstance(obj, list):
            # Convert lists to tuples.
            new_obj = []
            for item in obj:
                new_obj.append(self._to_hashable(item))
            return tuple(new_obj)
        elif isinstance(obj, dict):
            # Convert dicts to frozensets of tuples.
            new_obj = set()
            # Sort to ensure fixed order.
            for (k2, v2) in sorted(obj.items(), key=MultitypeSortKey):
                new_obj.add((self._to_hashable(k2), self._to_hashable(v2)))
            return frozenset(new_obj)
        elif hasattr(obj, '__dict__'):
            items = []
            # Sort properties to ensure fixed order.
            for (k, v) in sorted(obj.__dict__.items(), key=MultitypeSortKey):
                items.append((k, self._to_hashable(v)))
            return tuple(items)
        else:
            return obj

    def _find_all(self, ast, label, max_results=sys.maxsize):
        """Searches the AST for tuples with a given label. The PegParser
    output is composed of lists and tuples, where the tuple 1st argument
    is a label. If ast root is a list, will search recursively inside each
    member in the list.

    Args:
      ast -- the AST to search.
      label -- the label to look for.
      res -- results are put into this list.
      max_results -- maximum number of results.
    """
        res = []
        if max_results <= 0:
            return res

        if isinstance(ast, list):
            for childAst in ast:
                if childAst and \
                   not(isinstance(childAst, dict)) and \
                   not(isinstance(childAst, str)) and \
                   not(isinstance(childAst, tuple)) and \
                   childAst.__module__ == "idl_definitions":
                    field_name = self._convert_label_to_field(label)
                    if hasattr(childAst, field_name):
                        field_value = getattr(childAst, field_name)
                        # It's an IdlType we need the string name of the type.
                        if field_name == 'idl_type':
                            field_value = getattr(field_value, 'base_type')
                        res.append(field_value)
                else:
                    sub_res = self._find_all(childAst, label,
                                             max_results - len(res))
                    res.extend(sub_res)
        elif isinstance(ast, tuple):
            (nodeLabel, value) = ast
            if nodeLabel == label:
                res.append(value)
        # TODO(terry): Seems bogus to check for so many things probably better to just
        #              pass in blink_compile and drive it off from that...
        elif (ast and not (isinstance(ast, dict)) and
              not (isinstance(ast, str)) and
              (ast.__module__ == "idl_definitions" or
               ast.__module__ == "idl_types")):
            field_name = self._convert_label_to_field(label)
            if hasattr(ast, field_name):
                field_value = getattr(ast, field_name)
                if field_value:
                    if label == 'Interface' or label == 'Enum' or label == "Dictionary":
                        for key in field_value:
                            value = field_value[key]
                            res.append(value)
                    elif isinstance(field_value, list):
                        for item in field_value:
                            res.append(item)
                    elif label == 'ParentInterface' or label == 'InterfaceType':
                        # Fetch the AST for the parent interface.
                        parent_idlnode = new_asts[field_value]
                        res.append(parent_idlnode.interfaces[field_value])
                    else:
                        res.append(field_value)

        return res

    def _find_first(self, ast, label):
        """Convenience method for _find_all(..., max_results=1).
    Returns a single element instead of a list, or None if nothing
    is found."""
        res = self._find_all(ast, label, max_results=1)
        if len(res):
            return res[0]
        return None

    def _has(self, ast, label):
        """Returns true if an element with the given label is
    in the AST by searching for it."""
        return len(self._find_all(ast, label, max_results=1)) == 1

    # Mapping from original AST tuple names to new AST field names idl_definitions.Idl*.
    def _convert_label_to_field(self, label):
        label_field = {
            # Keys old AST names, Values Blink IdlInterface names.
            'ParentInterface': 'parent',
            'Id': 'name',
            'Interface': 'interfaces',
            'Callback_Function': 'callback_functions',
            'Callback': 'is_callback',
            'Partial': 'is_partial',
            'Operation': 'operations',
            'Attribute': 'attributes',
            'Const': 'constants',
            'Type': 'idl_type',
            'ExtAttrs': 'extended_attributes',
            'Special': 'specials',
            'ReturnType': 'idl_type',
            'Argument': 'arguments',
            'InterfaceType': 'name',
            'ConstExpr': 'value',
            'Static': 'is_static',
            'ReadOnly': 'is_read_only',
            'Optional': 'is_optional',
            'Nullable': 'is_nullable',
            'Enum': 'enumerations',
            'Annotation':
            '',  # TODO(terry): Ignore annotation used for database cache.
            'TypeDef': '',  # typedef in an IDL are already resolved.
            'Dictionary': 'dictionaries',
            'Member': 'members',
            'Default': 'default_value',  # Dictionary member default value
        }
        result = label_field.get(label)
        if result != '' and not (result):
            print('FATAL ERROR: AST mapping name not found %s.' % label)
        return result if result else ''

    def _convert_all(self, ast, label, idlnode_ctor):
        """Converts AST elements into IDLNode elements.
    Uses _find_all to find elements with a given label and converts
    them into IDLNodes with a given constructor.
    Returns:
      A list of the converted nodes.
    Args:
      ast -- the ast element to start a search at.
      label -- the element label to look for.
      idlnode_ctor -- a constructor function of one of the IDLNode
        sub-classes.
    """
        res = []
        found = self._find_all(ast, label)
        if not found:
            return res
        if not isinstance(found, list):
            raise RuntimeError("Expected list but %s found" % type(found))
        for childAst in found:
            converted = idlnode_ctor(childAst)
            res.append(converted)
        return res

    def _convert_first(self, ast, label, idlnode_ctor):
        """Like _convert_all, but only converts the first found results."""
        childAst = self._find_first(ast, label)
        if not childAst:
            return None
        return idlnode_ctor(childAst)

    def _convert_ext_attrs(self, ast):
        """Helper method for uniform conversion of extended attributes."""
        self.ext_attrs = IDLExtAttrs(ast)

    def _convert_annotations(self, ast):
        """Helper method for uniform conversion of annotations."""
        self.annotations = IDLAnnotations(ast)

    def _convert_constants(self, ast, js_name):
        """Helper method for uniform conversion of dictionary members."""
        self.members = IDLDictionaryMembers(ast, js_name)


class IDLDictNode(IDLNode):
    """Base class for dictionary-like IDL nodes such as extended attributes
  and annotations. The base class implements various dict interfaces."""

    def __init__(self, ast):
        IDLNode.__init__(self, None)
        if ast is not None and isinstance(ast, dict):
            self.__map = ast
        else:
            self.__map = {}

    def __len__(self):
        return len(self.__map)

    def __getitem__(self, key):
        return self.__map[key]

    def __setitem__(self, key, value):
        self.__map[key] = value

    def __delitem__(self, key):
        del self.__map[key]

    def __contains__(self, key):
        return key in self.__map

    def __iter__(self):
        return self.__map.__iter__()

    def get(self, key, default=None):
        return self.__map.get(key, default)

    def setdefault(self, key, value=None):
        return self.__map.setdefault(key, value)

    def items(self):
        return self.__map.items()

    def keys(self):
        return self.__map.keys()

    def values(self):
        return self.__map.values()

    def clear(self):
        self.__map = {}

    def to_dict(self):
        """Overrides the default IDLNode.to_dict behavior.
    The IDLDictNode members are copied into a new dictionary, and
    IDLNode members are recursively converted into dicts as well.
    """
        res = {}
        for (k, v) in self.__map.items():
            if isinstance(v, IDLNode):
                v = v.to_dict()
            res[k] = v
        return res

    def _all_subnodes(self):
        # Usually an IDLDictNode does not contain further IDLNodes.
        return []


class IDLFile(IDLNode):
    """IDLFile is the top-level node in each IDL file. It may contain interfaces."""

    DART_IDL = 'dart.idl'

    def __init__(self, ast, filename=None):
        IDLNode.__init__(self, ast)
        self.filename = filename

        filename_basename = os.path.basename(filename)

        # Report of union types mapped to any.

        # Remember all the typedefs before we start walking the AST.  Some
        # IDLs now have typedefs before interfaces.  So we need to remember
        # to resolve the typedefs.
        self.typeDefs = self._convert_all(ast, 'TypeDef', IDLTypeDef)
        for typedefName in ast.typedefs:
            typedef_type = ast.typedefs[typedefName]
            # Ignore unions and dictionaries for now we just want normal typedefs to resolve our arguments/types.
            if not (isinstance(typedef_type.idl_type, IdlUnionType)) and not (
                    typedef_type.idl_type.base_type == 'Dictionary'):
                _addTypedef(IDLTypeDef(typedef_type))

        self.interfaces = self._convert_all(ast, 'Interface', IDLInterface)
        self.dictionaries = self._convert_all(ast, 'Dictionary', IDLDictionary)

        if len(ast.callback_functions) > 0:
            callback_functions = self._convert_all(ast, 'Callback_Function',
                                                   IDLCallbackFunction)
            for callback_function in callback_functions:
                for annotation in callback_function.annotations:
                    callback = callback_function.annotations[annotation]
                    cb_interface = IDLInterface(None, callback.name)
                    cb_interface.ext_attrs['Callback'] = len(callback.arguments)
                    op = IDLOperation(None, cb_interface.id, "handleEvent")
                    op.type = IDLType(callback.idl_type)
                    op.type = resolveTypedef(op.type)

                    if len(callback.arguments) > 0:
                        op.arguments = self._convert_all(
                            callback, 'Argument', IDLArgument)

                    cb_interface.operations = [op]
                    self.interfaces.append(cb_interface)

        is_blink = not (isinstance(
            ast, list)) and ast.__module__ == 'idl_definitions'

        if is_blink:
            # implements is handled by the interface merging step (see the function
            # merge_interface_dependencies).
            for interface in self.interfaces:
                blink_interface = ast.interfaces.get(interface.id)
                if filename_basename == self.DART_IDL:
                    # Special handling for dart.idl we need to remember the interface,
                    # since we could have many (not one interface / file). Then build up
                    # the IDLImplementsStatement for any implements in dart.idl.
                    interface_info = dependency.get_interfaces_info(
                    )['__dart_idl___']

                    self.implementsStatements = []

                    implement_pairs = interface_info['implement_pairs']
                    for implement_pair in implement_pairs:
                        interface_name = implement_pair[0]
                        implemented_name = implement_pair[1]

                        implementor = new_asts[interface_name].interfaces.get(
                            interface_name)
                        implement_statement = self._createImplementsStatement(
                            implementor, implemented_name)

                        self.implementsStatements.append(implement_statement)
                elif interface.id in dependency.get_interfaces_info():
                    interface_info = dependency.get_interfaces_info()[interface.
                                                                      id]

                    implements = []
                    if 'implements_interfaces' in interface_info:
                        implements = interface_info['implements_interfaces']
                    if not (blink_interface.is_partial) and len(implements) > 0:
                        implementor = new_asts[interface.id].interfaces.get(
                            interface.id)

                        self.implementsStatements = []

                        # TODO(terry): Need to handle more than one implements.
                        for implemented_name in implements:
                            implement_statement = self._createImplementsStatement(
                                implementor, implemented_name)
                            self.implementsStatements.append(
                                implement_statement)
                    else:
                        self.implementsStatements = []
        else:
            self.implementsStatements = self._convert_all(
                ast, 'ImplStmt', IDLImplementsStatement)

        # Record typedefs that are unions.
        for typedefName in ast.typedefs:
            typedef_type = ast.typedefs[typedefName]
            if isinstance(typedef_type.idl_type, IdlUnionType):
                self.typeDefs.append(IDLTypeDef(typedef_type))
            elif typedef_type.idl_type.base_type == 'Dictionary':
                dictionary = IDLDictionary(typedef_type, True)
                self.dictionaries.append(dictionary)

        self.enums = self._convert_all(ast, 'Enum', IDLEnum)

    def _createImplementsStatement(self, implementor, implemented_name):
        implemented = new_asts[implemented_name].interfaces.get(
            implemented_name)

        implement_statement = IDLImplementsStatement(implemented)

        implement_statement.implementor = IDLType(implementor)
        implement_statement.implemented = IDLType(implemented)

        return implement_statement


class IDLModule(IDLNode):
    """IDLModule has an id, and may contain interfaces, type defs and
  implements statements."""

    def __init__(self, ast):
        IDLNode.__init__(self, ast)
        self._convert_ext_attrs(ast)
        self._convert_annotations(ast)
        self.interfaces = self._convert_all(ast, 'Interface', IDLInterface)

        is_blink = ast.__module__ == 'idl_definitions'

        # No reason to handle typedef they're already aliased in Blink's AST.
        self.typeDefs = [] if is_blink else self._convert_all(
            ast, 'TypeDef', IDLTypeDef)

        self.enums = self._convert_all(ast, 'Enum', IDLNode)

        if is_blink:
            # implements is handled by the interface merging step (see the function
            # merge_interface_dependencies).
            for interface in self.interfaces:
                interface_info = get_interfaces_info()[interface.id]
                # TODO(terry): Same handling for implementsStatements as in IDLFile?
                self.implementsStatements = interface_info[
                    'implements_interfaces']
        else:
            self.implementsStatements = self._convert_all(
                ast, 'ImplStmt', IDLImplementsStatement)


class IDLExtAttrs(IDLDictNode):
    """IDLExtAttrs is an IDLDictNode that stores IDL Extended Attributes.
  Modules, interfaces, members and arguments can all own IDLExtAttrs."""

    def __init__(self, ast=None):
        IDLDictNode.__init__(self, None)
        if not ast:
            return
        if not (isinstance(ast, list)) and ast.__module__ == "idl_definitions":
            # Pull out extended attributes from Blink AST.
            for name, value in ast.extended_attributes.items():
                # TODO(terry): Handle constructors...
                if name == 'NamedConstructor' or name == 'Constructor':
                    for constructor in ast.constructors:
                        if constructor.name == 'NamedConstructor':
                            constructor_name = ast.extended_attributes[
                                'NamedConstructor']
                        else:
                            constructor_name = None
                        func_value = IDLExtAttrFunctionValue(
                            constructor_name, constructor.arguments, True)
                        if name == 'Constructor':
                            self.setdefault('Constructor',
                                            []).append(func_value)
                        else:
                            self[name] = func_value
                elif name == 'SetWrapperReferenceTo':
                    # NOTE: No need to process handling for GC wrapper.  But if its a reference
                    # to another type via an IdlArgument we'd need to convert to IDLArgument
                    # otherwise the type might be a reference to another type and the circularity
                    # will break deep_copy which is done later to the interfaces in the
                    # database.  If we every need SetWrapperReferenceTo then we'd need to
                    # convert IdlArgument to IDLArgument.
                    continue
                else:
                    self[name] = value
        else:
            ext_attrs_ast = self._find_first(ast, 'ExtAttrs')
            if not ext_attrs_ast:
                return
            for ext_attr in self._find_all(ext_attrs_ast, 'ExtAttr'):
                name = self._find_first(ext_attr, 'Id')
                value = self._find_first(ext_attr, 'ExtAttrValue')

                if name == 'Constructor':
                    # There might be multiple constructor attributes, collect them
                    # as a list.  Represent plain Constructor attribute
                    # (without any signature) as None.
                    assert value is None
                    func_value = None
                    ctor_args = self._find_first(ext_attr, 'ExtAttrArgList')
                    if ctor_args:
                        func_value = IDLExtAttrFunctionValue(None, ctor_args)
                    self.setdefault('Constructor', []).append(func_value)
                    continue

                func_value = self._find_first(value, 'ExtAttrFunctionValue')
                if func_value:
                    # E.g. NamedConstructor=Audio(optional DOMString src)
                    self[name] = IDLExtAttrFunctionValue(
                        func_value,
                        self._find_first(func_value, 'ExtAttrArgList'))
                    continue

                self[name] = value

    def _all_subnodes(self):
        # Extended attributes may contain IDLNodes, e.g. IDLExtAttrFunctionValue
        return self.values()


# IDLExtAttrFunctionValue is used for constructors defined in the IDL.
class IDLExtAttrFunctionValue(IDLNode):
    """IDLExtAttrFunctionValue."""

    def __init__(self, func_value_ast, arg_list_ast, is_blink=False):
        IDLNode.__init__(self, func_value_ast)
        if is_blink:
            # Blink path
            self.id = func_value_ast  # func_value_ast is the function name for Blink.
            self.arguments = []
            for argument in arg_list_ast:
                self.arguments.append(IDLArgument(argument))
        else:
            self.arguments = self._convert_all(arg_list_ast, 'Argument',
                                               IDLArgument)


class IDLType(IDLNode):
    """IDLType is used to describe constants, attributes and operations'
  return and input types. IDLType matches AST labels such as ScopedName,
  StringType, VoidType, IntegerType, etc.
  NOTE: AST of None implies synthesize IDLType the id is passed in used by
        setlike."""

    def __init__(self, ast, id=None):
        global _unions_to_any

        IDLNode.__init__(self, ast, id)

        if not ast:
            # Support synthesized IDLType with no AST (e.g., setlike support).
            return

        self.nullable = self._has(ast, 'Nullable')
        # Search for a 'ScopedName' or any label ending with 'Type'.
        if isinstance(ast, list):
            self.id = self._find_first(ast, 'ScopedName')
            if not self.id:
                # FIXME: use regexp search instead
                def findType(ast):
                    for label, childAst in ast:
                        if label.endswith('Type'):
                            type = self._label_to_type(label, ast)
                            if type != 'sequence':
                                return type
                            type_ast = self._find_first(childAst, 'Type')
                            if not type_ast:
                                return type
                            return 'sequence<%s>' % findType(type_ast)
                    raise Exception('No type declaration found in %s' % ast)

                self.id = findType(ast)
            # TODO(terry): Remove array_modifiers id has [] appended, keep for old
            #              parsing.
            array_modifiers = self._find_first(ast, 'ArrayModifiers')
            if array_modifiers:
                self.id += array_modifiers
        elif isinstance(ast, tuple):
            (label, value) = ast
            if label == 'ScopedName':
                self.id = value
            else:
                self.id = self._label_to_type(label, ast)
        elif isinstance(ast, str):
            self.id = ast
        # New blink handling.
        elif ast.__module__ == "idl_types":
            if isinstance(ast, IdlType) or isinstance(ast, IdlArrayOrSequenceType) or \
               isinstance(ast, IdlNullableType):
                if isinstance(ast,
                              IdlNullableType) and ast.inner_type.is_union_type:
                    # Report of union types mapped to any.
                    if not (self.id in _unions_to_any):
                        _unions_to_any.append(self.id)
                    # TODO(terry): For union types use any otherwise type is unionType is
                    #              not found and is removed during merging.
                    self.id = 'any'
                else:
                    type_name = str(ast)
                    # TODO(terry): For now don't handle unrestricted types see
                    #              https://code.google.com/p/chromium/issues/detail?id=354298
                    type_name = type_name.replace('unrestricted ', '', 1)

                    # TODO(terry): Handled USVString as a DOMString.
                    type_name = type_name.replace('USVString', 'DOMString', 1)
                    type_name = type_name.replace('HTMLString', 'DOMString', 1)

                    # TODO(terry); WindowTimers setInterval/setTimeout overloads with a
                    #              Function type - map to any until the IDL uses union.
                    type_name = type_name.replace('Function', 'any', 1)

                    self.id = type_name
            else:
                # IdlUnionType
                if ast.is_union_type:
                    if not (self.id in _unions_to_any):
                        _unions_to_any.append(self.id)
                    # TODO(terry): For union types use any otherwise type is unionType is
                    #              not found and is removed during merging.
                    self.id = 'any'
                    # TODO(terry): Any union type e.g. 'type1 or type2 or type2',
                    #                            'typedef (Type1 or Type2) UnionType'
                    # Is a problem we need to extend IDLType and IDLTypeDef to handle more
                    # than one type.
                    #
                    # Also for typedef's e.g.,
                    #                 typedef (Type1 or Type2) UnionType
                    # should consider synthesizing a new interface (e.g., UnionType) that's
                    # both Type1 and Type2.
        if not self.id:
            print('>>>> __module__ %s' % ast.__module__)
            raise SyntaxError('Could not parse type %s' % (ast))

    def _label_to_type(self, label, ast):
        if label == 'LongLongType':
            label = 'long long'
        elif label.endswith('Type'):
            # Omit 'Type' suffix and lowercase the rest.
            label = '%s%s' % (label[0].lower(), label[1:-4])

        # Add unsigned qualifier.
        if self._has(ast, 'Unsigned'):
            label = 'unsigned %s' % label
        return label


class IDLEnum(IDLNode):
    """IDLNode for 'enum [id] { [string]+ }'"""

    def __init__(self, ast):
        IDLNode.__init__(self, ast)
        self._convert_annotations(ast)
        if not (isinstance(ast, list)) and ast.__module__ == "idl_definitions":
            # Blink AST
            self.values = ast.values
        else:
            self.values = self._find_all(ast, 'StringLiteral')

        # TODO(terry): Need to handle emitting of enums for dart:html


class IDLCallbackFunction(IDLNode):
    """IDLNode for 'callback [type] [id]' declarations."""

    def __init__(self, ast):
        IDLNode.__init__(self, ast)
        self._convert_annotations(ast)
        self.type = self._convert_first(ast, 'Type', IDLType)


class IDLTypeDef(IDLNode):
    """IDLNode for 'typedef [type] [id]' declarations."""

    def __init__(self, ast):
        IDLNode.__init__(self, ast)
        self._convert_annotations(ast)
        self.type = self._convert_first(ast, 'Type', IDLType)


class IDLDictionary(IDLNode):
    """IDLDictionary node contains members,
  as well as parent references."""

    def __init__(self, ast, typedefDictionary=False):
        IDLNode.__init__(self, ast)

        self.javascript_binding_name = self.id
        if (typedefDictionary):
            # Dictionary is a typedef to a union.
            self._convert_ext_attrs(None)
        else:
            self._convert_ext_attrs(ast)
            self._convert_constants(ast, self.id)


class IDLDictionaryMembers(IDLDictNode):
    """IDLDictionaryMembers specialization for a list of FremontCut dictionary values."""

    def __init__(self, ast=None, js_name=None):
        IDLDictNode.__init__(self, ast)
        self.id = None
        if not ast:
            return
        for member in self._find_all(ast, 'Member'):
            name = self._find_first(member, 'Id')
            value = IDLDictionaryMember(member, js_name)
            self[name] = value


def generate_callback(interface_name, result_type, arguments):
    syn_op = IDLOperation(None, interface_name, 'callback')

    syn_op.type = resolveTypedef(result_type)
    syn_op.arguments = arguments

    return syn_op


def generate_operation(interface_name,
                       result_type_name,
                       oper_name,
                       arguments,
                       result_nullable=False):
    """ Synthesize an IDLOperation with no AST used for support of setlike."""
    """ Arguments is a list of argument where each argument is:
          [IDLType, argument_name, optional_boolean] """

    syn_op = IDLOperation(None, interface_name, oper_name)

    syn_op.type = IDLType(None, result_type_name)
    syn_op.type = resolveTypedef(syn_op.type)
    syn_op.type.nullable = result_nullable

    for argument in arguments:
        arg = IDLArgument(None, argument[1])
        arg.type = argument[0]
        arg.optional = argument[2] if len(argument) > 2 else False
        syn_op.arguments.append(arg)

    return syn_op


def generate_setLike_operations_properties(interface, set_like):
    """
  Need to create (in our database) a number of operations.  This is a new IDL
  syntax, the implied operations for a set now use setlike<T> where T is a known
  type e.g., setlike<FontFace> setlike implies these operations are generated:

       void forEach(any callback, optional any thisArg);
       boolean has(FontFace fontFace);
       boolean has(FontFace fontFace);

  if setlike is not read-only these operations are generated:

           FontFaceSet add(FontFace value);
           boolean delete(FontFace value);
           void clear();
  """
    setlike_ops = []
    """
  Need to create a typedef for a function callback e.g.,
  a setlike will need a callback that has the proper args in FontFaceSet that is
  three arguments, etc.

      typedef void FontFaceSetForEachCallback(
        FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);

      void forEach(FontFaceSetForEachCallback callback, [Object thisArg]);
  """
    callback_name = '%sForEachCallback' % interface.id
    set_op = generate_operation(interface.id, 'void', 'forEach',
                                [[IDLType(None, callback_name), 'callback'],
                                 [IDLType(None, 'any'), 'thisArg', True]])
    setlike_ops.append(set_op)

    set_op = generate_operation(
        interface.id, 'boolean', 'has',
        [[IDLType(None, set_like.value_type.base_type), 'arg']])
    setlike_ops.append(set_op)

    if not set_like.is_read_only:
        # Issue #45676: `add` can return null on Firefox, so this should be
        # typed nullable.
        add_result_nullable = True
        set_op = generate_operation(
            interface.id, interface.id, 'add',
            [[IDLType(None, set_like.value_type.base_type), 'arg']],
            add_result_nullable)
        setlike_ops.append(set_op)
        set_op = generate_operation(
            interface.id, 'boolean', 'delete',
            [[IDLType(None, set_like.value_type.base_type), 'arg']])
        setlike_ops.append(set_op)
        set_op = generate_operation(interface.id, 'void', 'clear', [])
        setlike_ops.append(set_op)

    return setlike_ops


class IDLInterface(IDLNode):
    """IDLInterface node contains operations, attributes, constants,
  as well as parent references."""

    def __init__(self, ast, id=None):
        IDLNode.__init__(self, ast)

        if id:
            self.id = id

        self._convert_ext_attrs(ast)
        self._convert_annotations(ast)

        self.parents = self._convert_all(ast, 'ParentInterface',
                                         IDLParentInterface)

        javascript_interface_name = self.ext_attrs.get('InterfaceName', self.id)
        self.javascript_binding_name = javascript_interface_name
        self.doc_js_name = javascript_interface_name

        if not (self._find_first(ast, 'Callback') is None):
            self.ext_attrs['Callback'] = None
        if not (self._find_first(ast, 'Partial') is None):
            self.is_supplemental = True
            self.ext_attrs['DartSupplemental'] = None
        self.isMaplike = False
        self.isMaplike_ro = False
        self.maplike_key_value = [None, None]
        if ast is not None and ast.maplike is not None:
            self.isMaplike = True
            self.isMaplike_ro = ast.maplike.is_read_only
            self.maplike_key_value = [
                IDLType(ast.maplike.key_type),
                IDLType(ast.maplike.value_type)
            ]

        self.operations = self._convert_all(
            ast, 'Operation', lambda ast: IDLOperation(ast, self.doc_js_name))

        if not (id) and ast.setlike:
            setlike_ops = generate_setLike_operations_properties(
                self, ast.setlike)
            for op in setlike_ops:
                self.operations.append(op)

        self.attributes = self._convert_all(
            ast, 'Attribute', lambda ast: IDLAttribute(ast, self.doc_js_name))
        self.constants = self._convert_all(
            ast, 'Const', lambda ast: IDLConstant(ast, self.doc_js_name))
        self.is_supplemental = 'DartSupplemental' in self.ext_attrs
        self.is_no_interface_object = 'NoInterfaceObject' in self.ext_attrs
        # TODO(terry): Can eliminate Suppressed when we're only using blink parser.
        self.is_fc_suppressed = 'Suppressed' in self.ext_attrs or \
                                'DartSuppress' in self.ext_attrs

    def reset_id(self, new_id):
        """Reset the id of the Interface and corresponding the JS names."""
        if self.id != new_id:
            self.id = new_id
            self.doc_js_name = new_id
            self.javascript_binding_name = new_id
            for member in self.operations:
                member.doc_js_interface_name = new_id
            for member in self.attributes:
                member.doc_js_interface_name = new_id
            for member in self.constants:
                member.doc_js_interface_name = new_id

    def has_attribute(self, candidate):
        for attribute in self.attributes:
            if (attribute.id == candidate.id and
                    attribute.is_read_only == candidate.is_read_only):
                return True
        return False


class IDLParentInterface(IDLNode):
    """This IDLNode specialization is for 'Interface Child : Parent {}'
  declarations."""

    def __init__(self, ast):
        IDLNode.__init__(self, ast)
        self._convert_annotations(ast)
        self.type = self._convert_first(ast, 'InterfaceType', IDLType)


class IDLMember(IDLNode):
    """A base class for constants, attributes and operations."""

    def __init__(self, ast, doc_js_interface_name, member_id=None):
        if ast:
            IDLNode.__init__(self, ast)
        else:
            # The ast is None to support synthesizing an IDLMember, member_id is only
            # used when ast is None.
            IDLNode.__init__(self, ast, member_id)
            self.type = None
            self.doc_js_interface_name = doc_js_interface_name
            return

        self.type = self._convert_first(ast, 'Type', IDLType)
        self.type = resolveTypedef(self.type)

        self._convert_ext_attrs(ast)
        self._convert_annotations(ast)
        self.doc_js_interface_name = doc_js_interface_name
        # TODO(terry): Can eliminate Suppressed when we're only using blink parser.
        self.is_fc_suppressed = 'Suppressed' in self.ext_attrs or \
                                'DartSuppress' in self.ext_attrs
        self.is_static = self._has(ast, 'Static')


class IDLOperation(IDLMember):
    """IDLNode specialization for 'type name(args)' declarations."""

    def __init__(self, ast, doc_js_interface_name, id=None):
        IDLMember.__init__(self, ast, doc_js_interface_name, id)

        if not ast:
            # Synthesize an IDLOperation with no ast used for setlike.
            self.ext_attrs = IDLExtAttrs()
            self.annotations = IDLAnnotations()
            self.is_fc_suppressed = False
            self.specials = []
            self.is_static = False
            self.arguments = []
            return

        self.type = self._convert_first(ast, 'ReturnType', IDLType)
        self.type = resolveTypedef(self.type)

        self.arguments = self._convert_all(ast, 'Argument', IDLArgument)
        self.specials = self._find_all(ast, 'Special')
        # Special case: there are getters of the form
        # getter <ReturnType>(args).  For now force the name to be __getter__,
        # but it should be operator[] later.
        if self.id is None:
            if self.specials == ['getter']:
                if self.ext_attrs.get('Custom') == 'PropertyQuery':
                    # Handling __propertyQuery__ the extended attribute is:
                    # [Custom=PropertyQuery] getter boolean (DOMString name);
                    self.id = '__propertyQuery__'
                elif self.ext_attrs.get('ImplementedAs'):
                    self.id = self.ext_attrs.get('ImplementedAs')
                else:
                    self.id = '__getter__'
            elif self.specials == ['setter']:
                self.id = '__setter__'
                # Special case: if it's a setter, ignore 'declared' return type
                self.type = IDLType([('VoidType', None)])
            elif self.specials == ['deleter']:
                self.id = '__delete__'
            else:
                raise Exception('Cannot handle %s: operation has no id' % ast)

            if len(self.arguments) >= 1 and (
                    self.id in _operation_suffix_map
            ) and not self.ext_attrs.get('ImplementedAs'):
                arg = self.arguments[0]
                operation_category = 'Named' if arg.type.id == 'DOMString' else 'Indexed'
                self.ext_attrs.setdefault(
                    'ImplementedAs', 'anonymous%s%s' %
                    (operation_category, _operation_suffix_map[self.id]))

    def __repr__(self):
        return '<IDLOperation(id = %s)>' % (self.id)

    def _extra_repr(self):
        return [self.arguments]

    def SameSignatureAs(self, operation):
        if self.type != operation.type:
            return False
        return [a.type for a in self.arguments] == [
            a.type for a in operation.arguments
        ]

class IDLAttribute(IDLMember):
    """IDLNode specialization for 'attribute type name' declarations."""

    def __init__(self, ast, doc_js_interface_name):
        IDLMember.__init__(self, ast, doc_js_interface_name)
        self.is_read_only = self._has(ast, 'ReadOnly')
        # There are various ways to define exceptions for attributes:

    def _extra_repr(self):
        extra = []
        if self.is_read_only: extra.append('readonly')
        return extra


class IDLConstant(IDLMember):
    """IDLNode specialization for 'const type name = value' declarations."""

    def __init__(self, ast, doc_js_interface_name):
        IDLMember.__init__(self, ast, doc_js_interface_name)
        self.value = self._find_first(ast, 'ConstExpr')


class IDLArgument(IDLNode):
    """IDLNode specialization for operation arguments."""

    def __init__(self, ast, id=None):
        if ast:
            IDLNode.__init__(self, ast)
        else:
            # Synthesize an IDLArgument with no ast used for setlike.
            IDLNode.__init__(self, ast, id)
            self.ext_attrs = IDLExtAttrs()
            self.default_value = None
            self.default_value_is_null = False
            return

        self.default_value = None
        self.default_value_is_null = False
        # Handle the 'argType arg = default'. IDL syntax changed from
        # [default=NullString].
        if not isinstance(ast, list):
            if isinstance(ast.default_value,
                          idl_definitions.IdlLiteral) and ast.default_value:
                self.default_value = ast.default_value.value
                self.default_value_is_null = ast.default_value.is_null
            elif 'Default' in ast.extended_attributes:
                # Work around [Default=Undefined] for arguments - only look in the model's
                # default_value
                self.default_value = ast.extended_attributes.get('Default')
                self.default_value_is_null = False

        self.type = self._convert_first(ast, 'Type', IDLType)
        self.type = resolveTypedef(self.type)

        self.optional = self._has(ast, 'Optional')
        self._convert_ext_attrs(ast)
        # TODO(vsm): Recover this from the type instead.
        if 'Callback' in self.type.id:
            self.ext_attrs['Callback'] = None

    def __repr__(self):
        return '<IDLArgument(type = %s, id = %s)>' % (self.type, self.id)


class IDLDictionaryMember(IDLMember):
    """IDLNode specialization for 'const type name = value' declarations."""

    def __init__(self, ast, doc_js_interface_name):
        IDLMember.__init__(self, ast, doc_js_interface_name)
        default_value = self._find_first(ast, 'Default')
        self.value = default_value.value if default_value else None


class IDLImplementsStatement(IDLNode):
    """IDLNode specialization for 'IMPLEMENTOR implements IMPLEMENTED' declarations."""

    def __init__(self, ast):
        IDLNode.__init__(self, ast)
        if isinstance(ast, list) or ast.__module__ != 'idl_definitions':
            self.implementor = self._convert_first(ast, 'ImplStmtImplementor',
                                                   IDLType)
            self.implemented = self._convert_first(ast, 'ImplStmtImplemented',
                                                   IDLType)


class IDLAnnotations(IDLDictNode):
    """IDLDictNode specialization for a list of FremontCut annotations."""

    def __init__(self, ast=None):
        IDLDictNode.__init__(self, ast)
        self.id = None
        if not ast:
            return
        for annotation in self._find_all(ast, 'Annotation'):
            name = self._find_first(annotation, 'Id')
            value = IDLAnnotation(annotation)
            self[name] = value


class IDLAnnotation(IDLDictNode):
    """IDLDictNode specialization for one annotation."""

    def __init__(self, ast=None):
        IDLDictNode.__init__(self, ast)
        self.id = None
        if not ast:
            return
        for arg in self._find_all(ast, 'AnnotationArg'):
            name = self._find_first(arg, 'Id')
            value = self._find_first(arg, 'AnnotationArgValue')
            self[name] = value
