#!/usr/bin/python
# Copyright (c) 2012, 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.

"""This module provides shared functionality for systems to generate
Dart APIs from the IDL database."""

import copy
import json
import monitored
import os
import re
from htmlrenamer import custom_html_constructors, html_interface_renames, \
    typed_array_renames

_pure_interfaces = monitored.Set('generator._pure_interfaces', [
    # TODO(sra): DOMStringMap should be a class implementing Map<String,String>.
    'DOMStringMap',
    'ChildNode',
    'EventListener',
    'MediaQueryListListener',
    'MutationCallback',
    'NavigatorID',
    'NavigatorOnLine',
    'ParentNode',
    'SVGExternalResourcesRequired',
    'SVGFilterPrimitiveStandardAttributes',
    'SVGFitToViewBox',
    'SVGTests',
    'SVGURIReference',
    'SVGZoomAndPan',
    'TimeoutHandler',
    'WindowBase64',
    'WindowTimers',
    ])

def IsPureInterface(interface_name):
  return interface_name in _pure_interfaces

#
# Classes which have native constructors but which we are suppressing because
# they are not cross-platform.
#
_suppressed_native_constructors = monitored.Set(
    'generator._suppressed_native_constructors', [
  'DocumentFragment',
  'Range',
  'Text',
  ])

_custom_types = monitored.Set('generator._custom_types',
                              typed_array_renames.keys())

def IsCustomType(interface_name):
  return interface_name in _custom_types

_methods_with_named_formals = monitored.Set(
    'generator._methods_with_named_formals', [
  'DirectoryEntry.getDirectory',
  'DirectoryEntry.getFile',
  'Entry.copyTo',
  'Entry.moveTo',
  'HTMLInputElement.setRangeText',
  'HTMLTextAreaElement.setRangeText',
  'XMLHttpRequest.open',
  ])

#
# Renames for attributes that have names that are not legal Dart names.
#
_dart_attribute_renames = monitored.Dict('generator._dart_attribute_renames', {
    'default': 'defaultValue',
})

#
# Interface version of the DOM needs to delegate typed array constructors to a
# factory provider.
#
interface_factories = monitored.Dict('generator.interface_factories', {
})


#
# Custom native specs for the dart2js dom.
#
_dart2js_dom_custom_native_specs = monitored.Dict(
      'generator._dart2js_dom_custom_native_specs', {

    # Nodes with different tags in different browsers can be listed as multiple
    # tags here provided there is not conflict in usage (e.g. browser X has tag
    # T and no other browser has tag T).

    'AnalyserNode': 'AnalyserNode,RealtimeAnalyserNode',
    'AudioContext': 'AudioContext,webkitAudioContext',

    'ChannelMergerNode': 'ChannelMergerNode,AudioChannelMerger',
    'ChannelSplitterNode': 'ChannelSplitterNode,AudioChannelSplitter',

    'CSSStyleDeclaration':
        #                    IE                   Firefox
        'CSSStyleDeclaration,MSStyleCSSProperties,CSS2Properties',

    'ApplicationCache':
        'ApplicationCache,DOMApplicationCache,OfflineResourceList',

    'HTMLTableCellElement':
        'HTMLTableCellElement,HTMLTableDataCellElement,HTMLTableHeaderCellElement',

    'GainNode': 'GainNode,AudioGainNode',

    'IDBOpenDBRequest':
        'IDBOpenDBRequest,IDBVersionChangeRequest',

    'MouseEvent': 'MouseEvent,DragEvent,PointerEvent,MSPointerEvent',

    'MutationObserver': 'MutationObserver,WebKitMutationObserver',

    'NamedNodeMap': 'NamedNodeMap,MozNamedAttrMap',

    'NodeList': 'NodeList,RadioNodeList',

    'OscillatorNode': 'OscillatorNode,Oscillator',

    'PannerNode': 'PannerNode,AudioPannerNode',

    'RTCPeerConnection': 'RTCPeerConnection,mozRTCPeerConnection',

    'RTCIceCandidate': 'RTCIceCandidate,mozRTCIceCandidate',

    'RTCSessionDescription': 'RTCSessionDescription,mozRTCSessionDescription',

    'RTCDataChannel': 'RTCDataChannel,DataChannel',

    'ScriptProcessorNode': 'ScriptProcessorNode,JavaScriptAudioNode',

    'TransitionEvent': 'TransitionEvent,WebKitTransitionEvent',

    'WebGLLoseContext': 'WebGLLoseContext,WebGLExtensionLoseContext',

    'CSSKeyframeRule':
        'CSSKeyframeRule,MozCSSKeyframeRule,WebKitCSSKeyframeRule',

    'CSSKeyframesRule':
        'CSSKeyframesRule,MozCSSKeyframesRule,WebKitCSSKeyframesRule',

    'WheelEvent': 'WheelEvent,MouseWheelEvent,MouseScrollEvent',

    'XMLHttpRequestUpload': 'XMLHttpRequestUpload,XMLHttpRequestEventTarget',

}, dart2jsOnly=True)

def IsRegisteredType(type_name):
  return type_name in _idl_type_registry

def MakeNativeSpec(javascript_binding_name):
  if javascript_binding_name in _dart2js_dom_custom_native_specs:
    return _dart2js_dom_custom_native_specs[javascript_binding_name]
  else:
    # Make the class 'hidden' so it is dynamically patched at runtime.  This
    # is useful for browser compat.
    return javascript_binding_name


def MatchSourceFilter(thing):
  return 'WebKit' in thing.annotations or 'Dart' in thing.annotations


class ParamInfo(object):
  """Holder for various information about a parameter of a Dart operation.

  Attributes:
    name: Name of parameter.
    type_id: Original type id.  None for merged types.
    is_optional: Parameter optionality.
  """
  def __init__(self, name, type_id, is_optional):
    self.name = name
    self.type_id = type_id
    self.is_optional = is_optional

  def Copy(self):
    return ParamInfo(self.name, self.type_id, self.is_optional)

  def __repr__(self):
    content = 'name = %s, type_id = %s, is_optional = %s' % (
        self.name, self.type_id, self.is_optional)
    return '<ParamInfo(%s)>' % content

def GetCallbackInfo(interface):
  """For the given interface, find operations that take callbacks (for use in
  auto-transforming callbacks into futures)."""
  callback_handlers = [operation for operation in interface.operations
      if operation.id == 'handleEvent']
  return AnalyzeOperation(interface, callback_handlers)

# Given a list of overloaded arguments, render dart arguments.
def _BuildArguments(args, interface, constructor=False):
  def IsOptional(argument):
    if 'Callback' in argument.ext_attrs:
      # Optional callbacks arguments are treated as optional arguments.
      return argument.optional
    if constructor:
      # FIXME: Optional constructors arguments should not be treated as
      # optional arguments.
      return argument.optional
    if 'ForceOptional' in argument.ext_attrs:
      return True
    return False

  # Given a list of overloaded arguments, choose a suitable name.
  def OverloadedName(args):
    return '_OR_'.join(sorted(set(arg.id for arg in args)))

  def DartType(idl_type_name):
   if idl_type_name in _idl_type_registry:
     return _idl_type_registry[idl_type_name].dart_type or idl_type_name
   return idl_type_name

  # Given a list of overloaded arguments, choose a suitable type.
  def OverloadedType(args):
    type_ids = sorted(set(arg.type.id for arg in args))
    if len(set(DartType(arg.type.id) for arg in args)) == 1:
      return type_ids[0]
    else:
      return None

  result = []

  is_optional = False
  for arg_tuple in map(lambda *x: x, *args):
    is_optional = is_optional or any(arg is None or IsOptional(arg) for arg in arg_tuple)

    filtered = filter(None, arg_tuple)
    type_id = OverloadedType(filtered)
    name = OverloadedName(filtered)
    result.append(ParamInfo(name, type_id, is_optional))

  return result

def IsOptional(argument):
  return argument.optional and ('Default' not in argument.ext_attrs)\
      or 'ForceOptional' in argument.ext_attrs

def AnalyzeOperation(interface, operations):
  """Makes operation calling convention decision for a set of overloads.

  Returns: An OperationInfo object.
  """

  # split operations with optional args into multiple operations
  split_operations = []
  for operation in operations:
    for i in range(0, len(operation.arguments)):
      if IsOptional(operation.arguments[i]):
        new_operation = copy.deepcopy(operation)
        new_operation.arguments = new_operation.arguments[:i]
        split_operations.append(new_operation)
    split_operations.append(operation)

  # Zip together arguments from each overload by position, then convert
  # to a dart argument.
  info = OperationInfo()
  info.operations = operations
  info.overloads = split_operations
  info.declared_name = operations[0].id
  info.name = operations[0].ext_attrs.get('DartName', info.declared_name)
  info.constructor_name = None
  info.js_name = info.declared_name
  info.type_name = operations[0].type.id   # TODO: widen.
  info.param_infos = _BuildArguments([op.arguments for op in split_operations], interface)
  full_name = '%s.%s' % (interface.id, info.declared_name)
  info.requires_named_arguments = full_name in _methods_with_named_formals
  # The arguments in that the original operation took as callbacks (for
  # conversion to futures).
  info.callback_args = []
  return info

def ConvertToFuture(info):
  """Given an OperationInfo object, convert the operation's signature so that it
  instead uses futures instead of callbacks."""
  new_info = copy.deepcopy(info)
  def IsNotCallbackType(param):
    return 'Callback' not in param.type_id
  # Success callback is the first argument (change if this no longer holds).
  new_info.callback_args = filter(
      lambda x: not IsNotCallbackType(x), new_info.param_infos)
  new_info.param_infos = filter(IsNotCallbackType, new_info.param_infos)
  new_info.type_name = 'Future'

  return new_info


def AnalyzeConstructor(interface):
  """Returns an OperationInfo object for the constructor.

  Returns None if the interface has no Constructor.
  """
  if interface.id in _suppressed_native_constructors:
    return None

  if 'Constructor' in interface.ext_attrs:
    name = None
    overloads = interface.ext_attrs['Constructor']
    idl_args = [[] if f is None else f.arguments for f in overloads]
  elif 'NamedConstructor' in interface.ext_attrs:
    func_value = interface.ext_attrs.get('NamedConstructor')
    idl_args = [func_value.arguments]
    name = func_value.id
  else:
    return None

  info = OperationInfo()
  info.overloads = None
  info.idl_args = idl_args
  info.declared_name = name
  info.name = name
  info.constructor_name = ('_' if interface.id in custom_html_constructors
      else None)
  info.js_name = name
  info.type_name = interface.id
  info.param_infos = _BuildArguments(idl_args, interface, constructor=True)
  info.requires_named_arguments = False
  info.pure_dart_constructor = False
  return info

def IsDartListType(type):
  return type == 'List' or type.startswith('sequence<')

def IsDartCollectionType(type):
  return IsDartListType(type)

def FindMatchingAttribute(interface, attr1):
  matches = [attr2 for attr2 in interface.attributes
             if attr1.id == attr2.id]
  if matches:
    assert len(matches) == 1
    return matches[0]
  return None


def DartDomNameOfAttribute(attr):
  """Returns the Dart name for an IDLAttribute.

  attr.id is the 'native' or JavaScript name.

  To ensure uniformity, work with the true IDL name until as late a possible,
  e.g. translate to the Dart name when generating Dart code.
  """
  name = attr.id
  name = _dart_attribute_renames.get(name, name)
  name = attr.ext_attrs.get('DartName', None) or name
  return name


def TypeOrNothing(dart_type, comment=None):
  """Returns string for declaring something with |dart_type| in a context
  where a type may be omitted.
  The string is empty or has a trailing space.
  """
  if dart_type == 'dynamic':
    if comment:
      return '/*%s*/ ' % comment   # Just a comment foo(/*T*/ x)
    else:
      return ''                    # foo(x) looks nicer than foo(var|dynamic x)
  else:
    return dart_type + ' '


def TypeOrVar(dart_type, comment=None):
  """Returns string for declaring something with |dart_type| in a context
  where if a type is omitted, 'var' must be used instead."""
  if dart_type == 'dynamic':
    if comment:
      return 'var /*%s*/' % comment   # e.g.  var /*T*/ x;
    else:
      return 'var'                    # e.g.  var x;
  else:
    return dart_type


class OperationInfo(object):
  """Holder for various derived information from a set of overloaded operations.

  Attributes:
    overloads: A list of IDL operation overloads with the same name.
    name: A string, the simple name of the operation.
    constructor_name: A string, the name of the constructor iff the constructor
       is named, e.g. 'fromList' in  Int8Array.fromList(list).
    type_name: A string, the name of the return type of the operation.
    param_infos: A list of ParamInfo.
    factory_parameters: A list of parameters used for custom designed Factory
        calls.
  """

  def __init__(self):
    self.factory_parameters = None

  def ParametersDeclaration(self, rename_type, force_optional=False):
    def FormatParam(param):
      dart_type = rename_type(param.type_id) if param.type_id else 'dynamic'
      return '%s%s' % (TypeOrNothing(dart_type, param.type_id), param.name)

    required = []
    optional = []
    for param_info in self.param_infos:
      if param_info.is_optional:
        optional.append(param_info)
      else:
        if optional:
          raise Exception('Optional parameters cannot precede required ones: '
                          + str(params))
        required.append(param_info)
    argtexts = map(FormatParam, required)
    if optional:
      needs_named = self.requires_named_arguments and not force_optional
      left_bracket, right_bracket = '{}' if needs_named else '[]'
      argtexts.append(
          left_bracket +
          ', '.join(map(FormatParam, optional)) +
          right_bracket)
    return ', '.join(argtexts)

  def NumberOfRequiredInDart(self):
    """ Returns a number of required arguments in Dart declaration of
    the operation.
    """
    return len(filter(lambda i: not i.is_optional, self.param_infos))

  def ParametersAsArgumentList(self, parameter_count=None):
    """Returns a string of the parameter names suitable for passing the
    parameters as arguments.
    """
    def param_name(param_info):
      if self.requires_named_arguments and param_info.is_optional:
        return '%s : %s' % (param_info.name, param_info.name)
      else:
        return param_info.name

    if parameter_count is None:
      parameter_count = len(self.param_infos)
    return ', '.join(map(param_name, self.param_infos[:parameter_count]))

  def IsStatic(self):
    is_static = self.overloads[0].is_static
    assert any([is_static == o.is_static for o in self.overloads])
    return is_static

  def _ConstructorFullName(self, rename_type):
    if self.constructor_name:
      return rename_type(self.type_name) + '.' + self.constructor_name
    else:
      # TODO(antonm): temporary ugly hack.
      # While in transition phase we allow both DOM's ArrayBuffer
      # and dart:typed_data's ByteBuffer for IDLs' ArrayBuffers,
      # hence ArrayBuffer is mapped to dynamic in arguments and return
      # values.  To compensate for that when generating ArrayBuffer itself,
      # we need to lie a bit:
      if self.type_name == 'ArrayBuffer': return 'ByteBuffer'
      return rename_type(self.type_name)

def ConstantOutputOrder(a, b):
  """Canonical output ordering for constants."""
  return cmp(a.id, b.id)


def _FormatNameList(names):
  """Returns JavaScript array literal expression with one name per line."""
  #names = sorted(names)
  if len(names) <= 1:
    expression_string = str(names)  # e.g.  ['length']
  else:
    expression_string = ',\n   '.join(str(names).split(','))
    expression_string = expression_string.replace('[', '[\n    ')
  return expression_string


def IndentText(text, indent):
  """Format lines of text with indent."""
  def FormatLine(line):
    if line.strip():
      return '%s%s\n' % (indent, line)
    else:
      return '\n'
  return ''.join(FormatLine(line) for line in text.split('\n'))

# Given a sorted sequence of type identifiers, return an appropriate type
# name
def TypeName(type_ids, interface):
  # Dynamically type this field for now.
  return 'dynamic'

# ------------------------------------------------------------------------------

class Conversion(object):
  """Represents a way of converting between types."""
  def __init__(self, name, input_type, output_type):
    # input_type is the type of the API input (and the argument type of the
    # conversion function)
    # output_type is the type of the API output (and the result type of the
    # conversion function)
    self.function_name = name
    self.input_type = input_type
    self.output_type = output_type

#  "TYPE DIRECTION INTERFACE.MEMBER" -> conversion
#     Specific member of interface
#  "TYPE DIRECTION INTERFACE.*" -> conversion
#     All members of interface getting (setting) with type.
#  "TYPE DIRECTION" -> conversion
#     All getters (setters) of type.
#
# where DIRECTION is 'get' for getters and operation return values, 'set' for
# setters and operation arguments.  INTERFACE and MEMBER are the idl names.
#

_serialize_SSV = Conversion('convertDartToNative_SerializedScriptValue',
                           'dynamic', 'dynamic')

dart2js_conversions = monitored.Dict('generator.dart2js_conversions', {
    'Date get':
      Conversion('convertNativeToDart_DateTime', 'dynamic', 'DateTime'),
    'Date set':
      Conversion('convertDartToNative_DateTime', 'DateTime', 'dynamic'),
    # Wrap non-local Windows.  We need to check EventTarget (the base type)
    # as well.  Note, there are no functions that take a non-local Window
    # as a parameter / setter.
    'Window get':
      Conversion('_convertNativeToDart_Window', 'dynamic', 'WindowBase'),
    'EventTarget get':
      Conversion('_convertNativeToDart_EventTarget', 'dynamic',
                 'EventTarget'),
    'EventTarget set':
      Conversion('_convertDartToNative_EventTarget', 'EventTarget',
                 'dynamic'),

    'ImageData get':
      Conversion('convertNativeToDart_ImageData', 'dynamic', 'ImageData'),
    'ImageData set':
      Conversion('convertDartToNative_ImageData', 'ImageData', 'dynamic'),

    'Dictionary get':
      Conversion('convertNativeToDart_Dictionary', 'dynamic', 'Map'),
    'Dictionary set':
      Conversion('convertDartToNative_Dictionary', 'Map', 'dynamic'),

    'sequence<DOMString> set':
      Conversion('convertDartToNative_StringArray', 'List<String>', 'List'),

    'any set IDBObjectStore.add': _serialize_SSV,
    'any set IDBObjectStore.put': _serialize_SSV,
    'any set IDBCursor.update': _serialize_SSV,

    # postMessage
    'any set MessagePort.postMessage': _serialize_SSV,
    'SerializedScriptValue set Window.postMessage': _serialize_SSV,

    '* get CustomEvent.detail':
      Conversion('convertNativeToDart_SerializedScriptValue',
                 'dynamic', 'dynamic'),

    # receiving message via MessageEvent
    '* get MessageEvent.data':
      Conversion('convertNativeToDart_SerializedScriptValue',
                 'dynamic', 'dynamic'),

    '* get History.state':
      Conversion('convertNativeToDart_SerializedScriptValue',
                 'dynamic', 'dynamic'),

    '* get PopStateEvent.state':
      Conversion('convertNativeToDart_SerializedScriptValue',
                 'dynamic', 'dynamic'),

    # IDBAny is problematic.  Some uses are just a union of other IDB types,
    # which need no conversion..  Others include data values which require
    # serialized script value processing.
    '* get IDBCursorWithValue.value':
      Conversion('_convertNativeToDart_IDBAny', 'dynamic', 'dynamic'),

    # This is problematic.  The result property of IDBRequest is used for
    # all requests.  Read requests like IDBDataStore.getObject need
    # conversion, but other requests like opening a database return
    # something that does not need conversion.
    'IDBAny get IDBRequest.result':
      Conversion('_convertNativeToDart_IDBAny', 'dynamic', 'dynamic'),

    # "source: On getting, returns the IDBObjectStore or IDBIndex that the
    # cursor is iterating. ...".  So we should not try to convert it.
    'IDBAny get IDBCursor.source': None,

    # Should be either a DOMString, an Array of DOMStrings or null.
    'IDBAny get IDBObjectStore.keyPath': None,

    '* get XMLHttpRequest.response':
      Conversion('_convertNativeToDart_XHR_Response',
                 'dynamic', 'dynamic'),
}, dart2jsOnly=True)

def FindConversion(idl_type, direction, interface, member):
  table = dart2js_conversions
  return (table.get('%s %s %s.%s' % (idl_type, direction, interface, member)) or
          table.get('* %s %s.%s' % (direction, interface, member)) or
          table.get('%s %s %s.*' % (idl_type, direction, interface)) or
          table.get('%s %s' % (idl_type, direction)))
  return None


# ------------------------------------------------------------------------------

class IDLTypeInfo(object):
  def __init__(self, idl_type, data):
    self._idl_type = idl_type
    self._data = data

  def idl_type(self):
    return self._idl_type

  def dart_type(self):
    return self._data.dart_type or self._idl_type

  def narrow_dart_type(self):
    return self.dart_type()

  def interface_name(self):
    raise NotImplementedError()

  def implementation_name(self):
    raise NotImplementedError()

  def has_generated_interface(self):
    raise NotImplementedError()

  def list_item_type(self):
    raise NotImplementedError()

  def merged_interface(self):
    return None

  def merged_into(self):
    return None

  def native_type(self):
    return self._data.native_type or self._idl_type

  def bindings_class(self):
    return 'Dart%s' % self.idl_type()

  def vector_to_dart_template_parameter(self):
    return self.native_type()

  def to_native_info(self, idl_node, interface_name):
    cls = self.bindings_class()

    if 'Callback' in idl_node.ext_attrs:
      return '%s', 'RefPtr<%s>' % self.native_type(), cls, 'create'

    if self.custom_to_native():
      type = 'RefPtr<%s>' % self.native_type()
      argument_expression_template = '%s.get()'
    else:
      type = '%s*' % self.native_type()
      if isinstance(self, SVGTearOffIDLTypeInfo) and not interface_name.endswith('List'):
        argument_expression_template = '%s->propertyReference()'
      else:
        argument_expression_template = '%s'
    return argument_expression_template, type, cls, 'toNative'

  def pass_native_by_ref(self): return False

  def custom_to_native(self):
    return self._data.custom_to_native

  def parameter_type(self):
    return '%s*' % self.native_type()

  def webcore_includes(self):
    WTF_INCLUDES = [
        'ArrayBuffer',
        'ArrayBufferView',
        'Float32Array',
        'Float64Array',
        'Int8Array',
        'Int16Array',
        'Int32Array',
        'Uint8Array',
        'Uint8ClampedArray',
        'Uint16Array',
        'Uint32Array',
    ]

    if self._idl_type in WTF_INCLUDES:
      return ['<wtf/%s.h>' % self.native_type()]

    # TODO(vsm): Why does this need special casing?
    if self._idl_type == 'AnalyserNode':
      return ['"AnalyserNode.h"', '<wtf/Uint8Array.h>']

    if not self._idl_type.startswith('SVG'):
      return ['"%s.h"' % self.native_type()]

    include = self._idl_type
    return ['"%s.h"' % include] + _svg_supplemental_includes

  def receiver(self):
    return 'receiver->'

  def conversion_includes(self):
    includes = [self._idl_type] + (self._data.conversion_includes or [])
    return ['"Dart%s.h"' % include for include in includes]

  def to_dart_conversion(self, value, interface_name=None, attributes=None):
    return 'Dart%s::toDart(%s)' % (self._idl_type, value)

  def return_to_dart_conversion(self, value,
                                interface_name=None, attributes=None):
    return 'Dart%s::returnToDart(args, %s)' % (self._idl_type, value)

  def custom_to_dart(self):
    return self._data.custom_to_dart


class InterfaceIDLTypeInfo(IDLTypeInfo):
  def __init__(self, idl_type, data, dart_interface_name, type_registry):
    super(InterfaceIDLTypeInfo, self).__init__(idl_type, data)
    self._dart_interface_name = dart_interface_name
    self._type_registry = type_registry

  def dart_type(self):
    if self._data.dart_type:
      return self._data.dart_type
    if self.list_item_type() and not self.has_generated_interface():
      return 'List<%s>' % self._type_registry.TypeInfo(self._data.item_type).dart_type()
    return self._dart_interface_name

  def narrow_dart_type(self):
    if self.list_item_type():
      return self.implementation_name()
    # TODO(podivilov): only primitive and collection types should override
    # dart_type.
    if self._data.dart_type != None:
      return self.dart_type()
    if IsPureInterface(self.idl_type()):
      return self.idl_type()
    return self.interface_name()

  def interface_name(self):
    return self._dart_interface_name

  def implementation_name(self):
    implementation_name = self._dart_interface_name

    if not self.has_generated_interface():
      implementation_name = '_%s' % implementation_name

    return implementation_name

  def native_type(self):
    database = self._type_registry._database

    if database.HasInterface(self.idl_type()):
      interface = database.GetInterface(self.idl_type())
      if 'ImplementedAs' in interface.ext_attrs:
        return interface.ext_attrs['ImplementedAs']
    return super(InterfaceIDLTypeInfo, self).native_type()

  def has_generated_interface(self):
    return not self._data.suppress_interface

  def list_item_type(self):
    return self._data.item_type

  def merged_interface(self):
    # All constants, attributes, and operations of merged interface should be
    # added to this interface. Merged idl interface does not have corresponding
    # Dart generated interface, and all references to merged idl interface
    # (e.g. parameter types, return types, parent interfaces) should be replaced
    # with this interface. There are two important restrictions:
    # 1) Merged and target interfaces shouldn't have common members, otherwise
    # there would be duplicated declarations in generated Dart code.
    # 2) Merged interface should be direct child of target interface, so the
    # children of merged interface are not affected by the merge.
    # As a consequence, target interface implementation and its direct children
    # interface implementations should implement merged attribute accessors and
    # operations. For example, SVGElement and Element implementation classes
    # should implement HTMLElement.insertAdjacentElement(),
    # HTMLElement.innerHTML, etc.
    return self._data.merged_interface

  def merged_into(self):
    return self._data.merged_into


class CallbackIDLTypeInfo(IDLTypeInfo):
  def __init__(self, idl_type, data):
    super(CallbackIDLTypeInfo, self).__init__(idl_type, data)

  def implementation_name(self):
    return ""


def array_type(data_type):
  matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
  if not matched:
      return None
  return matched.group(1)

class SequenceIDLTypeInfo(IDLTypeInfo):
  def __init__(self, idl_type, data, item_info):
    super(SequenceIDLTypeInfo, self).__init__(idl_type, data)
    self._item_info = item_info

  def dart_type(self):
    return 'List<%s>' % self._item_info.dart_type()

  def interface_name(self):
    return self.dart_type()

  def implementation_name(self):
    return self.dart_type()

  def vector_to_dart_template_parameter(self):
    raise Exception('sequences of sequences are not supported yet')

  def to_native_info(self, idl_node, interface_name):
    item_native_type = self._item_info.vector_to_dart_template_parameter()
    if isinstance(self._item_info, PrimitiveIDLTypeInfo):
      return '%s', 'Vector<%s>' % item_native_type, 'DartUtilities', 'toNativeVector<%s>' % item_native_type
    return '%s', 'Vector< RefPtr<%s> >' % item_native_type, 'DartUtilities', 'toNativeVector< RefPtr<%s> >' % item_native_type

  def parameter_type(self):
    native_type = self.native_type()
    if array_type(native_type):
      return 'const Vector<RefPtr<%s> > &' % array_type(native_type)

    return native_type

  def pass_native_by_ref(self): return True

  def to_dart_conversion(self, value, interface_name=None, attributes=None):
    if isinstance(self._item_info, PrimitiveIDLTypeInfo):
      return 'DartDOMWrapper::vectorToDart(%s)' % value
    return 'DartDOMWrapper::vectorToDart<%s>(%s)' % (self._item_info.bindings_class(), value)

  def return_to_dart_conversion(self, value,
                                interface_name=None, attributes=None):
    return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
        value,
        interface_name,
        attributes)

  def conversion_includes(self):
    return self._item_info.conversion_includes()


class DOMStringArrayTypeInfo(SequenceIDLTypeInfo):
  def __init__(self, data, item_info):
    super(DOMStringArrayTypeInfo, self).__init__('DOMString[]', data, item_info)

  def to_native_info(self, idl_node, interface_name):
    return '%s', 'RefPtr<DOMStringList>', 'DartDOMStringList', 'toNative'

  def pass_native_by_ref(self): return False

  def implementation_name(self):
    return ""


class PrimitiveIDLTypeInfo(IDLTypeInfo):
  def __init__(self, idl_type, data):
    super(PrimitiveIDLTypeInfo, self).__init__(idl_type, data)

  def vector_to_dart_template_parameter(self):
    # Ugly hack. Usually IDLs floats are treated as C++ doubles, however
    # sequence<float> should map to Vector<float>
    if self.idl_type() == 'float': return 'float'
    return self.native_type()

  def to_native_info(self, idl_node, interface_name):
    type = self.native_type()
    if type == 'SerializedScriptValue':
      type = 'RefPtr<%s>' % type
    if type == 'String':
      type = 'DartStringAdapter'
    target_type = self._capitalized_native_type()
    if self.idl_type() == 'Date':
      target_type = 'Date'
    return '%s', type, 'DartUtilities', 'dartTo%s' % target_type

  def parameter_type(self):
    if self.native_type() == 'String':
      return 'const String&'
    return self.native_type()

  def conversion_includes(self):
    return []

  def to_dart_conversion(self, value, interface_name=None, attributes=None):
    # TODO(antonm): if there are more instances of the case
    # when conversion depends on both Dart type and C++ type,
    # consider introducing a corresponding argument/class.
    if self.idl_type() == 'Date':
      function_name = 'date'
    else:
      function_name = self._capitalized_native_type()
      function_name = function_name[0].lower() + function_name[1:]
    function_name = 'DartUtilities::%sToDart' % function_name
    if attributes and 'TreatReturnedNullStringAs' in attributes:
      function_name += 'WithNullCheck'
    return '%s(%s)' % (function_name, value)

  def return_to_dart_conversion(self, value,
                                interface_name=None, attributes=None):
    return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
        value,
        interface_name,
        attributes)

  def webcore_getter_name(self):
    return self._data.webcore_getter_name

  def webcore_setter_name(self):
    return self._data.webcore_setter_name

  def _capitalized_native_type(self):
    return re.sub(r'(^| )([a-z])', lambda x: x.group(2).upper(), self.native_type())


class SVGTearOffIDLTypeInfo(InterfaceIDLTypeInfo):
  def __init__(self, idl_type, data, interface_name, type_registry):
    super(SVGTearOffIDLTypeInfo, self).__init__(
        idl_type, data, interface_name, type_registry)

  def native_type(self):
    if self._data.native_type:
      return self._data.native_type
    tear_off_type = 'SVGPropertyTearOff'
    if self._idl_type.endswith('List'):
      tear_off_type = 'SVGListPropertyTearOff'
    return '%s<%s>' % (tear_off_type, self._idl_type)

  def receiver(self):
    if self._idl_type.endswith('List'):
      return 'receiver->'
    return 'receiver->propertyReference().'

  def to_conversion_cast(self, value, interface_name, attributes):
    svg_primitive_types = ['SVGAngle', 'SVGLength', 'SVGMatrix',
        'SVGNumber', 'SVGPoint', 'SVGRect', 'SVGTransform']
    conversion_cast = '%s::create(%s)'
    if interface_name.startswith('SVGAnimated'):
      conversion_cast = 'static_cast<%s*>(%s)'
    elif self.idl_type() == 'SVGStringList':
      conversion_cast = '%s::create(receiver, %s)'
    elif interface_name.endswith('List'):
      conversion_cast = 'static_cast<%s*>(%s.get())'
    elif self.idl_type() in svg_primitive_types:
      conversion_cast = '%s::create(%s)'
    else:
      conversion_cast = 'static_cast<%s*>(%s)'
    conversion_cast = conversion_cast % (self.native_type(), value)
    return '%s' % (conversion_cast)

  def to_dart_conversion(self, value, interface_name, attributes):
    return 'Dart%s::toDart(%s)' % (self._idl_type, self.to_conversion_cast(value, interface_name, attributes))

  def return_to_dart_conversion(self, value, interface_name, attr):
    return 'Dart%s::returnToDart(args, %s)' % (self._idl_type,
                                               self.to_conversion_cast(
                                                   value,
                                                   interface_name,
                                                   attr))

  def argument_expression(self, name, interface_name):
    return name if interface_name.endswith('List') else '%s->propertyReference()' % name


class TypedListIDLTypeInfo(InterfaceIDLTypeInfo):
  def __init__(self, idl_type, data, interface_name, type_registry):
    super(TypedListIDLTypeInfo, self).__init__(
        idl_type, data, interface_name, type_registry)

  def conversion_includes(self):
    return [ '"wtf/%s.h"' % self._idl_type ]

  def to_dart_conversion(self, value, interface_name, attributes):
    return 'DartUtilities::arrayBufferViewToDart(%s)' % value

  def return_to_dart_conversion(self, value, interface_name, attributes):
    return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
        value,
        interface_name,
        attributes)

  def to_native_info(self, idl_node, interface_name):
    return '%s.get()', 'RefPtr<%s>' % self._idl_type, 'DartUtilities', 'dartTo%s' % self._idl_type


class BasicTypedListIDLTypeInfo(InterfaceIDLTypeInfo):
  def __init__(self, idl_type, data, interface_name, type_registry):
    super(BasicTypedListIDLTypeInfo, self).__init__(
        idl_type, data, interface_name, type_registry)

  def conversion_includes(self):
    return []

  def to_dart_conversion(self, value, interface_name, attributes):
    function_name = 'DartUtilities::%sToDart' % self._idl_type
    function_name = function_name[0].lower() + function_name[1:]
    return '%s(%s)' % (function_name, value)

  def return_to_dart_conversion(self, value, interface_name, attributes):
    return 'Dart_SetReturnValue(args, %s)' % self.to_dart_conversion(
        value,
        interface_name,
        attributes)

  def to_native_info(self, idl_node, interface_name):
    return '%s.get()', 'RefPtr<%s>' % self._idl_type, 'DartUtilities', 'dartTo%s' % self._idl_type


class TypeData(object):
  def __init__(self, clazz, dart_type=None, native_type=None,
               merged_interface=None, merged_into=None,
               custom_to_dart=False, custom_to_native=False,
               conversion_includes=None,
               webcore_getter_name='getAttribute',
               webcore_setter_name='setAttribute',
               item_type=None, suppress_interface=False):
    self.clazz = clazz
    self.dart_type = dart_type
    self.native_type = native_type
    self.merged_interface = merged_interface
    self.merged_into = merged_into
    self.custom_to_dart = custom_to_dart
    self.custom_to_native = custom_to_native
    self.conversion_includes = conversion_includes
    self.webcore_getter_name = webcore_getter_name
    self.webcore_setter_name = webcore_setter_name
    self.item_type = item_type
    self.suppress_interface = suppress_interface


def TypedListTypeData(item_type):
  return TypeData(clazz='TypedList', item_type=item_type)


_idl_type_registry = monitored.Dict('generator._idl_type_registry', {
    'boolean': TypeData(clazz='Primitive', dart_type='bool', native_type='bool',
                        webcore_getter_name='hasAttribute',
                        webcore_setter_name='setBooleanAttribute'),
    'byte': TypeData(clazz='Primitive', dart_type='int', native_type='int'),
    'octet': TypeData(clazz='Primitive', dart_type='int', native_type='int'),
    'short': TypeData(clazz='Primitive', dart_type='int', native_type='int'),
    'unsigned short': TypeData(clazz='Primitive', dart_type='int',
        native_type='int'),
    'int': TypeData(clazz='Primitive', dart_type='int'),
    'long': TypeData(clazz='Primitive', dart_type='int', native_type='int',
        webcore_getter_name='getIntegralAttribute',
        webcore_setter_name='setIntegralAttribute'),
    'unsigned long': TypeData(clazz='Primitive', dart_type='int',
                              native_type='unsigned',
                              webcore_getter_name='getUnsignedIntegralAttribute',
                              webcore_setter_name='setUnsignedIntegralAttribute'),
    'long long': TypeData(clazz='Primitive', dart_type='int'),
    'unsigned long long': TypeData(clazz='Primitive', dart_type='int'),
    'float': TypeData(clazz='Primitive', dart_type='num', native_type='double'),
    'double': TypeData(clazz='Primitive', dart_type='num'),

    'any': TypeData(clazz='Primitive', dart_type='Object', native_type='ScriptValue'),
    'Array': TypeData(clazz='Primitive', dart_type='List'),
    'custom': TypeData(clazz='Primitive', dart_type='dynamic'),
    'ClientRect': TypeData(clazz='Interface',
        dart_type='Rectangle', suppress_interface=True),
    'Date': TypeData(clazz='Primitive', dart_type='DateTime', native_type='double'),
    'DOMObject': TypeData(clazz='Primitive', dart_type='Object', native_type='ScriptValue'),
    'DOMString': TypeData(clazz='Primitive', dart_type='String', native_type='String'),
    # TODO(vsm): This won't actually work until we convert the Map to
    # a native JS Map for JS DOM.
    'Dictionary': TypeData(clazz='Primitive', dart_type='Map'),
    'DOMTimeStamp': TypeData(clazz='Primitive', dart_type='int', native_type='unsigned long long'),
    'object': TypeData(clazz='Primitive', dart_type='Object', native_type='ScriptValue'),
    'ObjectArray': TypeData(clazz='Primitive', dart_type='List'),
    'PositionOptions': TypeData(clazz='Primitive', dart_type='Object'),
    # TODO(sra): Come up with some meaningful name so that where this appears in
    # the documentation, the user is made aware that only a limited subset of
    # serializable types are actually permitted.
    'SerializedScriptValue': TypeData(clazz='Primitive', dart_type='dynamic'),
    'sequence': TypeData(clazz='Primitive', dart_type='List'),
    'void': TypeData(clazz='Primitive', dart_type='void'),

    'CSSRule': TypeData(clazz='Interface', conversion_includes=['CSSImportRule']),
    'DOMStringMap': TypeData(clazz='Interface', dart_type='Map<String, String>'),
    'Window': TypeData(clazz='Interface', custom_to_dart=True),
    'Element': TypeData(clazz='Interface', merged_interface='HTMLElement',
        custom_to_dart=True),
    'EventListener': TypeData(clazz='Interface', custom_to_native=True),
    'EventHandler': TypeData(clazz='Interface', custom_to_native=True),
    'EventTarget': TypeData(clazz='Interface', custom_to_native=True),
    'HTMLElement': TypeData(clazz='Interface', merged_into='Element',
        custom_to_dart=True),
    'IDBAny': TypeData(clazz='Interface', dart_type='dynamic', custom_to_native=True),
    'MutationRecordArray': TypeData(clazz='Interface',  # C++ pass by pointer.
        native_type='MutationRecordArray', dart_type='List<MutationRecord>'),
    'StyleSheet': TypeData(clazz='Interface', conversion_includes=['CSSStyleSheet']),
    'SVGElement': TypeData(clazz='Interface', custom_to_dart=True),

    'ClientRectList': TypeData(clazz='Interface',
        item_type='ClientRect', dart_type='List<Rectangle>',
        suppress_interface=True),
    'CSSRuleList': TypeData(clazz='Interface',
        item_type='CSSRule', suppress_interface=True),
    'CSSValueList': TypeData(clazz='Interface',
        item_type='CSSValue', suppress_interface=True),
    'MimeTypeArray': TypeData(clazz='Interface', item_type='MimeType'),
    'PluginArray': TypeData(clazz='Interface', item_type='Plugin'),
    'DOMStringList': TypeData(clazz='Interface', item_type='DOMString',
        dart_type='List<String>', custom_to_native=True),
    'FileList': TypeData(clazz='Interface', item_type='File',
        dart_type='List<File>'),
    'Future': TypeData(clazz='Interface', dart_type='Future'),
    'GamepadList': TypeData(clazz='Interface', item_type='Gamepad',
        suppress_interface=True),
    'GLenum': TypeData(clazz='Primitive', dart_type='int',
        native_type='unsigned'),
    'HTMLAllCollection': TypeData(clazz='Interface', item_type='Node'),
    'HTMLCollection': TypeData(clazz='Interface', item_type='Node'),
    'NamedNodeMap': TypeData(clazz='Interface', item_type='Node'),
    'NodeList': TypeData(clazz='Interface', item_type='Node',
                         suppress_interface=False, dart_type='List<Node>'),
    'SVGElementInstanceList': TypeData(clazz='Interface',
        item_type='SVGElementInstance', suppress_interface=True),
    'SourceBufferList': TypeData(clazz='Interface', item_type='SourceBuffer'),
    'SpeechGrammarList': TypeData(clazz='Interface', item_type='SpeechGrammar'),
    'SpeechInputResultList': TypeData(clazz='Interface',
        item_type='SpeechInputResult', suppress_interface=True),
    'SpeechRecognitionResultList': TypeData(clazz='Interface',
        item_type='SpeechRecognitionResult', suppress_interface=True),
    'SQLResultSetRowList': TypeData(clazz='Interface', item_type='Dictionary'),
    'StyleSheetList': TypeData(clazz='Interface',
        item_type='StyleSheet', suppress_interface=True),
    'TextTrackCueList': TypeData(clazz='Interface', item_type='TextTrackCue'),
    'TextTrackList': TypeData(clazz='Interface', item_type='TextTrack'),
    'TouchList': TypeData(clazz='Interface', item_type='Touch'),

    'Float32Array': TypedListTypeData('double'),
    'Float64Array': TypedListTypeData('double'),
    'Int8Array': TypedListTypeData('int'),
    'Int16Array': TypedListTypeData('int'),
    'Int32Array': TypedListTypeData('int'),
    'Uint8Array': TypedListTypeData('int'),
    'Uint8ClampedArray': TypedListTypeData('int'),
    'Uint16Array': TypedListTypeData('int'),
    'Uint32Array': TypedListTypeData('int'),

    'ArrayBufferView': TypeData(clazz='BasicTypedList'),
    'ArrayBuffer': TypeData(clazz='BasicTypedList'),

    'SVGAngle': TypeData(clazz='SVGTearOff'),
    'SVGLength': TypeData(clazz='SVGTearOff'),
    'SVGLengthList': TypeData(clazz='SVGTearOff', item_type='SVGLength'),
    'SVGMatrix': TypeData(clazz='SVGTearOff'),
    'SVGNumber': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<SVGNumber>'),
    'SVGNumberList': TypeData(clazz='SVGTearOff', item_type='SVGNumber'),
    'SVGPathSegList': TypeData(clazz='SVGTearOff', item_type='SVGPathSeg',
        native_type='SVGPathSegListPropertyTearOff'),
    'SVGPoint': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<FloatPoint>'),
    'SVGPointList': TypeData(clazz='SVGTearOff'),
    'SVGPreserveAspectRatio': TypeData(clazz='SVGTearOff'),
    'SVGRect': TypeData(clazz='SVGTearOff', native_type='SVGPropertyTearOff<FloatRect>'),
    'SVGStringList': TypeData(clazz='SVGTearOff', item_type='DOMString',
        native_type='SVGStaticListPropertyTearOff<SVGStringList>'),
    'SVGTransform': TypeData(clazz='SVGTearOff'),
    'SVGTransformList': TypeData(clazz='SVGTearOff', item_type='SVGTransform',
        native_type='SVGTransformListPropertyTearOff'),
})

_svg_supplemental_includes = [
    '"SVGAnimatedPropertyTearOff.h"',
    '"SVGAnimatedListPropertyTearOff.h"',
    '"SVGStaticListPropertyTearOff.h"',
    '"SVGAnimatedListPropertyTearOff.h"',
    '"SVGTransformListPropertyTearOff.h"',
    '"SVGPathSegListPropertyTearOff.h"',
]

class TypeRegistry(object):
  def __init__(self, database, renamer=None):
    self._database = database
    self._renamer = renamer
    self._cache = {}

  def TypeInfo(self, type_name):
    if not type_name in self._cache:
      self._cache[type_name] = self._TypeInfo(type_name)
    return self._cache[type_name]

  def DartType(self, type_name):
    return self.TypeInfo(type_name).dart_type()

  def _TypeInfo(self, type_name):
    match = re.match(r'(?:sequence<(\w+)>|(\w+)\[\])$', type_name)
    if match:
      type_data = TypeData('Sequence')
      item_info = self.TypeInfo(match.group(1) or match.group(2))
      # TODO(vsm): Generalize this code.
      if 'SourceInfo' in type_name:
        type_data.native_type = 'const Vector<RefPtr<SourceInfo> >& '
      return SequenceIDLTypeInfo(type_name, type_data, item_info)

    if not type_name in _idl_type_registry:
      if self._database.HasEnum(type_name):
        return PrimitiveIDLTypeInfo(
            type_name,
            TypeData(clazz='Primitive', dart_type='String', native_type='String'))

      interface = self._database.GetInterface(type_name)
      if 'Callback' in interface.ext_attrs:
        return CallbackIDLTypeInfo(type_name, TypeData('Callback',
            self._renamer.DartifyTypeName(type_name)))
      return InterfaceIDLTypeInfo(
          type_name,
          TypeData('Interface'),
          self._renamer.RenameInterface(interface),
          self)

    type_data = _idl_type_registry.get(type_name)

    if type_data.clazz == 'Interface':
      if self._database.HasInterface(type_name):
        dart_interface_name = self._renamer.RenameInterface(
            self._database.GetInterface(type_name))
      else:
        dart_interface_name = self._renamer.DartifyTypeName(type_name)
      return InterfaceIDLTypeInfo(type_name, type_data, dart_interface_name,
                                  self)

    if type_data.clazz == 'SVGTearOff':
      dart_interface_name = self._renamer.RenameInterface(
          self._database.GetInterface(type_name))
      return SVGTearOffIDLTypeInfo(
          type_name, type_data, dart_interface_name, self)

    if type_data.clazz == 'TypedList':
      dart_interface_name = self._renamer.RenameInterfaceId(type_name)
      return TypedListIDLTypeInfo(
          type_name, type_data, dart_interface_name, self)

    if type_data.clazz == 'BasicTypedList':
      if type_name == 'ArrayBuffer':
        dart_interface_name = 'ByteBuffer'
      else:
        dart_interface_name = self._renamer.RenameInterfaceId(type_name)
      return BasicTypedListIDLTypeInfo(
          type_name, type_data, dart_interface_name, self)

    class_name = '%sIDLTypeInfo' % type_data.clazz
    return globals()[class_name](type_name, type_data)
