#!/usr/bin/env python3
# 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
from generator import AnalyzeOperation, ConstantOutputOrder, \
    DartDomNameOfAttribute, FindMatchingAttribute, IsPureInterface, \
    TypeOrNothing, ConvertToFuture, GetCallbackInfo
from copy import deepcopy
from htmlrenamer import convert_to_future_members, custom_html_constructors, \
    GetDDC_Extension, keep_overloaded_members, overloaded_and_renamed,\
    private_html_members, renamed_html_members, renamed_overloads, \
    removed_html_members
from generator import TypeOrVar
import logging
from mdnreader import MDNReader
import monitored
import sys

_logger = logging.getLogger('htmldartgenerator')

# Types that are accessible cross-frame in a limited fashion.
# In these cases, the base type (e.g., WindowBase) provides restricted access
# while the subtype (e.g., Window) provides full access to the
# corresponding objects if there are from the same frame.
_secure_base_types = {
    'Window': 'WindowBase',
    'Location': 'LocationBase',
    'History': 'HistoryBase',
}

_custom_factories = [
    'Notification',
    'EventSource',
]


class HtmlDartGenerator(object):

    def __init__(self, interface, options, dart_use_blink, logger):
        self._dart_use_blink = dart_use_blink
        self._database = options.database
        self._interface = interface
        self._type_registry = options.type_registry
        self._interface_type_info = self._type_registry.TypeInfo(
            self._interface.id)
        self._renamer = options.renamer
        self._metadata = options.metadata
        self._library_name = self._renamer.GetLibraryName(self._interface)
        self._mdn_reader = MDNReader()
        _logger.setLevel(logger.level)

    def EmitSupportCheck(self):
        if self.HasSupportCheck():
            check = self.GetSupportCheck()
            if type(check) != tuple:
                signature = 'get supported'
            else:
                signature = check[0]
                check = check[1]
            self._members_emitter.Emit(
                '\n'
                '  /// Checks if this type is supported on the current platform.\n'
                '  static bool $SIGNATURE => $SUPPORT_CHECK;\n',
                SIGNATURE=signature,
                SUPPORT_CHECK=check)

    def EmitEventGetter(self, events_class_name):
        self._members_emitter.Emit(
            "EventTarget.removeEventListener, EventTarget.dispatchEvent')"
            "\n  @deprecated"
            "\n  $TYPE get on =>\n    new $TYPE(this);\n",
            TYPE=events_class_name)

    def AddMembers(self, interface, declare_only=False, dart_js_interop=False):
        if self._interface.id == 'WebGLRenderingContextBase' or self._interface.id == 'WebGL2RenderingContextBase' or \
            self._interface.id == 'WebGLDrawBuffers':
            # Constants in classes WebGLRenderingContextBase, WebGL2RenderingContext, WebGLDrawBuffers are consolidated into
            # one synthesized class (WebGL).
            self._gl_constants.extend(interface.constants)
        else:
            for const in sorted(interface.constants, ConstantOutputOrder):
                self.AddConstant(const)

        for attr in sorted(interface.attributes, ConstantOutputOrder):
            if attr.type.id != 'EventHandler' and attr.type.id != 'EventListener':
                self.AddAttribute(attr, declare_only)

        # The implementation should define an indexer if the interface directly
        # extends List.
        element_type = None
        requires_indexer = False
        if self._interface_type_info.list_item_type():
            self.AddIndexer(self._interface_type_info.list_item_type(),
                            self._interface_type_info.list_item_type_nullable())
        else:
            for parent in self._database.Hierarchy(self._interface):
                if parent == self._interface:
                    continue
                parent_type_info = self._type_registry.TypeInfo(parent.id)
                if parent_type_info.list_item_type():
                    self.AmendIndexer(parent_type_info.list_item_type())
                    break

        # Group overloaded operations by name.
        self._AddRenamedOverloads(interface)
        operationsByName = self._OperationsByName(interface)
        if self.OmitOperationOverrides():
            self._RemoveShadowingOperationsWithSameSignature(
                operationsByName, interface)

        # Generate operations.
        for id in sorted(operationsByName.keys()):
            operations = operationsByName[id]
            info = AnalyzeOperation(interface, operations)
            self.AddOperation(info, declare_only, dart_js_interop)
            if ('%s.%s' % (interface.id,
                           info.declared_name) in convert_to_future_members):
                self.AddOperation(ConvertToFuture(info), declare_only)

    def AddSecondaryMembers(self, interface):
        secondary_parents = self._database.TransitiveSecondaryParents(
            interface, not self._dart_use_blink)
        remove_duplicate_parents = list(set(secondary_parents))
        if len(secondary_parents) != len(remove_duplicate_parents):
            secondary_parents = remove_duplicate_parents
            parent_list = ", ".join(
                ["  %s" % (parent.id) for parent in secondary_parents])
            _logger.warn('Interface %s has duplicate parent interfaces %s - ' \
                         'ignoring duplicates. Please file a bug with the dart:html team.' % (interface.id, parent_list))

        for parent_interface in sorted(secondary_parents):
            if isinstance(parent_interface, str):
                continue

            for attr in sorted(parent_interface.attributes,
                               ConstantOutputOrder):
                if not FindMatchingAttribute(interface, attr):
                    if attr.type.id != 'EventHandler':
                        self.SecondaryContext(parent_interface)
                        self.AddAttribute(attr)

            # Group overloaded operations by name.
            operationsByName = self._OperationsByName(parent_interface)

            if self.OmitOperationOverrides():
                self._RemoveShadowingOperationsWithSameSignature(
                    operationsByName, interface)

            # Generate operations.
            for id in sorted(operationsByName.keys()):
                if not any(op.id == id for op in interface.operations):
                    operations = operationsByName[id]
                    info = AnalyzeOperation(interface, operations)
                    self.SecondaryContext(parent_interface)
                    self.AddOperation(info)

    def _RemoveShadowingOperationsWithSameSignature(self, operationsByName,
                                                    interface):
        if not interface.parents:
            return

        parent_name = interface.parents[0].type.id
        parent = self._database.GetInterface(parent_name)
        if parent == self._interface or parent == interface:
            return

        # Never remove operations that are added as a result of an implements they
        # are pure interfaces (mixins to this interface).
        if (IsPureInterface(parent_name, self._database)):
            return

        for operation in parent.operations:
            if operation.id in operationsByName:
                operations = operationsByName[operation.id]
                for existing_operation in operations:
                    if existing_operation.SameSignatureAs(operation):
                        del operationsByName[operation.id]

    def _AddRenamedOverloads(self, interface):
        """The IDL has a number of functions with the same name but that accept
    different types. This is fine for JavaScript, but results in vague type
    signatures for Dart. We rename some of these (by adding a new identical
    operation with a different DartName), but leave the original version as
    well in some cases."""
        potential_added_operations = set()
        operations_by_name = self._OperationsByName(interface)
        already_renamed = [
            operation.ext_attrs['DartName']
            if 'DartName' in operation.ext_attrs else ''
            for operation in interface.operations
        ]

        added_operations = []
        for operation in interface.operations:
            full_operation_str = self._GetStringRepresentation(
                interface, operation)
            if (full_operation_str in renamed_overloads and
                    renamed_overloads[full_operation_str] not in already_renamed
               ):
                if '%s.%s' % (interface.id,
                              operation.id) in overloaded_and_renamed:
                    cloned_operation = deepcopy(operation)
                    cloned_operation.ext_attrs['DartName'] = renamed_overloads[
                        full_operation_str]
                    added_operations.append(cloned_operation)
                else:
                    dart_name = renamed_overloads[full_operation_str]
                    if not dart_name:
                        continue

                    operation.ext_attrs['DartName'] = dart_name
                    potential_added_operations.add(operation.id)
            self._EnsureNoMultipleTypeSignatures(interface, operation,
                                                 operations_by_name)
        interface.operations += added_operations
        self._AddDesiredOverloadedOperations(potential_added_operations,
                                             interface, operations_by_name)

    def _AddDesiredOverloadedOperations(self, potential_added_operations,
                                        interface, original_operations_by_name):
        """For some cases we desire to keep the overloaded version in dart, for
    simplicity of API, and explain the parameters accepted in documentation."""
        updated_operations_by_name = self._OperationsByName(interface)
        for operation_id in potential_added_operations:
            if (operation_id not in updated_operations_by_name and '%s.%s' %
                (interface.id, operation_id) in keep_overloaded_members):
                for operation in original_operations_by_name[operation_id]:
                    cloned_operation = deepcopy(operation)
                    cloned_operation.ext_attrs['DartName'] = operation_id
                    interface.operations.append(cloned_operation)

    def _EnsureNoMultipleTypeSignatures(self, interface, operation,
                                        operations_by_name):
        """Make sure that there is now at most one operation with a particular
    operation.id. If not, stop library generation, and throw an error, requiring
    programmer input about the best name change before proceeding."""
        operation_str = '%s.%s' % (interface.id, operation.id)

        if (operation.id in operations_by_name and
                len(operations_by_name[operation.id]) > 1 and len(
                    filter(lambda overload: overload.startswith(operation_str),
                           renamed_overloads.keys())) == 0 and
                operation_str not in keep_overloaded_members and
                operation_str not in overloaded_and_renamed and
                operation_str not in renamed_html_members and
                operation_str not in private_html_members and
                operation_str not in removed_html_members and
                operation.id != '__getter__' and
                operation.id != '__setter__' and operation.id != '__delete__'):
            _logger.warn(
                'Multiple type signatures for %s.%s. Please file a bug with'
                ' the dart:html team to determine if one of these functions should be'
                ' renamed.' % (interface.id, operation.id))

    def _GetStringRepresentation(self, interface, operation):
        """Given an IDLOperation, return a object-independent representation of the
    operations's signature."""
        return '%s.%s(%s)' % (interface.id, operation.id, ', '.join(
            ['%s %s' % (arg.type.id, arg.id) for arg in operation.arguments]))

    def _OperationsByName(self, interface):
        operationsByName = {}
        for operation in interface.operations:
            name = operation.ext_attrs.get('DartName', operation.id)
            operationsByName.setdefault(name, []).append(operation)
        return operationsByName

    def OmitOperationOverrides(self):
        return False

    def AddConstant(self, constant):
        const_name = self._renamer.RenameMember(
            self._interface.id,
            constant,
            constant.id,
            'get:',
            dartify_name=False)
        if not const_name:
            return

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

        type = TypeOrNothing(self._DartType(constant.type.id), constant.type.id)
        self._members_emitter.Emit(
            '\n  $(ANNOTATIONS)static const $TYPE$NAME = $VALUE;\n',
            ANNOTATIONS=annotations,
            NAME=const_name,
            TYPE=type,
            VALUE=constant.value)

    def AddAttribute(self, attribute, declare_only=False):
        """ Adds an attribute to the generated class.
    Arguments:
      attribute - The attribute which is to be added.
      declare_only- True if the attribute should be declared as an abstract
        member and not include invocation code.
    """
        dom_name = DartDomNameOfAttribute(attribute)
        attr_name = self._renamer.RenameMember(self._interface.id, attribute,
                                               dom_name, 'get:')
        if not attr_name:
            return

        html_setter_name = self._renamer.RenameMember(
            self._interface.id, attribute, dom_name, 'set:')
        read_only = (attribute.is_read_only or
                     'Replaceable' in attribute.ext_attrs or
                     not html_setter_name)

        # We don't yet handle inconsistent renames of the getter and setter yet.
        assert (not html_setter_name or attr_name == html_setter_name)

        # any is assumed to be nullable
        if attribute.type.id == 'any':
            attribute.type.nullable = True

        if declare_only:
            self.DeclareAttribute(attribute, attr_name, read_only)
        else:
            self.EmitAttribute(attribute, attr_name, read_only)

    def AddOperation(self, info, declare_only=False, dart_js_interop=False):
        # TODO(terry): Hack window has 2 overloaded getter one returns Window and
        #              and other object (we'll always return Window)?
        if self._interface.id == "Window" and info.name == '__getter__':
            info.operations[1].type = info.operations[0].type
        """ Adds an operation to the generated class.
    Arguments:
      info - The operation info of the operation to be added.
      declare_only- True if the operation should be declared as an abstract
        member and not include invocation code.
    """
        # FIXME: When we pass in operations[0] below, we're assuming all
        # overloaded operations have the same security attributes.  This
        # is currently true, but we should consider filtering earlier or
        # merging the relevant data into info itself.
        method_name = self._renamer.RenameMember(
            self._interface.id, info.operations[0], info.name, 'call:')
        if not method_name:
            if info.name == 'item':
                # FIXME: item should be renamed to operator[], not removed.
                self.EmitOperation(info, '_item')
            return

        if declare_only:
            self.DeclareOperation(info,
                                  self.SecureOutputType(info.type_name,
                                      nullable=info.type_nullable),
                                  method_name)
        else:
            self.EmitOperation(info, method_name, dart_js_interop)

    def _GenerateOverloadDispatcher(
            self,
            info,
            signatures,
            is_void,
            declaration,
            generate_call,
            is_optional,
            emitter,
            can_omit_type_check=lambda type, pos: False):

        parameter_names = [p.name for p in info.param_infos]
        number_of_required_in_dart = info.NumberOfRequiredInDart()

        body_emitter = emitter.Emit('\n'
                                    '  $DECLARATION {\n'
                                    '$!BODY'
                                    '  }\n',
                                    DECLARATION=declaration)

        version = [0]

        def GenerateCall(signature_index, argument_count, checks):
            if checks:
                (stmts_emitter, call_emitter) = body_emitter.Emit(
                    '    if ($CHECKS) {\n$!STMTS$!CALL    }\n',
                    INDENT='      ',
                    CHECKS=' && '.join(checks))
            else:
                (stmts_emitter, call_emitter) = body_emitter.Emit(
                    '$!STMTS$!CALL', INDENT='    ')

            if is_void:
                call_emitter = call_emitter.Emit(
                    '$(INDENT)$!CALL;\n$(INDENT)return;\n')
            else:
                call_emitter = call_emitter.Emit('$(INDENT)return $!CALL;\n')

            version[0] += 1
            generate_call(stmts_emitter, call_emitter, version[0],
                          signature_index, argument_count)

        def IsTypeChecking(interface_argument):
            return 'LegacyInterfaceTypeChecking' in interface_argument.ext_attrs or \
            self._database.HasInterface(interface_argument.id)

        def GenerateChecksAndCall(signature_index, argument_count):
            checks = []
            typechecked_interface = IsTypeChecking(self._interface)

            for i in reversed(range(0, argument_count)):
                argument = signatures[signature_index][i]
                parameter_name = parameter_names[i]

                test_type = self._NarrowToImplementationType(argument.type.id)

                if test_type in ['dynamic', 'Object']:
                    checks.append('%s != null' % parameter_name)
                elif not can_omit_type_check(test_type, i):
                    typechecked = typechecked_interface or IsTypeChecking(
                        argument)
                    converts_null = \
                        ('TreatNullAs' in argument.ext_attrs) or \
                        (argument.default_value is not None) or \
                        (argument.default_value_is_null)
                    if argument.type.nullable or converts_null or not typechecked:
                        checks.append(
                            '(%s is %s || %s == null)' %
                            (parameter_name, test_type, parameter_name))
                    else:
                        checks.append(
                            '(%s is %s)' % (parameter_name, test_type))
                elif i >= number_of_required_in_dart and not argument.type.nullable:
                    checks.append('%s != null' % parameter_name)

            # There can be multiple presence checks.  We need them all since a later
            # optional argument could have been passed by name, leaving 'holes'.
            checks.extend([
                '%s == null' % name for name in parameter_names[argument_count:]
            ])

            GenerateCall(signature_index, argument_count, checks)

        # TODO: Optimize the dispatch to avoid repeated checks.
        if len(signatures) > 1:
            index_swaps = {}
            for signature_index, signature in enumerate(signatures):
                for argument_position, argument in enumerate(signature):
                    if argument.type.id != 'ArrayBuffer':
                        continue
                    candidates = enumerate(signatures[signature_index + 1:],
                                           signature_index + 1)
                    for candidate_index, candidate in candidates:
                        if len(candidate) <= argument_position:
                            continue
                        if candidate[
                                argument_position].type.id != 'ArrayBufferView':
                            continue
                        if len(index_swaps):
                            raise Exception(
                                'Cannot deal with more than a single swap')
                        index_swaps[candidate_index] = signature_index
                        index_swaps[signature_index] = candidate_index

            for signature_index in range(len(signatures)):
                signature_index = index_swaps.get(signature_index,
                                                  signature_index)
                signature = signatures[signature_index]
                for argument_position, argument in enumerate(signature):
                    if is_optional(signature_index, argument):
                        GenerateChecksAndCall(signature_index,
                                              argument_position)
                GenerateChecksAndCall(signature_index, len(signature))
            body_emitter.Emit(
                '    throw new ArgumentError("Incorrect number or type of arguments");'
                '\n')
        else:
            signature = signatures[0]
            argument_count = len(signature)
            for argument_position, argument in list(enumerate(signature))[::-1]:
                if is_optional(0, argument):
                    check = '%s != null' % parameter_names[argument_position]
                    # argument_count instead of argument_position + 1 is used here to cover one
                    # complicated case with the effectively optional argument in the middle.
                    # Consider foo(x, optional y, [Default=NullString] optional z)
                    # (as of now it's modelled after HTMLMediaElement.webkitAddKey).
                    # y is optional in WebCore, while z is not.
                    # In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation,
                    # not foo(x, y).
                    GenerateCall(0, argument_count, [check])
                    argument_count = argument_position
            GenerateCall(0, argument_count, [])

    def _GenerateDispatcherBody(self,
                                info,
                                operations,
                                declaration,
                                generate_call,
                                is_optional,
                                can_omit_type_check=lambda type, pos: False):

        def GenerateCall(stmts_emitter, call_emitter, version, signature_index,
                         argument_count):
            generate_call(stmts_emitter, call_emitter, version,
                          operations[signature_index], argument_count)

        def IsOptional(signature_index, argument):
            return is_optional(argument)

        emitter = self._members_emitter

        self._GenerateOverloadDispatcher(
            info, [operation.arguments for operation in operations],
            operations[0].type.id == 'void', declaration, GenerateCall,
            IsOptional, emitter, can_omit_type_check)

    def AdditionalImplementedInterfaces(self):
        # TODO: Include all implemented interfaces, including other Lists.
        implements = []
        if self._interface_type_info.list_item_type():
            item_type = self._type_registry.TypeInfo(
                self._interface_type_info.list_item_type()).dart_type()
            if self._interface_type_info.list_item_type_nullable():
                item_type += '?'
            implements.append('List<%s>' % item_type)
        return implements

    def Mixins(self):
        mixins = []
        if self._interface_type_info.list_item_type():
            item_type = self._type_registry.TypeInfo(
                self._interface_type_info.list_item_type()).dart_type()
            if self._interface_type_info.list_item_type_nullable():
                item_type += '?'
            mixins.append('ListMixin<%s>' % item_type)
            mixins.append('ImmutableListMixin<%s>' % item_type)

        return mixins

    def AddConstructors(self, constructors, factory_name,
                        factory_constructor_name):
        """ Adds all of the constructors.
    Arguments:
      constructors - List of the constructors to be added.
      factory_name - Name of the factory for this class.
      factory_constructor_name - The name of the constructor on the
          factory_name to call (calls an autogenerated FactoryProvider
          if unspecified)
    """
        for constructor_info in constructors:
            self._AddConstructor(constructor_info, factory_name,
                                 factory_constructor_name)

    def _AddConstructor(self, constructor_info, factory_name,
                        factory_constructor_name):
        # Hack to ignore the constructor used by JavaScript.
        if ((self._interface.id == 'HTMLImageElement' or
             self._interface.id == 'Blob' or
             self._interface.id == 'DOMException') and
                not constructor_info.pure_dart_constructor):
            return

        if self.GenerateCustomFactory(constructor_info):
            return

        metadata = self._metadata.GetFormattedMetadata(
            self._library_name, self._interface, self._interface.id, '  ')

        if not factory_constructor_name:
            factory_constructor_name = '_create'
            factory_parameters = constructor_info.ParametersAsArgumentList()
        else:
            factory_parameters = ', '.join(constructor_info.factory_parameters)

        def InputType(type_name):
            conversion = self._InputConversion(type_name,
                                               constructor_info.declared_name)
            if conversion:
                return conversion.input_type
            else:
                return self._NarrowInputType(
                    type_name) if type_name else 'dynamic'

        if constructor_info.pure_dart_constructor:
            # TODO(antonm): use common dispatcher generation for this case as well.
            has_optional = any(param_info.is_optional
                               for param_info in constructor_info.param_infos)
            factory_call = self.MakeFactoryCall(
                factory_name, factory_constructor_name, factory_parameters,
                constructor_info)
            if not has_optional:
                self._members_emitter.Emit(
                    '\n  $(METADATA)'
                    'factory $CTOR($PARAMS) => '
                    '$FACTORY_CALL;\n',
                    CTOR=constructor_info._ConstructorFullName(self._DartType),
                    PARAMS=constructor_info.ParametersAsDeclaration(InputType),
                    FACTORY_CALL=factory_call,
                    METADATA=metadata)
            else:
                inits = self._members_emitter.Emit(
                    '\n  $(METADATA)'
                    'factory $CONSTRUCTOR($PARAMS) {\n'
                    '    $CONSTRUCTOR e = $FACTORY_CALL;\n'
                    '$!INITS'
                    '    return e;\n'
                    '  }\n',
                    CONSTRUCTOR=constructor_info._ConstructorFullName(
                        self._DartType),
                    METADATA=metadata,
                    FACTORY_CALL=factory_call,
                    PARAMS=constructor_info.ParametersAsDeclaration(InputType))

                for index, param_info in enumerate(
                        constructor_info.param_infos):
                    if param_info.is_optional:
                        inits.Emit(
                            '    if ($E != null) e.$E = $E;\n',
                            E=param_info.name)
        else:
            custom_factory_ctr = self._interface.id in _custom_factories
            if self._interface_type_info.has_generated_interface():
                constructor_full_name = constructor_info._ConstructorFullName(
                    self._DartType)
            else:
                # The interface is suppress_interface so use the implementation_name not
                # the dart_type.
                constructor_full_name = self._interface_type_info.implementation_name(
                )
                factory_name = constructor_full_name

            def GenerateCall(stmts_emitter, call_emitter, version,
                             signature_index, argument_count):
                name = emitter.Format('_create_$VERSION', VERSION=version)
                arguments = constructor_info.idl_args[
                    signature_index][:argument_count]
                args = None
                call_template = ''
                if self._dart_use_blink:
                    type_ids = [p.type.id for p in arguments]
                    base_name, rs = \
                        self.DeriveNativeEntry("constructorCallback", 'Constructor', argument_count)
                    qualified_name = \
                        self.DeriveQualifiedBlinkName(self._interface.id,
                                                      base_name)
                    args = constructor_info.ParametersAsArgumentList(
                        argument_count)

                    # Handle converting Maps to Dictionaries, etc.
                    (factory_params, converted_arguments,
                     calling_params) = self._ConvertArgumentTypes(
                         stmts_emitter, arguments, argument_count,
                         constructor_info)
                    args = ', '.join(converted_arguments)
                    call_template = '$FACTORY_NAME($FACTORY_PARAMS)'
                else:
                    qualified_name = emitter.Format(
                        '$FACTORY.$NAME', FACTORY=factory_name, NAME=name)
                    (factory_params, converted_arguments,
                     calling_params) = self._ConvertArgumentTypes(
                         stmts_emitter, arguments, argument_count,
                         constructor_info)
                    args = ', '.join(converted_arguments)
                    call_template = '$FACTORY_NAME($FACTORY_PARAMS)'
                call_emitter.Emit(
                    call_template,
                    FACTORY_NAME=qualified_name,
                    FACTORY_PARAMS=args)
                self.EmitStaticFactoryOverload(constructor_info, name,
                                               arguments)

            def IsOptional(signature_index, argument):
                return self.IsConstructorArgumentOptional(argument)

            entry_declaration = emitter.Format(
                '$(METADATA)$FACTORY_KEYWORD $CTOR($PARAMS)',
                FACTORY_KEYWORD=('factory' if not custom_factory_ctr else
                                 'static %s' % constructor_full_name),
                CTOR=(('' if not custom_factory_ctr else '_factory') +
                      constructor_full_name),
                METADATA=metadata,
                PARAMS=constructor_info.ParametersAsDeclaration(InputType))

            overload_emitter = self._members_emitter
            overload_declaration = entry_declaration

            self._GenerateOverloadDispatcher(constructor_info,
                                             constructor_info.idl_args, False,
                                             overload_declaration, GenerateCall,
                                             IsOptional, overload_emitter)

    def _AddFutureifiedOperation(self, info, html_name):
        """Given a API function that uses callbacks, convert it to using Futures.

    This conversion assumes the success callback is always provided before the
    error callback (and so far in the DOM API, this is the case)."""
        callback_info = GetCallbackInfo(
            self._database.GetInterface(info.callback_args[0].type_id))

        # Generated private members never have named arguments.
        ignore_named_parameters = True if html_name.startswith('_') else False

        # If more than one callback then the second argument is the error callback.
        # Some error callbacks have 2 args (e.g., executeSql) where the second arg
        # is the error - this is the argument we want.
        error_callback = ""
        if len(info.callback_args) > 1:
            error_callback_info = GetCallbackInfo(
                self._database.GetInterface(info.callback_args[1].type_id))
            error_callbackNames = []
            for paramInfo in error_callback_info.param_infos:
                error_callbackNames.append(paramInfo.name)
            errorCallbackVariables = ", ".join(error_callbackNames)
            errorName = error_callback_info.param_infos[-1].name
            error_callback = (
                ',\n        %s(%s) { completer.completeError(%s); }' % (
                    ('%s : ' % info.callback_args[1].name
                     if info.requires_named_arguments and
                     info.callback_args[1].is_optional and
                     not (ignore_named_parameters) else ''),
                    errorCallbackVariables, errorName))

        extensions = GetDDC_Extension(self._interface, info.declared_name)
        if extensions:
            ddc_extensions = "\n".join(extensions)
        else:
            ddc_extensions = ''

        # Some callbacks have more than one parameters.  If so use all of
        # those parameters.  However, if more than one argument use the
        # type of the last argument to be returned e.g., executeSql the callback
        # is (transaction, resultSet) and only the resultSet is returned SqlResultSet.
        callbackArgsLen = len(callback_info.param_infos)
        future_generic = ''
        callbackVariables = ''
        completerVariable = ''
        if callbackArgsLen == 1:
            callbackVariables = 'value'
            completerVariable = callbackVariables
            if callback_info.param_infos[0].type_id:
                future_generic = '<%s>' % self._DartType(
                    callback_info.param_infos[0].type_id)
        elif callbackArgsLen > 1:
            callbackNames = []
            for paramInfo in callback_info.param_infos:
                callbackNames.append(paramInfo.name)
            callbackVariables = ",".join(callbackNames)
            completerVariable = callbackNames[-1]
            future_generic = '<%s>' % self._DartType(
                callback_info.param_infos[-1].type_id)

        param_list = info.ParametersAsArgumentList(None,
                                                   ignore_named_parameters)
        dictionary_argument = info.dictionaryArgumentName()

        convert_map = ''
        if dictionary_argument is not None:
            mapArg = dictionary_argument[0]
            tempVariable = '%s_dict' % mapArg
            mapArgOptional = dictionary_argument[1]

            if not (extensions):
                if not (param_list.endswith(', mapArg') or
                        param_list.endswith(', options') or
                        param_list == mapArg):
                    print(
                        "ERROR: %s.%s - Last parameter or only parameter %s is not of type Map"
                        % (self._interface.id, html_name, mapArg))
                param_list = '%s_dict' % param_list

                if mapArgOptional:
                    convert_map = '    var %s = null;\n'\
                                  '    if (%s != null) {\n'\
                                  '      %s = convertDartToNative_Dictionary(%s);\n'\
                                  '    }\n' % (tempVariable, mapArg, tempVariable, mapArg)
                else:
                    convert_map = '    var %s = convertDartToNative_Dictionary(%s);\n' % (
                        tempVariable, mapArg)

        metadata = ''
        if '_RenamingAnnotation' in dir(self):
            metadata = (
                self._RenamingAnnotation(info.declared_name, html_name) +
                self._Metadata(info.type_name, info.declared_name, None,
                    info.type_nullable))
        self._members_emitter.Emit(
            '\n'
            '  $METADATA$MODIFIERS$TYPE$FUTURE_GENERIC $NAME($PARAMS) {\n'
            '    $CONVERT_DICTIONARY'
            '    var completer = new Completer$(FUTURE_GENERIC)();\n'
            '    $ORIGINAL_FUNCTION($PARAMS_LIST\n'
            '        $NAMED_PARAM($VARIABLE_NAME) { '
            '$DDC_EXTENSION\n'
            'completer.complete($COMPLETER_NAME); }'
            '$ERROR_CALLBACK);\n'
            '    return completer.future;\n'
            '  }\n',
            METADATA=metadata,
            MODIFIERS='static ' if info.IsStatic() else '',
            TYPE=self.SecureOutputType(info.type_name,
                nullable=info.type_nullable),
            NAME=html_name[1:],
            PARAMS=info.
            ParametersAsDeclaration(self._NarrowInputType if '_NarrowInputType'
                                    in dir(self) else self._DartType),
            CONVERT_DICTIONARY=convert_map,
            PARAMS_LIST='' if param_list == '' else param_list + ',',
            NAMED_PARAM=('%s : ' % info.callback_args[0].name
                         if info.requires_named_arguments and
                         info.callback_args[0].is_optional and
                         not (ignore_named_parameters) else ''),
            VARIABLE_NAME=callbackVariables,
            COMPLETER_NAME=completerVariable,
            DDC_EXTENSION=ddc_extensions,
            ERROR_CALLBACK=error_callback,
            FUTURE_GENERIC=future_generic,
            ORIGINAL_FUNCTION=html_name)

    def EmitHelpers(self, base_class):
        if not self._members_emitter:
            return

        if self._interface.id not in custom_html_constructors:
            self._members_emitter.Emit(
                '  // To suppress missing implicit constructor warnings.\n'
                '  factory $CLASSNAME._() { '
                'throw new UnsupportedError("Not supported"); }\n',
                CLASSNAME=self._interface_type_info.implementation_name())

    def DeclareAttribute(self, attribute, attr_name, read_only):
        """ Declares an attribute but does not include the code to invoke it.
    """
        if read_only:
            # HACK(terry): Element is not abstract for Dartium so isContentEditable
            # must have a body see impl_Element.darttemplate
            if (self._interface.id == 'Element' and
                    attr_name == 'isContentEditable' and self._dart_js_interop):
                return
            else:
                template = '\n  $TYPE get $NAME;\n'
        else:
            template = '\n  $TYPE get $NAME native;\n' \
                       '\n  set $NAME($TYPE value) native;\n'

        # Nullability is determined by attribute compatibility.
        is_compat = self._mdn_reader.is_compatible(attribute)
        nullable = attribute.type.nullable or not is_compat

        self._members_emitter.Emit(template,
                                   NAME=attr_name,
                                   TYPE=self.SecureOutputType(
                                       attribute.type.id, nullable=nullable))

    def DeclareOperation(self, operation, return_type_name, method_name):
        """ Declares an operation but does not include the code to invoke it.
    Arguments:
      operation - The operation to be declared.
      return_type_name - The name of the return type.
      method_name - The name of the method.
    """
        # HACK(terry): Element is not abstract for Dartium so click
        # must have a body see impl_Element.darttemplate
        if (self._interface.id == 'Element' and method_name == 'click' and
                self._dart_js_interop):
            return
        else:
            template = '\n  $TYPE $NAME($PARAMS);\n'

        self._members_emitter.Emit(
            template,
            TYPE=return_type_name,
            NAME=method_name,
            PARAMS=operation.ParametersAsDeclaration(self._DartType))

    def EmitListMixin(self, element_name, nullable):
        # TODO(sra): Use separate mixins for mutable implementations of List<T>.
        # TODO(sra): Use separate mixins for typed array implementations of List<T>.
        template_file = 'immutable_list_mixin.darttemplate'
        has_length = False
        has_length_setter = False

        def _HasExplicitIndexedGetter(self):
            return any(op.id == 'getItem' for op in self._interface.operations)

        def _HasCustomIndexedGetter(self):
            return 'CustomIndexedGetter' in self._interface.ext_attrs

        def _HasNativeIndexedGetter(self):
            return not (_HasCustomIndexedGetter(self) or
                        _HasExplicitIndexedGetter(self))

        if _HasExplicitIndexedGetter(self):
            getter_name = 'getItem'
        else:
            getter_name = '_nativeIndexedGetter'

        for attr in self._interface.attributes:
            if attr.id == 'length':
                has_length = True
                has_length_setter = not attr.is_read_only

        has_num_items = any(
            attr.id == 'numberOfItems' for attr in self._interface.attributes)

        template = self._template_loader.Load(
            template_file, {
                'DEFINE_LENGTH_AS_NUM_ITEMS':
                not has_length and has_num_items,
                'DEFINE_LENGTH_SETTER':
                not has_length_setter,
                'USE_NATIVE_INDEXED_GETTER':
                _HasNativeIndexedGetter(self) or
                _HasExplicitIndexedGetter(self),
            })
        if nullable:
            element_js = element_name + "|Null"
            element_name += '?'
        else:
            element_js = element_name
        self._members_emitter.Emit(
            template, E=element_name, EJS=element_js, GETTER=getter_name)

    def SecureOutputType(self,
                         type_name,
                         is_dart_type=False,
                         can_narrow_type=False,
                         nullable=False):
        """ Converts the type name to the secure type name for return types.
    Arguments:
      can_narrow_type - True if the output type can be narrowed further than
        what would be accepted for input, used to narrow num APIs down to double
        or int.
    """
        if is_dart_type:
            dart_name = type_name
        else:
            type_info = self._TypeInfo(type_name)
            dart_name = type_info.dart_type()
            if can_narrow_type and dart_name == 'num':
                dart_name = type_info.native_type()

        # We only need to secure Window.  Only local History and Location are
        # returned in generated code.
        assert (dart_name != 'HistoryBase' and dart_name != 'LocationBase')
        if dart_name == 'Window':
            dart_name = _secure_base_types[dart_name]
        if type_name == 'any':
            dart_name = 'Object'
        if nullable and dart_name != 'dynamic':
            dart_name = dart_name + '?'
        return dart_name

    def SecureBaseName(self, type_name):
        if type_name in _secure_base_types:
            return _secure_base_types[type_name]

    def is_DOM_type(self, type_name):
        try:
            self._type_registry.TypeInfo(type_name)
            return True
        except RuntimeError:
            return False

    def _NarrowToImplementationType(self, type_name):
        return self._type_registry.TypeInfo(type_name).narrow_dart_type()

    def _NarrowInputType(self, type_name):
        return self._NarrowToImplementationType(type_name)

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

    def _TypeInfo(self, type_name):
        return self._type_registry.TypeInfo(type_name)

    def _CallbackConvert(self, argType, info):
        if self._database.HasInterface(argType):
            interface = self._database.GetInterface(argType)
            if "Callback" in interface.ext_attrs:
                return interface.ext_attrs['Callback']
        return None

    def _ConvertArgumentTypes(self, stmts_emitter, arguments, argument_count,
                              info):
        temp_version = [0]
        converted_arguments = []
        target_parameters = []
        calling_parameters = []
        for position, arg in enumerate(arguments[:argument_count]):
            callBackInfo = self._CallbackConvert(
                arg.type.id, info)  # Returns callback arity (# of parameters)
            if callBackInfo is None:
                conversion = self._InputConversion(arg.type.id,
                                                   info.declared_name)
            else:
                conversion = self._InputConversion('Callback',
                                                   info.declared_name)

            param_name = arguments[position].id
            if conversion:
                temp_version[0] += 1
                temp_name = '%s_%s' % (param_name, temp_version[0])
                temp_type = conversion.output_type
                null_assert_needed = info.param_infos[position].is_nullable \
                    and not conversion.nullable_input
                stmts_emitter.Emit(
                    '$(INDENT)$TYPE $NAME = $CONVERT($ARG$NULLASSERT);\n'
                    if callBackInfo is None else
                    '$(INDENT)$TYPE $NAME = $CONVERT($ARG$NULLASSERT, $ARITY);\n',
                    TYPE=TypeOrVar(temp_type),
                    NAME=temp_name,
                    CONVERT=conversion.function_name,
                    ARG=info.param_infos[position].name,
                    NULLASSERT='!' if null_assert_needed else '',
                    ARITY=callBackInfo)
                converted_arguments.append(temp_name)
                param_type = temp_type
                verified_type = temp_type  # verified by assignment in checked mode.
            else:
                converted_arguments.append(info.param_infos[position].name)
                if self._database.HasTypeDef(arg.type.id):
                    param_type = 'dynamic'
                else:
                    param_type = self._NarrowInputType(arg.type.id)
                    # Verified by argument checking on entry to the dispatcher.

                    verified_type = self._InputType(
                        info.param_infos[position].type_id, info)
                    # The native method does not need an argument type if we know the type.
                    # But we do need the native methods to have correct function types, so
                    # be conservative.
                    if param_type == verified_type:
                        if param_type in [
                                'String', 'num', 'int', 'double', 'bool',
                                'Object'
                        ]:
                            param_type = 'dynamic'
            arg_is_nullable = arg.type.nullable
            # If the parameter is either nullable or optional with no non-null
            # default value, it is nullable.
            if (info.param_infos[position].is_optional and
                (info.param_infos[position].default_value_is_null == True or
                 info.param_infos[position].default_value == None)
               ) or info.param_infos[position].is_nullable:
                arg_is_nullable = True
            target_parameters.append(
                '%s%s' % (TypeOrNothing(param_type, nullable=arg_is_nullable),
                          param_name))
            calling_parameters.append(',%s ' % param_name)

        return target_parameters, converted_arguments, calling_parameters

    def _InputType(self, type_name, info):
        conversion = self._InputConversion(type_name, info.declared_name)
        if conversion:
            return conversion.input_type
        else:
            # If typedef it's a union return dynamic.
            if self._database.HasTypeDef(type_name):
                return 'dynamic'
            else:
                return self._NarrowInputType(
                    type_name) if type_name else 'dynamic'
