### Begin File: InspectorBackendCommands.js
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

// Database
InspectorBackend.registerDomain("Database", null);
InspectorBackend.registerEnum("Database.MouseButton", {None: "None", Left: "Left", Middle: "Middle", Right: "Right"});
InspectorBackend.registerEnum("Database.OptionalParameterBundleDirectionality", {LTR: "LTR", RTL: "RTL"});
InspectorBackend.registerEnum("Database.ParameterBundleDirectionality", {LTR: "LTR", RTL: "RTL"});
InspectorBackend.activateDomain("Database", null);
### End File: InspectorBackendCommands.js

### Begin File: TestAlternateBackendDispatchers.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#pragma once

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)

#include "TestProtocolTypes.h"
#include <JavaScriptCore/InspectorBackendDispatcher.h>
#include <JavaScriptCore/InspectorFrontendRouter.h>

namespace Inspector {

class AlternateBackendDispatcher {
public:
    void setBackendDispatcher(RefPtr<BackendDispatcher>&& dispatcher) { m_backendDispatcher = WTFMove(dispatcher); }
    BackendDispatcher* backendDispatcher() const { return m_backendDispatcher.get(); }
private:
    RefPtr<BackendDispatcher> m_backendDispatcher;
};




} // namespace Inspector

#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
### End File: TestAlternateBackendDispatchers.h

### Begin File: TestBackendDispatchers.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#pragma once

#include "TestProtocolObjects.h"
#include <JavaScriptCore/InspectorBackendDispatcher.h>
#include <wtf/text/WTFString.h>

namespace Inspector {

typedef String ErrorString;



} // namespace Inspector
### End File: TestBackendDispatchers.h

### Begin File: TestBackendDispatchers.cpp
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#include "config.h"
#include "TestBackendDispatchers.h"

#include <JavaScriptCore/InspectorFrontendRouter.h>
#include <wtf/JSONValues.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/CString.h>

#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)
#include "TestAlternateBackendDispatchers.h"
#endif

namespace Inspector {



} // namespace Inspector

### End File: TestBackendDispatchers.cpp

### Begin File: TestFrontendDispatchers.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#pragma once

#include "TestProtocolObjects.h"
#include <wtf/JSONValues.h>
#include <wtf/text/WTFString.h>

namespace Inspector {

class FrontendRouter;

} // namespace Inspector
### End File: TestFrontendDispatchers.h

### Begin File: TestFrontendDispatchers.cpp
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#include "config.h"
#include "TestFrontendDispatchers.h"

#include <JavaScriptCore/InspectorFrontendRouter.h>
#include <wtf/text/CString.h>

namespace Inspector {

} // namespace Inspector

### End File: TestFrontendDispatchers.cpp

### Begin File: TestProtocolObjects.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#pragma once

#include <JavaScriptCore/InspectorProtocolTypes.h>
#include <wtf/Assertions.h>

namespace Inspector {



namespace Protocol {



// Forward declarations.
namespace Database {
class Error;
class OptionalParameterBundle;
class ParameterBundle;
class ObjectWithPropertyNameConflicts;
class DummyObject;
enum class MouseButton;
} // Database

namespace Test {
class ParameterBundle;
} // Test
// End of forward declarations.


// Typedefs.
namespace Database {
typedef JSON::ArrayOf<Inspector::Protocol::Database::Error> ErrorList;
} // Database
// End of typedefs.

namespace TestHelpers {

String getEnumConstantValue(int code);

template<typename T> String getEnumConstantValue(T enumValue)
{
    return getEnumConstantValue(static_cast<int>(enumValue));
}

} // namespace TestHelpers

namespace Database {
/* Database error. */
class Error : public JSON::ObjectBase {
public:
    enum {
        NoFieldsSet = 0,
        MessageSet = 1 << 0,
        CodeSet = 1 << 1,
        AllFieldsSet = (MessageSet | CodeSet)
    };

    template<int STATE>
    class Builder {
    private:
        RefPtr<JSON::Object> m_result;

        template<int STEP> Builder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
        }

        Builder(Ref</*Error*/JSON::Object>&& object)
            : m_result(WTFMove(object))
        {
            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
        }
        friend class Error;
    public:

        Builder<STATE | MessageSet>& setMessage(const String& value)
        {
            COMPILE_ASSERT(!(STATE & MessageSet), property_message_already_set);
            m_result->setString("message"_s, value);
            return castState<MessageSet>();
        }

        Builder<STATE | CodeSet>& setCode(int value)
        {
            COMPILE_ASSERT(!(STATE & CodeSet), property_code_already_set);
            m_result->setInteger("code"_s, value);
            return castState<CodeSet>();
        }

        Ref<Error> release()
        {
            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
            COMPILE_ASSERT(sizeof(Error) == sizeof(JSON::Object), cannot_cast);

            Ref<JSON::Object> jsonResult = m_result.releaseNonNull();
            auto result = WTFMove(*reinterpret_cast<Ref<Error>*>(&jsonResult));
            return result;
        }
    };

    /*
     * Synthetic constructor:
     * Ref<Error> result = Error::create()
     *     .setMessage(...)
     *     .setCode(...)
     *     .release();
     */
    static Builder<NoFieldsSet> create()
    {
        return Builder<NoFieldsSet>(JSON::Object::create());
    }
};

/* Enumerates different mouse buttons that can be used. */
enum class MouseButton {
    None = 0,
    Left = 1,
    Middle = 2,
    Right = 3,
}; // enum class MouseButton
class OptionalParameterBundle : public JSON::ObjectBase {
public:
    // Named after property name 'directionality' while generating OptionalParameterBundle.
    enum class Directionality {
        LTR = 4,
        RTL = 5,
    }; // enum class Directionality
    enum {
        NoFieldsSet = 0,
        AllFieldsSet = 0
    };

    template<int STATE>
    class Builder {
    private:
        RefPtr<JSON::Object> m_result;

        template<int STEP> Builder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
        }

        Builder(Ref</*OptionalParameterBundle*/JSON::Object>&& object)
            : m_result(WTFMove(object))
        {
            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
        }
        friend class OptionalParameterBundle;
    public:

        Ref<OptionalParameterBundle> release()
        {
            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
            COMPILE_ASSERT(sizeof(OptionalParameterBundle) == sizeof(JSON::Object), cannot_cast);

            Ref<JSON::Object> jsonResult = m_result.releaseNonNull();
            auto result = WTFMove(*reinterpret_cast<Ref<OptionalParameterBundle>*>(&jsonResult));
            return result;
        }
    };

    /*
     * Synthetic constructor:
     * Ref<OptionalParameterBundle> result = OptionalParameterBundle::create()
     *     .release();
     */
    static Builder<NoFieldsSet> create()
    {
        return Builder<NoFieldsSet>(JSON::Object::create());
    }

    void setColumnNames(RefPtr<JSON::ArrayOf<String>> value)
    {
        JSON::ObjectBase::setArray("columnNames"_s, WTFMove(value));
    }

    void setButtons(RefPtr<JSON::ArrayOf<Inspector::Protocol::Database::MouseButton>> value)
    {
        JSON::ObjectBase::setArray("buttons"_s, WTFMove(value));
    }

    void setDirectionality(Directionality value)
    {
        JSON::ObjectBase::setString("directionality"_s, Inspector::Protocol::TestHelpers::getEnumConstantValue(value));
    }

    void setNotes(const String& value)
    {
        JSON::ObjectBase::setString("notes"_s, value);
    }

    void setTimestamp(double value)
    {
        JSON::ObjectBase::setDouble("timestamp"_s, value);
    }

    void setValues(RefPtr<JSON::Object> value)
    {
        JSON::ObjectBase::setObject("values"_s, WTFMove(value));
    }

    void setPayload(RefPtr<JSON::Value> value)
    {
        JSON::ObjectBase::setValue("payload"_s, WTFMove(value));
    }

    void setError(RefPtr<Inspector::Protocol::Database::Error> value)
    {
        JSON::ObjectBase::setObject("error"_s, WTFMove(value));
    }

    void setErrorList(RefPtr<Inspector::Protocol::Database::ErrorList> value)
    {
        JSON::ObjectBase::setArray("errorList"_s, WTFMove(value));
    }
};

class ParameterBundle : public JSON::ObjectBase {
public:
    // Named after property name 'directionality' while generating ParameterBundle.
    enum class Directionality {
        LTR = 4,
        RTL = 5,
    }; // enum class Directionality
    enum {
        NoFieldsSet = 0,
        ColumnNamesSet = 1 << 0,
        ButtonsSet = 1 << 1,
        DirectionalitySet = 1 << 2,
        NotesSet = 1 << 3,
        TimestampSet = 1 << 4,
        ValuesSet = 1 << 5,
        PayloadSet = 1 << 6,
        ErrorSet = 1 << 7,
        ErrorListSet = 1 << 8,
        AllFieldsSet = (ColumnNamesSet | ButtonsSet | DirectionalitySet | NotesSet | TimestampSet | ValuesSet | PayloadSet | ErrorSet | ErrorListSet)
    };

    template<int STATE>
    class Builder {
    private:
        RefPtr<JSON::Object> m_result;

        template<int STEP> Builder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
        }

        Builder(Ref</*ParameterBundle*/JSON::Object>&& object)
            : m_result(WTFMove(object))
        {
            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
        }
        friend class ParameterBundle;
    public:

        Builder<STATE | ColumnNamesSet>& setColumnNames(RefPtr<JSON::ArrayOf<String>> value)
        {
            COMPILE_ASSERT(!(STATE & ColumnNamesSet), property_columnNames_already_set);
            m_result->setArray("columnNames"_s, value);
            return castState<ColumnNamesSet>();
        }

        Builder<STATE | ButtonsSet>& setButtons(RefPtr<JSON::ArrayOf<Inspector::Protocol::Database::MouseButton>> value)
        {
            COMPILE_ASSERT(!(STATE & ButtonsSet), property_buttons_already_set);
            m_result->setArray("buttons"_s, value);
            return castState<ButtonsSet>();
        }

        Builder<STATE | DirectionalitySet>& setDirectionality(Directionality value)
        {
            COMPILE_ASSERT(!(STATE & DirectionalitySet), property_directionality_already_set);
            m_result->setString("directionality"_s, Inspector::Protocol::TestHelpers::getEnumConstantValue(value));
            return castState<DirectionalitySet>();
        }

        Builder<STATE | NotesSet>& setNotes(const String& value)
        {
            COMPILE_ASSERT(!(STATE & NotesSet), property_notes_already_set);
            m_result->setString("notes"_s, value);
            return castState<NotesSet>();
        }

        Builder<STATE | TimestampSet>& setTimestamp(double value)
        {
            COMPILE_ASSERT(!(STATE & TimestampSet), property_timestamp_already_set);
            m_result->setDouble("timestamp"_s, value);
            return castState<TimestampSet>();
        }

        Builder<STATE | ValuesSet>& setValues(RefPtr<JSON::Object> value)
        {
            COMPILE_ASSERT(!(STATE & ValuesSet), property_values_already_set);
            m_result->setObject("values"_s, value);
            return castState<ValuesSet>();
        }

        Builder<STATE | PayloadSet>& setPayload(RefPtr<JSON::Value> value)
        {
            COMPILE_ASSERT(!(STATE & PayloadSet), property_payload_already_set);
            m_result->setValue("payload"_s, value);
            return castState<PayloadSet>();
        }

        Builder<STATE | ErrorSet>& setError(RefPtr<Inspector::Protocol::Database::Error> value)
        {
            COMPILE_ASSERT(!(STATE & ErrorSet), property_error_already_set);
            m_result->setObject("error"_s, value);
            return castState<ErrorSet>();
        }

        Builder<STATE | ErrorListSet>& setErrorList(RefPtr<Inspector::Protocol::Database::ErrorList> value)
        {
            COMPILE_ASSERT(!(STATE & ErrorListSet), property_errorList_already_set);
            m_result->setArray("errorList"_s, value);
            return castState<ErrorListSet>();
        }

        Ref<ParameterBundle> release()
        {
            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
            COMPILE_ASSERT(sizeof(ParameterBundle) == sizeof(JSON::Object), cannot_cast);

            Ref<JSON::Object> jsonResult = m_result.releaseNonNull();
            auto result = WTFMove(*reinterpret_cast<Ref<ParameterBundle>*>(&jsonResult));
            return result;
        }
    };

    /*
     * Synthetic constructor:
     * Ref<ParameterBundle> result = ParameterBundle::create()
     *     .setColumnNames(...)
     *     .setButtons(...)
     *     .setDirectionality(...)
     *     .setNotes(...)
     *     .setTimestamp(...)
     *     .setValues(...)
     *     .setPayload(...)
     *     .setError(...)
     *     .setErrorList(...)
     *     .release();
     */
    static Builder<NoFieldsSet> create()
    {
        return Builder<NoFieldsSet>(JSON::Object::create());
    }
};

/* Conflicted names may cause generated getters/setters to clash with built-in InspectorObject methods. */
class ObjectWithPropertyNameConflicts : public JSON::ObjectBase {
public:
    enum {
        NoFieldsSet = 0,
        IntegerSet = 1 << 0,
        ArraySet = 1 << 1,
        StringSet = 1 << 2,
        ValueSet = 1 << 3,
        ObjectSet = 1 << 4,
        AllFieldsSet = (IntegerSet | ArraySet | StringSet | ValueSet | ObjectSet)
    };

    template<int STATE>
    class Builder {
    private:
        RefPtr<JSON::Object> m_result;

        template<int STEP> Builder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
        }

        Builder(Ref</*ObjectWithPropertyNameConflicts*/JSON::Object>&& object)
            : m_result(WTFMove(object))
        {
            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
        }
        friend class ObjectWithPropertyNameConflicts;
    public:

        Builder<STATE | IntegerSet>& setInteger(const String& value)
        {
            COMPILE_ASSERT(!(STATE & IntegerSet), property_integer_already_set);
            m_result->setString("integer"_s, value);
            return castState<IntegerSet>();
        }

        Builder<STATE | ArraySet>& setArray(const String& value)
        {
            COMPILE_ASSERT(!(STATE & ArraySet), property_array_already_set);
            m_result->setString("array"_s, value);
            return castState<ArraySet>();
        }

        Builder<STATE | StringSet>& setString(const String& value)
        {
            COMPILE_ASSERT(!(STATE & StringSet), property_string_already_set);
            m_result->setString("string"_s, value);
            return castState<StringSet>();
        }

        Builder<STATE | ValueSet>& setValue(const String& value)
        {
            COMPILE_ASSERT(!(STATE & ValueSet), property_value_already_set);
            m_result->setString("value"_s, value);
            return castState<ValueSet>();
        }

        Builder<STATE | ObjectSet>& setObject(const String& value)
        {
            COMPILE_ASSERT(!(STATE & ObjectSet), property_object_already_set);
            m_result->setString("object"_s, value);
            return castState<ObjectSet>();
        }

        Ref<ObjectWithPropertyNameConflicts> release()
        {
            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
            COMPILE_ASSERT(sizeof(ObjectWithPropertyNameConflicts) == sizeof(JSON::Object), cannot_cast);

            Ref<JSON::Object> jsonResult = m_result.releaseNonNull();
            auto result = WTFMove(*reinterpret_cast<Ref<ObjectWithPropertyNameConflicts>*>(&jsonResult));
            return result;
        }
    };

    /*
     * Synthetic constructor:
     * Ref<ObjectWithPropertyNameConflicts> result = ObjectWithPropertyNameConflicts::create()
     *     .setInteger(...)
     *     .setArray(...)
     *     .setString(...)
     *     .setValue(...)
     *     .setObject(...)
     *     .release();
     */
    static Builder<NoFieldsSet> create()
    {
        return Builder<NoFieldsSet>(JSON::Object::create());
    }
};

} // Database

namespace Test {
class ParameterBundle : public JSON::ObjectBase {
public:
    // Named after property name 'directionality' while generating ParameterBundle.
    enum class Directionality {
        LTR = 4,
        RTL = 5,
    }; // enum class Directionality
    enum {
        NoFieldsSet = 0,
        DirectionalitySet = 1 << 0,
        ButtonsSet = 1 << 1,
        ColumnNamesSet = 1 << 2,
        NotesSet = 1 << 3,
        TimestampSet = 1 << 4,
        ValuesSet = 1 << 5,
        PayloadSet = 1 << 6,
        ErrorSet = 1 << 7,
        AllFieldsSet = (DirectionalitySet | ButtonsSet | ColumnNamesSet | NotesSet | TimestampSet | ValuesSet | PayloadSet | ErrorSet)
    };

    template<int STATE>
    class Builder {
    private:
        RefPtr<JSON::Object> m_result;

        template<int STEP> Builder<STATE | STEP>& castState()
        {
            return *reinterpret_cast<Builder<STATE | STEP>*>(this);
        }

        Builder(Ref</*ParameterBundle*/JSON::Object>&& object)
            : m_result(WTFMove(object))
        {
            COMPILE_ASSERT(STATE == NoFieldsSet, builder_created_in_non_init_state);
        }
        friend class ParameterBundle;
    public:

        Builder<STATE | DirectionalitySet>& setDirectionality(Directionality value)
        {
            COMPILE_ASSERT(!(STATE & DirectionalitySet), property_directionality_already_set);
            m_result->setString("directionality"_s, Inspector::Protocol::TestHelpers::getEnumConstantValue(value));
            return castState<DirectionalitySet>();
        }

        Builder<STATE | ButtonsSet>& setButtons(RefPtr<JSON::ArrayOf<Inspector::Protocol::Database::MouseButton>> value)
        {
            COMPILE_ASSERT(!(STATE & ButtonsSet), property_buttons_already_set);
            m_result->setArray("buttons"_s, value);
            return castState<ButtonsSet>();
        }

        Builder<STATE | ColumnNamesSet>& setColumnNames(RefPtr<JSON::ArrayOf<String>> value)
        {
            COMPILE_ASSERT(!(STATE & ColumnNamesSet), property_columnNames_already_set);
            m_result->setArray("columnNames"_s, value);
            return castState<ColumnNamesSet>();
        }

        Builder<STATE | NotesSet>& setNotes(const String& value)
        {
            COMPILE_ASSERT(!(STATE & NotesSet), property_notes_already_set);
            m_result->setString("notes"_s, value);
            return castState<NotesSet>();
        }

        Builder<STATE | TimestampSet>& setTimestamp(double value)
        {
            COMPILE_ASSERT(!(STATE & TimestampSet), property_timestamp_already_set);
            m_result->setDouble("timestamp"_s, value);
            return castState<TimestampSet>();
        }

        Builder<STATE | ValuesSet>& setValues(RefPtr<JSON::Object> value)
        {
            COMPILE_ASSERT(!(STATE & ValuesSet), property_values_already_set);
            m_result->setObject("values"_s, value);
            return castState<ValuesSet>();
        }

        Builder<STATE | PayloadSet>& setPayload(RefPtr<JSON::Value> value)
        {
            COMPILE_ASSERT(!(STATE & PayloadSet), property_payload_already_set);
            m_result->setValue("payload"_s, value);
            return castState<PayloadSet>();
        }

        Builder<STATE | ErrorSet>& setError(RefPtr<Inspector::Protocol::Database::Error> value)
        {
            COMPILE_ASSERT(!(STATE & ErrorSet), property_error_already_set);
            m_result->setObject("error"_s, value);
            return castState<ErrorSet>();
        }

        Ref<ParameterBundle> release()
        {
            COMPILE_ASSERT(STATE == AllFieldsSet, result_is_not_ready);
            COMPILE_ASSERT(sizeof(ParameterBundle) == sizeof(JSON::Object), cannot_cast);

            Ref<JSON::Object> jsonResult = m_result.releaseNonNull();
            auto result = WTFMove(*reinterpret_cast<Ref<ParameterBundle>*>(&jsonResult));
            return result;
        }
    };

    /*
     * Synthetic constructor:
     * Ref<ParameterBundle> result = ParameterBundle::create()
     *     .setDirectionality(...)
     *     .setButtons(...)
     *     .setColumnNames(...)
     *     .setNotes(...)
     *     .setTimestamp(...)
     *     .setValues(...)
     *     .setPayload(...)
     *     .setError(...)
     *     .release();
     */
    static Builder<NoFieldsSet> create()
    {
        return Builder<NoFieldsSet>(JSON::Object::create());
    }
};

} // Test



namespace TestHelpers {

template<typename ProtocolEnumType>
Optional<ProtocolEnumType> parseEnumValueFromString(const String&);

// Enums in the 'Database' Domain
template<>
Optional<Inspector::Protocol::Database::MouseButton> parseEnumValueFromString<Inspector::Protocol::Database::MouseButton>(const String&);
template<>
Optional<Inspector::Protocol::Database::OptionalParameterBundle::Directionality> parseEnumValueFromString<Inspector::Protocol::Database::OptionalParameterBundle::Directionality>(const String&);
template<>
Optional<Inspector::Protocol::Database::ParameterBundle::Directionality> parseEnumValueFromString<Inspector::Protocol::Database::ParameterBundle::Directionality>(const String&);

// Enums in the 'Test' Domain
template<>
Optional<Inspector::Protocol::Test::ParameterBundle::Directionality> parseEnumValueFromString<Inspector::Protocol::Test::ParameterBundle::Directionality>(const String&);

} // namespace TestHelpers

} // namespace Protocol

} // namespace Inspector

namespace WTF {

template<typename T> struct DefaultHash;

// Hash declarations in the 'Database' Domain
template<>
struct DefaultHash<Inspector::Protocol::Database::MouseButton> {
    typedef IntHash<Inspector::Protocol::Database::MouseButton> Hash;
};

} // namespace WTF
### End File: TestProtocolObjects.h

### Begin File: TestProtocolObjects.cpp
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#include "config.h"
#include "TestProtocolObjects.h"

#include <wtf/Optional.h>
#include <wtf/text/CString.h>

namespace Inspector {

namespace Protocol {

namespace TestHelpers {

static const char* const enum_constant_values[] = {
    "None",
    "Left",
    "Middle",
    "Right",
    "LTR",
    "RTL",
};

String getEnumConstantValue(int code) {
    return enum_constant_values[code];
}

// Enums in the 'Database' Domain
template<>
Optional<Inspector::Protocol::Database::MouseButton> parseEnumValueFromString<Inspector::Protocol::Database::MouseButton>(const String& protocolString)
{
    static const size_t constantValues[] = {
        (size_t)Inspector::Protocol::Database::MouseButton::None,
        (size_t)Inspector::Protocol::Database::MouseButton::Left,
        (size_t)Inspector::Protocol::Database::MouseButton::Middle,
        (size_t)Inspector::Protocol::Database::MouseButton::Right,
    };
    for (size_t i = 0; i < 4; ++i)
        if (protocolString == enum_constant_values[constantValues[i]])
            return (Inspector::Protocol::Database::MouseButton)constantValues[i];

    return WTF::nullopt;
}

template<>
Optional<Inspector::Protocol::Database::OptionalParameterBundle::Directionality> parseEnumValueFromString<Inspector::Protocol::Database::OptionalParameterBundle::Directionality>(const String& protocolString)
{
    static const size_t constantValues[] = {
        (size_t)Inspector::Protocol::Database::OptionalParameterBundle::Directionality::LTR,
        (size_t)Inspector::Protocol::Database::OptionalParameterBundle::Directionality::RTL,
    };
    for (size_t i = 0; i < 2; ++i)
        if (protocolString == enum_constant_values[constantValues[i]])
            return (Inspector::Protocol::Database::OptionalParameterBundle::Directionality)constantValues[i];

    return WTF::nullopt;
}

template<>
Optional<Inspector::Protocol::Database::ParameterBundle::Directionality> parseEnumValueFromString<Inspector::Protocol::Database::ParameterBundle::Directionality>(const String& protocolString)
{
    static const size_t constantValues[] = {
        (size_t)Inspector::Protocol::Database::ParameterBundle::Directionality::LTR,
        (size_t)Inspector::Protocol::Database::ParameterBundle::Directionality::RTL,
    };
    for (size_t i = 0; i < 2; ++i)
        if (protocolString == enum_constant_values[constantValues[i]])
            return (Inspector::Protocol::Database::ParameterBundle::Directionality)constantValues[i];

    return WTF::nullopt;
}


// Enums in the 'Test' Domain
template<>
Optional<Inspector::Protocol::Test::ParameterBundle::Directionality> parseEnumValueFromString<Inspector::Protocol::Test::ParameterBundle::Directionality>(const String& protocolString)
{
    static const size_t constantValues[] = {
        (size_t)Inspector::Protocol::Test::ParameterBundle::Directionality::LTR,
        (size_t)Inspector::Protocol::Test::ParameterBundle::Directionality::RTL,
    };
    for (size_t i = 0; i < 2; ++i)
        if (protocolString == enum_constant_values[constantValues[i]])
            return (Inspector::Protocol::Test::ParameterBundle::Directionality)constantValues[i];

    return WTF::nullopt;
}


} // namespace TestHelpers



} // namespace Protocol

} // namespace Inspector

### End File: TestProtocolObjects.cpp

### Begin File: TestProtocolBackendDispatchers.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#include <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
#include <wtf/RetainPtr.h>



namespace Inspector {


} // namespace Inspector

### End File: TestProtocolBackendDispatchers.h

### Begin File: TestProtocolBackendDispatchers.mm
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "config.h"
#import "TestProtocolBackendDispatchers.h"

#include "TestProtocolInternal.h"
#include "TestProtocolTypeConversions.h"
#include <wtf/JSONValues.h>

namespace Inspector {

} // namespace Inspector

### End File: TestProtocolBackendDispatchers.mm

### Begin File: TestProtocolConfiguration.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import <WebInspector/TestProtocol.h>

__attribute__((visibility ("default")))
@interface TestProtocolConfiguration : NSObject
@end


### End File: TestProtocolConfiguration.h

### Begin File: TestProtocolConfiguration.mm
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "TestProtocolConfiguration.h"

#import "TestProtocolInternal.h"
#import "TestProtocolBackendDispatchers.h"
#import <JavaScriptCore/AlternateDispatchableAgent.h>
#import <JavaScriptCore/AugmentableInspectorController.h>
#import <JavaScriptCore/InspectorAlternateBackendDispatchers.h>
#import <JavaScriptCore/InspectorBackendDispatchers.h>

using namespace Inspector;

@implementation TestProtocolConfiguration
{
    AugmentableInspectorController* _controller;
}

- (instancetype)initWithController:(AugmentableInspectorController*)controller
{
    self = [super init];
    if (!self)
        return nil;
    ASSERT(controller);
    _controller = controller;
    return self;
}

- (void)dealloc
{
    [super dealloc];
}

@end


### End File: TestProtocolConfiguration.mm

### Begin File: TestProtocolEventDispatchers.mm
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "TestProtocolInternal.h"

#import "TestProtocolTypeConversions.h"
#import <wtf/JSONValues.h>

using namespace Inspector;


### End File: TestProtocolEventDispatchers.mm

### Begin File: TestProtocol.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import <Foundation/Foundation.h>

#import <WebInspector/RWIProtocolJSONObject.h>


@class TestProtocolDatabaseError;
@class TestProtocolDatabaseOptionalParameterBundle;
@class TestProtocolDatabaseParameterBundle;
@class TestProtocolDatabaseObjectWithPropertyNameConflicts;
@class TestProtocolDatabaseDummyObject;
@class TestProtocolTestParameterBundle;

typedef NS_ENUM(NSInteger, TestProtocolPlatform) {
    TestProtocolPlatformAll,
    TestProtocolPlatformGeneric,
    TestProtocolPlatformIOS,
    TestProtocolPlatformMacOS,
};


typedef NS_ENUM(NSInteger, TestProtocolDatabaseMouseButton) {
    TestProtocolDatabaseMouseButtonNone,
    TestProtocolDatabaseMouseButtonLeft,
    TestProtocolDatabaseMouseButtonMiddle,
    TestProtocolDatabaseMouseButtonRight,
};

typedef NS_ENUM(NSInteger, TestProtocolDatabaseOptionalParameterBundleDirectionality) {
    TestProtocolDatabaseOptionalParameterBundleDirectionalityLTR,
    TestProtocolDatabaseOptionalParameterBundleDirectionalityRTL,
};

typedef NS_ENUM(NSInteger, TestProtocolDatabaseParameterBundleDirectionality) {
    TestProtocolDatabaseParameterBundleDirectionalityLTR,
    TestProtocolDatabaseParameterBundleDirectionalityRTL,
};

typedef NS_ENUM(NSInteger, TestProtocolTestParameterBundleDirectionality) {
    TestProtocolTestParameterBundleDirectionalityLTR,
    TestProtocolTestParameterBundleDirectionalityRTL,
};


__attribute__((visibility ("default")))
@interface TestProtocolDatabaseError : RWIProtocolJSONObject
- (instancetype)initWithPayload:(NSDictionary<NSString *, id> *)payload;
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)jsonObject;
- (instancetype)initWithMessage:(NSString *)message code:(int)code;
/* required */ @property (nonatomic, copy) NSString *message;
/* required */ @property (nonatomic, assign) int code;
@end

__attribute__((visibility ("default")))
@interface TestProtocolDatabaseOptionalParameterBundle : RWIProtocolJSONObject
- (instancetype)initWithPayload:(NSDictionary<NSString *, id> *)payload;
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)jsonObject;
/* optional */ @property (nonatomic, copy) NSArray/*<NSString>*/ *columnNames;
/* optional */ @property (nonatomic, copy) NSArray/*<NSString>*/ *buttons;
/* optional */ @property (nonatomic, assign) TestProtocolDatabaseOptionalParameterBundleDirectionality directionality;
/* optional */ @property (nonatomic, copy) NSString *notes;
/* optional */ @property (nonatomic, assign) double timestamp;
/* optional */ @property (nonatomic, retain) RWIProtocolJSONObject *values;
/* optional */ @property (nonatomic, retain) RWIProtocolJSONObject *payload;
/* optional */ @property (nonatomic, retain) TestProtocolDatabaseError *error;
/* optional */ @property (nonatomic, copy) NSArray/*<TestProtocolDatabaseError>*/ *errorList;
@end

__attribute__((visibility ("default")))
@interface TestProtocolDatabaseParameterBundle : RWIProtocolJSONObject
- (instancetype)initWithPayload:(NSDictionary<NSString *, id> *)payload;
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)jsonObject;
- (instancetype)initWithColumnNames:(NSArray/*<NSString>*/ *)columnNames buttons:(NSArray/*<NSString>*/ *)buttons directionality:(TestProtocolDatabaseParameterBundleDirectionality)directionality notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(TestProtocolDatabaseError *)error errorList:(NSArray/*<TestProtocolDatabaseError>*/ *)errorList;
/* required */ @property (nonatomic, copy) NSArray/*<NSString>*/ *columnNames;
/* required */ @property (nonatomic, copy) NSArray/*<NSString>*/ *buttons;
/* required */ @property (nonatomic, assign) TestProtocolDatabaseParameterBundleDirectionality directionality;
/* required */ @property (nonatomic, copy) NSString *notes;
/* required */ @property (nonatomic, assign) double timestamp;
/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *values;
/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *payload;
/* required */ @property (nonatomic, retain) TestProtocolDatabaseError *error;
/* required */ @property (nonatomic, copy) NSArray/*<TestProtocolDatabaseError>*/ *errorList;
@end

__attribute__((visibility ("default")))
@interface TestProtocolDatabaseObjectWithPropertyNameConflicts : RWIProtocolJSONObject
- (instancetype)initWithPayload:(NSDictionary<NSString *, id> *)payload;
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)jsonObject;
- (instancetype)initWithInteger:(NSString *)integer array:(NSString *)array string:(NSString *)string value:(NSString *)value object:(NSString *)object;
/* required */ @property (nonatomic, copy) NSString *integer;
/* required */ @property (nonatomic, copy) NSString *array;
/* required */ @property (nonatomic, copy) NSString *string;
/* required */ @property (nonatomic, copy) NSString *value;
/* required */ @property (nonatomic, copy) NSString *object;
@end

__attribute__((visibility ("default")))
@interface TestProtocolDatabaseDummyObject : RWIProtocolJSONObject
- (instancetype)initWithPayload:(NSDictionary<NSString *, id> *)payload;
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)jsonObject;
@end

__attribute__((visibility ("default")))
@interface TestProtocolTestParameterBundle : RWIProtocolJSONObject
- (instancetype)initWithPayload:(NSDictionary<NSString *, id> *)payload;
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)jsonObject;
- (instancetype)initWithDirectionality:(TestProtocolTestParameterBundleDirectionality)directionality buttons:(NSArray/*<NSString>*/ *)buttons columnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(TestProtocolDatabaseError *)error;
/* required */ @property (nonatomic, assign) TestProtocolTestParameterBundleDirectionality directionality;
/* required */ @property (nonatomic, copy) NSArray/*<NSString>*/ *buttons;
/* required */ @property (nonatomic, copy) NSArray/*<NSString>*/ *columnNames;
/* required */ @property (nonatomic, copy) NSString *notes;
/* required */ @property (nonatomic, assign) double timestamp;
/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *values;
/* required */ @property (nonatomic, retain) RWIProtocolJSONObject *payload;
/* required */ @property (nonatomic, retain) TestProtocolDatabaseError *error;
@end






#import <WebInspector/RWIProtocolBuildCompatibilityObjects.h>

### End File: TestProtocol.h

### Begin File: TestProtocolInternal.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "TestProtocol.h"
#import "TestProtocolJSONObjectPrivate.h"
#import <JavaScriptCore/AugmentableInspectorController.h>
#import <wtf/JSONValues.h>




### End File: TestProtocolInternal.h

### Begin File: TestProtocolTypeConversions.h
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "TestProtocol.h"
#import <WebInspector/RWIProtocolArrayConversions.h>

namespace Inspector {

template<typename ObjCEnumType>
Optional<ObjCEnumType> fromProtocolString(const String& value);

inline String toProtocolString(TestProtocolPlatform value)
{
    switch(value) {
    case TestProtocolPlatformAll:
        return "all"_s;
    case TestProtocolPlatformGeneric:
        return "generic"_s;
    case TestProtocolPlatformIOS:
        return "ios"_s;
    case TestProtocolPlatformMacOS:
        return "macos"_s;
    }
}

template<>
inline Optional<TestProtocolPlatform> fromProtocolString(const String& value)
{
    if (value == "all")
        return TestProtocolPlatformAll;
    if (value == "generic")
        return TestProtocolPlatformGeneric;
    if (value == "ios")
        return TestProtocolPlatformIOS;
    if (value == "macos")
        return TestProtocolPlatformMacOS;
    return WTF::nullopt;
}


inline String toProtocolString(TestProtocolDatabaseMouseButton value)
{
    switch(value) {
    case TestProtocolDatabaseMouseButtonNone:
        return "None"_s;
    case TestProtocolDatabaseMouseButtonLeft:
        return "Left"_s;
    case TestProtocolDatabaseMouseButtonMiddle:
        return "Middle"_s;
    case TestProtocolDatabaseMouseButtonRight:
        return "Right"_s;
    }
}

template<>
inline Optional<TestProtocolDatabaseMouseButton> fromProtocolString(const String& value)
{
    if (value == "None")
        return TestProtocolDatabaseMouseButtonNone;
    if (value == "Left")
        return TestProtocolDatabaseMouseButtonLeft;
    if (value == "Middle")
        return TestProtocolDatabaseMouseButtonMiddle;
    if (value == "Right")
        return TestProtocolDatabaseMouseButtonRight;
    return WTF::nullopt;
}

inline String toProtocolString(TestProtocolDatabaseOptionalParameterBundleDirectionality value)
{
    switch(value) {
    case TestProtocolDatabaseOptionalParameterBundleDirectionalityLTR:
        return "LTR"_s;
    case TestProtocolDatabaseOptionalParameterBundleDirectionalityRTL:
        return "RTL"_s;
    }
}

template<>
inline Optional<TestProtocolDatabaseOptionalParameterBundleDirectionality> fromProtocolString(const String& value)
{
    if (value == "LTR")
        return TestProtocolDatabaseOptionalParameterBundleDirectionalityLTR;
    if (value == "RTL")
        return TestProtocolDatabaseOptionalParameterBundleDirectionalityRTL;
    return WTF::nullopt;
}

inline String toProtocolString(TestProtocolDatabaseParameterBundleDirectionality value)
{
    switch(value) {
    case TestProtocolDatabaseParameterBundleDirectionalityLTR:
        return "LTR"_s;
    case TestProtocolDatabaseParameterBundleDirectionalityRTL:
        return "RTL"_s;
    }
}

template<>
inline Optional<TestProtocolDatabaseParameterBundleDirectionality> fromProtocolString(const String& value)
{
    if (value == "LTR")
        return TestProtocolDatabaseParameterBundleDirectionalityLTR;
    if (value == "RTL")
        return TestProtocolDatabaseParameterBundleDirectionalityRTL;
    return WTF::nullopt;
}


inline String toProtocolString(TestProtocolTestParameterBundleDirectionality value)
{
    switch(value) {
    case TestProtocolTestParameterBundleDirectionalityLTR:
        return "LTR"_s;
    case TestProtocolTestParameterBundleDirectionalityRTL:
        return "RTL"_s;
    }
}

template<>
inline Optional<TestProtocolTestParameterBundleDirectionality> fromProtocolString(const String& value)
{
    if (value == "LTR")
        return TestProtocolTestParameterBundleDirectionalityLTR;
    if (value == "RTL")
        return TestProtocolTestParameterBundleDirectionalityRTL;
    return WTF::nullopt;
}

} // namespace Inspector

### End File: TestProtocolTypeConversions.h

### Begin File: TestProtocolTypeConversions.mm
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "TestProtocolTypeConversions.h"

#import "TestProtocol.h"
#import "TestProtocolTypeParser.h"
#import <WebInspector/RWIProtocolJSONObjectPrivate.h>

using namespace Inspector;

@interface TestProtocolTypeConversions (DatabaseDomain)

+ (void)_parseError:(TestProtocolDatabaseError **)outValue fromPayload:(id)payload;
+ (void)_parseErrorList:(NSArray/*<TestProtocolDatabaseError>*/ **)outValue fromPayload:(id)payload;
+ (void)_parseMouseButton:(NSNumber **)outValue fromPayload:(id)payload;
+ (void)_parseOptionalParameterBundle:(TestProtocolDatabaseOptionalParameterBundle **)outValue fromPayload:(id)payload;
+ (void)_parseParameterBundle:(TestProtocolDatabaseParameterBundle **)outValue fromPayload:(id)payload;
+ (void)_parseObjectWithPropertyNameConflicts:(TestProtocolDatabaseObjectWithPropertyNameConflicts **)outValue fromPayload:(id)payload;
+ (void)_parseDummyObject:(TestProtocolDatabaseDummyObject **)outValue fromPayload:(id)payload;

@end
@interface TestProtocolTypeConversions (TestDomain)

+ (void)_parseParameterBundle:(TestProtocolTestParameterBundle **)outValue fromPayload:(id)payload;

@end

@implementation TestProtocolTypeConversions (DatabaseDomain)

+ (void)_parseError:(TestProtocolDatabaseError **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSDictionary class]);
    *outValue = [[TestProtocolDatabaseError alloc] initWithPayload:payload];
}

+ (void)_parseErrorList:(NSArray/*<TestProtocolDatabaseError>*/ **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSArray/*<TestProtocolDatabaseError>*/ class]);
    *outValue = (NSArray/*<TestProtocolDatabaseError>*/ *)payload;
}

+ (void)_parseMouseButton:(NSNumber **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSString class]);
    Optional<TestProtocolDatabaseMouseButton> result = Inspector::fromProtocolString<TestProtocolDatabaseMouseButton>(payload);
    THROW_EXCEPTION_FOR_BAD_ENUM_VALUE(result, @"MouseButton");
    *outValue = @(result.value());
}

+ (void)_parseOptionalParameterBundle:(TestProtocolDatabaseOptionalParameterBundle **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSDictionary class]);
    *outValue = [[TestProtocolDatabaseOptionalParameterBundle alloc] initWithPayload:payload];
}

+ (void)_parseParameterBundle:(TestProtocolDatabaseParameterBundle **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSDictionary class]);
    *outValue = [[TestProtocolDatabaseParameterBundle alloc] initWithPayload:payload];
}

+ (void)_parseObjectWithPropertyNameConflicts:(TestProtocolDatabaseObjectWithPropertyNameConflicts **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSDictionary class]);
    *outValue = [[TestProtocolDatabaseObjectWithPropertyNameConflicts alloc] initWithPayload:payload];
}

+ (void)_parseDummyObject:(TestProtocolDatabaseDummyObject **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSDictionary class]);
    *outValue = [[TestProtocolDatabaseDummyObject alloc] initWithPayload:payload];
}

@end
@implementation TestProtocolTypeConversions (TestDomain)

+ (void)_parseParameterBundle:(TestProtocolTestParameterBundle **)outValue fromPayload:(id)payload
{
    THROW_EXCEPTION_FOR_BAD_TYPE(payload, [NSDictionary class]);
    *outValue = [[TestProtocolTestParameterBundle alloc] initWithPayload:payload];
}

@end


### End File: TestProtocolTypeConversions.mm

### Begin File: TestProtocolTypes.mm
/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
 * Copyright (C) 2014 University of Washington. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
 */

// DO NOT EDIT THIS FILE. It is automatically generated from type-declaration-object-type.json
// by the script: Source/JavaScriptCore/inspector/scripts/generate-inspector-protocol-bindings.py

#import "TestProtocolInternal.h"

#import "TestProtocolTypeConversions.h"
#import <WebInspector/RWIProtocolJSONObjectPrivate.h>
#import <wtf/Assertions.h>
#import <wtf/JSONValues.h>

using namespace Inspector;


@implementation TestProtocolDatabaseError

- (instancetype)initWithPayload:(nonnull NSDictionary<NSString *, id> *)payload
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"message"], @"message");
    self.message = payload[@"message"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"code"], @"code");
    self.code = [payload[@"code"] integerValue];

    return self;
}
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)object
{
    if (!(self = [super initWithJSONObject:[object toJSONObject].get()]))
        return nil;

    return self;
}

- (instancetype)initWithMessage:(NSString *)message code:(int)code
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(message, @"message");

    self.message = message;
    self.code = code;

    return self;
}

- (void)setMessage:(NSString *)message
{
    [super setString:message forKey:@"message"];
}

- (NSString *)message
{
    return [super stringForKey:@"message"];
}

- (void)setCode:(int)code
{
    [super setInteger:code forKey:@"code"];
}

- (int)code
{
    return [super integerForKey:@"code"];
}

@end

@implementation TestProtocolDatabaseOptionalParameterBundle

- (instancetype)initWithPayload:(nonnull NSDictionary<NSString *, id> *)payload
{
    if (!(self = [super init]))
        return nil;

    self.columnNames = payload[@"columnNames"];

    self.buttons = payload[@"buttons"];

    Optional<TestProtocolDatabaseOptionalParameterBundleDirectionality> directionality = fromProtocolString<TestProtocolDatabaseOptionalParameterBundleDirectionality>(payload[@"directionality"]);
    if (directionality)
        self.directionality = directionality.value();

    self.notes = payload[@"notes"];

    self.timestamp = [payload[@"timestamp"] doubleValue];

    self.values = payload[@"values"];

    self.payload = payload[@"payload"];

    self.error = [[TestProtocolDatabaseError alloc] initWithPayload:payload[@"error"]];

    self.errorList = objcArrayFromPayload<TestProtocolDatabaseError>(payload[@"errorList"]);

    return self;
}
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)object
{
    if (!(self = [super initWithJSONObject:[object toJSONObject].get()]))
        return nil;

    return self;
}

- (void)setColumnNames:(NSArray/*<NSString>*/ *)columnNames
{
    [super setJSONArray:toJSONStringArray(columnNames) forKey:@"columnNames"];
}

- (NSArray/*<NSString>*/ *)columnNames
{
    return toObjCStringArray([super JSONArrayForKey:@"columnNames"]);
}

- (void)setButtons:(NSArray/*<NSString>*/ *)buttons
{
    [super setJSONArray:toJSONStringArray(buttons) forKey:@"buttons"];
}

- (NSArray/*<NSString>*/ *)buttons
{
    return toObjCStringArray([super JSONArrayForKey:@"buttons"]);
}

- (void)setDirectionality:(TestProtocolDatabaseOptionalParameterBundleDirectionality)directionality
{
    [super setString:toProtocolString(directionality) forKey:@"directionality"];
}

- (TestProtocolDatabaseOptionalParameterBundleDirectionality)directionality
{
    return fromProtocolString<TestProtocolDatabaseOptionalParameterBundleDirectionality>([super stringForKey:@"directionality"]).value();
}

- (void)setNotes:(NSString *)notes
{
    [super setString:notes forKey:@"notes"];
}

- (NSString *)notes
{
    return [super stringForKey:@"notes"];
}

- (void)setTimestamp:(double)timestamp
{
    [super setDouble:timestamp forKey:@"timestamp"];
}

- (double)timestamp
{
    return [super doubleForKey:@"timestamp"];
}

- (void)setValues:(RWIProtocolJSONObject *)values
{
    [super setObject:values forKey:@"values"];
}

- (RWIProtocolJSONObject *)values
{
    RWIProtocolJSONObject *object = [super objectForKey:@"values"];
    if (!object)
        return nil;
    return [[RWIProtocolJSONObject alloc] initWithJSONObject:[[super objectForKey:@"values"] toJSONObject].get()];
}

- (void)setPayload:(RWIProtocolJSONObject *)payload
{
    [super setObject:payload forKey:@"payload"];
}

- (RWIProtocolJSONObject *)payload
{
    RWIProtocolJSONObject *object = [super objectForKey:@"payload"];
    if (!object)
        return nil;
    return [[RWIProtocolJSONObject alloc] initWithJSONObject:[[super objectForKey:@"payload"] toJSONObject].get()];
}

- (void)setError:(TestProtocolDatabaseError *)error
{
    [super setObject:error forKey:@"error"];
}

- (TestProtocolDatabaseError *)error
{
    RWIProtocolJSONObject *object = [super objectForKey:@"error"];
    if (!object)
        return nil;
    return [[TestProtocolDatabaseError alloc] initWithJSONObject:[[super objectForKey:@"error"] toJSONObject].get()];
}

- (void)setErrorList:(NSArray/*<TestProtocolDatabaseError>*/ *)errorList
{
    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(errorList, [TestProtocolDatabaseError class]);
    [super setJSONArray:toJSONObjectArray(errorList) forKey:@"errorList"];
}

- (NSArray/*<TestProtocolDatabaseError>*/ *)errorList
{
    return toObjCArray<TestProtocolDatabaseError>([super JSONArrayForKey:@"errorList"]);
}

@end

@implementation TestProtocolDatabaseParameterBundle

- (instancetype)initWithPayload:(nonnull NSDictionary<NSString *, id> *)payload
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"columnNames"], @"columnNames");
    self.columnNames = payload[@"columnNames"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"buttons"], @"buttons");
    self.buttons = payload[@"buttons"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"directionality"], @"directionality");
    Optional<TestProtocolDatabaseParameterBundleDirectionality> directionality = fromProtocolString<TestProtocolDatabaseParameterBundleDirectionality>(payload[@"directionality"]);
    THROW_EXCEPTION_FOR_BAD_ENUM_VALUE(directionality, @"directionality");
    self.directionality = directionality.value();

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"notes"], @"notes");
    self.notes = payload[@"notes"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"timestamp"], @"timestamp");
    self.timestamp = [payload[@"timestamp"] doubleValue];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"values"], @"values");
    self.values = payload[@"values"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"payload"], @"payload");
    self.payload = payload[@"payload"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"error"], @"error");
    self.error = [[TestProtocolDatabaseError alloc] initWithPayload:payload[@"error"]];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"errorList"], @"errorList");
    self.errorList = objcArrayFromPayload<TestProtocolDatabaseError>(payload[@"errorList"]);

    return self;
}
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)object
{
    if (!(self = [super initWithJSONObject:[object toJSONObject].get()]))
        return nil;

    return self;
}

- (instancetype)initWithColumnNames:(NSArray/*<NSString>*/ *)columnNames buttons:(NSArray/*<NSString>*/ *)buttons directionality:(TestProtocolDatabaseParameterBundleDirectionality)directionality notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(TestProtocolDatabaseError *)error errorList:(NSArray/*<TestProtocolDatabaseError>*/ *)errorList
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(columnNames, @"columnNames");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(buttons, @"buttons");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(notes, @"notes");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(values, @"values");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload, @"payload");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(error, @"error");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(errorList, @"errorList");
    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(errorList, [TestProtocolDatabaseError class]);

    self.columnNames = columnNames;
    self.buttons = buttons;
    self.directionality = directionality;
    self.notes = notes;
    self.timestamp = timestamp;
    self.values = values;
    self.payload = payload;
    self.error = error;
    self.errorList = errorList;

    return self;
}

- (void)setColumnNames:(NSArray/*<NSString>*/ *)columnNames
{
    [super setJSONArray:toJSONStringArray(columnNames) forKey:@"columnNames"];
}

- (NSArray/*<NSString>*/ *)columnNames
{
    return toObjCStringArray([super JSONArrayForKey:@"columnNames"]);
}

- (void)setButtons:(NSArray/*<NSString>*/ *)buttons
{
    [super setJSONArray:toJSONStringArray(buttons) forKey:@"buttons"];
}

- (NSArray/*<NSString>*/ *)buttons
{
    return toObjCStringArray([super JSONArrayForKey:@"buttons"]);
}

- (void)setDirectionality:(TestProtocolDatabaseParameterBundleDirectionality)directionality
{
    [super setString:toProtocolString(directionality) forKey:@"directionality"];
}

- (TestProtocolDatabaseParameterBundleDirectionality)directionality
{
    return fromProtocolString<TestProtocolDatabaseParameterBundleDirectionality>([super stringForKey:@"directionality"]).value();
}

- (void)setNotes:(NSString *)notes
{
    [super setString:notes forKey:@"notes"];
}

- (NSString *)notes
{
    return [super stringForKey:@"notes"];
}

- (void)setTimestamp:(double)timestamp
{
    [super setDouble:timestamp forKey:@"timestamp"];
}

- (double)timestamp
{
    return [super doubleForKey:@"timestamp"];
}

- (void)setValues:(RWIProtocolJSONObject *)values
{
    [super setObject:values forKey:@"values"];
}

- (RWIProtocolJSONObject *)values
{
    RWIProtocolJSONObject *object = [super objectForKey:@"values"];
    if (!object)
        return nil;
    return [[RWIProtocolJSONObject alloc] initWithJSONObject:[[super objectForKey:@"values"] toJSONObject].get()];
}

- (void)setPayload:(RWIProtocolJSONObject *)payload
{
    [super setObject:payload forKey:@"payload"];
}

- (RWIProtocolJSONObject *)payload
{
    RWIProtocolJSONObject *object = [super objectForKey:@"payload"];
    if (!object)
        return nil;
    return [[RWIProtocolJSONObject alloc] initWithJSONObject:[[super objectForKey:@"payload"] toJSONObject].get()];
}

- (void)setError:(TestProtocolDatabaseError *)error
{
    [super setObject:error forKey:@"error"];
}

- (TestProtocolDatabaseError *)error
{
    RWIProtocolJSONObject *object = [super objectForKey:@"error"];
    if (!object)
        return nil;
    return [[TestProtocolDatabaseError alloc] initWithJSONObject:[[super objectForKey:@"error"] toJSONObject].get()];
}

- (void)setErrorList:(NSArray/*<TestProtocolDatabaseError>*/ *)errorList
{
    THROW_EXCEPTION_FOR_BAD_TYPE_IN_ARRAY(errorList, [TestProtocolDatabaseError class]);
    [super setJSONArray:toJSONObjectArray(errorList) forKey:@"errorList"];
}

- (NSArray/*<TestProtocolDatabaseError>*/ *)errorList
{
    return toObjCArray<TestProtocolDatabaseError>([super JSONArrayForKey:@"errorList"]);
}

@end

@implementation TestProtocolDatabaseObjectWithPropertyNameConflicts

- (instancetype)initWithPayload:(nonnull NSDictionary<NSString *, id> *)payload
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"integer"], @"integer");
    self.integer = payload[@"integer"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"array"], @"array");
    self.array = payload[@"array"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"string"], @"string");
    self.string = payload[@"string"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"value"], @"value");
    self.value = payload[@"value"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"object"], @"object");
    self.object = payload[@"object"];

    return self;
}
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)object
{
    if (!(self = [super initWithJSONObject:[object toJSONObject].get()]))
        return nil;

    return self;
}

- (instancetype)initWithInteger:(NSString *)integer array:(NSString *)array string:(NSString *)string value:(NSString *)value object:(NSString *)object
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(integer, @"integer");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(array, @"array");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(string, @"string");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(value, @"value");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(object, @"object");

    self.integer = integer;
    self.array = array;
    self.string = string;
    self.value = value;
    self.object = object;

    return self;
}

- (void)setInteger:(NSString *)integer
{
    [super setString:integer forKey:@"integer"];
}

- (NSString *)integer
{
    return [super stringForKey:@"integer"];
}

- (void)setArray:(NSString *)array
{
    [super setString:array forKey:@"array"];
}

- (NSString *)array
{
    return [super stringForKey:@"array"];
}

- (void)setString:(NSString *)string
{
    [super setString:string forKey:@"string"];
}

- (NSString *)string
{
    return [super stringForKey:@"string"];
}

- (void)setValue:(NSString *)value
{
    [super setString:value forKey:@"value"];
}

- (NSString *)value
{
    return [super stringForKey:@"value"];
}

- (void)setObject:(NSString *)object
{
    [super setString:object forKey:@"object"];
}

- (NSString *)object
{
    return [super stringForKey:@"object"];
}

@end

@implementation TestProtocolDatabaseDummyObject

- (instancetype)initWithPayload:(nonnull NSDictionary<NSString *, id> *)payload
{
    if (!(self = [super init]))
        return nil;

    return self;
}
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)object
{
    if (!(self = [super initWithJSONObject:[object toJSONObject].get()]))
        return nil;

    return self;
}

@end


@implementation TestProtocolTestParameterBundle

- (instancetype)initWithPayload:(nonnull NSDictionary<NSString *, id> *)payload
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"directionality"], @"directionality");
    Optional<TestProtocolTestParameterBundleDirectionality> directionality = fromProtocolString<TestProtocolTestParameterBundleDirectionality>(payload[@"directionality"]);
    THROW_EXCEPTION_FOR_BAD_ENUM_VALUE(directionality, @"directionality");
    self.directionality = directionality.value();

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"buttons"], @"buttons");
    self.buttons = payload[@"buttons"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"columnNames"], @"columnNames");
    self.columnNames = payload[@"columnNames"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"notes"], @"notes");
    self.notes = payload[@"notes"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"timestamp"], @"timestamp");
    self.timestamp = [payload[@"timestamp"] doubleValue];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"values"], @"values");
    self.values = payload[@"values"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"payload"], @"payload");
    self.payload = payload[@"payload"];

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload[@"error"], @"error");
    self.error = [[TestProtocolDatabaseError alloc] initWithPayload:payload[@"error"]];

    return self;
}
- (instancetype)initWithProtocolObject:(RWIProtocolJSONObject *)object
{
    if (!(self = [super initWithJSONObject:[object toJSONObject].get()]))
        return nil;

    return self;
}

- (instancetype)initWithDirectionality:(TestProtocolTestParameterBundleDirectionality)directionality buttons:(NSArray/*<NSString>*/ *)buttons columnNames:(NSArray/*<NSString>*/ *)columnNames notes:(NSString *)notes timestamp:(double)timestamp values:(RWIProtocolJSONObject *)values payload:(RWIProtocolJSONObject *)payload error:(TestProtocolDatabaseError *)error
{
    if (!(self = [super init]))
        return nil;

    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(buttons, @"buttons");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(columnNames, @"columnNames");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(notes, @"notes");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(values, @"values");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(payload, @"payload");
    THROW_EXCEPTION_FOR_REQUIRED_PROPERTY(error, @"error");

    self.directionality = directionality;
    self.buttons = buttons;
    self.columnNames = columnNames;
    self.notes = notes;
    self.timestamp = timestamp;
    self.values = values;
    self.payload = payload;
    self.error = error;

    return self;
}

- (void)setDirectionality:(TestProtocolTestParameterBundleDirectionality)directionality
{
    [super setString:toProtocolString(directionality) forKey:@"directionality"];
}

- (TestProtocolTestParameterBundleDirectionality)directionality
{
    return fromProtocolString<TestProtocolTestParameterBundleDirectionality>([super stringForKey:@"directionality"]).value();
}

- (void)setButtons:(NSArray/*<NSString>*/ *)buttons
{
    [super setJSONArray:toJSONStringArray(buttons) forKey:@"buttons"];
}

- (NSArray/*<NSString>*/ *)buttons
{
    return toObjCStringArray([super JSONArrayForKey:@"buttons"]);
}

- (void)setColumnNames:(NSArray/*<NSString>*/ *)columnNames
{
    [super setJSONArray:toJSONStringArray(columnNames) forKey:@"columnNames"];
}

- (NSArray/*<NSString>*/ *)columnNames
{
    return toObjCStringArray([super JSONArrayForKey:@"columnNames"]);
}

- (void)setNotes:(NSString *)notes
{
    [super setString:notes forKey:@"notes"];
}

- (NSString *)notes
{
    return [super stringForKey:@"notes"];
}

- (void)setTimestamp:(double)timestamp
{
    [super setDouble:timestamp forKey:@"timestamp"];
}

- (double)timestamp
{
    return [super doubleForKey:@"timestamp"];
}

- (void)setValues:(RWIProtocolJSONObject *)values
{
    [super setObject:values forKey:@"values"];
}

- (RWIProtocolJSONObject *)values
{
    RWIProtocolJSONObject *object = [super objectForKey:@"values"];
    if (!object)
        return nil;
    return [[RWIProtocolJSONObject alloc] initWithJSONObject:[[super objectForKey:@"values"] toJSONObject].get()];
}

- (void)setPayload:(RWIProtocolJSONObject *)payload
{
    [super setObject:payload forKey:@"payload"];
}

- (RWIProtocolJSONObject *)payload
{
    RWIProtocolJSONObject *object = [super objectForKey:@"payload"];
    if (!object)
        return nil;
    return [[RWIProtocolJSONObject alloc] initWithJSONObject:[[super objectForKey:@"payload"] toJSONObject].get()];
}

- (void)setError:(TestProtocolDatabaseError *)error
{
    [super setObject:error forKey:@"error"];
}

- (TestProtocolDatabaseError *)error
{
    RWIProtocolJSONObject *object = [super objectForKey:@"error"];
    if (!object)
        return nil;
    return [[TestProtocolDatabaseError alloc] initWithJSONObject:[[super objectForKey:@"error"] toJSONObject].get()];
}

@end


### End File: TestProtocolTypes.mm
