def _generate_dispatcher_implementation_for_command(self, command, domain):
        in_parameter_declarations = []
        out_parameter_declarations = []
        out_parameter_assignments = []
        alternate_dispatcher_method_parameters = ['requestId']
        method_parameters = ['error']

        for parameter in command.call_parameters:
            parameter_name = 'in_' + parameter.parameter_name
            if parameter.is_optional:
                parameter_name = 'opt_' + parameter_name

            out_success_argument = 'nullptr'
            if parameter.is_optional:
                out_success_argument = '&%s_valueFound' % parameter_name
                in_parameter_declarations.append(
                    '    bool %s_valueFound = false;' % parameter_name)

            # Now add appropriate operators.
            parameter_expression = parameter_name

            if CppGenerator.should_use_references_for_type(parameter.type):
                if parameter.is_optional:
                    parameter_expression = '%s.get()' % parameter_expression
                else:
                    # This assumes that we have already proved the object is non-null.
                    # If a required property is missing, InspectorBackend::getObject will
                    # append a protocol error, and the method dispatcher will return without
                    # invoking the backend method (and dereferencing the object).
                    parameter_expression = '*%s' % parameter_expression
            elif parameter.is_optional:
                parameter_expression = '&%s' % parameter_expression

            param_args = {
                'parameterType':
                CppGenerator.cpp_type_for_stack_in_parameter(parameter),
                'parameterKey':
                parameter.parameter_name,
                'parameterName':
                parameter_name,
                'parameterExpression':
                parameter_expression,
                'keyedGetMethod':
                CppGenerator.cpp_getter_method_for_type(parameter.type),
                'successOutParam':
                out_success_argument
            }

            in_parameter_declarations.append(
                '    %(parameterType)s %(parameterName)s = m_backendDispatcher->%(keyedGetMethod)s(parameters.get(), ASCIILiteral("%(parameterKey)s"), %(successOutParam)s);'
                % param_args)

            if parameter.is_optional:
                optional_in_parameter_string = '%(parameterName)s_valueFound ? %(parameterExpression)s : nullptr' % param_args
                alternate_dispatcher_method_parameters.append(
                    optional_in_parameter_string)
                method_parameters.append(optional_in_parameter_string)
            else:
                alternate_dispatcher_method_parameters.append(
                    parameter_expression)
                method_parameters.append(parameter_expression)

        if command.is_async:
            async_args = {
                'domainName': domain.domain_name,
                'callbackName': ucfirst(command.command_name) + 'Callback'
            }

            out_parameter_assignments.append('        callback->disable();')
            out_parameter_assignments.append(
                '        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);'
            )
            out_parameter_assignments.append('        return;')
            method_parameters.append('callback.copyRef()')

        else:
            for parameter in command.return_parameters:
                param_args = {
                    'parameterType':
                    CppGenerator.cpp_type_for_stack_out_parameter(parameter),
                    'parameterKey':
                    parameter.parameter_name,
                    'parameterName':
                    parameter.parameter_name,
                    'keyedSetMethod':
                    CppGenerator.cpp_setter_method_for_type(parameter.type),
                    'helpersNamespace':
                    self.helpers_namespace(),
                }

                out_parameter_declarations.append(
                    '    %(parameterType)s out_%(parameterName)s;' %
                    param_args)
                if parameter.is_optional:
                    if CppGenerator.should_use_wrapper_for_return_type(
                            parameter.type):
                        out_parameter_assignments.append(
                            '        if (out_%(parameterName)s.isAssigned())' %
                            param_args)
                        out_parameter_assignments.append(
                            '            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s.getValue());'
                            % param_args)
                    else:
                        out_parameter_assignments.append(
                            '        if (out_%(parameterName)s)' % param_args)
                        out_parameter_assignments.append(
                            '            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);'
                            % param_args)
                elif parameter.type.is_enum():
                    out_parameter_assignments.append(
                        '        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), Inspector::Protocol::%(helpersNamespace)s::getEnumConstantValue(out_%(parameterName)s));'
                        % param_args)
                else:
                    out_parameter_assignments.append(
                        '        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);'
                        % param_args)

                if CppGenerator.should_pass_by_copy_for_return_type(
                        parameter.type):
                    method_parameters.append('out_' + parameter.parameter_name)
                else:
                    method_parameters.append('&out_' +
                                             parameter.parameter_name)

        command_args = {
            'domainName':
            domain.domain_name,
            'callbackName':
            '%sCallback' % ucfirst(command.command_name),
            'commandName':
            command.command_name,
            'inParameterDeclarations':
            '\n'.join(in_parameter_declarations),
            'invocationParameters':
            ', '.join(method_parameters),
            'alternateInvocationParameters':
            ', '.join(alternate_dispatcher_method_parameters),
        }

        lines = []
        if len(command.call_parameters) == 0:
            lines.append(
                'void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&&)'
                % command_args)
        else:
            lines.append(
                'void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&& parameters)'
                % command_args)
        lines.append('{')

        if len(command.call_parameters) > 0:
            lines.append(
                Template(CppTemplates.
                         BackendDispatcherImplementationPrepareCommandArguments
                         ).substitute(None, **command_args))

        if self.model().framework.setting('alternate_dispatchers', False):
            lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
            lines.append('    if (m_alternateDispatcher) {')
            lines.append(
                '        m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);'
                % command_args)
            lines.append('        return;')
            lines.append('    }')
            lines.append('#endif')
            lines.append('')

        lines.append('    ErrorString error;')
        lines.append(
            '    Ref<InspectorObject> result = InspectorObject::create();')
        if command.is_async:
            lines.append(
                '    Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), requestId));'
                % command_args)
        if len(command.return_parameters) > 0:
            lines.extend(out_parameter_declarations)
        lines.append(
            '    m_agent->%(commandName)s(%(invocationParameters)s);' %
            command_args)
        lines.append('')
        if command.is_async:
            lines.append('    if (error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) > 1:
            lines.append('    if (!error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) == 1:
            lines.append('    if (!error.length())')
            lines.extend(out_parameter_assignments)
            lines.append('')

        if not command.is_async:
            lines.append('    if (!error.length())')
            lines.append(
                '        m_backendDispatcher->sendResponse(requestId, WTFMove(result));'
            )
            lines.append('    else')
            lines.append(
                '        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTFMove(error));'
            )
        lines.append('}')
        return "\n".join(lines)
    def _generate_dispatcher_implementation_for_command(self, command, domain):
        in_parameter_declarations = []
        out_parameter_declarations = []
        out_parameter_assignments = []
        alternate_dispatcher_method_parameters = ['requestId']
        method_parameters = ['error']

        for parameter in command.call_parameters:
            parameter_name = 'in_' + parameter.parameter_name
            if parameter.is_optional:
                parameter_name = 'opt_' + parameter_name

            out_success_argument = 'nullptr'
            if parameter.is_optional:
                out_success_argument = '&%s_valueFound' % parameter_name
                in_parameter_declarations.append('    bool %s_valueFound = false;' % parameter_name)

            # Now add appropriate operators.
            parameter_expression = parameter_name

            if CppGenerator.should_use_references_for_type(parameter.type):
                if parameter.is_optional:
                    parameter_expression = '%s.get()' % parameter_expression
                else:
                    # This assumes that we have already proved the object is non-null.
                    # If a required property is missing, InspectorBackend::getObject will
                    # append a protocol error, and the method dispatcher will return without
                    # invoking the backend method (and dereferencing the object).
                    parameter_expression = '*%s' % parameter_expression
            elif parameter.is_optional:
                parameter_expression = '&%s' % parameter_expression

            param_args = {
                'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter),
                'parameterKey': parameter.parameter_name,
                'parameterName': parameter_name,
                'parameterExpression': parameter_expression,
                'keyedGetMethod': CppGenerator.cpp_getter_method_for_type(parameter.type),
                'successOutParam': out_success_argument
            }

            in_parameter_declarations.append('    %(parameterType)s %(parameterName)s = m_backendDispatcher->%(keyedGetMethod)s(parameters.get(), ASCIILiteral("%(parameterKey)s"), %(successOutParam)s);' % param_args)

            if parameter.is_optional:
                optional_in_parameter_string = '%(parameterName)s_valueFound ? %(parameterExpression)s : nullptr' % param_args
                alternate_dispatcher_method_parameters.append(optional_in_parameter_string)
                method_parameters.append(optional_in_parameter_string)
            else:
                alternate_dispatcher_method_parameters.append(parameter_expression)
                method_parameters.append(parameter_expression)

        if command.is_async:
            async_args = {
                'domainName': domain.domain_name,
                'callbackName': ucfirst(command.command_name) + 'Callback'
            }

            out_parameter_assignments.append('        callback->disable();')
            out_parameter_assignments.append('        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, error);')
            out_parameter_assignments.append('        return;')
            method_parameters.append('callback.copyRef()')

        else:
            for parameter in command.return_parameters:
                param_args = {
                    'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter),
                    'parameterKey': parameter.parameter_name,
                    'parameterName': parameter.parameter_name,
                    'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type),

                }

                out_parameter_declarations.append('    %(parameterType)s out_%(parameterName)s;' % param_args)
                if parameter.is_optional:
                    if CppGenerator.should_use_wrapper_for_return_type(parameter.type):
                        out_parameter_assignments.append('        if (out_%(parameterName)s.isAssigned())' % param_args)
                        out_parameter_assignments.append('            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s.getValue());' % param_args)
                    else:
                        out_parameter_assignments.append('        if (out_%(parameterName)s)' % param_args)
                        out_parameter_assignments.append('            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);' % param_args)
                elif parameter.type.is_enum():
                    out_parameter_assignments.append('        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), Inspector::Protocol::getEnumConstantValue(out_%(parameterName)s));' % param_args)
                else:
                    out_parameter_assignments.append('        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterKey)s"), out_%(parameterName)s);' % param_args)

                if CppGenerator.should_pass_by_copy_for_return_type(parameter.type):
                    method_parameters.append('out_' + parameter.parameter_name)
                else:
                    method_parameters.append('&out_' + parameter.parameter_name)

        command_args = {
            'domainName': domain.domain_name,
            'callbackName': '%sCallback' % ucfirst(command.command_name),
            'commandName': command.command_name,
            'inParameterDeclarations': '\n'.join(in_parameter_declarations),
            'invocationParameters': ', '.join(method_parameters),
            'alternateInvocationParameters': ', '.join(alternate_dispatcher_method_parameters),
        }

        lines = []
        if len(command.call_parameters) == 0:
            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&&)' % command_args)
        else:
            lines.append('void %(domainName)sBackendDispatcher::%(commandName)s(long requestId, RefPtr<InspectorObject>&& parameters)' % command_args)
        lines.append('{')

        if len(command.call_parameters) > 0:
            lines.append(Template(CppTemplates.BackendDispatcherImplementationPrepareCommandArguments).substitute(None, **command_args))

        lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
        lines.append('    if (m_alternateDispatcher) {')
        lines.append('        m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);' % command_args)
        lines.append('        return;')
        lines.append('    }')
        lines.append('#endif')
        lines.append('')

        lines.append('    ErrorString error;')
        lines.append('    Ref<InspectorObject> result = InspectorObject::create();')
        if command.is_async:
            lines.append('    Ref<%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new %(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), requestId));' % command_args)
        if len(command.return_parameters) > 0:
            lines.extend(out_parameter_declarations)
        lines.append('    m_agent->%(commandName)s(%(invocationParameters)s);' % command_args)
        lines.append('')
        if command.is_async:
            lines.append('    if (error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) > 1:
            lines.append('    if (!error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) == 1:
            lines.append('    if (!error.length())')
            lines.extend(out_parameter_assignments)
            lines.append('')

        if not command.is_async:
            lines.append('    if (!error.length())')
            lines.append('        m_backendDispatcher->sendResponse(requestId, WTF::move(result));')
            lines.append('    else')
            lines.append('        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, WTF::move(error));')
        lines.append('}')
        return "\n".join(lines)
Esempio n. 3
0
    def _generate_dispatcher_implementation_for_command(self, command, domain):
        in_parameter_declarations = []
        out_parameter_declarations = []
        out_parameter_assignments = []
        alternate_dispatcher_method_parameters = ['callId']
        method_parameters = ['error']

        for parameter in command.call_parameters:
            out_success_argument = 'nullptr'
            if parameter.is_optional:
                out_success_argument = '&%s_valueFound' % parameter.parameter_name
                in_parameter_declarations.append(
                    '    bool %s_valueFound = false;' %
                    parameter.parameter_name)

            parameter_expression = 'in_' + parameter.parameter_name
            if CppGenerator.should_use_references_for_type(parameter.type):
                parameter_expression = '%s.copyRef()' % parameter_expression
            elif parameter.is_optional:
                parameter_expression = '&%s' % parameter_expression

            param_args = {
                'parameterType':
                CppGenerator.cpp_type_for_stack_in_parameter(parameter),
                'parameterName':
                parameter.parameter_name,
                'parameterExpression':
                parameter_expression,
                'keyedGetMethod':
                CppGenerator.cpp_getter_method_for_type(parameter.type),
                'successOutParam':
                out_success_argument
            }

            in_parameter_declarations.append(
                '    %(parameterType)s in_%(parameterName)s = InspectorBackendDispatcher::%(keyedGetMethod)s(paramsContainer.get(), ASCIILiteral("%(parameterName)s"), %(successOutParam)s, protocolErrors.get());'
                % param_args)

            if parameter.is_optional:
                optional_in_parameter_string = '%(parameterName)s_valueFound ? %(parameterExpression)s : nullptr' % param_args
                alternate_dispatcher_method_parameters.append(
                    optional_in_parameter_string)
                method_parameters.append(optional_in_parameter_string)
            else:
                alternate_dispatcher_method_parameters.append(
                    parameter_expression)
                method_parameters.append(parameter_expression)

        if command.is_async:
            async_args = {
                'domainName': domain.domain_name,
                'callbackName': ucfirst(command.command_name) + 'Callback'
            }

            out_parameter_assignments.append('        callback->disable();')
            out_parameter_assignments.append(
                '        m_backendDispatcher->reportProtocolError(&callId, Inspector::InspectorBackendDispatcher::ServerError, error);'
            )
            out_parameter_assignments.append('        return;')
            method_parameters.append('callback.copyRef()')

        else:
            for parameter in command.return_parameters:
                param_args = {
                    'parameterType':
                    CppGenerator.cpp_type_for_stack_out_parameter(parameter),
                    'parameterName':
                    parameter.parameter_name,
                    'keyedSetMethod':
                    CppGenerator.cpp_setter_method_for_type(parameter.type),
                }

                out_parameter_declarations.append(
                    '    %(parameterType)s out_%(parameterName)s;' %
                    param_args)
                if parameter.is_optional:
                    if CppGenerator.should_use_wrapper_for_return_type(
                            parameter.type):
                        out_parameter_assignments.append(
                            '        if (out_%(parameterName)s.isAssigned())' %
                            param_args)
                        out_parameter_assignments.append(
                            '            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s.getValue());'
                            % param_args)
                    else:
                        out_parameter_assignments.append(
                            '        if (out_%(parameterName)s)' % param_args)
                        out_parameter_assignments.append(
                            '            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);'
                            % param_args)
                elif parameter.type.is_enum():
                    out_parameter_assignments.append(
                        '        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), Inspector::Protocol::getEnumConstantValue(out_%(parameterName)s));'
                        % param_args)
                else:
                    out_parameter_assignments.append(
                        '        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);'
                        % param_args)

                if CppGenerator.should_pass_by_copy_for_return_type(
                        parameter.type):
                    method_parameters.append('out_' + parameter.parameter_name)
                else:
                    method_parameters.append('&out_' +
                                             parameter.parameter_name)

        command_args = {
            'domainName':
            domain.domain_name,
            'callbackName':
            '%sCallback' % ucfirst(command.command_name),
            'commandName':
            command.command_name,
            'inParameterDeclarations':
            '\n'.join(in_parameter_declarations),
            'invocationParameters':
            ', '.join(method_parameters),
            'alternateInvocationParameters':
            ', '.join(alternate_dispatcher_method_parameters),
        }

        lines = []
        if len(command.call_parameters) == 0:
            lines.append(
                'void Inspector%(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject&)'
                % command_args)
        else:
            lines.append(
                'void Inspector%(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject& message)'
                % command_args)
        lines.append('{')

        if len(command.call_parameters) > 0:
            lines.append(
                Template(CppTemplates.
                         BackendDispatcherImplementationPrepareCommandArguments
                         ).substitute(None, **command_args))

        lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
        lines.append('    if (m_alternateDispatcher) {')
        lines.append(
            '        m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);'
            % command_args)
        lines.append('        return;')
        lines.append('    }')
        lines.append('#endif')
        lines.append('')

        lines.append('    ErrorString error;')
        lines.append(
            '    Ref<InspectorObject> result = InspectorObject::create();')
        if command.is_async:
            lines.append(
                '    Ref<Inspector%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(*new Inspector%(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher.copyRef(), callId));'
                % command_args)
        if len(command.return_parameters) > 0:
            lines.extend(out_parameter_declarations)
        lines.append(
            '    m_agent->%(commandName)s(%(invocationParameters)s);' %
            command_args)
        lines.append('')
        if command.is_async:
            lines.append('    if (error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) > 1:
            lines.append('    if (!error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) == 1:
            lines.append('    if (!error.length())')
            lines.extend(out_parameter_assignments)
            lines.append('')

        if not command.is_async:
            lines.append(
                '    m_backendDispatcher->sendResponse(callId, WTF::move(result), error);'
            )
        lines.append('}')
        return "\n".join(lines)
Esempio n. 4
0
    def _generate_dispatcher_implementation_for_command(self, command, domain):
        parameter_declarations = []
        parameter_enum_resolutions = []
        alternate_dispatcher_method_parameters = ['protocol_requestId']
        method_parameters = []

        for parameter in command.call_parameters:
            parameter_name = parameter.parameter_name
            if parameter.is_optional:
                parameter_name = 'opt_' + parameter_name
            parameter_name = 'in_' + parameter_name

            variable_name = parameter_name

            _type = parameter.type
            if isinstance(_type, AliasedType):
                _type = _type.aliased_type
            if isinstance(_type, EnumType) and _type.is_anonymous:
                _type = _type.primitive_type

            if _type.is_enum():
                parameter_name = parameter_name + '_json'

                alternate_dispatcher_method_parameters.append(parameter_name)

                enum_args = {
                    'helpersNamespace': self.helpers_namespace(),
                    'parameterKey': parameter.parameter_name,
                    'enumType': CppGenerator.cpp_protocol_type_for_type(_type),
                    'enumVariableName': variable_name,
                    'stringVariableName': parameter_name,
                }

                if len(parameter_enum_resolutions):
                    parameter_enum_resolutions.append('')
                parameter_enum_resolutions.append(
                    '    auto %(enumVariableName)s = Protocol::%(helpersNamespace)s::parseEnumValueFromString<%(enumType)s>(%(stringVariableName)s);'
                    % enum_args)
                if parameter.is_optional:
                    parameter_expression = 'WTFMove(%s)' % variable_name
                else:
                    parameter_enum_resolutions.append(
                        '    if (!%(enumVariableName)s) {' % enum_args)
                    parameter_enum_resolutions.append(
                        '        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, makeString("Unknown %(parameterKey)s: "_s, %(stringVariableName)s));'
                        % enum_args)
                    parameter_enum_resolutions.append('        return;')
                    parameter_enum_resolutions.append('    }')
                    parameter_expression = '*' + variable_name
            else:
                if _type.raw_name() == 'string':
                    parameter_expression = variable_name
                elif parameter.is_optional:
                    parameter_expression = 'WTFMove(%s)' % variable_name
                elif _type.raw_name() in ['boolean', 'integer', 'number']:
                    parameter_expression = '*' + variable_name
                else:
                    parameter_expression = variable_name + '.releaseNonNull()'
                alternate_dispatcher_method_parameters.append(
                    parameter_expression)
            method_parameters.append(parameter_expression)

            param_args = {
                'parameterKey': parameter.parameter_name,
                'parameterName': parameter_name,
                'keyedGetMethod':
                CppGenerator.cpp_getter_method_for_type(_type),
                'required': 'false' if parameter.is_optional else 'true',
            }
            parameter_declarations.append(
                '    auto %(parameterName)s = m_backendDispatcher->%(keyedGetMethod)s(protocol_parameters.get(), "%(parameterKey)s"_s, %(required)s);'
                % param_args)

        if command.is_async:
            method_parameters.append(
                'adoptRef(*new %sBackendDispatcherHandler::%s(m_backendDispatcher.copyRef(), protocol_requestId))'
                % (domain.domain_name,
                   '%sCallback' % ucfirst(command.command_name)))

        command_args = {
            'domainName':
            domain.domain_name,
            'commandName':
            command.command_name,
            'parameterDeclarations':
            '\n'.join(parameter_declarations),
            'invocationParameters':
            ', '.join(method_parameters),
            'alternateInvocationParameters':
            ', '.join(alternate_dispatcher_method_parameters),
        }

        lines = []
        if len(command.call_parameters) == 0:
            lines.append(
                'void %(domainName)sBackendDispatcher::%(commandName)s(long protocol_requestId, RefPtr<JSON::Object>&&)'
                % command_args)
        else:
            lines.append(
                'void %(domainName)sBackendDispatcher::%(commandName)s(long protocol_requestId, RefPtr<JSON::Object>&& protocol_parameters)'
                % command_args)
        lines.append('{')

        if len(command.call_parameters) > 0:
            lines.append(
                Template(CppTemplates.
                         BackendDispatcherImplementationPrepareCommandArguments
                         ).substitute(None, **command_args))

        if self.model().framework.setting('alternate_dispatchers', False):
            lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
            lines.append('    if (m_alternateDispatcher) {')
            lines.append(
                '        m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);'
                % command_args)
            lines.append('        return;')
            lines.append('    }')
            lines.append('#endif // ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
            lines.append('')

        if len(parameter_enum_resolutions):
            lines.extend(parameter_enum_resolutions)
            lines.append('')

        if command.is_async:
            lines.append(
                '    m_agent->%(commandName)s(%(invocationParameters)s);' %
                command_args)
        else:
            result_destructured_names = []
            result_conversion_lines = []
            for parameter in command.return_parameters:
                parameter_name = parameter.parameter_name
                if parameter.is_optional:
                    parameter_name = 'opt_' + parameter_name
                parameter_name = 'out_' + parameter_name

                result_destructured_names.append(parameter_name)

                parameter_value = parameter_name

                _type = parameter.type
                if isinstance(_type, AliasedType):
                    _type = _type.aliased_type
                if isinstance(_type, EnumType) and _type.is_anonymous:
                    _type = _type.primitive_type

                if _type.is_enum():
                    if parameter.is_optional:
                        parameter_value = '*' + parameter_value
                    parameter_value = 'Protocol::%s::getEnumConstantValue(%s)' % (
                        self.helpers_namespace(), parameter_value)
                elif CppGenerator.should_release_argument(
                        _type, parameter.is_optional):
                    parameter_value = parameter_value + '.releaseNonNull()'
                elif CppGenerator.should_dereference_argument(
                        _type, parameter.is_optional):
                    parameter_value = '*' + parameter_value
                elif CppGenerator.should_move_argument(_type,
                                                       parameter.is_optional):
                    parameter_value = 'WTFMove(%s)' % parameter_value

                param_args = {
                    'keyedSetMethod':
                    CppGenerator.cpp_setter_method_for_type(_type),
                    'parameterKey':
                    parameter.parameter_name,
                    'parameterName':
                    parameter_name,
                    'parameterValue':
                    parameter_value,
                }

                if parameter.is_optional:
                    result_conversion_lines.append(
                        '    if (!!%(parameterName)s)' % param_args)
                    result_conversion_lines.append(
                        '        protocol_jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, %(parameterValue)s);'
                        % param_args)
                else:
                    result_conversion_lines.append(
                        '    protocol_jsonMessage->%(keyedSetMethod)s("%(parameterKey)s"_s, %(parameterValue)s);'
                        % param_args)

            lines.append(
                '    auto result = m_agent->%(commandName)s(%(invocationParameters)s);'
                % command_args)
            lines.append('    if (!result) {')
            lines.append('        ASSERT(!result.error().isEmpty());')
            lines.append(
                '        m_backendDispatcher->reportProtocolError(BackendDispatcher::ServerError, result.error());'
            )
            lines.append('        return;')
            lines.append('    }')
            lines.append('')
            if len(result_destructured_names) == 1:
                lines.append('    auto %s = WTFMove(result.value());' %
                             result_destructured_names[0])
                lines.append('')
            elif len(result_destructured_names) > 1:
                lines.append('    auto [%s] = WTFMove(result.value());' %
                             ", ".join(result_destructured_names))
                lines.append('')
            lines.append(
                '    auto protocol_jsonMessage = JSON::Object::create();')
            lines.extend(result_conversion_lines)
            lines.append(
                '    m_backendDispatcher->sendResponse(protocol_requestId, WTFMove(protocol_jsonMessage), false);'
            )

        lines.append('}')
        return self.wrap_with_guard_for_condition(command.condition,
                                                  "\n".join(lines))
    def _generate_dispatcher_implementation_for_command(self, command, domain):
        in_parameter_declarations = []
        out_parameter_declarations = []
        out_parameter_assignments = []
        alternate_dispatcher_method_parameters = ['callId']
        method_parameters = ['error']

        for parameter in command.call_parameters:
            out_success_argument = 'nullptr'
            if parameter.is_optional:
                out_success_argument = '&%s_valueFound' % parameter.parameter_name
                in_parameter_declarations.append('    bool %s_valueFound = false;' % parameter.parameter_name)

            param_args = {
                'parameterType': CppGenerator.cpp_type_for_stack_in_parameter(parameter),
                'parameterName': parameter.parameter_name,
                'keyedGetMethod': CppGenerator.cpp_getter_method_for_type(parameter.type),
                'successOutParam': out_success_argument
            }

            in_parameter_declarations.append('    %(parameterType)s in_%(parameterName)s = InspectorBackendDispatcher::%(keyedGetMethod)s(paramsContainerPtr, ASCIILiteral("%(parameterName)s"), %(successOutParam)s, protocolErrorsPtr);' % param_args)

            if parameter.is_optional:
                optional_in_parameter_string = '%(parameterName)s_valueFound ? &in_%(parameterName)s : nullptr' % param_args
                alternate_dispatcher_method_parameters.append(optional_in_parameter_string)
                method_parameters.append(optional_in_parameter_string)
            else:
                alternate_dispatcher_method_parameters.append('in_' + parameter.parameter_name)
                method_parameters.append('in_' + parameter.parameter_name)

        if command.is_async:
            async_args = {
                'domainName': domain.domain_name,
                'callbackName': ucfirst(command.command_name) + 'Callback'
            }

            out_parameter_assignments.append('        callback->disable();')
            out_parameter_assignments.append('        m_backendDispatcher->reportProtocolError(&callId, Inspector::InspectorBackendDispatcher::ServerError, error);')
            out_parameter_assignments.append('        return;')
            method_parameters.append('callback')

        else:
            for parameter in command.return_parameters:
                param_args = {
                    'parameterType': CppGenerator.cpp_type_for_stack_out_parameter(parameter),
                    'parameterName': parameter.parameter_name,
                    'keyedSetMethod': CppGenerator.cpp_setter_method_for_type(parameter.type),

                }

                out_parameter_declarations.append('    %(parameterType)s out_%(parameterName)s;' % param_args)
                if parameter.is_optional:
                    if CppGenerator.should_use_wrapper_for_return_type(parameter.type):
                        out_parameter_assignments.append('        if (out_%(parameterName)s.isAssigned())' % param_args)
                        out_parameter_assignments.append('            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s.getValue());' % param_args)
                    else:
                        out_parameter_assignments.append('        if (out_%(parameterName)s)' % param_args)
                        out_parameter_assignments.append('            result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);' % param_args)
                elif parameter.type.is_enum():
                    out_parameter_assignments.append('        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), Inspector::Protocol::getEnumConstantValue(out_%(parameterName)s));' % param_args)
                else:
                    out_parameter_assignments.append('        result->%(keyedSetMethod)s(ASCIILiteral("%(parameterName)s"), out_%(parameterName)s);' % param_args)

                if CppGenerator.should_pass_by_copy_for_return_type(parameter.type):
                    method_parameters.append('out_' + parameter.parameter_name)
                else:
                    method_parameters.append('&out_' + parameter.parameter_name)

        command_args = {
            'domainName': domain.domain_name,
            'callbackName': '%sCallback' % ucfirst(command.command_name),
            'commandName': command.command_name,
            'inParameterDeclarations': '\n'.join(in_parameter_declarations),
            'invocationParameters': ', '.join(method_parameters),
            'alternateInvocationParameters': ', '.join(alternate_dispatcher_method_parameters),
        }

        lines = []
        if len(command.call_parameters) == 0:
            lines.append('void Inspector%(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject&)' % command_args)
        else:
            lines.append('void Inspector%(domainName)sBackendDispatcher::%(commandName)s(long callId, const InspectorObject& message)' % command_args)
        lines.append('{')

        if len(command.call_parameters) > 0:
            lines.append(Template(CppTemplates.BackendDispatcherImplementationPrepareCommandArguments).substitute(None, **command_args))

        lines.append('#if ENABLE(INSPECTOR_ALTERNATE_DISPATCHERS)')
        lines.append('    if (m_alternateDispatcher) {')
        lines.append('        m_alternateDispatcher->%(commandName)s(%(alternateInvocationParameters)s);' % command_args)
        lines.append('        return;')
        lines.append('    }')
        lines.append('#endif')
        lines.append('')

        lines.append('    ErrorString error;')
        lines.append('    RefPtr<InspectorObject> result = InspectorObject::create();')
        if command.is_async:
            lines.append('    RefPtr<Inspector%(domainName)sBackendDispatcherHandler::%(callbackName)s> callback = adoptRef(new Inspector%(domainName)sBackendDispatcherHandler::%(callbackName)s(m_backendDispatcher,callId));' % command_args)
        if len(command.return_parameters) > 0:
            lines.extend(out_parameter_declarations)
        lines.append('    m_agent->%(commandName)s(%(invocationParameters)s);' % command_args)
        lines.append('')
        if command.is_async:
            lines.append('    if (error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) > 1:
            lines.append('    if (!error.length()) {')
            lines.extend(out_parameter_assignments)
            lines.append('    }')
        elif len(command.return_parameters) == 1:
            lines.append('    if (!error.length())')
            lines.extend(out_parameter_assignments)
            lines.append('')

        if not command.is_async:
            lines.append('    m_backendDispatcher->sendResponse(callId, result.release(), error);')
        lines.append('}')
        return "\n".join(lines)