# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# pylint: disable=relative-import

"""Blink IDL Intermediate Representation (IR) classes.

Classes are primarily constructors, which build an IdlDefinitions object
(and various contained objects) from an AST (produced by blink_idl_parser).

IR stores typedefs and they are resolved by the code generator.

Typedef resolution uses some auxiliary classes and OOP techniques to make this
a generic call. See TypedefResolver class in code_generator_v8.py.

Class hierarchy (mostly containment, '<' for inheritance):

IdlDefinitions
    IdlCallbackFunction < TypedObject
    IdlEnum :: FIXME: remove, just use a dict for enums
    IdlInterface
        IdlAttribute < TypedObject
        IdlConstant < TypedObject
        IdlLiteral
        IdlOperation < TypedObject
            IdlArgument < TypedObject
        IdlSerializer
        IdlStringifier
        IdlIterable < IdlIterableOrMaplikeOrSetlike
        IdlMaplike < IdlIterableOrMaplikeOrSetlike
        IdlSetlike < IdlIterableOrMaplikeOrSetlike
    IdlException < IdlInterface
        (same contents as IdlInterface)

TypedObject :: Object with one or more attributes that is a type.

IdlArgument is 'picklable', as it is stored in interfaces_info.

Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
"""

import abc

from idl_types import IdlArrayType
from idl_types import IdlFrozenArrayType
from idl_types import IdlNullableType
from idl_types import IdlPromiseType
from idl_types import IdlRecordType
from idl_types import IdlSequenceType
from idl_types import IdlType
from idl_types import IdlUnionType

SPECIAL_KEYWORD_LIST = ['LEGACYCALLER', 'GETTER', 'SETTER', 'DELETER']


################################################################################
# TypedObject
################################################################################

class TypedObject(object):
    """Object with a type, such as an Attribute or Operation (return value).

    The type can be an actual type, or can be a typedef, which must be resolved
    by the TypedefResolver before passing data to the code generator.
    """
    __metaclass__ = abc.ABCMeta
    idl_type_attributes = ('idl_type',)


################################################################################
# Definitions (main container class)
################################################################################

class IdlDefinitions(object):
    def __init__(self, node):
        """Args: node: AST root node, class == 'File'"""
        self.callback_functions = {}
        self.dictionaries = {}
        self.enumerations = {}
        self.implements = []
        self.interfaces = {}
        self.typedefs = {}

        node_class = node.GetClass()
        if node_class != 'File':
            raise ValueError('Unrecognized node class: %s' % node_class)

        children = node.GetChildren()
        for child in children:
            child_class = child.GetClass()
            if child_class == 'Interface':
                interface = IdlInterface(child)
                self.interfaces[interface.name] = interface
            elif child_class == 'Exception':
                exception = IdlException(child)
                # For simplicity, treat exceptions as interfaces
                self.interfaces[exception.name] = exception
            elif child_class == 'Typedef':
                typedef = IdlTypedef(child)
                self.typedefs[typedef.name] = typedef
            elif child_class == 'Enum':
                enumeration = IdlEnum(child)
                self.enumerations[enumeration.name] = enumeration
            elif child_class == 'Callback':
                callback_function = IdlCallbackFunction(child)
                self.callback_functions[callback_function.name] = callback_function
            elif child_class == 'Implements':
                self.implements.append(IdlImplement(child))
            elif child_class == 'Dictionary':
                dictionary = IdlDictionary(child)
                self.dictionaries[dictionary.name] = dictionary
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

    def accept(self, visitor):
        visitor.visit_definitions(self)
        for interface in self.interfaces.values():
            interface.accept(visitor)
        for callback_function in self.callback_functions.values():
            callback_function.accept(visitor)
        for dictionary in self.dictionaries.values():
            dictionary.accept(visitor)
        for enumeration in self.enumerations.values():
            enumeration.accept(visitor)
        for implement in self.implements:
            implement.accept(visitor)
        for typedef in self.typedefs.values():
            typedef.accept(visitor)

    def update(self, other):
        """Update with additional IdlDefinitions."""
        for interface_name, new_interface in other.interfaces.items():
            if not new_interface.is_partial:
                # Add as new interface
                self.interfaces[interface_name] = new_interface
            else:
                # Merge partial to existing interface
                try:
                    self.interfaces[interface_name].merge(new_interface)
                except KeyError:
                    raise Exception('Tried to merge partial interface for {0}, '
                                    'but no existing interface by that name'
                                    .format(interface_name))

            # Merge callbacks and enumerations
            self.enumerations.update(other.enumerations)
            self.callback_functions.update(other.callback_functions)


################################################################################
# Callback Functions
################################################################################

class IdlCallbackFunction(TypedObject):
    def __init__(self, node):
        children = node.GetChildren()
        num_children = len(children)
        if num_children < 2 or num_children > 3:
            raise ValueError('Expected 2 or 3 children, got %s' % num_children)
        type_node = children[0]
        arguments_node = children[1]
        if num_children == 3:
            ext_attributes_node = children[2]
            self.extended_attributes = (
                ext_attributes_node_to_extended_attributes(ext_attributes_node))
        else:
            self.extended_attributes = {}
        arguments_node_class = arguments_node.GetClass()
        if arguments_node_class != 'Arguments':
            raise ValueError('Expected Arguments node, got %s' % arguments_node_class)

        self.name = node.GetName()
        self.idl_type = type_node_to_type(type_node)
        self.arguments = arguments_node_to_arguments(arguments_node)

    def accept(self, visitor):
        visitor.visit_callback_function(self)
        for argument in self.arguments:
            argument.accept(visitor)


################################################################################
# Dictionary
################################################################################

class IdlDictionary(object):
    def __init__(self, node):
        self.extended_attributes = {}
        self.is_partial = bool(node.GetProperty('Partial'))
        self.name = node.GetName()
        self.members = []
        self.parent = None
        for child in node.GetChildren():
            child_class = child.GetClass()
            if child_class == 'Inherit':
                self.parent = child.GetName()
            elif child_class == 'Key':
                self.members.append(IdlDictionaryMember(child))
            elif child_class == 'ExtAttributes':
                self.extended_attributes = (
                    ext_attributes_node_to_extended_attributes(child))
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

    def accept(self, visitor):
        visitor.visit_dictionary(self)
        for member in self.members:
            member.accept(visitor)


class IdlDictionaryMember(TypedObject):
    def __init__(self, node):
        self.default_value = None
        self.extended_attributes = {}
        self.idl_type = None
        self.is_required = bool(node.GetProperty('REQUIRED'))
        self.name = node.GetName()
        for child in node.GetChildren():
            child_class = child.GetClass()
            if child_class == 'Type':
                self.idl_type = type_node_to_type(child)
            elif child_class == 'Default':
                self.default_value = default_node_to_idl_literal(child)
            elif child_class == 'ExtAttributes':
                self.extended_attributes = (
                    ext_attributes_node_to_extended_attributes(child))
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

    def accept(self, visitor):
        visitor.visit_dictionary_member(self)


################################################################################
# Enumerations
################################################################################

class IdlEnum(object):
    def __init__(self, node):
        self.name = node.GetName()
        self.values = []
        for child in node.GetChildren():
            self.values.append(child.GetName())

    def accept(self, visitor):
        visitor.visit_enumeration(self)


################################################################################
# Typedefs
################################################################################

class IdlTypedef(object):
    idl_type_attributes = ('idl_type',)

    def __init__(self, node):
        self.name = node.GetName()
        self.idl_type = typedef_node_to_type(node)

    def accept(self, visitor):
        visitor.visit_typedef(self)


################################################################################
# Interfaces and Exceptions
################################################################################

class IdlInterface(object):
    def __init__(self, node=None):
        self.attributes = []
        self.constants = []
        self.constructors = []
        self.custom_constructors = []
        self.extended_attributes = {}
        self.operations = []
        self.parent = None
        self.serializer = None
        self.stringifier = None
        self.iterable = None
        self.has_indexed_elements = False
        self.maplike = None
        self.setlike = None
        self.original_interface = None
        self.partial_interfaces = []
        if not node:  # Early exit for IdlException.__init__
            return

        self.is_callback = bool(node.GetProperty('CALLBACK'))
        self.is_exception = False
        # FIXME: uppercase 'Partial' => 'PARTIAL' in base IDL parser
        self.is_partial = bool(node.GetProperty('Partial'))
        self.name = node.GetName()
        self.idl_type = IdlType(self.name)

        has_indexed_property_getter = False
        has_integer_typed_length = False

        children = node.GetChildren()
        for child in children:
            child_class = child.GetClass()
            if child_class == 'Attribute':
                attr = IdlAttribute(child)
                if attr.idl_type.is_integer_type and attr.name == 'length':
                    has_integer_typed_length = True
                self.attributes.append(attr)
            elif child_class == 'Const':
                self.constants.append(IdlConstant(child))
            elif child_class == 'ExtAttributes':
                extended_attributes = ext_attributes_node_to_extended_attributes(child)
                self.constructors, self.custom_constructors = (
                    extended_attributes_to_constructors(extended_attributes))
                clear_constructor_attributes(extended_attributes)
                self.extended_attributes = extended_attributes
            elif child_class == 'Operation':
                op = IdlOperation(child)
                if 'getter' in op.specials and str(op.arguments[0].idl_type) == 'unsigned long':
                    has_indexed_property_getter = True
                self.operations.append(op)
            elif child_class == 'Inherit':
                self.parent = child.GetName()
            elif child_class == 'Serializer':
                self.serializer = IdlSerializer(child)
                self.process_serializer()
            elif child_class == 'Stringifier':
                self.stringifier = IdlStringifier(child)
                self.process_stringifier()
            elif child_class == 'Iterable':
                self.iterable = IdlIterable(child)
            elif child_class == 'Maplike':
                self.maplike = IdlMaplike(child)
            elif child_class == 'Setlike':
                self.setlike = IdlSetlike(child)
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

        if len(list(filter(None, [self.iterable, self.maplike, self.setlike]))) > 1:
            raise ValueError('Interface can only have one of iterable<>, maplike<> and setlike<>.')

        if has_integer_typed_length and has_indexed_property_getter:
            self.has_indexed_elements = True
        else:
            if self.iterable is not None and self.iterable.key_type is None:
                raise ValueError('Value iterators (iterable<V>) must be accompanied by an indexed '
                                 'property getter and an integer-typed length attribute.')

    def accept(self, visitor):
        visitor.visit_interface(self)
        for attribute in self.attributes:
            attribute.accept(visitor)
        for constant in self.constants:
            constant.accept(visitor)
        for constructor in self.constructors:
            constructor.accept(visitor)
        for custom_constructor in self.custom_constructors:
            custom_constructor.accept(visitor)
        for operation in self.operations:
            operation.accept(visitor)
        if self.iterable:
            self.iterable.accept(visitor)
        elif self.maplike:
            self.maplike.accept(visitor)
        elif self.setlike:
            self.setlike.accept(visitor)

    def process_serializer(self):
        """Add the serializer's named operation child, if it has one, as a regular
        operation of this interface."""
        if self.serializer.operation:
            self.operations.append(self.serializer.operation)

    def process_stringifier(self):
        """Add the stringifier's attribute or named operation child, if it has
        one, as a regular attribute/operation of this interface."""
        if self.stringifier.attribute:
            self.attributes.append(self.stringifier.attribute)
        elif self.stringifier.operation:
            self.operations.append(self.stringifier.operation)

    def merge(self, other):
        """Merge in another interface's members (e.g., partial interface)"""
        self.attributes.extend(other.attributes)
        self.constants.extend(other.constants)
        self.operations.extend(other.operations)
        if self.serializer is None:
            self.serializer = other.serializer
        if self.stringifier is None:
            self.stringifier = other.stringifier


class IdlException(IdlInterface):
    # Properly exceptions and interfaces are distinct, and thus should inherit a
    # common base class (say, "IdlExceptionOrInterface").
    # However, there is only one exception (DOMException), and new exceptions
    # are not expected. Thus it is easier to implement exceptions as a
    # restricted subclass of interfaces.
    # http://www.w3.org/TR/WebIDL/#idl-exceptions
    def __init__(self, node):
        # Exceptions are similar to Interfaces, but simpler
        IdlInterface.__init__(self)
        self.is_callback = False
        self.is_exception = True
        self.is_partial = False
        self.name = node.GetName()
        self.idl_type = IdlType(self.name)

        children = node.GetChildren()
        for child in children:
            child_class = child.GetClass()
            if child_class == 'Attribute':
                attribute = IdlAttribute(child)
                self.attributes.append(attribute)
            elif child_class == 'Const':
                self.constants.append(IdlConstant(child))
            elif child_class == 'ExtAttributes':
                extended_attributes = ext_attributes_node_to_extended_attributes(child)
                self.constructors, self.custom_constructors = (
                    extended_attributes_to_constructors(extended_attributes))
                clear_constructor_attributes(extended_attributes)
                self.extended_attributes = extended_attributes
            elif child_class == 'ExceptionOperation':
                self.operations.append(IdlOperation.from_exception_operation_node(child))
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)


################################################################################
# Attributes
################################################################################

class IdlAttribute(TypedObject):
    def __init__(self, node=None):
        self.is_read_only = bool(node.GetProperty('READONLY')) if node else False
        self.is_static = bool(node.GetProperty('STATIC')) if node else False
        self.name = node.GetName() if node else None
        self.idl_type = None
        self.extended_attributes = {}

        if node:
            children = node.GetChildren()
            for child in children:
                child_class = child.GetClass()
                if child_class == 'Type':
                    self.idl_type = type_node_to_type(child)
                elif child_class == 'ExtAttributes':
                    self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
                else:
                    raise ValueError('Unrecognized node class: %s' % child_class)

    def accept(self, visitor):
        visitor.visit_attribute(self)

    def __lt__(self, other):
        return id(self) < id(other)


################################################################################
# Constants
################################################################################

class IdlConstant(TypedObject):
    def __init__(self, node):
        children = node.GetChildren()
        num_children = len(children)
        if num_children < 2 or num_children > 3:
            raise ValueError('Expected 2 or 3 children, got %s' % num_children)
        type_node = children[0]
        value_node = children[1]
        value_node_class = value_node.GetClass()
        if value_node_class != 'Value':
            raise ValueError('Expected Value node, got %s' % value_node_class)

        self.name = node.GetName()
        # ConstType is more limited than Type, so subtree is smaller and
        # we don't use the full type_node_to_type function.
        self.idl_type = type_node_inner_to_type(type_node)
        # FIXME: This code is unnecessarily complicated due to the rather
        # inconsistent way the upstream IDL parser outputs default values.
        # http://crbug.com/374178
        if value_node.GetProperty('TYPE') == 'float':
            self.value = value_node.GetProperty('VALUE')
        else:
            self.value = value_node.GetName()

        if num_children == 3:
            ext_attributes_node = children[2]
            self.extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)
        else:
            self.extended_attributes = {}

    def accept(self, visitor):
        visitor.visit_constant(self)


################################################################################
# Literals
################################################################################

class IdlLiteral(object):
    def __init__(self, idl_type, value):
        self.idl_type = idl_type
        self.value = value
        self.is_null = False

    def __str__(self):
        if self.idl_type == 'DOMString':
            if self.value:
                return '"%s"' % self.value
            else:
                return '""'
        if self.idl_type == 'integer':
            return '%d' % self.value
        if self.idl_type == 'float':
            return '%g' % self.value
        if self.idl_type == 'boolean':
            return 'true' if self.value else 'false'
        raise ValueError('Unsupported literal type: %s' % self.idl_type)


class IdlLiteralNull(IdlLiteral):
    def __init__(self):
        self.idl_type = 'NULL'
        self.value = None
        self.is_null = True

    def __str__(self):
        return 'NULL'


def default_node_to_idl_literal(node):
    # FIXME: This code is unnecessarily complicated due to the rather
    # inconsistent way the upstream IDL parser outputs default values.
    # http://crbug.com/374178
    idl_type = node.GetProperty('TYPE')
    if idl_type == 'DOMString':
        value = node.GetProperty('NAME')
        if '"' in value or '\\' in value:
            raise ValueError('Unsupported string value: %r' % value)
        return IdlLiteral(idl_type, value)
    if idl_type == 'integer':
        return IdlLiteral(idl_type, int(node.GetProperty('NAME'), base=0))
    if idl_type == 'float':
        return IdlLiteral(idl_type, float(node.GetProperty('VALUE')))
    if idl_type in ['boolean', 'sequence']:
        return IdlLiteral(idl_type, node.GetProperty('VALUE'))
    if idl_type == 'NULL':
        return IdlLiteralNull()
    raise ValueError('Unrecognized default value type: %s' % idl_type)


################################################################################
# Operations
################################################################################

class IdlOperation(TypedObject):
    def __init__(self, node=None):
        self.arguments = []
        self.extended_attributes = {}
        self.specials = []
        self.is_constructor = False
        self.idl_type = None
        self.is_static = False

        if not node:
            return

        self.name = node.GetName()  # FIXME: should just be: or ''
        # FIXME: AST should use None internally
        if self.name == '_unnamed_':
            self.name = ''

        self.is_static = bool(node.GetProperty('STATIC'))
        property_dictionary = node.GetProperties()
        for special_keyword in SPECIAL_KEYWORD_LIST:
            if special_keyword in property_dictionary:
                self.specials.append(special_keyword.lower())

        children = node.GetChildren()
        for child in children:
            child_class = child.GetClass()
            if child_class == 'Arguments':
                self.arguments = arguments_node_to_arguments(child)
            elif child_class == 'Type':
                self.idl_type = type_node_to_type(child)
            elif child_class == 'ExtAttributes':
                self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

    @classmethod
    def from_exception_operation_node(cls, node):
        # Needed to handle one case in DOMException.idl:
        # // Override in a Mozilla compatible format
        # [NotEnumerable] DOMString toString();
        # FIXME: can we remove this? replace with a stringifier?
        operation = cls()
        operation.name = node.GetName()
        children = node.GetChildren()
        if len(children) < 1 or len(children) > 2:
            raise ValueError('ExceptionOperation node with %s children, expected 1 or 2' % len(children))

        type_node = children[0]
        operation.idl_type = type_node_to_type(type_node)

        if len(children) > 1:
            ext_attributes_node = children[1]
            operation.extended_attributes = ext_attributes_node_to_extended_attributes(ext_attributes_node)

        return operation

    @classmethod
    def constructor_from_arguments_node(cls, name, arguments_node):
        constructor = cls()
        constructor.name = name
        constructor.arguments = arguments_node_to_arguments(arguments_node)
        constructor.is_constructor = True
        return constructor

    def accept(self, visitor):
        visitor.visit_operation(self)
        for argument in self.arguments:
            argument.accept(visitor)


################################################################################
# Arguments
################################################################################

class IdlArgument(TypedObject):
    def __init__(self, node=None):
        self.extended_attributes = {}
        self.idl_type = None
        self.is_optional = False  # syntax: (optional T)
        self.is_variadic = False  # syntax: (T...)
        self.default_value = None

        if not node:
            return

        self.is_optional = node.GetProperty('OPTIONAL')
        self.name = node.GetName()

        children = node.GetChildren()
        for child in children:
            child_class = child.GetClass()
            if child_class == 'Type':
                self.idl_type = type_node_to_type(child)
            elif child_class == 'ExtAttributes':
                self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
            elif child_class == 'Argument':
                child_name = child.GetName()
                if child_name != '...':
                    raise ValueError('Unrecognized Argument node; expected "...", got "%s"' % child_name)
                self.is_variadic = bool(child.GetProperty('ELLIPSIS'))
            elif child_class == 'Default':
                self.default_value = default_node_to_idl_literal(child)
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

    def accept(self, visitor):
        visitor.visit_argument(self)


def arguments_node_to_arguments(node):
    # [Constructor] and [CustomConstructor] without arguments (the bare form)
    # have None instead of an arguments node, but have the same meaning as using
    # an empty argument list, [Constructor()], so special-case this.
    # http://www.w3.org/TR/WebIDL/#Constructor
    if node is None:
        return []
    return [IdlArgument(argument_node) for argument_node in node.GetChildren()]


################################################################################
# Serializers
################################################################################

class IdlSerializer(object):
    def __init__(self, node):
        self.attribute_name = node.GetProperty('ATTRIBUTE')
        self.attribute_names = None
        self.operation = None
        self.extended_attributes = {}
        self.is_attribute = False
        self.is_getter = False
        self.is_inherit = False
        self.is_list = False
        self.is_map = False

        for child in node.GetChildren():
            child_class = child.GetClass()
            if child_class == 'Operation':
                self.operation = IdlOperation(child)
            elif child_class == 'List':
                self.is_list = True
                self.is_getter = bool(child.GetProperty('GETTER'))
                self.attributes = child.GetProperty('ATTRIBUTES')
            elif child_class == 'Map':
                self.is_map = True
                self.is_attribute = bool(child.GetProperty('ATTRIBUTE'))
                self.is_getter = bool(child.GetProperty('GETTER'))
                self.is_inherit = bool(child.GetProperty('INHERIT'))
                self.attributes = child.GetProperty('ATTRIBUTES')
            elif child_class == 'ExtAttributes':
                self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)


################################################################################
# Stringifiers
################################################################################

class IdlStringifier(object):
    def __init__(self, node):
        self.attribute = None
        self.operation = None
        self.extended_attributes = {}

        for child in node.GetChildren():
            child_class = child.GetClass()
            if child_class == 'Attribute':
                self.attribute = IdlAttribute(child)
            elif child_class == 'Operation':
                operation = IdlOperation(child)
                if operation.name:
                    self.operation = operation
            elif child_class == 'ExtAttributes':
                self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)

        # Copy the stringifier's extended attributes (such as [Unforgable]) onto
        # the underlying attribute or operation, if there is one.
        if self.attribute or self.operation:
            (self.attribute or self.operation).extended_attributes.update(
                self.extended_attributes)


################################################################################
# Iterable, Maplike, Setlike
################################################################################

class IdlIterableOrMaplikeOrSetlike(TypedObject):
    def __init__(self, node):
        self.extended_attributes = {}
        self.type_children = []

        for child in node.GetChildren():
            child_class = child.GetClass()
            if child_class == 'ExtAttributes':
                self.extended_attributes = ext_attributes_node_to_extended_attributes(child)
            elif child_class == 'Type':
                self.type_children.append(child)
            else:
                raise ValueError('Unrecognized node class: %s' % child_class)


class IdlIterable(IdlIterableOrMaplikeOrSetlike):
    idl_type_attributes = ('key_type', 'value_type')

    def __init__(self, node):
        super(IdlIterable, self).__init__(node)

        if len(self.type_children) == 1:
            self.key_type = None
            self.value_type = type_node_to_type(self.type_children[0])
        elif len(self.type_children) == 2:
            self.key_type = type_node_to_type(self.type_children[0])
            self.value_type = type_node_to_type(self.type_children[1])
        else:
            raise ValueError('Unexpected number of type children: %d' % len(self.type_children))
        del self.type_children

    def accept(self, visitor):
        visitor.visit_iterable(self)


class IdlMaplike(IdlIterableOrMaplikeOrSetlike):
    idl_type_attributes = ('key_type', 'value_type')

    def __init__(self, node):
        super(IdlMaplike, self).__init__(node)

        self.is_read_only = bool(node.GetProperty('READONLY'))

        if len(self.type_children) == 2:
            self.key_type = type_node_to_type(self.type_children[0])
            self.value_type = type_node_to_type(self.type_children[1])
        else:
            raise ValueError('Unexpected number of children: %d' % len(self.type_children))
        del self.type_children

    def accept(self, visitor):
        visitor.visit_maplike(self)


class IdlSetlike(IdlIterableOrMaplikeOrSetlike):
    idl_type_attributes = ('value_type',)

    def __init__(self, node):
        super(IdlSetlike, self).__init__(node)

        self.is_read_only = bool(node.GetProperty('READONLY'))

        if len(self.type_children) == 1:
            self.value_type = type_node_to_type(self.type_children[0])
        else:
            raise ValueError('Unexpected number of children: %d' % len(self.type_children))
        del self.type_children

    def accept(self, visitor):
        visitor.visit_setlike(self)


################################################################################
# Implement statements
################################################################################

class IdlImplement(object):
    def __init__(self, node):
        self.left_interface = node.GetName()
        self.right_interface = node.GetProperty('REFERENCE')

    def accept(self, visitor):
        visitor.visit_implement(self)


################################################################################
# Extended attributes
################################################################################

class Exposure:
    """An Exposure holds one Exposed or RuntimeEnabled condition.
    Each exposure has two properties: exposed and runtime_enabled.
    Exposure(e, r) corresponds to [Exposed(e r)]. Exposure(e) corresponds to
    [Exposed=e].
    """
    def __init__(self, exposed, runtime_enabled=None):
        self.exposed = exposed
        self.runtime_enabled = runtime_enabled


def ext_attributes_node_to_extended_attributes(node):
    """
    Returns:
      Dictionary of {ExtAttributeName: ExtAttributeValue}.
      Value is usually a string, with these exceptions:
      Constructors: value is a list of Arguments nodes, corresponding to
        possible signatures of the constructor.
      CustomConstructors: value is a list of Arguments nodes, corresponding to
        possible signatures of the custom constructor.
      NamedConstructor: value is a Call node, corresponding to the single
        signature of the named constructor.
      SetWrapperReferenceTo: value is an Arguments node.
    """
    # Primarily just make a dictionary from the children.
    # The only complexity is handling various types of constructors:
    # Constructors and Custom Constructors can have duplicate entries due to
    # overloading, and thus are stored in temporary lists.
    # However, Named Constructors cannot be overloaded, and thus do not have
    # a list.
    # FIXME: move Constructor logic into separate function, instead of modifying
    #        extended attributes in-place.
    constructors = []
    custom_constructors = []
    extended_attributes = {}

    def child_node(extended_attribute_node):
        children = extended_attribute_node.GetChildren()
        if not children:
            return None
        if len(children) > 1:
            raise ValueError('ExtAttributes node with %s children, expected at most 1' % len(children))
        return children[0]

    extended_attribute_node_list = node.GetChildren()
    for extended_attribute_node in extended_attribute_node_list:
        name = extended_attribute_node.GetName()
        child = child_node(extended_attribute_node)
        child_class = child and child.GetClass()
        if name == 'Constructor':
            if child_class and child_class != 'Arguments':
                raise ValueError('Constructor only supports Arguments as child, but has child of class: %s' % child_class)
            constructors.append(child)
        elif name == 'CustomConstructor':
            if child_class and child_class != 'Arguments':
                raise ValueError('[CustomConstructor] only supports Arguments as child, but has child of class: %s' % child_class)
            custom_constructors.append(child)
        elif name == 'NamedConstructor':
            if child_class and child_class != 'Call':
                raise ValueError('[NamedConstructor] only supports Call as child, but has child of class: %s' % child_class)
            extended_attributes[name] = child
        elif name == 'SetWrapperReferenceTo':
            if not child:
                raise ValueError('[SetWrapperReferenceTo] requires a child, but has none.')
            children = child.GetChildren()
            if len(children) != 1:
                raise ValueError('[SetWrapperReferenceTo] supports only one child.')
            if child_class != 'Arguments':
                raise ValueError('[SetWrapperReferenceTo] only supports Arguments as child, but has child of class: %s' % child_class)
            extended_attributes[name] = IdlArgument(children[0])
        elif name == 'Exposed':
            if child_class and child_class != 'Arguments':
                raise ValueError('[Exposed] only supports Arguments as child, but has child of class: %s' % child_class)
            exposures = []
            if child_class == 'Arguments':
                exposures = [Exposure(exposed=str(arg.idl_type),
                                      runtime_enabled=arg.name)
                             for arg in arguments_node_to_arguments(child)]
            else:
                value = extended_attribute_node.GetProperty('VALUE')
                if type(value) is str:
                    exposures = [Exposure(exposed=value)]
                else:
                    exposures = [Exposure(exposed=v) for v in value]
            extended_attributes[name] = exposures
        elif child:
            raise ValueError('ExtAttributes node with unexpected children: %s' % name)
        else:
            value = extended_attribute_node.GetProperty('VALUE')
            extended_attributes[name] = value

    # Store constructors and custom constructors in special list attributes,
    # which are deleted later. Note plural in key.
    if constructors:
        extended_attributes['Constructors'] = constructors
    if custom_constructors:
        extended_attributes['CustomConstructors'] = custom_constructors

    return extended_attributes


def extended_attributes_to_constructors(extended_attributes):
    """Returns constructors and custom_constructors (lists of IdlOperations).

    Auxiliary function for IdlInterface.__init__.
    """

    constructor_list = extended_attributes.get('Constructors', [])
    constructors = [
        IdlOperation.constructor_from_arguments_node('Constructor', arguments_node)
        for arguments_node in constructor_list]

    custom_constructor_list = extended_attributes.get('CustomConstructors', [])
    custom_constructors = [
        IdlOperation.constructor_from_arguments_node('CustomConstructor', arguments_node)
        for arguments_node in custom_constructor_list]

    if 'NamedConstructor' in extended_attributes:
        # FIXME: support overloaded named constructors, and make homogeneous
        name = 'NamedConstructor'
        call_node = extended_attributes['NamedConstructor']
        extended_attributes['NamedConstructor'] = call_node.GetName()
        children = call_node.GetChildren()
        if len(children) != 1:
            raise ValueError('NamedConstructor node expects 1 child, got %s.' % len(children))
        arguments_node = children[0]
        named_constructor = IdlOperation.constructor_from_arguments_node('NamedConstructor', arguments_node)
        # FIXME: should return named_constructor separately; appended for Perl
        constructors.append(named_constructor)

    return constructors, custom_constructors


def clear_constructor_attributes(extended_attributes):
    # Deletes Constructor*s* (plural), sets Constructor (singular)
    if 'Constructors' in extended_attributes:
        del extended_attributes['Constructors']
        extended_attributes['Constructor'] = None
    if 'CustomConstructors' in extended_attributes:
        del extended_attributes['CustomConstructors']
        extended_attributes['CustomConstructor'] = None


################################################################################
# Types
################################################################################

def type_node_to_type(node):
    children = node.GetChildren()
    if len(children) < 1 or len(children) > 2:
        raise ValueError('Type node expects 1 or 2 children (type + optional array []), got %s (multi-dimensional arrays are not supported).' % len(children))

    base_type = type_node_inner_to_type(children[0])

    if node.GetProperty('NULLABLE'):
        base_type = IdlNullableType(base_type)

    if len(children) == 2:
        array_node = children[1]
        array_node_class = array_node.GetClass()
        if array_node_class != 'Array':
            raise ValueError('Expected Array node as TypeSuffix, got %s node.' % array_node_class)
        array_type = IdlArrayType(base_type)
        if array_node.GetProperty('NULLABLE'):
            return IdlNullableType(array_type)
        return array_type

    return base_type


def type_node_inner_to_type(node):
    node_class = node.GetClass()
    # Note Type*r*ef, not Typedef, meaning the type is an identifier, thus
    # either a typedef shorthand (but not a Typedef declaration itself) or an
    # interface type. We do not distinguish these, and just use the type name.
    if node_class in ['PrimitiveType', 'StringType', 'Typeref']:
        # unrestricted syntax: unrestricted double | unrestricted float
        is_unrestricted = bool(node.GetProperty('UNRESTRICTED'))
        return IdlType(node.GetName(), is_unrestricted=is_unrestricted)
    elif node_class == 'Any':
        return IdlType('any')
    elif node_class in ['Sequence', 'FrozenArray']:
        return sequence_node_to_type(node)
    elif node_class == 'UnionType':
        return union_type_node_to_idl_union_type(node)
    elif node_class == 'Promise':
        return promise_node_to_type(node)
    elif node_class == 'Record':
        return record_node_to_type(node)
    raise ValueError('Unrecognized node class: %s' % node_class)


def record_node_to_type(node):
    children = node.GetChildren()
    if len(children) != 2:
        raise ValueError('record<K,V> node expects exactly 2 children, got %d' % (len(children)))
    key_child = children[0]
    value_child = children[1]
    if key_child.GetClass() != 'StringType':
        raise ValueError('Keys in record<K,V> nodes must be string types.')
    if value_child.GetClass() != 'Type':
        raise ValueError('Unrecognized node class for record<K,V> value: %s' % value_child.GetClass())
    return IdlRecordType(IdlType(key_child.GetName()), type_node_to_type(value_child))


def sequence_node_to_type(node):
    children = node.GetChildren()
    class_name = node.GetClass()
    if len(children) != 1:
        raise ValueError('%s node expects exactly 1 child, got %s' % (class_name, len(children)))
    sequence_child = children[0]
    sequence_child_class = sequence_child.GetClass()
    if sequence_child_class != 'Type':
        raise ValueError('Unrecognized node class: %s' % sequence_child_class)
    element_type = type_node_to_type(sequence_child)
    if class_name == 'Sequence':
        sequence_type = IdlSequenceType(element_type)
    elif class_name == 'FrozenArray':
        sequence_type = IdlFrozenArrayType(element_type)
    else:
        raise ValueError('Unexpected node: %s' % class_name)
    if node.GetProperty('NULLABLE'):
        return IdlNullableType(sequence_type)
    return sequence_type


def typedef_node_to_type(node):
    children = node.GetChildren()
    if len(children) != 1:
        raise ValueError('Typedef node with %s children, expected 1' % len(children))
    child = children[0]
    child_class = child.GetClass()
    if child_class != 'Type':
        raise ValueError('Unrecognized node class: %s' % child_class)
    return type_node_to_type(child)


def union_type_node_to_idl_union_type(node):
    member_types = [type_node_to_type(member_type_node)
                    for member_type_node in node.GetChildren()]
    return IdlUnionType(member_types)


def promise_node_to_type(node):
    children = node.GetChildren()
    class_name = node.GetClass()
    if len(children) != 1:
        raise ValueError('%s node expects exactly 1 child, got %s' % (class_name, len(children)))
    promise_child = children[0]
    promise_child_class = promise_child.GetClass()
    if promise_child_class != 'Type':
        raise ValueError('Unrecognized node class: %s' % sequence_child_class)
    element_type = type_node_to_type(promise_child)
    if class_name == 'Promise':
        promise_type = IdlPromiseType(element_type)
    else:
        raise ValueError('Unexpected node: %s' % class_name)
    return promise_type


################################################################################
# Visitor
################################################################################

class Visitor(object):
    """Abstract visitor class for IDL definitions traverse."""

    def visit_definitions(self, definitions):
        pass

    def visit_typed_object(self, typed_object):
        pass

    def visit_callback_function(self, callback_function):
        self.visit_typed_object(callback_function)

    def visit_dictionary(self, dictionary):
        pass

    def visit_dictionary_member(self, member):
        self.visit_typed_object(member)

    def visit_enumeration(self, enumeration):
        pass

    def visit_implement(self, implement):
        pass

    def visit_interface(self, interface):
        pass

    def visit_typedef(self, typedef):
        self.visit_typed_object(typedef)

    def visit_attribute(self, attribute):
        self.visit_typed_object(attribute)

    def visit_constant(self, constant):
        self.visit_typed_object(constant)

    def visit_operation(self, operation):
        self.visit_typed_object(operation)

    def visit_argument(self, argument):
        self.visit_typed_object(argument)

    def visit_iterable(self, iterable):
        self.visit_typed_object(iterable)

    def visit_maplike(self, maplike):
        self.visit_typed_object(maplike)

    def visit_setlike(self, setlike):
        self.visit_typed_object(setlike)
