#!/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
