#!/usr/bin/env python
# Copyright (c) 2011 Google Inc. All rights reserved.
# Copyright (c) 2012 Intel Corporation. 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.

import os.path
import sys
import string
import optparse
import re
try:
    import json
except ImportError:
    import simplejson as json

import CodeGeneratorInspectorStrings

# Manually-filled map of type name replacements.
TYPE_NAME_FIX_MAP = {
    "RGBA": "Rgba",  # RGBA is reported to be conflicting with a define name in Windows CE.
    "": "Empty",
}


TYPES_WITH_RUNTIME_CAST_SET = frozenset(["Runtime.RemoteObject", "Runtime.PropertyDescriptor", "Runtime.InternalPropertyDescriptor",
                                         "Debugger.FunctionDetails", "Debugger.CallFrame", "Debugger.Location",
                                         "Canvas.TraceLog", "Canvas.ResourceState"])

TYPES_WITH_OPEN_FIELD_LIST_SET = frozenset([
                                            # InspectorStyleSheet not only creates this property but wants to read it and modify it.
                                            "CSS.CSSProperty",
                                            # InspectorResourceAgent needs to update mime-type.
                                            "Network.Response"])

EXACTLY_INT_SUPPORTED = False

cmdline_parser = optparse.OptionParser()
cmdline_parser.add_option("--output_dir")

try:
    arg_options, arg_values = cmdline_parser.parse_args()
    if (len(arg_values) != 1):
        raise Exception("Exactly one plain argument expected (found %s)" % len(arg_values))
    input_json_filename = arg_values[0]
    output_dirname = arg_options.output_dir
    if not output_dirname:
        raise Exception("Output directory must be specified")
except Exception:
    # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html
    exc = sys.exc_info()[1]
    sys.stderr.write("Failed to parse command-line arguments: %s\n\n" % exc)
    sys.stderr.write("Usage: <script> --output_dir <output_dir> protocol.json\n")
    exit(1)


# FIXME: move this methods under Capitalizer class below and remove duplications.
def dash_to_camelcase(word):
    return ''.join(x.capitalize() or '-' for x in word.split('-'))


def fix_camel_case(name):
    refined = re.sub(r'-(\w)', lambda pat: pat.group(1).upper(), name)
    refined = to_title_case(refined)
    return re.sub(r'(?i)HTML|XML|WML|API', lambda pat: pat.group(0).upper(), refined)


def to_title_case(name):
    return name[:1].upper() + name[1:]


class Capitalizer:
    @staticmethod
    def lower_camel_case_to_upper(str):
        if len(str) > 0 and str[0].islower():
            str = str[0].upper() + str[1:]
        return str

    @staticmethod
    def upper_camel_case_to_lower(str):
        pos = 0
        while pos < len(str) and str[pos].isupper():
            pos += 1
        if pos == 0:
            return str
        if pos == 1:
            return str[0].lower() + str[1:]
        if pos < len(str):
            pos -= 1
        possible_abbreviation = str[0:pos]
        if possible_abbreviation not in Capitalizer.ABBREVIATION:
            raise Exception("Unknown abbreviation %s" % possible_abbreviation)
        str = possible_abbreviation.lower() + str[pos:]
        return str

    @staticmethod
    def camel_case_to_capitalized_with_underscores(str):
        if len(str) == 0:
            return str
        output = Capitalizer.split_camel_case_(str)
        return "_".join(output).upper()

    @staticmethod
    def split_camel_case_(str):
        output = []
        pos_being = 0
        pos = 1
        has_oneletter = False
        while pos < len(str):
            if str[pos].isupper():
                output.append(str[pos_being:pos].upper())
                if pos - pos_being == 1:
                    has_oneletter = True
                pos_being = pos
            pos += 1
        output.append(str[pos_being:])
        if has_oneletter:
            array_pos = 0
            while array_pos < len(output) - 1:
                if len(output[array_pos]) == 1:
                    array_pos_end = array_pos + 1
                    while array_pos_end < len(output) and len(output[array_pos_end]) == 1:
                        array_pos_end += 1
                    if array_pos_end - array_pos > 1:
                        possible_abbreviation = "".join(output[array_pos:array_pos_end])
                        if possible_abbreviation.upper() in Capitalizer.ABBREVIATION:
                            output[array_pos:array_pos_end] = [possible_abbreviation]
                        else:
                            array_pos = array_pos_end - 1
                array_pos += 1
        return output

    ABBREVIATION = frozenset(["XHR", "DOM", "CSS"])

VALIDATOR_IFDEF_NAME = "ASSERT_ENABLED"


class DomainNameFixes:
    @classmethod
    def get_fixed_data(cls, domain_name):
        field_name_res = Capitalizer.upper_camel_case_to_lower(domain_name) + "Agent"

        class Res(object):
            agent_field_name = field_name_res

        return Res


class RawTypes(object):
    @staticmethod
    def get(json_type):
        if json_type == "boolean":
            return RawTypes.Bool
        elif json_type == "string":
            return RawTypes.String
        elif json_type == "array":
            return RawTypes.Array
        elif json_type == "object":
            return RawTypes.Object
        elif json_type == "integer":
            return RawTypes.Int
        elif json_type == "number":
            return RawTypes.Number
        elif json_type == "any":
            return RawTypes.Any
        else:
            raise Exception("Unknown type: %s" % json_type)

    # For output parameter all values are passed by pointer except RefPtr-based types.
    class OutputPassModel:
        class ByPointer:
            @staticmethod
            def get_argument_prefix():
                return "&"

            @staticmethod
            def get_parameter_type_suffix():
                return "*"

        class ByReference:
            @staticmethod
            def get_argument_prefix():
                return ""

            @staticmethod
            def get_parameter_type_suffix():
                return "&"

    class BaseType(object):
        need_internal_runtime_cast_ = False

        @classmethod
        def request_raw_internal_runtime_cast(cls):
            if not cls.need_internal_runtime_cast_:
                cls.need_internal_runtime_cast_ = True

        @classmethod
        def get_raw_validator_call_text(cls):
            return "RuntimeCastHelper::assertType<JSONValue::Type%s>" % cls.get_validate_method_params().template_type

        @staticmethod
        def get_validate_method_params():
            raise Exception("Abstract method")

    class String(BaseType):
        @staticmethod
        def get_getter_name():
            return "String"

        get_setter_name = get_getter_name

        @staticmethod
        def get_constructor_pattern():
            return "InspectorString::create(%s)"

        @staticmethod
        def get_c_initializer():
            return "\"\""

        @staticmethod
        def get_validate_method_params():
            class ValidateMethodParams:
                template_type = "String"
            return ValidateMethodParams

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByPointer

        @staticmethod
        def is_heavy_value():
            return True

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "String"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.String

    class Int(BaseType):
        @staticmethod
        def get_getter_name():
            return "Int"

        @staticmethod
        def get_setter_name():
            return "Number"

        @staticmethod
        def get_constructor_pattern():
            return "InspectorBasicValue::create(%s)"

        @staticmethod
        def get_c_initializer():
            return "0"

        @classmethod
        def get_raw_validator_call_text(cls):
            return "RuntimeCastHelper::assertInt"

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByPointer

        @staticmethod
        def is_heavy_value():
            return False

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "int"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.Int

    class Number(BaseType):
        @staticmethod
        def get_getter_name():
            return "Double"

        @staticmethod
        def get_setter_name():
            return "Number"

        @staticmethod
        def get_constructor_pattern():
            return "InspectorBasicValue::create(%s)"

        @staticmethod
        def get_c_initializer():
            return "0"

        @staticmethod
        def get_validate_method_params():
            class ValidateMethodParams:
                template_type = "Number"
            return ValidateMethodParams

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByPointer

        @staticmethod
        def is_heavy_value():
            return False

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "double"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.Number

    class Bool(BaseType):
        @staticmethod
        def get_getter_name():
            return "Boolean"

        get_setter_name = get_getter_name

        @staticmethod
        def get_constructor_pattern():
            return "InspectorBasicValue::create(%s)"

        @staticmethod
        def get_c_initializer():
            return "false"

        @staticmethod
        def get_validate_method_params():
            class ValidateMethodParams:
                template_type = "Boolean"
            return ValidateMethodParams

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByPointer

        @staticmethod
        def is_heavy_value():
            return False

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "bool"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.Bool

    class Object(BaseType):
        @staticmethod
        def get_getter_name():
            return "Object"

        @staticmethod
        def get_setter_name():
            return "Value"

        @staticmethod
        def get_constructor_pattern():
            return "%s"

        @staticmethod
        def get_c_initializer():
            return "JSONObject::create()"

        @staticmethod
        def get_output_argument_prefix():
            return ""

        @staticmethod
        def get_validate_method_params():
            class ValidateMethodParams:
                template_type = "Object"
            return ValidateMethodParams

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByReference

        @staticmethod
        def is_heavy_value():
            return True

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "JSONObject"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.Object

    class Any(BaseType):
        @staticmethod
        def get_getter_name():
            return "Value"

        get_setter_name = get_getter_name

        @staticmethod
        def get_c_initializer():
            raise Exception("Unsupported")

        @staticmethod
        def get_constructor_pattern():
            raise Exception("Unsupported")

        @staticmethod
        def get_raw_validator_call_text():
            return "RuntimeCastHelper::assertAny"

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByReference

        @staticmethod
        def is_heavy_value():
            return True

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "JSONValue"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.Any

    class Array(BaseType):
        @staticmethod
        def get_getter_name():
            return "Array"

        @staticmethod
        def get_setter_name():
            return "Value"

        @staticmethod
        def get_constructor_pattern():
            return "%s"

        @staticmethod
        def get_c_initializer():
            return "JSONArray::create()"

        @staticmethod
        def get_output_argument_prefix():
            return ""

        @staticmethod
        def get_validate_method_params():
            class ValidateMethodParams:
                template_type = "Array"
            return ValidateMethodParams

        @staticmethod
        def get_output_pass_model():
            return RawTypes.OutputPassModel.ByReference

        @staticmethod
        def is_heavy_value():
            return True

        @staticmethod
        def get_array_item_raw_c_type_text():
            return "JSONArray"

        @staticmethod
        def get_raw_type_model():
            return TypeModel.Array


def replace_right_shift(input_str):
    return input_str.replace(">>", "> >")


class CommandReturnPassModel:
    class ByReference:
        def __init__(self, var_type, set_condition):
            self.var_type = var_type
            self.set_condition = set_condition

        def get_return_var_type(self):
            return self.var_type

        @staticmethod
        def get_output_argument_prefix():
            return ""

        @staticmethod
        def get_output_to_raw_expression():
            return "%s"

        def get_output_parameter_type(self):
            return self.var_type + "&"

        def get_set_return_condition(self):
            return self.set_condition

    class ByPointer:
        def __init__(self, var_type):
            self.var_type = var_type

        def get_return_var_type(self):
            return self.var_type

        @staticmethod
        def get_output_argument_prefix():
            return "&"

        @staticmethod
        def get_output_to_raw_expression():
            return "%s"

        def get_output_parameter_type(self):
            return self.var_type + "*"

        @staticmethod
        def get_set_return_condition():
            return None

    class OptOutput:
        def __init__(self, var_type):
            self.var_type = var_type

        def get_return_var_type(self):
            return "TypeBuilder::OptOutput<%s>" % self.var_type

        @staticmethod
        def get_output_argument_prefix():
            return "&"

        @staticmethod
        def get_output_to_raw_expression():
            return "%s.getValue()"

        def get_output_parameter_type(self):
            return "TypeBuilder::OptOutput<%s>*" % self.var_type

        @staticmethod
        def get_set_return_condition():
            return "%s.isAssigned()"


class TypeModel:
    class RefPtrBased(object):
        def __init__(self, class_name):
            self.class_name = class_name
            self.optional = False

        def get_optional(self):
            result = TypeModel.RefPtrBased(self.class_name)
            result.optional = True
            return result

        def get_command_return_pass_model(self):
            if self.optional:
                set_condition = "%s"
            else:
                set_condition = None
            return CommandReturnPassModel.ByReference(replace_right_shift("RefPtr<%s>" % self.class_name), set_condition)

        def get_input_param_type_text(self):
            return replace_right_shift("PassRefPtr<%s>" % self.class_name)

        @staticmethod
        def get_event_setter_expression_pattern():
            return "%s"

    class Enum(object):
        def __init__(self, base_type_name):
            self.type_name = base_type_name + "::Enum"

        def get_optional(base_self):
            class EnumOptional:
                @classmethod
                def get_optional(cls):
                    return cls

                @staticmethod
                def get_command_return_pass_model():
                    return CommandReturnPassModel.OptOutput(base_self.type_name)

                @staticmethod
                def get_input_param_type_text():
                    return base_self.type_name + "*"

                @staticmethod
                def get_event_setter_expression_pattern():
                    raise Exception("TODO")
            return EnumOptional

        def get_command_return_pass_model(self):
            return CommandReturnPassModel.ByPointer(self.type_name)

        def get_input_param_type_text(self):
            return self.type_name

        @staticmethod
        def get_event_setter_expression_pattern():
            return "%s"

    class ValueType(object):
        def __init__(self, type_name, is_heavy):
            self.type_name = type_name
            self.is_heavy = is_heavy

        def get_optional(self):
            return self.ValueOptional(self)

        def get_command_return_pass_model(self):
            return CommandReturnPassModel.ByPointer(self.type_name)

        def get_input_param_type_text(self):
            if self.is_heavy:
                return "const %s&" % self.type_name
            else:
                return self.type_name

        def get_opt_output_type_(self):
            return self.type_name

        @staticmethod
        def get_event_setter_expression_pattern():
            return "%s"

        class ValueOptional:
            def __init__(self, base):
                self.base = base

            def get_optional(self):
                return self

            def get_command_return_pass_model(self):
                return CommandReturnPassModel.OptOutput(self.base.get_opt_output_type_())

            def get_input_param_type_text(self):
                return "const %s* const" % self.base.type_name

            @staticmethod
            def get_event_setter_expression_pattern():
                return "*%s"

    class ExactlyInt(ValueType):
        def __init__(self):
            TypeModel.ValueType.__init__(self, "int", False)

        def get_input_param_type_text(self):
            return "TypeBuilder::ExactlyInt"

        def get_opt_output_type_(self):
            return "TypeBuilder::ExactlyInt"

    @classmethod
    def init_class(cls):
        cls.Bool = cls.ValueType("bool", False)
        if EXACTLY_INT_SUPPORTED:
            cls.Int = cls.ExactlyInt()
        else:
            cls.Int = cls.ValueType("int", False)
        cls.Number = cls.ValueType("double", False)
        cls.String = cls.ValueType("String", True,)
        cls.Object = cls.RefPtrBased("JSONObject")
        cls.Array = cls.RefPtrBased("JSONArray")
        cls.Any = cls.RefPtrBased("JSONValue")

TypeModel.init_class()


# Collection of JSONObject class methods that are likely to be overloaded in generated class.
# We must explicitly import all overloaded methods or they won't be available to user.
INSPECTOR_OBJECT_SETTER_NAMES = frozenset(["setValue", "setBoolean", "setNumber", "setString", "setValue", "setObject", "setArray"])


def fix_type_name(json_name):
    if json_name in TYPE_NAME_FIX_MAP:
        fixed = TYPE_NAME_FIX_MAP[json_name]

        class Result(object):
            class_name = fixed

            @staticmethod
            def output_comment(writer):
                writer.newline("// Type originally was named '%s'.\n" % json_name)
    else:

        class Result(object):
            class_name = json_name

            @staticmethod
            def output_comment(writer):
                pass

    return Result


class Writer:
    def __init__(self, output, indent):
        self.output = output
        self.indent = indent

    def newline(self, str):
        if (self.indent):
            self.output.append(self.indent)
        self.output.append(str)

    def append(self, str):
        self.output.append(str)

    def newline_multiline(self, str):
        parts = str.split('\n')
        self.newline(parts[0])
        for p in parts[1:]:
            self.output.append('\n')
            if p:
                self.newline(p)

    def append_multiline(self, str):
        parts = str.split('\n')
        self.append(parts[0])
        for p in parts[1:]:
            self.output.append('\n')
            if p:
                self.newline(p)

    def get_indent(self):
        return self.indent

    def get_indented(self, additional_indent):
        return Writer(self.output, self.indent + additional_indent)

    def insert_writer(self, additional_indent):
        new_output = []
        self.output.append(new_output)
        return Writer(new_output, self.indent + additional_indent)


class EnumConstants:
    map_ = {}
    constants_ = []

    @classmethod
    def add_constant(cls, value):
        if value in cls.map_:
            return cls.map_[value]
        else:
            pos = len(cls.map_)
            cls.map_[value] = pos
            cls.constants_.append(value)
            return pos

    @classmethod
    def get_enum_constant_code(cls):
        output = []
        for item in cls.constants_:
            output.append("    \"" + item + "\"")
        return ",\n".join(output) + "\n"


# Typebuilder code is generated in several passes: first typedefs, then other classes.
# Manual pass management is needed because we cannot have forward declarations for typedefs.
class TypeBuilderPass:
    TYPEDEF = "typedef"
    MAIN = "main"


class TypeBindings:
    @staticmethod
    def create_named_type_declaration(json_typable, context_domain_name, type_data):
        json_type = type_data.get_json_type()

        class Helper:
            is_ad_hoc = False
            full_name_prefix_for_use = "TypeBuilder::" + context_domain_name + "::"
            full_name_prefix_for_impl = "TypeBuilder::" + context_domain_name + "::"

            @staticmethod
            def write_doc(writer):
                if "description" in json_type:
                    writer.newline("/* ")
                    writer.append(json_type["description"])
                    writer.append(" */\n")

            @staticmethod
            def add_to_forward_listener(forward_listener):
                forward_listener.add_type_data(type_data)


        fixed_type_name = fix_type_name(json_type["id"])
        return TypeBindings.create_type_declaration_(json_typable, context_domain_name, fixed_type_name, Helper)

    @staticmethod
    def create_ad_hoc_type_declaration(json_typable, context_domain_name, ad_hoc_type_context):
        class Helper:
            is_ad_hoc = True
            full_name_prefix_for_use = ad_hoc_type_context.container_relative_name_prefix
            full_name_prefix_for_impl = ad_hoc_type_context.container_full_name_prefix

            @staticmethod
            def write_doc(writer):
                pass

            @staticmethod
            def add_to_forward_listener(forward_listener):
                pass
        fixed_type_name = ad_hoc_type_context.get_type_name_fix()
        return TypeBindings.create_type_declaration_(json_typable, context_domain_name, fixed_type_name, Helper)

    @staticmethod
    def create_type_declaration_(json_typable, context_domain_name, fixed_type_name, helper):
        if json_typable["type"] == "string":
            if "enum" in json_typable:

                class EnumBinding:
                    need_user_runtime_cast_ = False
                    need_internal_runtime_cast_ = False

                    @classmethod
                    def resolve_inner(cls, resolve_context):
                        pass

                    @classmethod
                    def request_user_runtime_cast(cls, request):
                        if request:
                            cls.need_user_runtime_cast_ = True
                            request.acknowledge()

                    @classmethod
                    def request_internal_runtime_cast(cls):
                        cls.need_internal_runtime_cast_ = True

                    @classmethod
                    def get_code_generator(enum_binding_cls):
                        #FIXME: generate ad-hoc enums too once we figure out how to better implement them in C++.
                        comment_out = helper.is_ad_hoc

                        class CodeGenerator:
                            @staticmethod
                            def generate_type_builder(writer, generate_context):
                                enum = json_typable["enum"]
                                helper.write_doc(writer)
                                enum_name = fixed_type_name.class_name
                                fixed_type_name.output_comment(writer)
                                writer.newline("struct ")
                                writer.append(enum_name)
                                writer.append(" {\n")
                                writer.newline("    enum Enum {\n")
                                for enum_item in enum:
                                    enum_pos = EnumConstants.add_constant(enum_item)

                                    item_c_name = enum_item.replace('-', '_')
                                    item_c_name = Capitalizer.lower_camel_case_to_upper(item_c_name)
                                    if item_c_name in TYPE_NAME_FIX_MAP:
                                        item_c_name = TYPE_NAME_FIX_MAP[item_c_name]
                                    writer.newline("        ")
                                    writer.append(item_c_name)
                                    writer.append(" = ")
                                    writer.append("%s" % enum_pos)
                                    writer.append(",\n")
                                writer.newline("    };\n")
                                if enum_binding_cls.need_user_runtime_cast_:
                                    raise Exception("Not yet implemented")

                                if enum_binding_cls.need_internal_runtime_cast_:
                                    writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
                                    writer.newline("    static void assertCorrectValue(JSONValue* value);\n")
                                    writer.append("#endif  // %s\n" % VALIDATOR_IFDEF_NAME)

                                    validator_writer = generate_context.validator_writer

                                    domain_fixes = DomainNameFixes.get_fixed_data(context_domain_name)

                                    validator_writer.newline("void %s%s::assertCorrectValue(JSONValue* value)\n" % (helper.full_name_prefix_for_impl, enum_name))
                                    validator_writer.newline("{\n")
                                    validator_writer.newline("    WTF::String s;\n")
                                    validator_writer.newline("    bool cast_res = value->asString(&s);\n")
                                    validator_writer.newline("    ASSERT(cast_res);\n")
                                    if len(enum) > 0:
                                        condition_list = []
                                        for enum_item in enum:
                                            enum_pos = EnumConstants.add_constant(enum_item)
                                            condition_list.append("s == \"%s\"" % enum_item)
                                        validator_writer.newline("    ASSERT(%s);\n" % " || ".join(condition_list))
                                    validator_writer.newline("}\n")

                                    validator_writer.newline("\n\n")

                                writer.newline("}; // struct ")
                                writer.append(enum_name)
                                writer.append("\n\n")

                            @staticmethod
                            def register_use(forward_listener):
                                pass

                            @staticmethod
                            def get_generate_pass_id():
                                return TypeBuilderPass.MAIN

                        return CodeGenerator

                    @classmethod
                    def get_validator_call_text(cls):
                        return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::assertCorrectValue"

                    @classmethod
                    def get_array_item_c_type_text(cls):
                        return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::Enum"

                    @staticmethod
                    def get_setter_value_expression_pattern():
                        return "TypeBuilder::getEnumConstantValue(%s)"

                    @staticmethod
                    def reduce_to_raw_type():
                        return RawTypes.String

                    @staticmethod
                    def get_type_model():
                        return TypeModel.Enum(helper.full_name_prefix_for_use + fixed_type_name.class_name)

                return EnumBinding
            else:
                if helper.is_ad_hoc:

                    class PlainString:
                        @classmethod
                        def resolve_inner(cls, resolve_context):
                            pass

                        @staticmethod
                        def request_user_runtime_cast(request):
                            raise Exception("Unsupported")

                        @staticmethod
                        def request_internal_runtime_cast():
                            pass

                        @staticmethod
                        def get_code_generator():
                            return None

                        @classmethod
                        def get_validator_call_text(cls):
                            return RawTypes.String.get_raw_validator_call_text()

                        @staticmethod
                        def reduce_to_raw_type():
                            return RawTypes.String

                        @staticmethod
                        def get_type_model():
                            return TypeModel.String

                        @staticmethod
                        def get_setter_value_expression_pattern():
                            return None

                        @classmethod
                        def get_array_item_c_type_text(cls):
                            return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()

                    return PlainString

                else:

                    class TypedefString:
                        @classmethod
                        def resolve_inner(cls, resolve_context):
                            pass

                        @staticmethod
                        def request_user_runtime_cast(request):
                            raise Exception("Unsupported")

                        @staticmethod
                        def request_internal_runtime_cast():
                            RawTypes.String.request_raw_internal_runtime_cast()

                        @staticmethod
                        def get_code_generator():
                            class CodeGenerator:
                                @staticmethod
                                def generate_type_builder(writer, generate_context):
                                    helper.write_doc(writer)
                                    fixed_type_name.output_comment(writer)
                                    writer.newline("typedef String ")
                                    writer.append(fixed_type_name.class_name)
                                    writer.append(";\n\n")

                                @staticmethod
                                def register_use(forward_listener):
                                    pass

                                @staticmethod
                                def get_generate_pass_id():
                                    return TypeBuilderPass.TYPEDEF

                            return CodeGenerator

                        @classmethod
                        def get_validator_call_text(cls):
                            return RawTypes.String.get_raw_validator_call_text()

                        @staticmethod
                        def reduce_to_raw_type():
                            return RawTypes.String

                        @staticmethod
                        def get_type_model():
                            return TypeModel.ValueType("%s%s" % (helper.full_name_prefix_for_use, fixed_type_name.class_name), True)

                        @staticmethod
                        def get_setter_value_expression_pattern():
                            return None

                        @classmethod
                        def get_array_item_c_type_text(cls):
                            return "%s%s" % (helper.full_name_prefix_for_use, fixed_type_name.class_name)

                    return TypedefString

        elif json_typable["type"] == "object":
            if "properties" in json_typable:

                class ClassBinding:
                    resolve_data_ = None
                    need_user_runtime_cast_ = False
                    need_internal_runtime_cast_ = False

                    @classmethod
                    def resolve_inner(cls, resolve_context):
                        if cls.resolve_data_:
                            return

                        properties = json_typable["properties"]
                        main = []
                        optional = []

                        ad_hoc_type_list = []

                        for prop in properties:
                            prop_name = prop["name"]
                            ad_hoc_type_context = cls.AdHocTypeContextImpl(prop_name, fixed_type_name.class_name, resolve_context, ad_hoc_type_list, helper.full_name_prefix_for_impl)
                            binding = resolve_param_type(prop, context_domain_name, ad_hoc_type_context)

                            code_generator = binding.get_code_generator()
                            if code_generator:
                                code_generator.register_use(resolve_context.forward_listener)

                            class PropertyData:
                                param_type_binding = binding
                                p = prop

                            if prop.get("optional"):
                                optional.append(PropertyData)
                            else:
                                main.append(PropertyData)

                        class ResolveData:
                            main_properties = main
                            optional_properties = optional
                            ad_hoc_types = ad_hoc_type_list

                        cls.resolve_data_ = ResolveData

                        for ad_hoc in ad_hoc_type_list:
                            ad_hoc.resolve_inner(resolve_context)

                    @classmethod
                    def request_user_runtime_cast(cls, request):
                        if not request:
                            return
                        cls.need_user_runtime_cast_ = True
                        request.acknowledge()
                        cls.request_internal_runtime_cast()

                    @classmethod
                    def request_internal_runtime_cast(cls):
                        if cls.need_internal_runtime_cast_:
                            return
                        cls.need_internal_runtime_cast_ = True
                        for p in cls.resolve_data_.main_properties:
                            p.param_type_binding.request_internal_runtime_cast()
                        for p in cls.resolve_data_.optional_properties:
                            p.param_type_binding.request_internal_runtime_cast()

                    @classmethod
                    def get_code_generator(class_binding_cls):
                        class CodeGenerator:
                            @classmethod
                            def generate_type_builder(cls, writer, generate_context):
                                resolve_data = class_binding_cls.resolve_data_
                                helper.write_doc(writer)
                                class_name = fixed_type_name.class_name

                                is_open_type = (context_domain_name + "." + class_name) in TYPES_WITH_OPEN_FIELD_LIST_SET

                                fixed_type_name.output_comment(writer)
                                writer.newline("class ")
                                writer.append(class_name)
                                writer.append(" : public ")
                                if is_open_type:
                                    writer.append("JSONObject")
                                else:
                                    writer.append("JSONObjectBase")
                                writer.append(" {\n")
                                writer.newline("public:\n")
                                ad_hoc_type_writer = writer.insert_writer("    ")

                                for ad_hoc_type in resolve_data.ad_hoc_types:
                                    code_generator = ad_hoc_type.get_code_generator()
                                    if code_generator:
                                        code_generator.generate_type_builder(ad_hoc_type_writer, generate_context)

                                writer.newline_multiline(
"""    enum {
        NoFieldsSet = 0,
""")

                                state_enum_items = []
                                if len(resolve_data.main_properties) > 0:
                                    pos = 0
                                    for prop_data in resolve_data.main_properties:
                                        item_name = Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]) + "Set"
                                        state_enum_items.append(item_name)
                                        writer.newline("        %s = 1 << %s,\n" % (item_name, pos))
                                        pos += 1
                                    all_fields_set_value = "(" + (" | ".join(state_enum_items)) + ")"
                                else:
                                    all_fields_set_value = "0"

                                writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_1
                                                         % (all_fields_set_value, class_name, class_name))

                                pos = 0
                                for prop_data in resolve_data.main_properties:
                                    prop_name = prop_data.p["name"]

                                    param_type_binding = prop_data.param_type_binding
                                    param_raw_type = param_type_binding.reduce_to_raw_type()

                                    writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_2
                                        % (state_enum_items[pos],
                                           Capitalizer.lower_camel_case_to_upper(prop_name),
                                           param_type_binding.get_type_model().get_input_param_type_text(),
                                           state_enum_items[pos], prop_name,
                                           param_raw_type.get_setter_name(), prop_name,
                                           format_setter_value_expression(param_type_binding, "value"),
                                           state_enum_items[pos]))

                                    pos += 1

                                writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_3
                                                         % (class_name, class_name, class_name, class_name, class_name))

                                writer.newline("    /*\n")
                                writer.newline("     * Synthetic constructor:\n")
                                writer.newline("     * RefPtr<%s> result = %s::create()" % (class_name, class_name))
                                for prop_data in resolve_data.main_properties:
                                    writer.append_multiline("\n     *     .set%s(...)" % Capitalizer.lower_camel_case_to_upper(prop_data.p["name"]))
                                writer.append_multiline(";\n     */\n")

                                writer.newline_multiline(CodeGeneratorInspectorStrings.class_binding_builder_part_4)

                                writer.newline("    typedef TypeBuilder::StructItemTraits ItemTraits;\n")

                                for prop_data in resolve_data.main_properties:
                                    prop_name = prop_data.p["name"]
                                    param_type_binding = prop_data.param_type_binding
                                    raw_type = param_type_binding.reduce_to_raw_type()
                                    if isinstance(param_type_binding.get_type_model(), TypeModel.ValueType):
                                        writer.append_multiline("\n    void %s" % prop_name)
                                        writer.append("(%s value)\n" % param_type_binding.get_type_model().get_command_return_pass_model().get_output_parameter_type())
                                        writer.newline("    {\n")
                                        writer.newline("        JSONObjectBase::get%s(\"%s\", value);\n"
                                            % (param_type_binding.reduce_to_raw_type().get_setter_name(), prop_data.p["name"]))
                                        writer.newline("    }\n")

                                for prop_data in resolve_data.optional_properties:
                                    prop_name = prop_data.p["name"]
                                    param_type_binding = prop_data.param_type_binding
                                    setter_name = "set%s" % Capitalizer.lower_camel_case_to_upper(prop_name)

                                    writer.append_multiline("\n    void %s" % setter_name)
                                    writer.append("(%s value)\n" % param_type_binding.get_type_model().get_input_param_type_text())
                                    writer.newline("    {\n")
                                    writer.newline("        this->set%s(\"%s\", %s);\n"
                                        % (param_type_binding.reduce_to_raw_type().get_setter_name(), prop_data.p["name"],
                                           format_setter_value_expression(param_type_binding, "value")))
                                    writer.newline("    }\n")

                                    if setter_name in INSPECTOR_OBJECT_SETTER_NAMES:
                                        writer.newline("    using JSONObjectBase::%s;\n\n" % setter_name)

                                if class_binding_cls.need_user_runtime_cast_:
                                    writer.newline("    static PassRefPtr<%s> runtimeCast(PassRefPtr<JSONValue> value)\n" % class_name)
                                    writer.newline("    {\n")
                                    writer.newline("        RefPtr<JSONObject> object;\n")
                                    writer.newline("        bool castRes = value->asObject(&object);\n")
                                    writer.newline("        ASSERT_UNUSED(castRes, castRes);\n")
                                    writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
                                    writer.newline("        assertCorrectValue(object.get());\n")
                                    writer.append("#endif  // %s\n" % VALIDATOR_IFDEF_NAME)
                                    writer.newline("        COMPILE_ASSERT(sizeof(%s) == sizeof(JSONObjectBase), type_cast_problem);\n" % class_name)
                                    writer.newline("        return static_cast<%s*>(static_cast<JSONObjectBase*>(object.get()));\n" % class_name)
                                    writer.newline("    }\n")
                                    writer.append("\n")

                                if class_binding_cls.need_internal_runtime_cast_:
                                    writer.append("#if %s\n" % VALIDATOR_IFDEF_NAME)
                                    writer.newline("    static void assertCorrectValue(JSONValue* value);\n")
                                    writer.append("#endif  // %s\n" % VALIDATOR_IFDEF_NAME)

                                    closed_field_set = (context_domain_name + "." + class_name) not in TYPES_WITH_OPEN_FIELD_LIST_SET

                                    validator_writer = generate_context.validator_writer

                                    domain_fixes = DomainNameFixes.get_fixed_data(context_domain_name)

                                    validator_writer.newline("void %s%s::assertCorrectValue(JSONValue* value)\n" % (helper.full_name_prefix_for_impl, class_name))
                                    validator_writer.newline("{\n")
                                    validator_writer.newline("    RefPtr<JSONObject> object;\n")
                                    validator_writer.newline("    bool castRes = value->asObject(&object);\n")
                                    validator_writer.newline("    ASSERT_UNUSED(castRes, castRes);\n")
                                    for prop_data in resolve_data.main_properties:
                                        validator_writer.newline("    {\n")
                                        it_name = "%sPos" % prop_data.p["name"]
                                        validator_writer.newline("        JSONObject::iterator %s;\n" % it_name)
                                        validator_writer.newline("        %s = object->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
                                        validator_writer.newline("        ASSERT(%s != object->end());\n" % it_name)
                                        validator_writer.newline("        %s(%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
                                        validator_writer.newline("    }\n")

                                    if closed_field_set:
                                        validator_writer.newline("    int foundPropertiesCount = %s;\n" % len(resolve_data.main_properties))

                                    for prop_data in resolve_data.optional_properties:
                                        validator_writer.newline("    {\n")
                                        it_name = "%sPos" % prop_data.p["name"]
                                        validator_writer.newline("        JSONObject::iterator %s;\n" % it_name)
                                        validator_writer.newline("        %s = object->find(\"%s\");\n" % (it_name, prop_data.p["name"]))
                                        validator_writer.newline("        if (%s != object->end()) {\n" % it_name)
                                        validator_writer.newline("            %s(%s->value.get());\n" % (prop_data.param_type_binding.get_validator_call_text(), it_name))
                                        if closed_field_set:
                                            validator_writer.newline("            ++foundPropertiesCount;\n")
                                        validator_writer.newline("        }\n")
                                        validator_writer.newline("    }\n")

                                    if closed_field_set:
                                        validator_writer.newline("    if (foundPropertiesCount != object->size()) {\n")
                                        validator_writer.newline("      FATAL(\"Unexpected properties in object: %s\\n\", object->toJSONString().ascii().data());\n")
                                        validator_writer.newline("    }\n")
                                    validator_writer.newline("}\n")

                                    validator_writer.newline("\n\n")

                                if is_open_type:
                                    cpp_writer = generate_context.cpp_writer
                                    writer.append("\n")
                                    writer.newline("    // Property names for type generated as open.\n")
                                    for prop_data in resolve_data.main_properties + resolve_data.optional_properties:
                                        prop_name = prop_data.p["name"]
                                        prop_field_name = Capitalizer.lower_camel_case_to_upper(prop_name)
                                        writer.newline("    static const char %s[];\n" % (prop_field_name))
                                        cpp_writer.newline("const char %s%s::%s[] = \"%s\";\n" % (helper.full_name_prefix_for_impl, class_name, prop_field_name, prop_name))


                                writer.newline("};\n\n")

                            @staticmethod
                            def generate_forward_declaration(writer):
                                class_name = fixed_type_name.class_name
                                writer.newline("class ")
                                writer.append(class_name)
                                writer.append(";\n")

                            @staticmethod
                            def register_use(forward_listener):
                                helper.add_to_forward_listener(forward_listener)

                            @staticmethod
                            def get_generate_pass_id():
                                return TypeBuilderPass.MAIN

                        return CodeGenerator

                    @staticmethod
                    def get_validator_call_text():
                        return helper.full_name_prefix_for_use + fixed_type_name.class_name + "::assertCorrectValue"

                    @classmethod
                    def get_array_item_c_type_text(cls):
                        return helper.full_name_prefix_for_use + fixed_type_name.class_name

                    @staticmethod
                    def get_setter_value_expression_pattern():
                        return None

                    @staticmethod
                    def reduce_to_raw_type():
                        return RawTypes.Object

                    @staticmethod
                    def get_type_model():
                        return TypeModel.RefPtrBased(helper.full_name_prefix_for_use + fixed_type_name.class_name)

                    class AdHocTypeContextImpl:
                        def __init__(self, property_name, class_name, resolve_context, ad_hoc_type_list, parent_full_name_prefix):
                            self.property_name = property_name
                            self.class_name = class_name
                            self.resolve_context = resolve_context
                            self.ad_hoc_type_list = ad_hoc_type_list
                            self.container_full_name_prefix = parent_full_name_prefix + class_name + "::"
                            self.container_relative_name_prefix = ""

                        def get_type_name_fix(self):
                            class NameFix:
                                class_name = Capitalizer.lower_camel_case_to_upper(self.property_name)

                                @staticmethod
                                def output_comment(writer):
                                    writer.newline("// Named after property name '%s' while generating %s.\n" % (self.property_name, self.class_name))

                            return NameFix

                        def add_type(self, binding):
                            self.ad_hoc_type_list.append(binding)

                return ClassBinding
            else:

                class PlainObjectBinding:
                    @classmethod
                    def resolve_inner(cls, resolve_context):
                        pass

                    @staticmethod
                    def request_user_runtime_cast(request):
                        pass

                    @staticmethod
                    def request_internal_runtime_cast():
                        RawTypes.Object.request_raw_internal_runtime_cast()

                    @staticmethod
                    def get_code_generator():
                        pass

                    @staticmethod
                    def get_validator_call_text():
                        return "RuntimeCastHelper::assertType<JSONValue::TypeObject>"

                    @classmethod
                    def get_array_item_c_type_text(cls):
                        return cls.reduce_to_raw_type().get_array_item_raw_c_type_text()

                    @staticmethod
                    def get_setter_value_expression_pattern():
                        return None

                    @staticmethod
                    def reduce_to_raw_type():
                        return RawTypes.Object

                    @staticmethod
                    def get_type_model():
                        return TypeModel.Object

                return PlainObjectBinding
        elif json_typable["type"] == "array":
            if "items" in json_typable:

                ad_hoc_types = []

                class AdHocTypeContext:
                    container_full_name_prefix = "<not yet defined>"
                    container_relative_name_prefix = ""

                    @staticmethod
                    def get_type_name_fix():
                        return fixed_type_name

                    @staticmethod
                    def add_type(binding):
                        ad_hoc_types.append(binding)

                item_binding = resolve_param_type(json_typable["items"], context_domain_name, AdHocTypeContext)

                class ArrayBinding:
                    resolve_data_ = None
                    need_internal_runtime_cast_ = False

                    @classmethod
                    def resolve_inner(cls, resolve_context):
                        if cls.resolve_data_:
                            return

                        class ResolveData:
                            item_type_binding = item_binding
                            ad_hoc_type_list = ad_hoc_types

                        cls.resolve_data_ = ResolveData

                        for t in ad_hoc_types:
                            t.resolve_inner(resolve_context)

                    @classmethod
                    def request_user_runtime_cast(cls, request):
                        raise Exception("Not implemented yet")

                    @classmethod
                    def request_internal_runtime_cast(cls):
                        if cls.need_internal_runtime_cast_:
                            return
                        cls.need_internal_runtime_cast_ = True
                        cls.resolve_data_.item_type_binding.request_internal_runtime_cast()

                    @classmethod
                    def get_code_generator(array_binding_cls):

                        class CodeGenerator:
                            @staticmethod
                            def generate_type_builder(writer, generate_context):
                                ad_hoc_type_writer = writer

                                resolve_data = array_binding_cls.resolve_data_

                                for ad_hoc_type in resolve_data.ad_hoc_type_list:
                                    code_generator = ad_hoc_type.get_code_generator()
                                    if code_generator:
                                        code_generator.generate_type_builder(ad_hoc_type_writer, generate_context)

                            @staticmethod
                            def generate_forward_declaration(writer):
                                pass

                            @staticmethod
                            def register_use(forward_listener):
                                item_code_generator = item_binding.get_code_generator()
                                if item_code_generator:
                                    item_code_generator.register_use(forward_listener)

                            @staticmethod
                            def get_generate_pass_id():
                                return TypeBuilderPass.MAIN

                        return CodeGenerator

                    @classmethod
                    def get_validator_call_text(cls):
                        return cls.get_array_item_c_type_text() + "::assertCorrectValue"

                    @classmethod
                    def get_array_item_c_type_text(cls):
                        return replace_right_shift("TypeBuilder::Array<%s>" % cls.resolve_data_.item_type_binding.get_array_item_c_type_text())

                    @staticmethod
                    def get_setter_value_expression_pattern():
                        return None

                    @staticmethod
                    def reduce_to_raw_type():
                        return RawTypes.Array

                    @classmethod
                    def get_type_model(cls):
                        return TypeModel.RefPtrBased(cls.get_array_item_c_type_text())

                return ArrayBinding
            else:
                # Fall-through to raw type.
                pass

        raw_type = RawTypes.get(json_typable["type"])

        return RawTypeBinding(raw_type)


class RawTypeBinding:
    def __init__(self, raw_type):
        self.raw_type_ = raw_type

    def resolve_inner(self, resolve_context):
        pass

    def request_user_runtime_cast(self, request):
        raise Exception("Unsupported")

    def request_internal_runtime_cast(self):
        self.raw_type_.request_raw_internal_runtime_cast()

    def get_code_generator(self):
        return None

    def get_validator_call_text(self):
        return self.raw_type_.get_raw_validator_call_text()

    def get_array_item_c_type_text(self):
        return self.raw_type_.get_array_item_raw_c_type_text()

    def get_setter_value_expression_pattern(self):
        return None

    def reduce_to_raw_type(self):
        return self.raw_type_

    def get_type_model(self):
        return self.raw_type_.get_raw_type_model()


class TypeData(object):
    def __init__(self, json_type, json_domain, domain_data):
        self.json_type_ = json_type
        self.json_domain_ = json_domain
        self.domain_data_ = domain_data

        if "type" not in json_type:
            raise Exception("Unknown type")

        json_type_name = json_type["type"]
        raw_type = RawTypes.get(json_type_name)
        self.raw_type_ = raw_type
        self.binding_being_resolved_ = False
        self.binding_ = None

    def get_raw_type(self):
        return self.raw_type_

    def get_binding(self):
        if not self.binding_:
            if self.binding_being_resolved_:
                raise Error("Type %s is already being resolved" % self.json_type_["type"])
            # Resolve only lazily, because resolving one named type may require resolving some other named type.
            self.binding_being_resolved_ = True
            try:
                self.binding_ = TypeBindings.create_named_type_declaration(self.json_type_, self.json_domain_["domain"], self)
            finally:
                self.binding_being_resolved_ = False

        return self.binding_

    def get_json_type(self):
        return self.json_type_

    def get_name(self):
        return self.json_type_["id"]

    def get_domain_name(self):
        return self.json_domain_["domain"]


class DomainData:
    def __init__(self, json_domain):
        self.json_domain = json_domain
        self.types_ = []

    def add_type(self, type_data):
        self.types_.append(type_data)

    def name(self):
        return self.json_domain["domain"]

    def types(self):
        return self.types_


class TypeMap:
    def __init__(self, api):
        self.map_ = {}
        self.domains_ = []
        for json_domain in api["domains"]:
            domain_name = json_domain["domain"]

            domain_map = {}
            self.map_[domain_name] = domain_map

            domain_data = DomainData(json_domain)
            self.domains_.append(domain_data)

            if "types" in json_domain:
                for json_type in json_domain["types"]:
                    type_name = json_type["id"]
                    type_data = TypeData(json_type, json_domain, domain_data)
                    domain_map[type_name] = type_data
                    domain_data.add_type(type_data)

    def domains(self):
        return self.domains_

    def get(self, domain_name, type_name):
        return self.map_[domain_name][type_name]


def resolve_param_type(json_parameter, scope_domain_name, ad_hoc_type_context):
    if "$ref" in json_parameter:
        json_ref = json_parameter["$ref"]
        type_data = get_ref_data(json_ref, scope_domain_name)
        return type_data.get_binding()
    elif "type" in json_parameter:
        result = TypeBindings.create_ad_hoc_type_declaration(json_parameter, scope_domain_name, ad_hoc_type_context)
        ad_hoc_type_context.add_type(result)
        return result
    else:
        raise Exception("Unknown type")

def resolve_param_raw_type(json_parameter, scope_domain_name):
    if "$ref" in json_parameter:
        json_ref = json_parameter["$ref"]
        type_data = get_ref_data(json_ref, scope_domain_name)
        return type_data.get_raw_type()
    elif "type" in json_parameter:
        json_type = json_parameter["type"]
        return RawTypes.get(json_type)
    else:
        raise Exception("Unknown type")


def get_ref_data(json_ref, scope_domain_name):
    dot_pos = json_ref.find(".")
    if dot_pos == -1:
        domain_name = scope_domain_name
        type_name = json_ref
    else:
        domain_name = json_ref[:dot_pos]
        type_name = json_ref[dot_pos + 1:]

    return type_map.get(domain_name, type_name)


input_file = open(input_json_filename, "r")
json_string = input_file.read()
json_api = json.loads(json_string)


class Templates:
    def get_this_script_path_(absolute_path):
        absolute_path = os.path.abspath(absolute_path)
        components = []

        def fill_recursive(path_part, depth):
            if depth <= 0 or path_part == '/':
                return
            fill_recursive(os.path.dirname(path_part), depth - 1)
            components.append(os.path.basename(path_part))

        # Typical path is /Source/WebCore/inspector/CodeGeneratorInspector.py
        # Let's take 4 components from the real path then.
        fill_recursive(absolute_path, 4)

        return "/".join(components)

    file_header_ = ("// File is generated by %s\n\n" % get_this_script_path_(sys.argv[0]) +
"""// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
""")

    frontend_domain_class = string.Template(CodeGeneratorInspectorStrings.frontend_domain_class)
    backend_method = string.Template(CodeGeneratorInspectorStrings.backend_method)
    frontend_method = string.Template(CodeGeneratorInspectorStrings.frontend_method)
    callback_main_methods = string.Template(CodeGeneratorInspectorStrings.callback_main_methods)
    callback_failure_method = string.Template(CodeGeneratorInspectorStrings.callback_failure_method)
    frontend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.frontend_h)
    backend_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_h)
    backend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.backend_cpp)
    frontend_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.frontend_cpp)
    typebuilder_h = string.Template(file_header_ + CodeGeneratorInspectorStrings.typebuilder_h)
    typebuilder_cpp = string.Template(file_header_ + CodeGeneratorInspectorStrings.typebuilder_cpp)
    param_container_access_code = CodeGeneratorInspectorStrings.param_container_access_code





type_map = TypeMap(json_api)


class NeedRuntimeCastRequest:
    def __init__(self):
        self.ack_ = None

    def acknowledge(self):
        self.ack_ = True

    def is_acknowledged(self):
        return self.ack_


def resolve_all_types():
    runtime_cast_generate_requests = {}
    for type_name in TYPES_WITH_RUNTIME_CAST_SET:
        runtime_cast_generate_requests[type_name] = NeedRuntimeCastRequest()

    class ForwardListener:
        type_data_set = set()
        already_declared_set = set()

        @classmethod
        def add_type_data(cls, type_data):
            if type_data not in cls.already_declared_set:
                cls.type_data_set.add(type_data)

    class ResolveContext:
        forward_listener = ForwardListener

    for domain_data in type_map.domains():
        for type_data in domain_data.types():
            # Do not generate forwards for this type any longer.
            ForwardListener.already_declared_set.add(type_data)

            binding = type_data.get_binding()
            binding.resolve_inner(ResolveContext)

    for domain_data in type_map.domains():
        for type_data in domain_data.types():
            full_type_name = "%s.%s" % (type_data.get_domain_name(), type_data.get_name())
            request = runtime_cast_generate_requests.pop(full_type_name, None)
            binding = type_data.get_binding()
            if request:
                binding.request_user_runtime_cast(request)

            if request and not request.is_acknowledged():
                raise Exception("Failed to generate runtimeCast in " + full_type_name)

    for full_type_name in runtime_cast_generate_requests:
        raise Exception("Failed to generate runtimeCast. Type " + full_type_name + " not found")

    return ForwardListener


global_forward_listener = resolve_all_types()


def get_annotated_type_text(raw_type, annotated_type):
    if annotated_type != raw_type:
        return "/*%s*/ %s" % (annotated_type, raw_type)
    else:
        return raw_type


def format_setter_value_expression(param_type_binding, value_ref):
    pattern = param_type_binding.get_setter_value_expression_pattern()
    if pattern:
        return pattern % value_ref
    else:
        return value_ref

class Generator:
    frontend_class_field_lines = []
    frontend_domain_class_lines = []

    method_name_enum_list = []
    backend_method_declaration_list = []
    backend_method_implementation_list = []
    backend_method_name_declaration_list = []
    backend_method_name_declaration_index_list = []
    backend_method_name_declaration_current_index = 0
    method_handler_list = []
    frontend_method_list = []

    backend_virtual_setters_list = []
    backend_agent_interface_list = []
    backend_setters_list = []
    backend_constructor_init_list = []
    backend_field_list = []
    frontend_constructor_init_list = []
    type_builder_fragments = []
    type_builder_forwards = []
    validator_impl_list = []
    type_builder_impl_list = []


    @staticmethod
    def go():
        Generator.process_types(type_map)

        first_cycle_guardable_list_list = [
            Generator.backend_method_declaration_list,
            Generator.backend_method_implementation_list,
            Generator.backend_method_name_declaration_list,
            Generator.backend_method_name_declaration_index_list,
            Generator.backend_agent_interface_list,
            Generator.frontend_class_field_lines,
            Generator.frontend_constructor_init_list,
            Generator.frontend_domain_class_lines,
            Generator.frontend_method_list,
            Generator.method_handler_list,
            Generator.method_name_enum_list,
            Generator.backend_constructor_init_list,
            Generator.backend_virtual_setters_list,
            Generator.backend_setters_list,
            Generator.backend_field_list]

        for json_domain in json_api["domains"]:
            domain_name = json_domain["domain"]
            domain_name_lower = domain_name.lower()

            domain_fixes = DomainNameFixes.get_fixed_data(domain_name)

            agent_field_name = domain_fixes.agent_field_name

            frontend_method_declaration_lines = []

            if "events" in json_domain:
                for json_event in json_domain["events"]:
                    Generator.process_event(json_event, domain_name, frontend_method_declaration_lines)

            Generator.frontend_class_field_lines.append("    %s m_%s;\n" % (domain_name, domain_name_lower))
            if Generator.frontend_constructor_init_list:
                Generator.frontend_constructor_init_list.append("    , ")
            Generator.frontend_constructor_init_list.append("m_%s(inspectorFrontendChannel)\n" % domain_name_lower)
            Generator.frontend_domain_class_lines.append(Templates.frontend_domain_class.substitute(None,
                domainClassName=domain_name,
                domainFieldName=domain_name_lower,
                frontendDomainMethodDeclarations="".join(flatten_list(frontend_method_declaration_lines))))

            agent_interface_name = Capitalizer.lower_camel_case_to_upper(domain_name) + "CommandHandler"
            Generator.backend_agent_interface_list.append("    class %s {\n" % agent_interface_name)
            Generator.backend_agent_interface_list.append("    public:\n")
            if "commands" in json_domain:
                for json_command in json_domain["commands"]:
                    Generator.process_command(json_command, domain_name, agent_field_name, agent_interface_name)
            Generator.backend_agent_interface_list.append("\n    protected:\n")
            Generator.backend_agent_interface_list.append("        virtual ~%s() { }\n" % agent_interface_name)
            Generator.backend_agent_interface_list.append("    };\n\n")

            Generator.backend_constructor_init_list.append("        , m_%s(0)" % agent_field_name)
            Generator.backend_virtual_setters_list.append("    virtual void registerAgent(%s* %s) = 0;" % (agent_interface_name, agent_field_name))
            Generator.backend_setters_list.append("    virtual void registerAgent(%s* %s) { ASSERT(!m_%s); m_%s = %s; }" % (agent_interface_name, agent_field_name, agent_field_name, agent_field_name, agent_field_name))
            Generator.backend_field_list.append("    %s* m_%s;" % (agent_interface_name, agent_field_name))

    @staticmethod
    def process_event(json_event, domain_name, frontend_method_declaration_lines):
        if (("handlers" in json_event) and (not ("renderer" in json_event["handlers"]))):
            return

        event_name = json_event["name"]

        ad_hoc_type_output = []
        frontend_method_declaration_lines.append(ad_hoc_type_output)
        ad_hoc_type_writer = Writer(ad_hoc_type_output, "        ")

        decl_parameter_list = []

        json_parameters = json_event.get("parameters")
        Generator.generate_send_method(json_parameters, event_name, domain_name, ad_hoc_type_writer,
                                       decl_parameter_list,
                                       Generator.EventMethodStructTemplate,
                                       Generator.frontend_method_list, Templates.frontend_method, {"eventName": event_name})

        frontend_method_declaration_lines.append(
            "        void %s(%s);\n" % (event_name, ", ".join(decl_parameter_list)))

    class EventMethodStructTemplate:
        @staticmethod
        def append_prolog(line_list):
            line_list.append("    RefPtr<JSONObject> paramsObject = JSONObject::create();\n")

        @staticmethod
        def append_epilog(line_list):
            line_list.append("    jsonMessage->setObject(\"params\", paramsObject);\n")

        container_name = "paramsObject"

    @staticmethod
    def process_command(json_command, domain_name, agent_field_name, agent_interface_name):
        if (("handlers" in json_command) and (not ("renderer" in json_command["handlers"]))):
            return

        json_command_name = json_command["name"]

        cmd_enum_name = "k%s_%sCmd" % (domain_name, json_command["name"])

        Generator.method_name_enum_list.append("        %s," % cmd_enum_name)
        Generator.method_handler_list.append("            &InspectorBackendDispatcherImpl::%s_%s," % (domain_name, json_command_name))
        Generator.backend_method_declaration_list.append("    void %s_%s(long callId, JSONObject* requestMessageObject, JSONArray* protocolErrors);" % (domain_name, json_command_name))

        backend_agent_interface_list = [] if "redirect" in json_command else Generator.backend_agent_interface_list

        ad_hoc_type_output = []
        backend_agent_interface_list.append(ad_hoc_type_output)
        ad_hoc_type_writer = Writer(ad_hoc_type_output, "        ")

        backend_agent_interface_list.append("        virtual void %s(ErrorString*" % json_command_name)

        method_in_code = ""
        method_out_code = ""
        result_object_declaration = ""
        agent_call_param_list = ["&error"]
        agent_call_params_declaration_list = ["    ErrorString error;"]
        send_response_call_params_list = ["error"]
        request_message_param = ""
        normal_response_cook_text = ""
        error_type_binding = None
        if "error" in json_command:
            json_error = json_command["error"]
            error_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_error, json_command_name + "Error", json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")
            error_type_model = error_type_binding.get_type_model().get_optional()
            error_annotated_type = error_type_model.get_command_return_pass_model().get_output_parameter_type()
            agent_call_param_list.append("%serrorData" % error_type_model.get_command_return_pass_model().get_output_argument_prefix())
            backend_agent_interface_list.append(", %s errorData" % error_annotated_type)
            method_in_code += "    %s errorData;\n" % error_type_model.get_command_return_pass_model().get_return_var_type()
            send_response_call_params_list.append("errorData")

        if "parameters" in json_command:
            json_params = json_command["parameters"]
            request_message_param = " requestMessageObject"

            if json_params:
                method_in_code += Templates.param_container_access_code

            for json_parameter in json_params:
                json_param_name = json_parameter["name"]
                param_raw_type = resolve_param_raw_type(json_parameter, domain_name)

                getter_name = param_raw_type.get_getter_name()

                optional = json_parameter.get("optional")

                non_optional_type_model = param_raw_type.get_raw_type_model()
                if optional:
                    type_model = non_optional_type_model.get_optional()
                else:
                    type_model = non_optional_type_model

                if optional:
                    code = ("    bool %s_valueFound = false;\n"
                            "    %s in_%s = get%s(paramsContainerPtr, \"%s\", &%s_valueFound, protocolErrors);\n" %
                           (json_param_name, non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name, json_param_name))
                    param = "%s_valueFound ? &in_%s : 0" % (json_param_name, json_param_name)
                    # FIXME: pass optional refptr-values as PassRefPtr
                    formal_param_type_pattern = "const %s*"
                else:
                    code = ("    %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrors);\n" %
                            (non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name))
                    param = "in_%s" % json_param_name
                    # FIXME: pass not-optional refptr-values as NonNullPassRefPtr
                    if param_raw_type.is_heavy_value():
                        formal_param_type_pattern = "const %s&"
                    else:
                        formal_param_type_pattern = "%s"

                method_in_code += code
                agent_call_param_list.append(param)
                backend_agent_interface_list.append(", %s in_%s" % (formal_param_type_pattern % non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name))

        if json_command.get("async") == True:
            callback_name = Capitalizer.lower_camel_case_to_upper(json_command_name) + "Callback"

            callback_output = []
            callback_writer = Writer(callback_output, ad_hoc_type_writer.get_indent())

            decl_parameter_list = []
            Generator.generate_send_method(json_command.get("returns"), json_command_name, domain_name, ad_hoc_type_writer,
                                           decl_parameter_list,
                                           Generator.CallbackMethodStructTemplate,
                                           Generator.backend_method_implementation_list, Templates.callback_main_methods,
                                           {"callbackName": callback_name, "agentName": agent_interface_name})

            callback_writer.newline("class " + callback_name + " : public CallbackBase {\n")
            callback_writer.newline("public:\n")
            callback_writer.newline("    " + callback_name + "(PassRefPtr<InspectorBackendDispatcherImpl>, int id);\n")
            callback_writer.newline("    void sendSuccess(" + ", ".join(decl_parameter_list) + ");\n")
            error_part_writer = callback_writer.insert_writer("")
            callback_writer.newline("};\n")

            if error_type_binding:
                annotated_type = error_type_model.get_input_param_type_text()
                error_part_writer.newline("    void sendFailure(const ErrorString&, %s);\n" % annotated_type)
                error_part_writer.newline("    using CallbackBase::sendFailure;\n")

                assigment_value = error_type_model.get_event_setter_expression_pattern() % "errorData"
                assigment_value = error_type_binding.reduce_to_raw_type().get_constructor_pattern() % assigment_value

                Generator.backend_method_implementation_list.append(Templates.callback_failure_method.substitute(None,
                    agentName=agent_interface_name,
                    callbackName=callback_name,
                    parameter=annotated_type + " errorData",
                    argument=assigment_value))

            ad_hoc_type_output.append(callback_output)

            method_out_code += "    RefPtr<" + agent_interface_name + "::" + callback_name + "> callback = adoptRef(new " + agent_interface_name + "::" + callback_name + "(this, callId));\n"
            agent_call_param_list.append("callback")
            normal_response_cook_text += "    if (!error.length()) \n"
            normal_response_cook_text += "        return;\n"
            normal_response_cook_text += "    callback->disable();\n"
            backend_agent_interface_list.append(", PassRefPtr<%s> callback" % callback_name)
        else:
            if "returns" in json_command:
                method_out_code += "\n"
                agent_call_params_declaration_list.append("    RefPtr<JSONObject> result = JSONObject::create();")
                send_response_call_params_list.append("result")
                response_cook_list = []
                for json_return in json_command["returns"]:

                    json_return_name = json_return["name"]

                    optional = bool(json_return.get("optional"))

                    return_type_binding = Generator.resolve_param_type_and_generate_ad_hoc(json_return, json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")

                    raw_type = return_type_binding.reduce_to_raw_type()
                    setter_type = raw_type.get_setter_name()
                    initializer = raw_type.get_c_initializer()

                    type_model = return_type_binding.get_type_model()
                    if optional:
                        type_model = type_model.get_optional()

                    code = "    %s out_%s;\n" % (type_model.get_command_return_pass_model().get_return_var_type(), json_return_name)
                    param = "%sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
                    var_name = "out_%s" % json_return_name
                    setter_argument = type_model.get_command_return_pass_model().get_output_to_raw_expression() % var_name
                    if return_type_binding.get_setter_value_expression_pattern():
                        setter_argument = return_type_binding.get_setter_value_expression_pattern() % setter_argument

                    cook = "        result->set%s(\"%s\", %s);\n" % (setter_type, json_return_name,
                                                                         setter_argument)

                    set_condition_pattern = type_model.get_command_return_pass_model().get_set_return_condition()
                    if set_condition_pattern:
                        cook = ("        if (%s)\n    " % (set_condition_pattern % var_name)) + cook
                    annotated_type = type_model.get_command_return_pass_model().get_output_parameter_type()

                    param_name = var_name
                    if optional:
                        param_name = "opt_" + param_name

                    backend_agent_interface_list.append(", %s %s" % (annotated_type, param_name))
                    response_cook_list.append(cook)

                    method_out_code += code
                    agent_call_param_list.append(param)

                normal_response_cook_text += "".join(response_cook_list)

                if len(normal_response_cook_text) != 0:
                    normal_response_cook_text = "    if (!error.length()) {\n" + normal_response_cook_text + "    }"

        # Redirect to another agent's implementation.
        agent_field = "m_" + agent_field_name
        if "redirect" in json_command:
            domain_fixes = DomainNameFixes.get_fixed_data(json_command.get("redirect"))
            agent_field = "m_" + domain_fixes.agent_field_name

        Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
            domainName=domain_name, methodName=json_command_name,
            agentField=agent_field,
            methodCode="".join([method_in_code, method_out_code]),
            agentCallParamsDeclaration="\n".join(agent_call_params_declaration_list),
            agentCallParams=", ".join(agent_call_param_list),
            requestMessageObject=request_message_param,
            responseCook=normal_response_cook_text,
            sendResponseCallParams=", ".join(send_response_call_params_list),
            commandNameIndex=cmd_enum_name))
        declaration_command_name = "%s.%s\\0" % (domain_name, json_command_name)
        Generator.backend_method_name_declaration_list.append("    \"%s\"" % declaration_command_name)
        Generator.backend_method_name_declaration_index_list.append("    %d," % Generator.backend_method_name_declaration_current_index)
        Generator.backend_method_name_declaration_current_index += len(declaration_command_name) - 1

        backend_agent_interface_list.append(") = 0;\n")

    class CallbackMethodStructTemplate:
        @staticmethod
        def append_prolog(line_list):
            pass

        @staticmethod
        def append_epilog(line_list):
            pass

        container_name = "jsonMessage"

    # Generates common code for event sending and callback response data sending.
    @staticmethod
    def generate_send_method(parameters, event_name, domain_name, ad_hoc_type_writer, decl_parameter_list,
                             method_struct_template,
                             generator_method_list, method_template, template_params):
        method_line_list = []
        if parameters:
            method_struct_template.append_prolog(method_line_list)
            for json_parameter in parameters:
                parameter_name = json_parameter["name"]

                param_type_binding = Generator.resolve_param_type_and_generate_ad_hoc(json_parameter, event_name, domain_name, ad_hoc_type_writer, "")

                raw_type = param_type_binding.reduce_to_raw_type()
                raw_type_binding = RawTypeBinding(raw_type)

                optional = bool(json_parameter.get("optional"))

                setter_type = raw_type.get_setter_name()

                type_model = param_type_binding.get_type_model()
                raw_type_model = raw_type_binding.get_type_model()
                if optional:
                    type_model = type_model.get_optional()
                    raw_type_model = raw_type_model.get_optional()

                annotated_type = type_model.get_input_param_type_text()
                mode_type_binding = param_type_binding

                decl_parameter_list.append("%s %s" % (annotated_type, parameter_name))

                setter_argument = raw_type_model.get_event_setter_expression_pattern() % parameter_name
                if mode_type_binding.get_setter_value_expression_pattern():
                    setter_argument = mode_type_binding.get_setter_value_expression_pattern() % setter_argument

                setter_code = "    %s->set%s(\"%s\", %s);\n" % (method_struct_template.container_name, setter_type, parameter_name, setter_argument)
                if optional:
                    setter_code = ("    if (%s)\n    " % parameter_name) + setter_code
                method_line_list.append(setter_code)

            method_struct_template.append_epilog(method_line_list)

        generator_method_list.append(method_template.substitute(None,
            domainName=domain_name,
            parameters=", ".join(decl_parameter_list),
            code="".join(method_line_list), **template_params))

    @classmethod
    def resolve_param_type_and_generate_ad_hoc(cls, json_param, method_name, domain_name, ad_hoc_type_writer, container_relative_name_prefix_param):
        param_name = json_param["name"]
        return cls.resolve_type_and_generate_ad_hoc(json_param, param_name, method_name, domain_name, ad_hoc_type_writer, container_relative_name_prefix_param)

    @staticmethod
    def resolve_type_and_generate_ad_hoc(typable_element, element_name, method_name, domain_name, ad_hoc_type_writer, container_relative_name_prefix_param):
        ad_hoc_type_list = []

        class AdHocTypeContext:
            container_full_name_prefix = "<not yet defined>"
            container_relative_name_prefix = container_relative_name_prefix_param

            @staticmethod
            def get_type_name_fix():
                class NameFix:
                    class_name = Capitalizer.lower_camel_case_to_upper(element_name)

                    @staticmethod
                    def output_comment(writer):
                        writer.newline("// Named after parameter '%s' while generating command/event %s.\n" % (element_name, method_name))

                return NameFix

            @staticmethod
            def add_type(binding):
                ad_hoc_type_list.append(binding)

        type_binding = resolve_param_type(typable_element, domain_name, AdHocTypeContext)

        class InterfaceForwardListener:
            @staticmethod
            def add_type_data(type_data):
                pass

        class InterfaceResolveContext:
            forward_listener = InterfaceForwardListener

        for type in ad_hoc_type_list:
            type.resolve_inner(InterfaceResolveContext)

        class InterfaceGenerateContext:
            validator_writer = "not supported in InterfaceGenerateContext"
            cpp_writer = validator_writer

        for type in ad_hoc_type_list:
            generator = type.get_code_generator()
            if generator:
                generator.generate_type_builder(ad_hoc_type_writer, InterfaceGenerateContext)

        return type_binding

    @staticmethod
    def process_types(type_map):
        output = Generator.type_builder_fragments

        class GenerateContext:
            validator_writer = Writer(Generator.validator_impl_list, "")
            cpp_writer = Writer(Generator.type_builder_impl_list, "")

        def generate_all_domains_code(out, type_data_callback):
            writer = Writer(out, "")
            for domain_data in type_map.domains():
                domain_fixes = DomainNameFixes.get_fixed_data(domain_data.name())

                namespace_declared = []

                def namespace_lazy_generator():
                    if not namespace_declared:
                        writer.newline("namespace ")
                        writer.append(domain_data.name())
                        writer.append(" {\n")
                        # What is a better way to change value from outer scope?
                        namespace_declared.append(True)
                    return writer

                for type_data in domain_data.types():
                    type_data_callback(type_data, namespace_lazy_generator)

                if namespace_declared:
                    writer.append("} // ")
                    writer.append(domain_data.name())
                    writer.append("\n\n")

        def create_type_builder_caller(generate_pass_id):
            def call_type_builder(type_data, writer_getter):
                code_generator = type_data.get_binding().get_code_generator()
                if code_generator and generate_pass_id == code_generator.get_generate_pass_id():
                    writer = writer_getter()

                    code_generator.generate_type_builder(writer, GenerateContext)
            return call_type_builder

        generate_all_domains_code(output, create_type_builder_caller(TypeBuilderPass.MAIN))

        Generator.type_builder_forwards.append("// Forward declarations.\n")

        def generate_forward_callback(type_data, writer_getter):
            if type_data in global_forward_listener.type_data_set:
                binding = type_data.get_binding()
                binding.get_code_generator().generate_forward_declaration(writer_getter())
        generate_all_domains_code(Generator.type_builder_forwards, generate_forward_callback)

        Generator.type_builder_forwards.append("// End of forward declarations.\n\n")

        Generator.type_builder_forwards.append("// Typedefs.\n")

        generate_all_domains_code(Generator.type_builder_forwards, create_type_builder_caller(TypeBuilderPass.TYPEDEF))

        Generator.type_builder_forwards.append("// End of typedefs.\n\n")


def flatten_list(input):
    res = []

    def fill_recursive(l):
        for item in l:
            if isinstance(item, list):
                fill_recursive(item)
            else:
                res.append(item)
    fill_recursive(input)
    return res


# A writer that only updates file if it actually changed to better support incremental build.
class SmartOutput:
    def __init__(self, file_name):
        self.file_name_ = file_name
        self.output_ = ""

    def write(self, text):
        self.output_ += text

    def close(self):
        text_changed = True

        try:
            read_file = open(self.file_name_, "r")
            old_text = read_file.read()
            read_file.close()
            text_changed = old_text != self.output_
        except:
            # Ignore, just overwrite by default
            pass

        if text_changed:
            out_file = open(self.file_name_, "w")
            out_file.write(self.output_)
            out_file.close()


def output_file(file_name):
    # For now, disable the incremental build optimisation in all cases.
    if False:
        return SmartOutput(file_name)
    else:
        return open(file_name, "w")


Generator.go()

backend_h_file = output_file(output_dirname + "/InspectorBackendDispatcher.h")
backend_cpp_file = output_file(output_dirname + "/InspectorBackendDispatcher.cpp")

frontend_h_file = output_file(output_dirname + "/InspectorFrontend.h")
frontend_cpp_file = output_file(output_dirname + "/InspectorFrontend.cpp")

typebuilder_h_file = output_file(output_dirname + "/InspectorTypeBuilder.h")
typebuilder_cpp_file = output_file(output_dirname + "/InspectorTypeBuilder.cpp")


backend_h_file.write(Templates.backend_h.substitute(None,
    virtualSetters="\n".join(Generator.backend_virtual_setters_list),
    agentInterfaces="".join(flatten_list(Generator.backend_agent_interface_list)),
    methodNamesEnumContent="\n".join(Generator.method_name_enum_list)))

backend_cpp_file.write(Templates.backend_cpp.substitute(None,
    constructorInit="\n".join(Generator.backend_constructor_init_list),
    setters="\n".join(Generator.backend_setters_list),
    fieldDeclarations="\n".join(Generator.backend_field_list),
    methodNameDeclarations="\n".join(Generator.backend_method_name_declaration_list),
    methodNameDeclarationsIndex="\n".join(Generator.backend_method_name_declaration_index_list),
    methods="\n".join(Generator.backend_method_implementation_list),
    methodDeclarations="\n".join(Generator.backend_method_declaration_list),
    messageHandlers="\n".join(Generator.method_handler_list)))

frontend_h_file.write(Templates.frontend_h.substitute(None,
    fieldDeclarations="".join(Generator.frontend_class_field_lines),
    domainClassList="".join(Generator.frontend_domain_class_lines)))

frontend_cpp_file.write(Templates.frontend_cpp.substitute(None,
    constructorInit="".join(Generator.frontend_constructor_init_list),
    methods="\n".join(Generator.frontend_method_list)))

typebuilder_h_file.write(Templates.typebuilder_h.substitute(None,
    typeBuilders="".join(flatten_list(Generator.type_builder_fragments)),
    forwards="".join(Generator.type_builder_forwards),
    validatorIfdefName=VALIDATOR_IFDEF_NAME))

typebuilder_cpp_file.write(Templates.typebuilder_cpp.substitute(None,
    enumConstantValues=EnumConstants.get_enum_constant_code(),
    implCode="".join(flatten_list(Generator.type_builder_impl_list)),
    validatorCode="".join(flatten_list(Generator.validator_impl_list)),
    validatorIfdefName=VALIDATOR_IFDEF_NAME))

backend_h_file.close()
backend_cpp_file.close()

frontend_h_file.close()
frontend_cpp_file.close()

typebuilder_h_file.close()
typebuilder_cpp_file.close()
