#!/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 the system to generate
Dart:html APIs from the IDL database."""

import emitter
import logging
import monitored
import os
import re
from generator import *
from htmldartgenerator import *

_logger = logging.getLogger('systemhtml')

HTML_LIBRARY_NAMES = ['html', 'indexed_db', 'svg',
                      'web_audio', 'web_gl', 'web_sql']

# The following two sets let us avoid shadowing fields with properties.
# This information could be derived from the IDL files but would require
# a significant refactor to compute accurately. Instead we manually compute
# these sets based on manual triage of strong mode errors.
_force_property_members = monitored.Set('systemhtml._force_property_members', [
    'Element.outerHtml',
    'Element.isContentEditable',
    'AudioContext.createGain',
    'AudioContext.createScriptProcessor',
    ])
_safe_to_ignore_shadowing_members = monitored.Set('systemhtml._safe_to_ignore_shadowing_members', [
    'SVGElement.tabIndex',
    'SVGStyleElement.title',
    ])

_js_custom_members = monitored.Set('systemhtml._js_custom_members', [
    'AudioBufferSourceNode.start',
    'AudioBufferSourceNode.stop',
    'AudioContext.createGain',
    'AudioContext.createScriptProcessor',
    'CanvasRenderingContext2D.drawImage',
    'CanvasRenderingContext2D.fill',
    'CanvasRenderingContext2D.fillText',
    'CanvasRenderingContext2D.lineDashOffset',
    'CanvasRenderingContext2D.setLineDash',
    'Console.memory',
    'ConsoleBase.assertCondition',
    'ConsoleBase.clear',
    'ConsoleBase.count',
    'ConsoleBase.debug',
    'ConsoleBase.dir',
    'ConsoleBase.dirxml',
    'ConsoleBase.error',
    'ConsoleBase.group',
    'ConsoleBase.groupCollapsed',
    'ConsoleBase.groupEnd',
    'ConsoleBase.info',
    'ConsoleBase.log',
    'ConsoleBase.markTimeline',
    'ConsoleBase.profile',
    'ConsoleBase.profileEnd',
    'ConsoleBase.table',
    'ConsoleBase.time',
    'ConsoleBase.timeEnd',
    'ConsoleBase.timeStamp',
    'ConsoleBase.trace',
    'ConsoleBase.warn',
    'WebKitCSSKeyframesRule.insertRule',
    'CSSStyleDeclaration.setProperty',
    'CSSStyleDeclaration.__propertyQuery__',
    'Document.createNodeIterator',
    'Document.createTreeWalker',
    'DOMException.name',
    'DOMException.toString',
    # ListMixin already provides this method although the implementation
    # is slower. As this class is obsolete anyway, we ignore the slowdown in
    # DOMStringList performance.
    'DOMStringList.contains',
    'Element.animate',
    'Element.createShadowRoot',
    'Element.insertAdjacentElement',
    'Element.insertAdjacentHTML',
    'Element.insertAdjacentText',
    'Element.remove',
    'Element.shadowRoot',
    'Element.matches',
    'ElementEvents.mouseWheel',
    'ElementEvents.transitionEnd',
    'FileReader.result',
    'HTMLAnchorElement.toString',
    'HTMLAreaElement.toString',
    'HTMLTableElement.createTBody',
    'IDBCursor.next',
    'IDBDatabase.transaction',
    'IDBDatabase.transactionList',
    'IDBDatabase.transactionStore',
    'IDBDatabase.transactionStores',
    'KeyboardEvent.initKeyboardEvent',
    'Location.origin',
    'Location.toString',
    'MouseEvent.offsetX',
    'MouseEvent.offsetY',
    'Navigator.language',
    'Navigator.webkitGetUserMedia',
    'ScriptProcessorNode._setEventListener',
    'URL.createObjectURL',
    'URL.createObjectUrlFromSource',
    'URL.createObjectUrlFromStream',
    'URL.createObjectUrlFromBlob',
    'URL.revokeObjectURL',
    'URL.toString',
    'WheelEvent.deltaMode',
    'Window.cancelAnimationFrame',
    'Window.console',
    'Window.document',
    'Window.indexedDB',
    'Window.location',
    'Window.open',
    'Window.requestAnimationFrame',
    'Window.scrollX',
    'Window.scrollY'
    # 'WorkerContext.indexedDB', # Workers
    ], dart2jsOnly=True)

_js_custom_constructors = monitored.Set('systemhtml._js_custom_constructors', [
    'AudioContext',
    'Blob',
    'Comment',
    'MutationObserver',
    'RTCIceCandidate',
    'RTCPeerConnection',
    'RTCSessionDescription',
    'SpeechRecognition',
    ], dart2jsOnly=True)

# Classes that offer only static methods, and therefore we should suppress
# constructor creation.
_static_classes = set(['Url'])

# Information for generating element constructors.
#
# TODO(sra): maybe remove all the argument complexity and use cascades.
#
#   var c = new CanvasElement(width: 100, height: 70);
#   var c = new CanvasElement()..width = 100..height = 70;
#
class ElementConstructorInfo(object):
  def __init__(self, name=None, tag=None,
               params=[], opt_params=[],
               factory_provider_name='document'):
    self.name = name          # The constructor name 'h1' in 'HeadingElement.h1'
    self.tag = tag or name    # The HTML or SVG tag
    self.params = params
    self.opt_params = opt_params
    self.factory_provider_name = factory_provider_name

  def ConstructorInfo(self, interface_name):
    info = OperationInfo()
    info.overloads = None
    info.declared_name = interface_name
    info.name = interface_name
    info.constructor_name = self.name
    info.js_name = None
    info.type_name = interface_name
    info.param_infos = map(lambda tXn: ParamInfo(tXn[1], tXn[0], True),
                           self.opt_params)
    info.requires_named_arguments = True
    info.factory_parameters = ['"%s"' % self.tag]
    info.pure_dart_constructor = True
    return info

_html_element_constructors = monitored.Dict(
      'systemhtml._html_element_constructors', {
  'HTMLAnchorElement' :
    ElementConstructorInfo(tag='a', opt_params=[('DOMString', 'href')]),
  'HTMLAreaElement': 'area',
  'HTMLButtonElement': 'button',
  'HTMLBRElement': 'br',
  'HTMLBaseElement': 'base',
  'HTMLBodyElement': 'body',
  'HTMLButtonElement': 'button',
  'HTMLCanvasElement':
    ElementConstructorInfo(tag='canvas',
                           opt_params=[('int', 'width'), ('int', 'height')]),
  'HTMLContentElement': 'content',
  'HTMLDataListElement': 'datalist',
  'HTMLDListElement': 'dl',
  'HTMLDetailsElement': 'details',
  'HTMLDivElement': 'div',
  'HTMLEmbedElement': 'embed',
  'HTMLFieldSetElement': 'fieldset',
  'HTMLFormElement': 'form',
  'HTMLHRElement': 'hr',
  'HTMLHeadElement': 'head',
  'HTMLHeadingElement': [ElementConstructorInfo('h1'),
                     ElementConstructorInfo('h2'),
                     ElementConstructorInfo('h3'),
                     ElementConstructorInfo('h4'),
                     ElementConstructorInfo('h5'),
                     ElementConstructorInfo('h6')],
  'HTMLHtmlElement': 'html',
  'HTMLIFrameElement': 'iframe',
  'HTMLImageElement':
    ElementConstructorInfo(tag='img',
                           opt_params=[('DOMString', 'src'),
                                       ('int', 'width'), ('int', 'height')]),
  'HTMLKeygenElement': 'keygen',
  'HTMLLIElement': 'li',
  'HTMLLabelElement': 'label',
  'HTMLLegendElement': 'legend',
  'HTMLLinkElement': 'link',
  'HTMLMapElement': 'map',
  'HTMLMenuElement': 'menu',
  'HTMLMetaElement': 'meta',
  'HTMLMeterElement': 'meter',
  'HTMLOListElement': 'ol',
  'HTMLObjectElement': 'object',
  'HTMLOptGroupElement': 'optgroup',
  'HTMLOutputElement': 'output',
  'HTMLParagraphElement': 'p',
  'HTMLParamElement': 'param',
  'HTMLPreElement': 'pre',
  'HTMLProgressElement': 'progress',
  'HTMLQuoteElement': 'q',
  'HTMLScriptElement': 'script',
  'HTMLSelectElement': 'select',
  'HTMLShadowElement': 'shadow',
  'HTMLSourceElement': 'source',
  'HTMLSpanElement': 'span',
  'HTMLStyleElement': 'style',
  'HTMLTableCaptionElement': 'caption',
  'HTMLTableCellElement': 'td',
  'HTMLTableColElement': 'col',
  'HTMLTableElement': 'table',
  'HTMLTableRowElement': 'tr',
  #'HTMLTableSectionElement'  <thead> <tbody> <tfoot>
  'HTMLTemplateElement': 'template',
  'HTMLTextAreaElement': 'textarea',
  'HTMLTitleElement': 'title',
  'HTMLTrackElement': 'track',
  'HTMLUListElement': 'ul',
  'HTMLVideoElement': 'video'
})

_svg_element_constructors = monitored.Dict(
      'systemhtml._svg_element_constructors', {
  'SVGAElement': 'a',
  'SVGAltGlyphElement': 'altGlyph',
  'SVGAnimateElement': 'animate',
  'SVGAnimateMotionElement': 'animateMotion',
  'SVGAnimateTransformElement': 'animateTransform',
  'SVGAnimationElement': 'animation',
  'SVGCircleElement': 'circle',
  'SVGClipPathElement': 'clipPath',
  'SVGCursorElement': 'cursor',
  'SVGDefsElement': 'defs',
  'SVGDescElement': 'desc',
  'SVGEllipseElement': 'ellipse',
  'SVGFEBlendElement': 'feBlend',
  'SVGFEColorMatrixElement': 'feColorMatrix',
  'SVGFEComponentTransferElement': 'feComponentTransfer',
  'SVGFEConvolveMatrixElement': 'feConvolveMatrix',
  'SVGFEDiffuseLightingElement': 'feDiffuseLighting',
  'SVGFEDisplacementMapElement': 'feDisplacementMap',
  'SVGFEDistantLightElement': 'feDistantLight',
  'SVGFEFloodElement': 'feFlood',
  'SVGFEFuncAElement': 'feFuncA',
  'SVGFEFuncBElement': 'feFuncB',
  'SVGFEFuncGElement': 'feFuncG',
  'SVGFEFuncRElement': 'feFuncR',
  'SVGFEGaussianBlurElement': 'feGaussianBlur',
  'SVGFEImageElement': 'feImage',
  'SVGFEMergeElement': 'feMerge',
  'SVGFEMergeNodeElement': 'feMergeNode',
  'SVGFEMorphology': 'feMorphology',
  'SVGFEOffsetElement': 'feOffset',
  'SVGFEPointLightElement': 'fePointLight',
  'SVGFESpecularLightingElement': 'feSpecularLighting',
  'SVGFESpotLightElement': 'feSpotLight',
  'SVGFETileElement': 'feTile',
  'SVGFETurbulenceElement': 'feTurbulence',
  'SVGFilterElement': 'filter',
  'SVGForeignObjectElement': 'foreignObject',
  'SVGGlyphElement': 'glyph',
  'SVGGElement': 'g',
  'SVGHKernElement': 'hkern',
  'SVGImageElement': 'image',
  'SVGLinearGradientElement': 'linearGradient',
  'SVGLineElement': 'line',
  'SVGMarkerElement': 'marker',
  'SVGMaskElement': 'mask',
  'SVGMPathElement': 'mpath',
  'SVGPathElement': 'path',
  'SVGPatternElement': 'pattern',
  'SVGPolygonElement': 'polygon',
  'SVGPolylineElement': 'polyline',
  'SVGRadialGradientElement': 'radialGradient',
  'SVGRectElement': 'rect',
  'SVGScriptElement': 'script',
  'SVGSetElement': 'set',
  'SVGStopElement': 'stop',
  'SVGStyleElement': 'style',
  'SVGSwitchElement': 'switch',
  'SVGSymbolElement': 'symbol',
  'SVGTextElement': 'text',
  'SVGTitleElement': 'title',
  'SVGTRefElement': 'tref',
  'SVGTSpanElement': 'tspan',
  'SVGUseElement': 'use',
  'SVGViewElement': 'view',
  'SVGVKernElement': 'vkern',
})

_element_constructors = {
  'html': _html_element_constructors,
  'indexed_db': {},
  'svg': _svg_element_constructors,
  'typed_data': {},
  'web_audio': {},
  'web_gl': {},
  'web_sql': {},
}

_factory_ctr_strings = {
  'html': {
      'provider_name': 'document',
      'constructor_name': 'createElement'
  },
  'indexed_db': {
      'provider_name': 'document',
      'constructor_name': 'createElement'
  },
  'svg': {
    'provider_name': '_SvgElementFactoryProvider',
    'constructor_name': 'createSvgElement_tag',
  },
  'typed_data': {
      'provider_name': 'document',
      'constructor_name': 'createElement'
  },
  'web_audio': {
    'provider_name': 'document',
    'constructor_name': 'createElement'
  },
  'web_gl': {
    'provider_name': 'document',
    'constructor_name': 'createElement'
  },
  'web_sql': {
    'provider_name': 'document',
    'constructor_name': 'createElement'
  },
}

def ElementConstructorInfos(typename, element_constructors,
                            factory_provider_name='_Elements'):
  """Returns list of ElementConstructorInfos about the convenience constructors
  for an Element or SvgElement."""
  # TODO(sra): Handle multiple and named constructors.
  if typename not in element_constructors:
    return []
  infos = element_constructors[typename]
  if isinstance(infos, str):
    infos = ElementConstructorInfo(tag=infos,
        factory_provider_name=factory_provider_name)
  if not isinstance(infos, list):
    infos = [infos]
  return infos

# ------------------------------------------------------------------------------
def SvgSupportStr(tagName):
  return 'Svg%s' % ElemSupportStr(tagName)

def ElemSupportStr(tagName):
  return "Element.isTagSupported('%s')" % tagName

_js_support_checks_basic_element_with_constructors = [
  'HTMLContentElement',
  'HTMLDataListElement',
  'HTMLDetailsElement',
  'HTMLEmbedElement',
  'HTMLMeterElement',
  'HTMLObjectElement',
  'HTMLOutputElement',
  'HTMLProgressElement',
  'HTMLTemplateElement',
  'HTMLTrackElement',
]

_js_support_checks_additional_element = [
  # IE creates keygen as Block elements
  'HTMLKeygenElement',
  'SVGAltGlyphElement',
  'SVGAnimateElement',
  'SVGAnimateMotionElement',
  'SVGAnimateTransformElement',
  'SVGCursorElement',
  'SVGFEBlendElement',
  'SVGFEColorMatrixElement',
  'SVGFEComponentTransferElement',
  'SVGFEConvolveMatrixElement',
  'SVGFEDiffuseLightingElement',
  'SVGFEDisplacementMapElement',
  'SVGFEDistantLightElement',
  'SVGFEFloodElement',
  'SVGFEFuncAElement',
  'SVGFEFuncBElement',
  'SVGFEFuncGElement',
  'SVGFEFuncRElement',
  'SVGFEGaussianBlurElement',
  'SVGFEImageElement',
  'SVGFEMergeElement',
  'SVGFEMergeNodeElement',
  'SVGFEMorphology',
  'SVGFEOffsetElement',
  'SVGFEPointLightElement',
  'SVGFESpecularLightingElement',
  'SVGFESpotLightElement',
  'SVGFETileElement',
  'SVGFETurbulenceElement',
  'SVGFilterElement',
  'SVGForeignObjectElement',
  'SVGSetElement',
]

js_support_checks = dict({
    'Animation': "JS('bool', '!!(document.body.animate)')",
    'AudioContext': "JS('bool', '!!(window.AudioContext ||"
        " window.webkitAudioContext)')",
    'Crypto':
        "JS('bool', '!!(window.crypto && window.crypto.getRandomValues)')",
    'Database': "JS('bool', '!!(window.openDatabase)')",
    'DOMPoint': "JS('bool', '!!(window.DOMPoint) || !!(window.WebKitPoint)')",
    'ApplicationCache': "JS('bool', '!!(window.applicationCache)')",
    'DOMFileSystem': "JS('bool', '!!(window.webkitRequestFileSystem)')",
    'FormData': "JS('bool', '!!(window.FormData)')",
    'HashChangeEvent': "Device.isEventTypeSupported('HashChangeEvent')",
    'HTMLShadowElement': ElemSupportStr('shadow'),
    'HTMLTemplateElement': ElemSupportStr('template'),
    'MediaStreamEvent': "Device.isEventTypeSupported('MediaStreamEvent')",
    'MediaStreamTrackEvent': "Device.isEventTypeSupported('MediaStreamTrackEvent')",
    'MediaSource': "JS('bool', '!!(window.MediaSource)')",
    'Notification': "JS('bool', '!!(window.Notification)')",
    'Performance': "JS('bool', '!!(window.performance)')",
    'SpeechRecognition': "JS('bool', '!!(window.SpeechRecognition || "
        "window.webkitSpeechRecognition)')",
    'SVGExternalResourcesRequired': ('supported(SvgElement element)',
        "JS('bool', '#.externalResourcesRequired !== undefined && "
        "#.externalResourcesRequired.animVal !== undefined', "
        "element, element)"),
    'SVGLangSpace': ('supported(SvgElement element)',
        "JS('bool', '#.xmlspace !== undefined && #.xmllang !== undefined', "
        "element, element)"),
    'TouchList': "JS('bool', '!!document.createTouchList')",
    'WebGLRenderingContext': "JS('bool', '!!(window.WebGLRenderingContext)')",
    'WebSocket': "JS('bool', 'typeof window.WebSocket != \"undefined\"')",
    'Worker': "JS('bool', '(typeof window.Worker != \"undefined\")')",
    'XSLTProcessor': "JS('bool', '!!(window.XSLTProcessor)')",
  }.items() +
  dict((key,
        SvgSupportStr(_svg_element_constructors[key]) if key.startswith('SVG')
            else ElemSupportStr(_html_element_constructors[key])) for key in
    _js_support_checks_basic_element_with_constructors +
    _js_support_checks_additional_element).items())
# ------------------------------------------------------------------------------

class HtmlDartInterfaceGenerator(object):
  """Generates dart interface and implementation for the DOM IDL interface."""

  def __init__(self, options, library_emitter, event_generator, interface,
               backend):
    self._renamer = options.renamer
    self._database = options.database
    self._template_loader = options.templates
    self._type_registry = options.type_registry
    self._options = options
    self._library_emitter = library_emitter
    self._event_generator = event_generator
    self._interface = interface
    self._backend = backend
    self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
    self._library_name = self._renamer.GetLibraryName(self._interface)
    self._metadata = options.metadata

  def Generate(self):
    if IsCustomType(self._interface.id):
      pass
    elif 'Callback' in self._interface.ext_attrs:
      self.GenerateCallback()
    else:
      self.GenerateInterface()

  def GenerateCallback(self):
    """Generates a typedef for the callback interface."""
    typedef_name = self._renamer.RenameInterface(self._interface)
    if not typedef_name:
      return

    info = GetCallbackInfo(self._interface)
    code = self._library_emitter.FileEmitter(self._interface.id,
        self._library_name)
    code.Emit(self._template_loader.Load('callback.darttemplate'))

    annotations = self._metadata.GetFormattedMetadata(self._library_name,
        self._interface)

    code.Emit('$(ANNOTATIONS)typedef void $NAME($PARAMS);\n',
              ANNOTATIONS=annotations,
              NAME=typedef_name,
              PARAMS=info.ParametersAsDeclaration(self._DartType))
    self._backend.GenerateCallback(info)

  def GenerateInterface(self):
    interface_name = self._interface_type_info.interface_name()

    implementation_name = self._interface_type_info.implementation_name()
    self._library_emitter.AddTypeEntry(self._library_name,
                                       self._interface.id, implementation_name)

    factory_provider = None
    if interface_name in interface_factories:
      factory_provider = interface_factories[interface_name]
    factory_constructor_name = None

    constructors = []
    if interface_name in _static_classes:
      constructor_info = None
    else:
      constructor_info = AnalyzeConstructor(self._interface)
    if constructor_info:
      constructors.append(constructor_info)
      # TODO(antonm): consider removing it later.
      factory_provider = interface_name

    # HTML Elements and SVG Elements have convenience constructors.
    infos = ElementConstructorInfos(self._interface.id,
        _element_constructors[self._library_name], factory_provider_name=
        _factory_ctr_strings[self._library_name]['provider_name'])

    if infos:
      factory_constructor_name = _factory_ctr_strings[
          self._library_name]['constructor_name']

    for info in infos:
      constructors.append(info.ConstructorInfo(self._interface.id))
      if factory_provider and factory_provider != info.factory_provider_name:
        _logger.warn('Conflicting factory provider names: %s != %s' %
          (factory_provider, info.factory_provider_name))
      factory_provider = info.factory_provider_name

    implementation_emitter = self._ImplementationEmitter()

    base_type_info = None
    if self._interface.parents:
      supertype = self._interface.parents[0].type.id
      if not IsDartCollectionType(supertype) and not IsPureInterface(supertype, self._database):
        base_type_info = self._type_registry.TypeInfo(supertype)

    if base_type_info:
      base_class = base_type_info.implementation_name()
    else:
      base_class = self._backend.RootClassName()

    implements = self._backend.AdditionalImplementedInterfaces()
    for parent in self._interface.parents:
      parent_type_info = self._type_registry.TypeInfo(parent.type.id)
      if parent_type_info.interface_name() != base_class and \
          parent_type_info != base_type_info:
        implements.append(parent_type_info.interface_name())

    secure_base_name = self._backend.SecureBaseName(interface_name)
    if secure_base_name:
      implements.append(secure_base_name)

    implements_str = ''
    if implements:
      implements_str = ' implements ' + ', '.join(set(implements))

    mixins = self._backend.Mixins()

    mixins_str = ''
    if mixins:
      mixins_str = ' with ' + ', '.join(mixins)
      if not base_class:
        base_class = 'Interceptor'
      elif (base_class == 'NativeFieldWrapperClass2' and
            self._options.dart_js_interop and
            not(isinstance(self._backend, Dart2JSBackend))):
        base_class = 'DartHtmlDomObject'

    annotations = self._metadata.GetFormattedMetadata(
        self._library_name, self._interface, None, '')

    class_modifiers = ''
    if (self._renamer.ShouldSuppressInterface(self._interface) or
      IsPureInterface(self._interface.id, self._database)):
      # XMLHttpRequestProgressEvent can't be abstract we need to instantiate
      # for JsInterop.
      if (not(isinstance(self._backend, Dart2JSBackend)) and
        (self._interface.id == 'XMLHttpRequestProgressEvent' or
         self._interface.id == 'DOMStringMap')):
        # Suppress abstract for XMLHttpRequestProgressEvent and DOMStringMap
        # for Dartium.  Need to be able to instantiate the class; can't be abstract.
        class_modifiers = ''
      else:
        # For Dartium w/ JsInterop these suppressed interfaces are needed to
        # instanciate the internal classes.
        if (self._renamer.ShouldSuppressInterface(self._interface) and
            not(isinstance(self._backend, Dart2JSBackend)) and
            self._options.dart_js_interop):
          class_modifiers = ''
        else:
          class_modifiers = 'abstract '

    native_spec = ''
    if not IsPureInterface(self._interface.id, self._database):
      native_spec = self._backend.NativeSpec()

    class_name = self._interface_type_info.implementation_name()

    js_interop_wrapper = '''

  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  {0}.internal_() : super.internal_();

'''.format(class_name)
    if base_class == 'NativeFieldWrapperClass2' or base_class == 'DartHtmlDomObject':
        js_interop_wrapper = '''

  @Deprecated("Internal Use Only")
  external static Type get instanceRuntimeType;

  @Deprecated("Internal Use Only")
  {0}.internal_() {{ }}
'''.format(class_name)
        # Change to use the synthesized class so we can construct with a mixin
        # classes prefixed with name of NativeFieldWrapperClass2 don't have a
        # default constructor so classes with mixins can't be new'd.
        if (self._options.templates._conditions['DARTIUM'] and
            self._options.dart_js_interop and
            (self._interface.id == 'NamedNodeMap' or
             self._interface.id == 'CSSStyleDeclaration')):
            base_class = 'DartHtmlDomObject'

    implementation_members_emitter = implementation_emitter.Emit(
        self._backend.ImplementationTemplate(),
        LIBRARYNAME='dart.dom.%s' % self._library_name,
        ANNOTATIONS=annotations,
        CLASS_MODIFIERS=class_modifiers,
        CLASSNAME=class_name,
        EXTENDS=' extends %s' % base_class if base_class else '',
        IMPLEMENTS=implements_str,
        MIXINS=mixins_str,
        DOMNAME=self._interface.doc_js_name,
        NATIVESPEC=native_spec)
    stream_getter_signatures_emitter = None
    element_stream_getters_emitter = None
    if type(implementation_members_emitter) == tuple:
        # We add event stream getters for both Element and ElementList, so in
        # impl_Element.darttemplate, we have two additional "holes" for emitters
        # to fill in, with small variations. These store these specialized
        # emitters.
        assert len(implementation_members_emitter) == 3;
        stream_getter_signatures_emitter = \
            implementation_members_emitter[0]
        element_stream_getters_emitter = implementation_members_emitter[1]
        implementation_members_emitter = \
            implementation_members_emitter[2]
    self._backend.StartInterface(implementation_members_emitter)
    self._backend.EmitHelpers(base_class)
    self._event_generator.EmitStreamProviders(
        self._interface,
        self._backend.CustomJSMembers(),
        implementation_members_emitter,
        self._library_name)
    self._backend.AddConstructors(
        constructors, factory_provider, factory_constructor_name)

    isElement = False
    for parent in self._database.Hierarchy(self._interface):
      if parent.id == 'Element':
        isElement = True

    # Write out the JsInterop code.
    if (implementation_members_emitter and
        self._options.templates._conditions['DARTIUM'] and
        self._options.dart_js_interop and
        not IsPureInterface(self._interface.id, self._database)):
      implementation_members_emitter.Emit(js_interop_wrapper)

    if isElement and self._interface.id != 'Element':
      implementation_members_emitter.Emit(
          '  /**\n'
          '   * Constructor instantiated by the DOM when a custom element has been created.\n'
          '   *\n'
          '   * This can only be called by subclasses from their created constructor.\n'
          '   */\n'
          '  $CLASSNAME.created() : super.created();\n',
          CLASSNAME=self._interface_type_info.implementation_name())

    self._backend.EmitSupportCheck()

    merged_interface = self._interface_type_info.merged_interface()
    if merged_interface:
      self._backend.AddMembers(self._database.GetInterface(merged_interface),
                               not self._backend.ImplementsMergedMembers())

    self._backend.AddMembers(self._interface, False, self._options.dart_js_interop)
    self._backend.AddSecondaryMembers(self._interface)
    self._event_generator.EmitStreamGetters(
        self._interface,
        [],
        implementation_members_emitter,
        self._library_name, stream_getter_signatures_emitter,
        element_stream_getters_emitter)
    self._backend.FinishInterface()

  def _ImplementationEmitter(self):
    basename = self._interface_type_info.implementation_name()
    if (self._interface_type_info.merged_into() and
        self._backend.ImplementsMergedMembers()):
      # Merged members are implemented in target interface implementation.
      return emitter.Emitter()
    return self._library_emitter.FileEmitter(basename, self._library_name)

  def _DartType(self, type_name):
    return self._type_registry.DartType(type_name)


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

class Dart2JSBackend(HtmlDartGenerator):
  """Generates a dart2js class for the dart:html library from a DOM IDL
  interface.
  """

  def __init__(self, interface, options, logging_level=logging.WARNING):
    super(Dart2JSBackend, self).__init__(interface, options, False, _logger)

    self._database = options.database
    self._template_loader = options.templates
    self._type_registry = options.type_registry
    self._renamer = options.renamer
    self._metadata = options.metadata
    self._interface_type_info = self._type_registry.TypeInfo(self._interface.id)
    self._current_secondary_parent = None
    self._library_name = self._renamer.GetLibraryName(self._interface)
    _logger.setLevel(logging_level)

  def ImplementsMergedMembers(self):
    return True

  def GenerateCallback(self, info):
    pass

  def AdditionalImplementedInterfaces(self):
    implements = super(Dart2JSBackend, self).AdditionalImplementedInterfaces()
    if self._interface_type_info.list_item_type() and self.HasIndexedGetter():
      item_type = self._type_registry.TypeInfo(
          self._interface_type_info.list_item_type()).dart_type()
      implements.append('JavaScriptIndexingBehavior<%s>' % item_type)
    return implements

  def NativeSpec(self):
    native_spec = MakeNativeSpec(self._interface.javascript_binding_name)
    return '@Native("%s")\n' % native_spec

  def ImplementationTemplate(self):
    template_file = ('impl_%s.darttemplate' %
                     self._interface.doc_js_name)
    return (self._template_loader.TryLoad(template_file) or
            self._template_loader.Load('dart2js_impl.darttemplate'))

  def StartInterface(self, members_emitter):
    self._members_emitter = members_emitter

  def FinishInterface(self):
    pass

  def HasSupportCheck(self):
    return self._interface.doc_js_name in js_support_checks

  def GetSupportCheck(self):
    """Return a tuple of the support check function signature and the support
    test itself. If no parameters are supplied, we assume the default."""
    if self._interface.doc_js_name in _js_support_checks_additional_element:
      if self._interface.doc_js_name in _svg_element_constructors:
        lib_prefix = 'Svg'
        constructors = _svg_element_constructors
      else:
        lib_prefix = ''
        constructors = _html_element_constructors
      return (js_support_checks.get(self._interface.doc_js_name) +
          " && (new %sElement.tag('%s') is %s)" % (lib_prefix,
        constructors[self._interface.doc_js_name],
        self._renamer.RenameInterface(self._interface)))
    return js_support_checks.get(self._interface.doc_js_name)

  def GenerateCustomFactory(self, constructor_info):
    # Custom factory will be taken from the template.
    return self._interface.doc_js_name in _js_custom_constructors

  def IsConstructorArgumentOptional(self, argument):
    return argument.optional

  def EmitStaticFactoryOverload(self, constructor_info, name, arguments):
    index = len(arguments)
    arguments = constructor_info.ParametersAsArgumentList(index)
    if arguments:
      arguments = ', ' + arguments
    self._members_emitter.Emit(
        "  static $INTERFACE_NAME $NAME($PARAMETERS) => "
          "JS('$INTERFACE_NAME', 'new $CTOR_NAME($PLACEHOLDERS)'$ARGUMENTS);\n",
        INTERFACE_NAME=self._interface_type_info.interface_name(),
        NAME=name,
        # TODO(antonm): add types to parameters.
        PARAMETERS=constructor_info.ParametersAsArgumentList(index),
        CTOR_NAME=constructor_info.name or self._interface.doc_js_name,
        PLACEHOLDERS=','.join(['#'] * index),
        ARGUMENTS=arguments)

  def SecondaryContext(self, interface):
    if interface is not self._current_secondary_parent:
      self._current_secondary_parent = interface
      self._members_emitter.Emit('\n  // From $WHERE\n', WHERE=interface.id)

  def HasIndexedGetter(self):
    ext_attrs = self._interface.ext_attrs
    has_indexed_getter = 'CustomIndexedGetter' in ext_attrs
    for operation in self._interface.operations:
      if operation.id == 'item' and 'getter' in operation.specials \
          and not self._OperationRequiresConversions(operation):
        has_indexed_getter = True
        break
    return has_indexed_getter

  def AddIndexer(self, element_type, nullable):
    """Adds all the methods required to complete implementation of List."""
    # We would like to simply inherit the implementation of everything except
    # length, [], and maybe []=.  It is possible to extend from a base
    # array implementation class only when there is no other implementation
    # inheritance.  There might be no implementation inheritance other than
    # DOMBaseWrapper for many classes, but there might be some where the
    # array-ness is introduced by a non-root interface:
    #
    #   interface Y extends X, List<T> ...
    #
    # In the non-root case we have to choose between:
    #
    #   class YImpl extends XImpl { add List<T> methods; }
    #
    # and
    #
    #   class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
    #

    has_indexed_getter = self.HasIndexedGetter()

    if has_indexed_getter:
      indexed_getter = ('JS("%s%s", "#[#]", this, index)' %
          (self.SecureOutputType(element_type), "|Null" if nullable else ""));
    elif any(op.id == 'getItem' for op in self._interface.operations):
      indexed_getter = 'this.getItem(index)'
    elif any(op.id == 'item' for op in self._interface.operations):
      indexed_getter = 'this.item(index)'

    if indexed_getter:
      self._members_emitter.Emit(
          '\n'
          '  $TYPE operator[](int index) {\n'
          '    if (JS("bool", "# >>> 0 !== # || # >= #", index,\n'
          '        index, index, length))\n'
          '      throw new RangeError.index(index, this);\n'
          '    return $INDEXED_GETTER;\n'
          '  }',
          INDEXED_GETTER=indexed_getter,
          TYPE=self.SecureOutputType(element_type, False, True))

    if 'CustomIndexedSetter' in self._interface.ext_attrs:
      self._members_emitter.Emit(
          '\n'
          '  void operator[]=(int index, $TYPE value) {'
          ' JS("void", "#[#] = #", this, index, value); }',
          TYPE=self._NarrowInputType(element_type))
    else:
      self._members_emitter.Emit(
          '\n'
          '  void operator[]=(int index, $TYPE value) {\n'
          '    throw new UnsupportedError("Cannot assign element of immutable List.");\n'
          '  }\n',
          TYPE=self._NarrowInputType(element_type))

    self.EmitListMixin(self._DartType(element_type), nullable)

  def EmitAttribute(self, attribute, html_name, read_only):
    if self._HasCustomImplementation(attribute.id):
      return

    if IsPureInterface(self._interface.id, self._database):
      self._AddInterfaceAttribute(attribute, html_name, read_only)
      return

    # If the attribute is shadowing, we can't generate a shadowing
    # field (Issue 1633).
    # TODO(sra): _FindShadowedAttribute does not take into account the html
    #  renaming.  we should be looking for another attribute that has the same
    #  html_name.  Two attributes with the same IDL name might not match if one
    #  is renamed.
    (super_attribute, super_attribute_interface) = self._FindShadowedAttribute(
        attribute)
    if self._ForcePropertyMember(html_name):
      self._members_emitter.Emit('\n  // Using property as subclass shadows.');
      self._AddAttributeUsingProperties(attribute, html_name, read_only)
      return

    if super_attribute:
      if read_only or self._SafeToIgnoreShadowingMember(html_name):
        if attribute.type.id == super_attribute.type.id:
          # Compatible attribute, use the superclass property.  This works
          # because JavaScript will do its own dynamic dispatch.
          self._members_emitter.Emit(
              '\n'
              '  // Use implementation from $SUPER.\n'
              '  // final $TYPE $NAME;\n',
              SUPER=super_attribute_interface,
              NAME=html_name,
              TYPE=self.SecureOutputType(attribute.type.id, False, read_only))
          return
      self._members_emitter.Emit('\n  // Shadowing definition.')
      self._AddAttributeUsingProperties(attribute, html_name, read_only)
      return

    # If the attribute is shadowed incompatibly in a subclass then we also
    # can't just generate it as a field. In particular, this happens with
    # DomMatrixReadOnly and its subclass DomMatrix. Force the superclass
    # to generate getters. Hardcoding the known problem classes for now.
    # TODO(alanknight): Fix this more generally.
    if (self._interface.id == 'DOMMatrixReadOnly' or self._interface.id == 'DOMPointReadOnly'
       or self._interface.id == 'DOMRectReadOnly'):
        self._AddAttributeUsingProperties(attribute, html_name, read_only)
        return

    # If the type has a conversion we need a getter or setter to contain the
    # conversion code.
    if (self._OutputConversion(attribute.type.id, attribute.id) or
        self._InputConversion(attribute.type.id, attribute.id)):
      self._AddAttributeUsingProperties(attribute, html_name, read_only)
      return

    output_type = self.SecureOutputType(attribute.type.id, False, read_only)
    input_type = self._NarrowInputType(attribute.type.id)
    metadata = self._Metadata(attribute.type.id, attribute.id, output_type)
    rename = self._RenamingAnnotation(attribute.id, html_name)
    if not read_only:
      self._members_emitter.Emit(
          '\n  $RENAME$METADATA$TYPE $NAME;'
          '\n',
          RENAME=rename,
          METADATA=metadata,
          NAME=html_name,
          TYPE=output_type)
    else:
      template = '\n  $RENAME$(ANNOTATIONS)final $TYPE $NAME;\n'
      # Need to use a getter for list.length properties so we can add a
      # setter which throws an exception, satisfying List API.
      if self._interface_type_info.list_item_type() and html_name == 'length':
        template = ('\n  $RENAME$(ANNOTATIONS)$TYPE get $NAME => ' +
            'JS("$TYPE", "#.$NAME", this);\n')
      self._members_emitter.Emit(
          template,
          RENAME=rename,
          ANNOTATIONS=metadata,
          NAME=html_name,
          TYPE=output_type)

  def _AddAttributeUsingProperties(self, attribute, html_name, read_only):
    self._AddRenamingGetter(attribute, html_name)
    if not read_only:
      self._AddRenamingSetter(attribute, html_name)

  def _AddInterfaceAttribute(self, attribute, html_name, read_only):
    self._members_emitter.Emit(
        '\n  $QUALIFIER$TYPE $NAME;'
        '\n',
        QUALIFIER='final ' if read_only else '',
        NAME=html_name,
        TYPE=self.SecureOutputType(attribute.type.id))

  def _AddRenamingGetter(self, attr, html_name):

    conversion = self._OutputConversion(attr.type.id, attr.id)
    if conversion:
      return self._AddConvertingGetter(attr, html_name, conversion)
    return_type = self.SecureOutputType(attr.type.id)
    native_type = self._NarrowToImplementationType(attr.type.id)
    self._members_emitter.Emit(
        # TODO(sra): Use metadata to provide native name.
        '\n  $TYPE get $HTML_NAME => JS("$NATIVE_TYPE", "#.$NAME", this);'
        '\n',
        HTML_NAME=html_name,
        NAME=attr.id,
        TYPE=return_type,
        NATIVE_TYPE=native_type)

  def _AddRenamingSetter(self, attr, html_name):

    conversion = self._InputConversion(attr.type.id, attr.id)
    if conversion:
      return self._AddConvertingSetter(attr, html_name, conversion)
    self._members_emitter.Emit(
        # TODO(sra): Use metadata to provide native name.
        '\n  set $HTML_NAME($TYPE value) {'
        '\n    JS("void", "#.$NAME = #", this, value);'
        '\n  }'
        '\n',
        HTML_NAME=html_name,
        NAME=attr.id,
        TYPE=self._NarrowInputType(attr.type.id))

  def _AddConvertingGetter(self, attr, html_name, conversion):
    self._members_emitter.Emit(
        '\n  $(METADATA)$RETURN_TYPE get $HTML_NAME => '
        '$CONVERT(this._get_$(HTML_NAME));'
        "\n  @JSName('$NAME')"
        '\n  $(JS_METADATA)final $NATIVE_TYPE _get_$HTML_NAME;'
        '\n',
        METADATA=self._metadata.GetFormattedMetadata(
            self._library_name, self._interface, html_name, '  '),
        JS_METADATA=self._Metadata(attr.type.id, html_name, conversion.input_type),
        CONVERT=conversion.function_name,
        HTML_NAME=html_name,
        NAME=attr.id,
        RETURN_TYPE=conversion.output_type,
        NATIVE_TYPE=conversion.input_type)

  def _AddConvertingSetter(self, attr, html_name, conversion):
    self._members_emitter.Emit(
        # TODO(sra): Use metadata to provide native name.
        '\n  set $HTML_NAME($INPUT_TYPE value) {'
        '\n    this._set_$HTML_NAME = $CONVERT(value);'
        '\n  }'
        '\n  set _set_$HTML_NAME(/*$NATIVE_TYPE*/ value) {'
        '\n    JS("void", "#.$NAME = #", this, value);'
        '\n  }'
        '\n',
        CONVERT=conversion.function_name,
        HTML_NAME=html_name,
        NAME=attr.id,
        INPUT_TYPE=conversion.input_type,
        NATIVE_TYPE=conversion.output_type)

  def AmendIndexer(self, element_type):
    pass

  def RootClassName(self):
    return 'Interceptor'

  def OmitOperationOverrides(self):
    return True

  def EmitOperation(self, info, html_name, dart_js_interop=False):
    """
    Arguments:
      info: An OperationInfo object.
    """
    if self._HasCustomImplementation(info.name):
      return

    if IsPureInterface(self._interface.id, self._database):
      self._AddInterfaceOperation(info, html_name)
    elif info.callback_args:
      self._AddFutureifiedOperation(info, html_name)
    elif any(self._OperationRequiresConversions(op) for op in info.overloads):
      # Any conversions needed?
      self._AddOperationWithConversions(info, html_name)
    else:
      self._AddDirectNativeOperation(info, html_name)

  def _AddDirectNativeOperation(self, info, html_name):
    self._members_emitter.Emit(
        '\n'
        '  $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
        RENAME=self._RenamingAnnotation(info.declared_name, html_name),
        METADATA=self._Metadata(info.type_name, info.declared_name,
            self.SecureOutputType(info.type_name)),
        MODIFIERS='static ' if info.IsStatic() else '',
        TYPE=self.SecureOutputType(info.type_name, False, True),
        NAME=html_name,
        PARAMS=info.ParametersAsDeclaration(self._NarrowInputType))

  def _AddOperationWithConversions(self, info, html_name):
    # Assert all operations have same return type.
    assert len(set([op.type.id for op in info.operations])) == 1
    output_conversion = self._OutputConversion(info.type_name,
                                               info.declared_name)
    if output_conversion:
      return_type = output_conversion.output_type
      native_return_type = output_conversion.input_type
    else:
      return_type = self._NarrowInputType(info.type_name)
      native_return_type = return_type

    parameter_names = [param_info.name for param_info in info.param_infos]
    parameter_types = [self._InputType(param_info.type_id, info)
                       for param_info in info.param_infos]
    operations = info.operations

    def InputType(type_name):
        return self._InputType(type_name, info)

    def GenerateCall(
        stmts_emitter, call_emitter, version, operation, argument_count):
      target = '_%s_%d' % (
          html_name[1:] if html_name.startswith('_') else html_name, version);

      (target_parameters, arguments) = self._ConvertArgumentTypes(
          stmts_emitter, operation.arguments, argument_count, info)

      argument_list = ', '.join(arguments)
      # TODO(sra): If the native method has zero type checks, we can 'inline' is
      # and call it directly with a JS-expression.
      call = '%s(%s)' % (target, argument_list)

      if output_conversion:
        call = '%s(%s)' % (output_conversion.function_name, call)

      call_emitter.Emit(call)

      self._members_emitter.Emit(
          '  $RENAME$METADATA$MODIFIERS$TYPE$TARGET($PARAMS) native;\n',
          RENAME=self._RenamingAnnotation(info.declared_name, target),
          METADATA=self._Metadata(info.type_name, info.declared_name, None),
          MODIFIERS='static ' if info.IsStatic() else '',
          TYPE=TypeOrNothing(native_return_type),
          TARGET=target,
          PARAMS=', '.join(target_parameters))

    declaration = '%s%s%s %s(%s)' % (
        self._Metadata(info.type_name, info.declared_name, return_type),
        'static ' if info.IsStatic() else '',
        return_type,
        html_name,
        info.ParametersAsDeclaration(InputType))
    self._GenerateDispatcherBody(
        info,
        operations,
        declaration,
        GenerateCall,
        IsOptional,
        can_omit_type_check=lambda type, pos: type == parameter_types[pos])

  def _AddInterfaceOperation(self, info, html_name):
    self._members_emitter.Emit(
        '\n'
        '  $TYPE $NAME($PARAMS);\n',
        TYPE=self.SecureOutputType(info.type_name, False, True),
        NAME=html_name,
        PARAMS=info.ParametersAsDeclaration(self._NarrowInputType))


  def _OperationRequiresConversions(self, operation):
    return (self._OperationRequiresOutputConversion(operation) or
            self._OperationRequiresInputConversions(operation))

  def _OperationRequiresOutputConversion(self, operation):
    return self._OutputConversion(operation.type.id, operation.id)

  def _OperationRequiresInputConversions(self, operation):
    return any(self._InputConversion(arg.type.id, operation.id)
               for arg in operation.arguments)

  def _OutputConversion(self, idl_type, member):
    return FindConversion(idl_type, 'get', self._interface.id, member)

  def _InputConversion(self, idl_type, member):
    return FindConversion(idl_type, 'set', self._interface.id, member)

  def _HasCustomImplementation(self, member_name):
    member_name = '%s.%s' % (self._interface.doc_js_name, member_name)
    return member_name in _js_custom_members

  def _ForcePropertyMember(self, member_name):
    member_name = '%s.%s' % (self._interface.doc_js_name, member_name)
    return member_name in _force_property_members

  def _SafeToIgnoreShadowingMember(self, member_name):
    member_name = '%s.%s' % (self._interface.doc_js_name, member_name)
    return member_name in _safe_to_ignore_shadowing_members

  def _RenamingAnnotation(self, idl_name, member_name):
    if member_name != idl_name:
      return  "@JSName('%s')\n  " % idl_name
    return ''

  def _Metadata(self, idl_type, idl_member_name, dart_type, indent='  '):
    anns = self._metadata.GetDart2JSMetadata(
        idl_type, self._library_name, self._interface, idl_member_name)

    if not self._metadata.AnyConversionAnnotations(
        idl_type, self._interface.id, idl_member_name):
      return_type = self.SecureOutputType(idl_type)
      native_type = self._NarrowToImplementationType(idl_type)

      if native_type != return_type:
        anns = anns + [
          "@Returns('%s')" % native_type,
          "@Creates('%s')" % native_type,
        ]
    if dart_type == 'dynamic' or dart_type == 'Object':
      def js_type_annotation(ann):
        return re.search('^@.*Returns', ann) or re.search('^@.*Creates', ann)
      if not filter(js_type_annotation, anns):
        _logger.warn('Member with wildcard native type: %s.%s' %
            (self._interface.id, idl_member_name))

    return self._metadata.FormatMetadata(anns, indent);

  def CustomJSMembers(self):
    return _js_custom_members

  def _FindShadowedAttribute(self, attr):
    """Returns (attribute, superinterface) or (None, None)."""
    def FindInParent(interface):
      """Returns matching attribute in parent, or None."""
      if interface.parents:
        parent = interface.parents[0]
        if IsDartCollectionType(parent.type.id):
          return (None, None)
        if IsPureInterface(parent.type.id, self._database):
          return (None, None)
        if self._database.HasInterface(parent.type.id):
          interfaces_to_search_in = []
          parent_interface_name = parent.type.id
          interfaces_to_search_in.append(parent_interface_name)
          parent_type_info = self._type_registry.TypeInfo(parent_interface_name)
          if parent_type_info.merged_into():
            # IDL parent was merged into another interface, which became a
            # parent interface in Dart.
            parent_interface_name = parent_type_info.merged_into()
            interfaces_to_search_in.append(parent_interface_name)
          elif parent_type_info.merged_interface():
            # IDL parent has another interface that was merged into it.
            interfaces_to_search_in.append(parent_type_info.merged_interface())

          for interface_name in interfaces_to_search_in:
            interface = self._database.GetInterface(interface_name)
            attr2 = FindMatchingAttribute(interface, attr)
            if attr2:
              return (attr2, parent_interface_name)

          return FindInParent(
              self._database.GetInterface(parent_interface_name))
      return (None, None)

    return FindInParent(self._interface) if attr else (None, None)

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

class DartLibraryEmitter():
  def __init__(self, multiemitter, dart_sources_dir, dart_libraries):
    self._multiemitter = multiemitter
    self._dart_sources_dir = dart_sources_dir
    self._path_to_emitter = {}
    self._dart_libraries = dart_libraries

  def FileEmitter(self, basename, library_name, template=None):
    aux_dir = os.path.join(self._dart_sources_dir, library_name)
    path = os.path.join(aux_dir, '%s.dart' % basename)
    if not path in self._path_to_emitter:
      emitter = self._multiemitter.FileEmitter(path)
      if not template is None:
        emitter = emitter.Emit(template)
      self._path_to_emitter[path] = emitter

      self._dart_libraries.AddFile(basename, library_name, path)
    return self._path_to_emitter[path]

  def AddTypeEntry(self, basename, idl_name, dart_name):
    self._dart_libraries.AddTypeEntry(basename, idl_name, dart_name)

  def EmitLibraries(self, auxiliary_dir, dart_js_interop):
    self._dart_libraries.Emit(self._multiemitter, auxiliary_dir)

# ------------------------------------------------------------------------------
class DartLibrary():
  def __init__(self, name, template_loader, library_type, output_dir, dart_js_interop):
    self._template = template_loader.Load(
        '%s_%s.darttemplate' % (name, library_type))
    self._dart_path = os.path.join(
        output_dir, '%s_%s.dart' % (name, library_type))
    self._paths = []
    self._typeMap = {}
    self._dart_js_interop = dart_js_interop

  def AddFile(self, path):
    self._paths.append(path)

  def AddTypeEntry(self, idl_name, dart_name):
    self._typeMap[idl_name] = dart_name

  def Emit(self, emitter, auxiliary_dir):
    def massage_path(path):
      # The most robust way to emit path separators is to use / always.
      return path.replace('\\', '/')

    library_emitter = emitter.FileEmitter(self._dart_path)
    library_file_dir = os.path.dirname(self._dart_path)
    auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir)
    emitters = library_emitter.Emit(
        self._template, AUXILIARY_DIR=massage_path(auxiliary_dir))
    if isinstance(emitters, tuple):
      imports_emitter, map_emitter = emitters
    else:
      imports_emitter, map_emitter = emitters, None

    for path in sorted(self._paths):
      relpath = os.path.relpath(path, library_file_dir)
      imports_emitter.Emit(
          "part '$PATH';\n", PATH=massage_path(relpath))

    # Emit the $!TYPE_MAP
    if map_emitter:
      items = self._typeMap.items()
      items.sort()
      for (idl_name, dart_name) in items:
        map_emitter.Emit(
          "  '$IDL_NAME': () => $DART_NAME.instanceRuntimeType,\n",
          IDL_NAME=idl_name,
          DART_NAME=dart_name)


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

class DartLibraries():
  def __init__(self, libraries, template_loader, library_type, output_dir, dart_js_interop):
    self._libraries = {}
    for library_name in libraries:
      self._libraries[library_name] = DartLibrary(
          library_name, template_loader, library_type, output_dir, dart_js_interop)

  def AddFile(self, basename, library_name, path):
    self._libraries[library_name].AddFile(path)

  def AddTypeEntry(self, library_name, idl_name, dart_name):
    self._libraries[library_name].AddTypeEntry(idl_name, dart_name)

  def Emit(self, emitter, auxiliary_dir):
    for lib in self._libraries.values():
      lib.Emit(emitter, auxiliary_dir)
