#!/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'] = None
          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.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
