#!/usr/bin/python
# 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 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, e:
            return "can't convert to string: %s" % e

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

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

    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 _find_all(self, ast, label, max_results=sys.maxint):
        """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 = interface_info[
                        'implements_interfaces'] if interface_info.has_key(
                            'implements_interfaces') else []
                    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):
    """ 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)

    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:
        set_op = generate_operation(
            interface.id, interface.id, 'add',
            [[IDLType(None, set_like.value_type.base_type), 'arg']])
        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
