// File is generated by JavaScriptCore/inspector/scripts/CodeGeneratorInspector.py

// Copyright (c) 2013 Apple Inc. All Rights Reserved.
// 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.

#include "config.h"
#include "InspectorJSBackendDispatchers.h"

#if ENABLE(INSPECTOR)

#include <inspector/InspectorFrontendChannel.h>
#include <inspector/InspectorValues.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>

namespace Inspector {

InspectorDebuggerBackendDispatcherHandler::~InspectorDebuggerBackendDispatcherHandler() { }
InspectorInspectorBackendDispatcherHandler::~InspectorInspectorBackendDispatcherHandler() { }
InspectorRuntimeBackendDispatcherHandler::~InspectorRuntimeBackendDispatcherHandler() { }


PassRefPtr<InspectorDebuggerBackendDispatcher> InspectorDebuggerBackendDispatcher::create(InspectorBackendDispatcher* backendDispatcher, InspectorDebuggerBackendDispatcherHandler* agent)
{
    return adoptRef(new InspectorDebuggerBackendDispatcher(backendDispatcher, agent));
}

InspectorDebuggerBackendDispatcher::InspectorDebuggerBackendDispatcher(InspectorBackendDispatcher* backendDispatcher, InspectorDebuggerBackendDispatcherHandler* agent)
    : InspectorSupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Debugger"), this);
}

void InspectorDebuggerBackendDispatcher::dispatch(long callId, const String& method, PassRefPtr<InspectorObject> message)
{
    Ref<InspectorDebuggerBackendDispatcher> protect(*this);

    typedef void (InspectorDebuggerBackendDispatcher::*CallHandler)(long callId, const Inspector::InspectorObject& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
    if (dispatchMap.isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "enable", &InspectorDebuggerBackendDispatcher::enable },
            { "disable", &InspectorDebuggerBackendDispatcher::disable },
            { "setBreakpointsActive", &InspectorDebuggerBackendDispatcher::setBreakpointsActive },
            { "setBreakpointByUrl", &InspectorDebuggerBackendDispatcher::setBreakpointByUrl },
            { "setBreakpoint", &InspectorDebuggerBackendDispatcher::setBreakpoint },
            { "removeBreakpoint", &InspectorDebuggerBackendDispatcher::removeBreakpoint },
            { "continueToLocation", &InspectorDebuggerBackendDispatcher::continueToLocation },
            { "stepOver", &InspectorDebuggerBackendDispatcher::stepOver },
            { "stepInto", &InspectorDebuggerBackendDispatcher::stepInto },
            { "stepOut", &InspectorDebuggerBackendDispatcher::stepOut },
            { "pause", &InspectorDebuggerBackendDispatcher::pause },
            { "resume", &InspectorDebuggerBackendDispatcher::resume },
            { "searchInContent", &InspectorDebuggerBackendDispatcher::searchInContent },
            { "getScriptSource", &InspectorDebuggerBackendDispatcher::getScriptSource },
            { "getFunctionDetails", &InspectorDebuggerBackendDispatcher::getFunctionDetails },
            { "setPauseOnExceptions", &InspectorDebuggerBackendDispatcher::setPauseOnExceptions },
            { "evaluateOnCallFrame", &InspectorDebuggerBackendDispatcher::evaluateOnCallFrame },
            { "setOverlayMessage", &InspectorDebuggerBackendDispatcher::setOverlayMessage },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.add(commands[i].name, commands[i].handler);
    }

    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
    if (it == dispatchMap.end()) {
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::MethodNotFound, String("'") + "Debugger" + '.' + method + "' was not found");
        return;
    }

    ((*this).*it->value)(callId, *message.get());
}

void InspectorDebuggerBackendDispatcher::enable(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->enable(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::disable(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->disable(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::setBreakpointsActive(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    bool in_active = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("active"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.setBreakpointsActive");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->setBreakpointsActive(&error, in_active);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::setBreakpointByUrl(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    int in_lineNumber = InspectorBackendDispatcher::getInt(paramsContainerPtr, ASCIILiteral("lineNumber"), nullptr, protocolErrorsPtr);
    bool url_valueFound = false;
    String in_url = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("url"), &url_valueFound, protocolErrorsPtr);
    bool urlRegex_valueFound = false;
    String in_urlRegex = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("urlRegex"), &urlRegex_valueFound, protocolErrorsPtr);
    bool columnNumber_valueFound = false;
    int in_columnNumber = InspectorBackendDispatcher::getInt(paramsContainerPtr, ASCIILiteral("columnNumber"), &columnNumber_valueFound, protocolErrorsPtr);
    bool options_valueFound = false;
    RefPtr<Inspector::InspectorObject> in_options = InspectorBackendDispatcher::getObject(paramsContainerPtr, ASCIILiteral("options"), &options_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.setBreakpointByUrl");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    Inspector::TypeBuilder::Debugger::BreakpointId out_breakpointId;
    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::Location> > out_locations;
    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier> > out_breakpointActionIdentifiers;
    m_agent->setBreakpointByUrl(&error, in_lineNumber, url_valueFound ? &in_url : nullptr, urlRegex_valueFound ? &in_urlRegex : nullptr, columnNumber_valueFound ? &in_columnNumber : nullptr, options_valueFound ? &in_options : nullptr, &out_breakpointId, out_locations, out_breakpointActionIdentifiers);

    if (!error.length()) {
        result->setString(ASCIILiteral("breakpointId"), out_breakpointId);
        result->setValue(ASCIILiteral("locations"), out_locations);
        result->setValue(ASCIILiteral("breakpointActionIdentifiers"), out_breakpointActionIdentifiers);
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::setBreakpoint(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    RefPtr<Inspector::InspectorObject> in_location = InspectorBackendDispatcher::getObject(paramsContainerPtr, ASCIILiteral("location"), nullptr, protocolErrorsPtr);
    bool options_valueFound = false;
    RefPtr<Inspector::InspectorObject> in_options = InspectorBackendDispatcher::getObject(paramsContainerPtr, ASCIILiteral("options"), &options_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.setBreakpoint");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    Inspector::TypeBuilder::Debugger::BreakpointId out_breakpointId;
    RefPtr<Inspector::TypeBuilder::Debugger::Location> out_actualLocation;
    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Debugger::BreakpointActionIdentifier> > out_breakpointActionIdentifiers;
    m_agent->setBreakpoint(&error, in_location, options_valueFound ? &in_options : nullptr, &out_breakpointId, out_actualLocation, out_breakpointActionIdentifiers);

    if (!error.length()) {
        result->setString(ASCIILiteral("breakpointId"), out_breakpointId);
        result->setValue(ASCIILiteral("actualLocation"), out_actualLocation);
        result->setValue(ASCIILiteral("breakpointActionIdentifiers"), out_breakpointActionIdentifiers);
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::removeBreakpoint(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_breakpointId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("breakpointId"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.removeBreakpoint");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->removeBreakpoint(&error, in_breakpointId);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::continueToLocation(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    RefPtr<Inspector::InspectorObject> in_location = InspectorBackendDispatcher::getObject(paramsContainerPtr, ASCIILiteral("location"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.continueToLocation");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->continueToLocation(&error, in_location);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::stepOver(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->stepOver(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::stepInto(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->stepInto(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::stepOut(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->stepOut(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::pause(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->pause(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::resume(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->resume(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::searchInContent(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_scriptId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("scriptId"), nullptr, protocolErrorsPtr);
    String in_query = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("query"), nullptr, protocolErrorsPtr);
    bool caseSensitive_valueFound = false;
    bool in_caseSensitive = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("caseSensitive"), &caseSensitive_valueFound, protocolErrorsPtr);
    bool isRegex_valueFound = false;
    bool in_isRegex = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("isRegex"), &isRegex_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.searchInContent");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::GenericTypes::SearchMatch> > out_result;
    m_agent->searchInContent(&error, in_scriptId, in_query, caseSensitive_valueFound ? &in_caseSensitive : nullptr, isRegex_valueFound ? &in_isRegex : nullptr, out_result);

    if (!error.length())
        result->setValue(ASCIILiteral("result"), out_result);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::getScriptSource(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_scriptId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("scriptId"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.getScriptSource");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    String out_scriptSource;
    m_agent->getScriptSource(&error, in_scriptId, &out_scriptSource);

    if (!error.length())
        result->setString(ASCIILiteral("scriptSource"), out_scriptSource);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::getFunctionDetails(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_functionId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("functionId"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.getFunctionDetails");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::TypeBuilder::Debugger::FunctionDetails> out_details;
    m_agent->getFunctionDetails(&error, in_functionId, out_details);

    if (!error.length())
        result->setValue(ASCIILiteral("details"), out_details);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::setPauseOnExceptions(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_state = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("state"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.setPauseOnExceptions");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->setPauseOnExceptions(&error, in_state);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::evaluateOnCallFrame(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_callFrameId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("callFrameId"), nullptr, protocolErrorsPtr);
    String in_expression = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("expression"), nullptr, protocolErrorsPtr);
    bool objectGroup_valueFound = false;
    String in_objectGroup = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("objectGroup"), &objectGroup_valueFound, protocolErrorsPtr);
    bool includeCommandLineAPI_valueFound = false;
    bool in_includeCommandLineAPI = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("includeCommandLineAPI"), &includeCommandLineAPI_valueFound, protocolErrorsPtr);
    bool doNotPauseOnExceptionsAndMuteConsole_valueFound = false;
    bool in_doNotPauseOnExceptionsAndMuteConsole = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("doNotPauseOnExceptionsAndMuteConsole"), &doNotPauseOnExceptionsAndMuteConsole_valueFound, protocolErrorsPtr);
    bool returnByValue_valueFound = false;
    bool in_returnByValue = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("returnByValue"), &returnByValue_valueFound, protocolErrorsPtr);
    bool generatePreview_valueFound = false;
    bool in_generatePreview = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("generatePreview"), &generatePreview_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.evaluateOnCallFrame");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> out_result;
    Inspector::TypeBuilder::OptOutput<bool> out_wasThrown;
    m_agent->evaluateOnCallFrame(&error, in_callFrameId, in_expression, objectGroup_valueFound ? &in_objectGroup : nullptr, includeCommandLineAPI_valueFound ? &in_includeCommandLineAPI : nullptr, doNotPauseOnExceptionsAndMuteConsole_valueFound ? &in_doNotPauseOnExceptionsAndMuteConsole : nullptr, returnByValue_valueFound ? &in_returnByValue : nullptr, generatePreview_valueFound ? &in_generatePreview : nullptr, out_result, &out_wasThrown);

    if (!error.length()) {
        result->setValue(ASCIILiteral("result"), out_result);
        if (out_wasThrown.isAssigned())
            result->setBoolean(ASCIILiteral("wasThrown"), out_wasThrown.getValue());
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorDebuggerBackendDispatcher::setOverlayMessage(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    bool message_valueFound = false;
    String in_message = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("message"), &message_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Debugger.setOverlayMessage");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->setOverlayMessage(&error, message_valueFound ? &in_message : nullptr);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

PassRefPtr<InspectorInspectorBackendDispatcher> InspectorInspectorBackendDispatcher::create(InspectorBackendDispatcher* backendDispatcher, InspectorInspectorBackendDispatcherHandler* agent)
{
    return adoptRef(new InspectorInspectorBackendDispatcher(backendDispatcher, agent));
}

InspectorInspectorBackendDispatcher::InspectorInspectorBackendDispatcher(InspectorBackendDispatcher* backendDispatcher, InspectorInspectorBackendDispatcherHandler* agent)
    : InspectorSupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Inspector"), this);
}

void InspectorInspectorBackendDispatcher::dispatch(long callId, const String& method, PassRefPtr<InspectorObject> message)
{
    Ref<InspectorInspectorBackendDispatcher> protect(*this);

    if (method == "enable")
        enable(callId, *message.get());
    else if (method == "disable")
        disable(callId, *message.get());
    else
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::MethodNotFound, String("'") + "Inspector" + '.' + method + "' was not found");
}

void InspectorInspectorBackendDispatcher::enable(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->enable(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorInspectorBackendDispatcher::disable(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->disable(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

PassRefPtr<InspectorRuntimeBackendDispatcher> InspectorRuntimeBackendDispatcher::create(InspectorBackendDispatcher* backendDispatcher, InspectorRuntimeBackendDispatcherHandler* agent)
{
    return adoptRef(new InspectorRuntimeBackendDispatcher(backendDispatcher, agent));
}

InspectorRuntimeBackendDispatcher::InspectorRuntimeBackendDispatcher(InspectorBackendDispatcher* backendDispatcher, InspectorRuntimeBackendDispatcherHandler* agent)
    : InspectorSupplementalBackendDispatcher(backendDispatcher)
    , m_agent(agent)
{
    m_backendDispatcher->registerDispatcherForDomain(ASCIILiteral("Runtime"), this);
}

void InspectorRuntimeBackendDispatcher::dispatch(long callId, const String& method, PassRefPtr<InspectorObject> message)
{
    Ref<InspectorRuntimeBackendDispatcher> protect(*this);

    typedef void (InspectorRuntimeBackendDispatcher::*CallHandler)(long callId, const Inspector::InspectorObject& message);
    typedef HashMap<String, CallHandler> DispatchMap;
    DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, ());
    if (dispatchMap.isEmpty()) {
        static const struct MethodTable {
            const char* name;
            CallHandler handler;
        } commands[] = {
            { "parse", &InspectorRuntimeBackendDispatcher::parse },
            { "evaluate", &InspectorRuntimeBackendDispatcher::evaluate },
            { "callFunctionOn", &InspectorRuntimeBackendDispatcher::callFunctionOn },
            { "getProperties", &InspectorRuntimeBackendDispatcher::getProperties },
            { "releaseObject", &InspectorRuntimeBackendDispatcher::releaseObject },
            { "releaseObjectGroup", &InspectorRuntimeBackendDispatcher::releaseObjectGroup },
            { "run", &InspectorRuntimeBackendDispatcher::run },
            { "enable", &InspectorRuntimeBackendDispatcher::enable },
            { "disable", &InspectorRuntimeBackendDispatcher::disable },
        };
        size_t length = WTF_ARRAY_LENGTH(commands);
        for (size_t i = 0; i < length; ++i)
            dispatchMap.add(commands[i].name, commands[i].handler);
    }

    HashMap<String, CallHandler>::iterator it = dispatchMap.find(method);
    if (it == dispatchMap.end()) {
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::MethodNotFound, String("'") + "Runtime" + '.' + method + "' was not found");
        return;
    }

    ((*this).*it->value)(callId, *message.get());
}

void InspectorRuntimeBackendDispatcher::parse(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_source = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("source"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Runtime.parse");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    Inspector::TypeBuilder::Runtime::SyntaxErrorType::Enum out_result;
    Inspector::TypeBuilder::OptOutput<String> out_message;
    RefPtr<Inspector::TypeBuilder::Runtime::ErrorRange> out_range;
    m_agent->parse(&error, in_source, &out_result, &out_message, out_range);

    if (!error.length()) {
        result->setString(ASCIILiteral("result"), Inspector::TypeBuilder::getJSEnumConstantValue(out_result));
        if (out_message.isAssigned())
            result->setString(ASCIILiteral("message"), out_message.getValue());
        if (out_range)
            result->setValue(ASCIILiteral("range"), out_range);
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::evaluate(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_expression = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("expression"), nullptr, protocolErrorsPtr);
    bool objectGroup_valueFound = false;
    String in_objectGroup = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("objectGroup"), &objectGroup_valueFound, protocolErrorsPtr);
    bool includeCommandLineAPI_valueFound = false;
    bool in_includeCommandLineAPI = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("includeCommandLineAPI"), &includeCommandLineAPI_valueFound, protocolErrorsPtr);
    bool doNotPauseOnExceptionsAndMuteConsole_valueFound = false;
    bool in_doNotPauseOnExceptionsAndMuteConsole = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("doNotPauseOnExceptionsAndMuteConsole"), &doNotPauseOnExceptionsAndMuteConsole_valueFound, protocolErrorsPtr);
    bool contextId_valueFound = false;
    int in_contextId = InspectorBackendDispatcher::getInt(paramsContainerPtr, ASCIILiteral("contextId"), &contextId_valueFound, protocolErrorsPtr);
    bool returnByValue_valueFound = false;
    bool in_returnByValue = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("returnByValue"), &returnByValue_valueFound, protocolErrorsPtr);
    bool generatePreview_valueFound = false;
    bool in_generatePreview = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("generatePreview"), &generatePreview_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Runtime.evaluate");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> out_result;
    Inspector::TypeBuilder::OptOutput<bool> out_wasThrown;
    m_agent->evaluate(&error, in_expression, objectGroup_valueFound ? &in_objectGroup : nullptr, includeCommandLineAPI_valueFound ? &in_includeCommandLineAPI : nullptr, doNotPauseOnExceptionsAndMuteConsole_valueFound ? &in_doNotPauseOnExceptionsAndMuteConsole : nullptr, contextId_valueFound ? &in_contextId : nullptr, returnByValue_valueFound ? &in_returnByValue : nullptr, generatePreview_valueFound ? &in_generatePreview : nullptr, out_result, &out_wasThrown);

    if (!error.length()) {
        result->setValue(ASCIILiteral("result"), out_result);
        if (out_wasThrown.isAssigned())
            result->setBoolean(ASCIILiteral("wasThrown"), out_wasThrown.getValue());
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::callFunctionOn(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_objectId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("objectId"), nullptr, protocolErrorsPtr);
    String in_functionDeclaration = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("functionDeclaration"), nullptr, protocolErrorsPtr);
    bool arguments_valueFound = false;
    RefPtr<Inspector::InspectorArray> in_arguments = InspectorBackendDispatcher::getArray(paramsContainerPtr, ASCIILiteral("arguments"), &arguments_valueFound, protocolErrorsPtr);
    bool doNotPauseOnExceptionsAndMuteConsole_valueFound = false;
    bool in_doNotPauseOnExceptionsAndMuteConsole = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("doNotPauseOnExceptionsAndMuteConsole"), &doNotPauseOnExceptionsAndMuteConsole_valueFound, protocolErrorsPtr);
    bool returnByValue_valueFound = false;
    bool in_returnByValue = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("returnByValue"), &returnByValue_valueFound, protocolErrorsPtr);
    bool generatePreview_valueFound = false;
    bool in_generatePreview = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("generatePreview"), &generatePreview_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Runtime.callFunctionOn");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::TypeBuilder::Runtime::RemoteObject> out_result;
    Inspector::TypeBuilder::OptOutput<bool> out_wasThrown;
    m_agent->callFunctionOn(&error, in_objectId, in_functionDeclaration, arguments_valueFound ? &in_arguments : nullptr, doNotPauseOnExceptionsAndMuteConsole_valueFound ? &in_doNotPauseOnExceptionsAndMuteConsole : nullptr, returnByValue_valueFound ? &in_returnByValue : nullptr, generatePreview_valueFound ? &in_generatePreview : nullptr, out_result, &out_wasThrown);

    if (!error.length()) {
        result->setValue(ASCIILiteral("result"), out_result);
        if (out_wasThrown.isAssigned())
            result->setBoolean(ASCIILiteral("wasThrown"), out_wasThrown.getValue());
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::getProperties(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_objectId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("objectId"), nullptr, protocolErrorsPtr);
    bool ownProperties_valueFound = false;
    bool in_ownProperties = InspectorBackendDispatcher::getBoolean(paramsContainerPtr, ASCIILiteral("ownProperties"), &ownProperties_valueFound, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Runtime.getProperties");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::PropertyDescriptor> > out_result;
    RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::Runtime::InternalPropertyDescriptor> > out_internalProperties;
    m_agent->getProperties(&error, in_objectId, ownProperties_valueFound ? &in_ownProperties : nullptr, out_result, out_internalProperties);

    if (!error.length()) {
        result->setValue(ASCIILiteral("result"), out_result);
        if (out_internalProperties)
            result->setValue(ASCIILiteral("internalProperties"), out_internalProperties);
    }

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::releaseObject(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_objectId = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("objectId"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Runtime.releaseObject");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->releaseObject(&error, in_objectId);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::releaseObjectGroup(long callId, const InspectorObject& message)
{
    RefPtr<InspectorArray> protocolErrors = InspectorArray::create();
    RefPtr<InspectorObject> paramsContainer = message.getObject(ASCIILiteral("params"));
    InspectorObject* paramsContainerPtr = paramsContainer.get();
    InspectorArray* protocolErrorsPtr = protocolErrors.get();
    String in_objectGroup = InspectorBackendDispatcher::getString(paramsContainerPtr, ASCIILiteral("objectGroup"), nullptr, protocolErrorsPtr);
    if (protocolErrors->length()) {
        String errorMessage = String::format("Some arguments of method '%s' can't be processed", "Runtime.releaseObjectGroup");
        m_backendDispatcher->reportProtocolError(&callId, InspectorBackendDispatcher::InvalidParams, errorMessage, protocolErrors.release());
        return;
    }

    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->releaseObjectGroup(&error, in_objectGroup);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::run(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->run(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::enable(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->enable(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

void InspectorRuntimeBackendDispatcher::disable(long callId, const InspectorObject&)
{
    ErrorString error;
    RefPtr<InspectorObject> result = InspectorObject::create();
    m_agent->disable(&error);

    m_backendDispatcher->sendResponse(callId, result.release(), error);
}

} // namespace Inspector

#endif // ENABLE(INSPECTOR)
