// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant

// this file was generated by the generate.ts script

#include <QtLanguageServer/private/qlanguageservergen_p_p.h>

#include <QtCore/QScopeGuard>

QT_BEGIN_NAMESPACE

namespace QLspSpecification {

QByteArray ProtocolBase::requestMethodToBaseCppName(const QByteArray &method)
{
    static QHash<QByteArray, QByteArray> map(
            { { QByteArray("initialize"), QByteArray("Initialize") },
              { QByteArray("shutdown"), QByteArray("Shutdown") },
              { QByteArray("window/showMessageRequest"), QByteArray("ShowMessageRequest") },
              { QByteArray("window/showDocument"), QByteArray("ShowDocument") },
              { QByteArray("window/workDoneProgress/create"),
                QByteArray("WorkDoneProgressCreate") },
              { QByteArray("client/registerCapability"), QByteArray("Registration") },
              { QByteArray("client/unregisterCapability"), QByteArray("Unregistration") },
              { QByteArray("workspace/workspaceFolders"), QByteArray("WorkspaceWorkspaceFolders") },
              { QByteArray("workspace/configuration"), QByteArray("Configuration") },
              { QByteArray("workspace/symbol"), QByteArray("WorkspaceSymbol") },
              { QByteArray("workspace/executeCommand"), QByteArray("ExecuteCommand") },
              { QByteArray("workspace/applyEdit"), QByteArray("ApplyWorkspaceEdit") },
              { QByteArray("workspace/willCreateFiles"), QByteArray("CreateFiles") },
              { QByteArray("workspace/willRenameFiles"), QByteArray("RenameFiles") },
              { QByteArray("workspace/willDeleteFiles"), QByteArray("DeleteFiles") },
              { QByteArray("textDocument/willSaveWaitUntil"), QByteArray("WillSaveTextDocument") },
              { QByteArray("textDocument/completion"), QByteArray("Completion") },
              { QByteArray("completionItem/resolve"), QByteArray("CompletionItemResolve") },
              { QByteArray("textDocument/hover"), QByteArray("Hover") },
              { QByteArray("textDocument/signatureHelp"), QByteArray("SignatureHelp") },
              { QByteArray("textDocument/declaration"), QByteArray("Declaration") },
              { QByteArray("textDocument/definition"), QByteArray("Definition") },
              { QByteArray("textDocument/typeDefinition"), QByteArray("TypeDefinition") },
              { QByteArray("textDocument/implementation"), QByteArray("Implementation") },
              { QByteArray("textDocument/references"), QByteArray("Reference") },
              { QByteArray("textDocument/documentHighlight"), QByteArray("DocumentHighlight") },
              { QByteArray("textDocument/documentSymbol"), QByteArray("DocumentSymbol") },
              { QByteArray("textDocument/codeAction"), QByteArray("CodeAction") },
              { QByteArray("codeAction/resolve"), QByteArray("CodeActionResolve") },
              { QByteArray("textDocument/codeLens"), QByteArray("CodeLens") },
              { QByteArray("codeLens/resolve"), QByteArray("CodeLensResolve") },
              { QByteArray("workspace/codeLens/refresh"), QByteArray("CodeLensRefresh") },
              { QByteArray("textDocument/documentLink"), QByteArray("DocumentLink") },
              { QByteArray("documentLink/resolve"), QByteArray("DocumentLinkResolve") },
              { QByteArray("textDocument/documentColor"), QByteArray("DocumentColor") },
              { QByteArray("textDocument/colorPresentation"), QByteArray("ColorPresentation") },
              { QByteArray("textDocument/formatting"), QByteArray("DocumentFormatting") },
              { QByteArray("textDocument/rangeFormatting"), QByteArray("DocumentRangeFormatting") },
              { QByteArray("textDocument/onTypeFormatting"),
                QByteArray("DocumentOnTypeFormatting") },
              { QByteArray("textDocument/rename"), QByteArray("Rename") },
              { QByteArray("textDocument/prepareRename"), QByteArray("PrepareRename") },
              { QByteArray("textDocument/foldingRange"), QByteArray("FoldingRange") },
              { QByteArray("textDocument/selectionRange"), QByteArray("SelectionRange") },
              { QByteArray("textDocument/prepareCallHierarchy"),
                QByteArray("CallHierarchyPrepare") },
              { QByteArray("callHierarchy/incomingCalls"),
                QByteArray("CallHierarchyIncomingCalls") },
              { QByteArray("callHierarchy/outgoingCalls"),
                QByteArray("CallHierarchyOutgoingCalls") },
              { QByteArray("textDocument/semanticTokens/full"), QByteArray("SemanticTokens") },
              { QByteArray("textDocument/semanticTokens/full/delta"),
                QByteArray("SemanticTokensDelta") },
              { QByteArray("textDocument/semanticTokens/range"),
                QByteArray("SemanticTokensRange") },
              { QByteArray("workspace/semanticTokens/refresh"),
                QByteArray("RequestingARefreshOfAllSemanticTokens") },
              { QByteArray("textDocument/linkedEditingRange"), QByteArray("LinkedEditingRange") },
              { QByteArray("textDocument/moniker"), QByteArray("Moniker") } });
    return map.value(method);
}

QByteArray ProtocolBase::notificationMethodToBaseCppName(const QByteArray &method)
{
    static QHash<QByteArray, QByteArray> map(
            { { QByteArray("$/cancelRequest"), QByteArray("Cancel") },
              { QByteArray("$/progress"), QByteArray("Progress") },
              { QByteArray("initialized"), QByteArray("Initialized") },
              { QByteArray("exit"), QByteArray("Exit") },
              { QByteArray("$/logTrace"), QByteArray("LogTrace") },
              { QByteArray("$/setTrace"), QByteArray("SetTrace") },
              { QByteArray("window/showMessage"), QByteArray("ShowMessage") },
              { QByteArray("window/logMessage"), QByteArray("LogMessage") },
              { QByteArray("window/workDoneProgress/cancel"),
                QByteArray("WorkDoneProgressCancel") },
              { QByteArray("telemetry/event"), QByteArray("TelemetryEvent") },
              { QByteArray("workspace/didChangeWorkspaceFolders"),
                QByteArray("DidChangeWorkspaceFolders") },
              { QByteArray("workspace/didChangeConfiguration"),
                QByteArray("DidChangeConfiguration") },
              { QByteArray("workspace/didChangeWatchedFiles"),
                QByteArray("DidChangeWatchedFiles") },
              { QByteArray("workspace/didCreateFiles"), QByteArray("CreateFiles") },
              { QByteArray("workspace/didRenameFiles"), QByteArray("RenameFiles") },
              { QByteArray("workspace/didDeleteFiles"), QByteArray("DeleteFiles") },
              { QByteArray("textDocument/didOpen"), QByteArray("DidOpenTextDocument") },
              { QByteArray("textDocument/didChange"), QByteArray("DidChangeTextDocument") },
              { QByteArray("textDocument/willSave"), QByteArray("WillSaveTextDocument") },
              { QByteArray("textDocument/didSave"), QByteArray("DidSaveTextDocument") },
              { QByteArray("textDocument/didClose"), QByteArray("DidCloseTextDocument") },
              { QByteArray("textDocument/publishDiagnostics"),
                QByteArray("PublishDiagnostics") } });
    return map.value(method);
}

ProtocolGen::ProtocolGen(std::unique_ptr<ProtocolGenPrivate> &&p) : ProtocolBase(std::move(p)) { }

ProtocolGen::~ProtocolGen() { }

void ProtocolGen::notifyCancel(const CancelParams &params)
{
    typedRpc()->sendNotification(Notifications::CancelMethod, params);
}

void ProtocolGen::notifyProgress(const ProgressParams &params)
{
    typedRpc()->sendNotification(Notifications::ProgressMethod, params);
}

void ProtocolGen::requestInitialize(const InitializeParams &params,
                                    std::function<void(const InitializeResult &)> responseHandler,
                                    ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::InitializeMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<InitializeResult>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyInitialized(const InitializedParams &params)
{
    typedRpc()->sendNotification(Notifications::InitializedMethod, params);
}

void ProtocolGen::requestShutdown(const std::nullptr_t &params,
                                  std::function<void()> responseHandler,
                                  ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ShutdownMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::nullptr_t>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyExit(const std::nullptr_t &params)
{
    typedRpc()->sendNotification(Notifications::ExitMethod, params);
}

void ProtocolGen::notifyLogTrace(const LogTraceParams &params)
{
    typedRpc()->sendNotification(Notifications::LogTraceMethod, params);
}

void ProtocolGen::notifySetTrace(const SetTraceParams &params)
{
    typedRpc()->sendNotification(Notifications::SetTraceMethod, params);
}

void ProtocolGen::notifyShowMessage(const ShowMessageParams &params)
{
    typedRpc()->sendNotification(Notifications::ShowMessageMethod, params);
}

void ProtocolGen::requestShowMessageRequest(
        const ShowMessageRequestParams &params,
        std::function<void(const std::variant<MessageActionItem, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ShowMessageRequestMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<MessageActionItem, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestShowDocument(
        const ShowDocumentParams &params,
        std::function<void(const ShowDocumentResult &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ShowDocumentMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<ShowDocumentResult>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyLogMessage(const LogMessageParams &params)
{
    typedRpc()->sendNotification(Notifications::LogMessageMethod, params);
}

void ProtocolGen::requestWorkDoneProgressCreate(const WorkDoneProgressCreateParams &params,
                                                std::function<void()> responseHandler,
                                                ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::WorkDoneProgressCreateMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::nullptr_t>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyWorkDoneProgressCancel(const WorkDoneProgressCancelParams &params)
{
    typedRpc()->sendNotification(Notifications::WorkDoneProgressCancelMethod, params);
}

void ProtocolGen::notifyTelemetryEvent(const QJsonObject &params)
{
    typedRpc()->sendNotification(Notifications::TelemetryEventMethod, params);
}

void ProtocolGen::requestRegistration(const RegistrationParams &params,
                                      std::function<void()> responseHandler,
                                      ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::RegistrationMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::nullptr_t>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestUnregistration(const UnregistrationParams &params,
                                        std::function<void()> responseHandler,
                                        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::UnregistrationMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::nullptr_t>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestWorkspaceWorkspaceFolders(
        const std::nullptr_t &params,
        std::function<void(const std::variant<QList<WorkspaceFolder>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::WorkspaceWorkspaceFoldersMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<WorkspaceFolder>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyDidChangeWorkspaceFolders(const DidChangeWorkspaceFoldersParams &params)
{
    typedRpc()->sendNotification(Notifications::DidChangeWorkspaceFoldersMethod, params);
}

void ProtocolGen::notifyDidChangeConfiguration(const DidChangeConfigurationParams &params)
{
    typedRpc()->sendNotification(Notifications::DidChangeConfigurationMethod, params);
}

void ProtocolGen::requestConfiguration(
        const ConfigurationParams &params,
        std::function<void(const QList<QJsonValue> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ConfigurationMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<QList<QJsonValue>>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyDidChangeWatchedFiles(const DidChangeWatchedFilesParams &params)
{
    typedRpc()->sendNotification(Notifications::DidChangeWatchedFilesMethod, params);
}

void ProtocolGen::requestWorkspaceSymbol(
        const WorkspaceSymbolParams &params,
        std::function<void(const std::variant<QList<SymbolInformation>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::WorkspaceSymbolMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<SymbolInformation>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestExecuteCommand(
        const ExecuteCommandParams &params,
        std::function<void(const std::variant<QJsonValue, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ExecuteCommandMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QJsonValue, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestApplyWorkspaceEdit(
        const ApplyWorkspaceEditParams &params,
        std::function<void(const ApplyWorkspaceEditResponse &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ApplyWorkspaceEditMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<ApplyWorkspaceEditResponse>(response.data, responseHandler,
                                                              errorHandler);
            },
            params);
}

void ProtocolGen::requestCreateFiles(
        const CreateFilesParams &params,
        std::function<void(const std::variant<WorkspaceEdit, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CreateFilesMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<WorkspaceEdit, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyCreateFiles(const CreateFilesParams &params)
{
    typedRpc()->sendNotification(Notifications::CreateFilesMethod, params);
}

void ProtocolGen::requestRenameFiles(
        const RenameFilesParams &params,
        std::function<void(const std::variant<WorkspaceEdit, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::RenameFilesMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<WorkspaceEdit, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyRenameFiles(const RenameFilesParams &params)
{
    typedRpc()->sendNotification(Notifications::RenameFilesMethod, params);
}

void ProtocolGen::requestDeleteFiles(
        const DeleteFilesParams &params,
        std::function<void(const std::variant<WorkspaceEdit, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DeleteFilesMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<WorkspaceEdit, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyDeleteFiles(const DeleteFilesParams &params)
{
    typedRpc()->sendNotification(Notifications::DeleteFilesMethod, params);
}

void ProtocolGen::notifyDidOpenTextDocument(const DidOpenTextDocumentParams &params)
{
    typedRpc()->sendNotification(Notifications::DidOpenTextDocumentMethod, params);
}

void ProtocolGen::notifyDidChangeTextDocument(const DidChangeTextDocumentParams &params)
{
    typedRpc()->sendNotification(Notifications::DidChangeTextDocumentMethod, params);
}

void ProtocolGen::notifyWillSaveTextDocument(const WillSaveTextDocumentParams &params)
{
    typedRpc()->sendNotification(Notifications::WillSaveTextDocumentMethod, params);
}

void ProtocolGen::requestWillSaveTextDocument(
        const WillSaveTextDocumentParams &params,
        std::function<void(const std::variant<QList<TextEdit>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::WillSaveTextDocumentMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<TextEdit>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::notifyDidSaveTextDocument(const DidSaveTextDocumentParams &params)
{
    typedRpc()->sendNotification(Notifications::DidSaveTextDocumentMethod, params);
}

void ProtocolGen::notifyDidCloseTextDocument(const DidCloseTextDocumentParams &params)
{
    typedRpc()->sendNotification(Notifications::DidCloseTextDocumentMethod, params);
}

void ProtocolGen::notifyPublishDiagnostics(const PublishDiagnosticsParams &params)
{
    typedRpc()->sendNotification(Notifications::PublishDiagnosticsMethod, params);
}

void ProtocolGen::requestCompletion(
        const CompletionParams &params,
        std::function<
                void(const std::variant<QList<CompletionItem>, CompletionList, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CompletionMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<
                            std::variant<QList<CompletionItem>, CompletionList, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCompletionItemResolve(
        const CompletionItem &params, std::function<void(const CompletionItem &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CompletionItemResolveMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<CompletionItem>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestHover(
        const HoverParams &params,
        std::function<void(const std::variant<Hover, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::HoverMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<Hover, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestSignatureHelp(
        const SignatureHelpParams &params,
        std::function<void(const std::variant<SignatureHelp, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::SignatureHelpMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<SignatureHelp, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDeclaration(
        const DeclarationParams &params,
        std::function<void(const std::variant<Location, QList<Location>, QList<LocationLink>,
                                              std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DeclarationMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<Location, QList<Location>, QList<LocationLink>,
                                               std::nullptr_t>>(response.data, responseHandler,
                                                                errorHandler);
            },
            params);
}

void ProtocolGen::requestDefinition(
        const DefinitionParams &params,
        std::function<void(const std::variant<Location, QList<Location>, QList<LocationLink>,
                                              std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DefinitionMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<Location, QList<Location>, QList<LocationLink>,
                                               std::nullptr_t>>(response.data, responseHandler,
                                                                errorHandler);
            },
            params);
}

void ProtocolGen::requestTypeDefinition(
        const TypeDefinitionParams &params,
        std::function<void(const std::variant<Location, QList<Location>, QList<LocationLink>,
                                              std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::TypeDefinitionMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<Location, QList<Location>, QList<LocationLink>,
                                               std::nullptr_t>>(response.data, responseHandler,
                                                                errorHandler);
            },
            params);
}

void ProtocolGen::requestImplementation(
        const ImplementationParams &params,
        std::function<void(const std::variant<Location, QList<Location>, QList<LocationLink>,
                                              std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ImplementationMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<Location, QList<Location>, QList<LocationLink>,
                                               std::nullptr_t>>(response.data, responseHandler,
                                                                errorHandler);
            },
            params);
}

void ProtocolGen::requestReference(
        const ReferenceParams &params,
        std::function<void(const std::variant<QList<Location>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ReferenceMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<Location>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentHighlight(
        const DocumentHighlightParams &params,
        std::function<void(const std::variant<QList<DocumentHighlight>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentHighlightMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<DocumentHighlight>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentSymbol(
        const DocumentSymbolParams &params,
        std::function<void(const std::variant<QList<DocumentSymbol>, QList<SymbolInformation>,
                                              std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentSymbolMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<DocumentSymbol>, QList<SymbolInformation>,
                                               std::nullptr_t>>(response.data, responseHandler,
                                                                errorHandler);
            },
            params);
}

void ProtocolGen::requestCodeAction(
        const CodeActionParams &params,
        std::function<void(
                const std::variant<QList<std::variant<Command, CodeAction>>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CodeActionMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<
                            std::variant<QList<std::variant<Command, CodeAction>>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCodeActionResolve(const CodeAction &params,
                                           std::function<void(const CodeAction &)> responseHandler,
                                           ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CodeActionResolveMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<CodeAction>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCodeLens(
        const CodeLensParams &params,
        std::function<void(const std::variant<QList<CodeLens>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CodeLensMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<CodeLens>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCodeLensResolve(const CodeLens &params,
                                         std::function<void(const CodeLens &)> responseHandler,
                                         ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CodeLensResolveMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<CodeLens>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCodeLensRefresh(const std::nullptr_t &params,
                                         std::function<void()> responseHandler,
                                         ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CodeLensRefreshMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::nullptr_t>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentLink(
        const DocumentLinkParams &params,
        std::function<void(const std::variant<QList<DocumentLink>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentLinkMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<DocumentLink>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentLinkResolve(
        const DocumentLink &params, std::function<void(const DocumentLink &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentLinkResolveMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<DocumentLink>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentColor(
        const DocumentColorParams &params,
        std::function<void(const QList<ColorInformation> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentColorMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<QList<ColorInformation>>(response.data, responseHandler,
                                                           errorHandler);
            },
            params);
}

void ProtocolGen::requestColorPresentation(
        const ColorPresentationParams &params,
        std::function<void(const QList<ColorPresentation> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::ColorPresentationMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<QList<ColorPresentation>>(response.data, responseHandler,
                                                            errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentFormatting(
        const DocumentFormattingParams &params,
        std::function<void(const std::variant<QList<TextEdit>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentFormattingMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<TextEdit>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentRangeFormatting(
        const DocumentRangeFormattingParams &params,
        std::function<void(const std::variant<QList<TextEdit>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentRangeFormattingMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<TextEdit>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestDocumentOnTypeFormatting(
        const DocumentOnTypeFormattingParams &params,
        std::function<void(const std::variant<QList<TextEdit>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::DocumentOnTypeFormattingMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<TextEdit>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestRename(
        const RenameParams &params,
        std::function<void(const std::variant<WorkspaceEdit, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::RenameMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<WorkspaceEdit, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestPrepareRename(
        const PrepareRenameParams &params,
        std::function<void(const std::variant<Range, RangePlaceHolder, DefaultBehaviorStruct,
                                              std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::PrepareRenameMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<Range, RangePlaceHolder, DefaultBehaviorStruct,
                                               std::nullptr_t>>(response.data, responseHandler,
                                                                errorHandler);
            },
            params);
}

void ProtocolGen::requestFoldingRange(
        const FoldingRangeParams &params,
        std::function<void(const std::variant<QList<FoldingRange>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::FoldingRangeMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<FoldingRange>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestSelectionRange(
        const SelectionRangeParams &params,
        std::function<void(const std::variant<QList<SelectionRange>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::SelectionRangeMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<SelectionRange>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCallHierarchyPrepare(
        const CallHierarchyPrepareParams &params,
        std::function<void(const std::variant<QList<CallHierarchyItem>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CallHierarchyPrepareMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<CallHierarchyItem>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCallHierarchyIncomingCalls(
        const CallHierarchyIncomingCallsParams &params,
        std::function<void(const std::variant<QList<CallHierarchyIncomingCall>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CallHierarchyIncomingCallsMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<CallHierarchyIncomingCall>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestCallHierarchyOutgoingCalls(
        const CallHierarchyOutgoingCallsParams &params,
        std::function<void(const std::variant<QList<CallHierarchyOutgoingCall>, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::CallHierarchyOutgoingCallsMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<CallHierarchyOutgoingCall>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestSemanticTokens(
        const SemanticTokensParams &params,
        std::function<void(const std::variant<SemanticTokens, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::SemanticTokensMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<SemanticTokens, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestSemanticTokensDelta(
        const SemanticTokensDeltaParams &params,
        std::function<
                void(const std::variant<SemanticTokens, SemanticTokensDelta, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::SemanticTokensDeltaMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<
                            std::variant<SemanticTokens, SemanticTokensDelta, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestSemanticTokensRange(
        const SemanticTokensRangeParams &params,
        std::function<void(const std::variant<SemanticTokens, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::SemanticTokensRangeMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<SemanticTokens, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestRequestingARefreshOfAllSemanticTokens(
        const std::nullptr_t &params, std::function<void()> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::RequestingARefreshOfAllSemanticTokensMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::nullptr_t>(response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestLinkedEditingRange(
        const LinkedEditingRangeParams &params,
        std::function<void(const std::variant<LinkedEditingRanges, std::nullptr_t> &)>
                responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::LinkedEditingRangeMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<LinkedEditingRanges, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::requestMoniker(
        const MonikerParams &params,
        std::function<void(const std::variant<QList<Moniker>, std::nullptr_t> &)> responseHandler,
        ResponseErrorHandler errorHandler)
{
    typedRpc()->sendRequest(
            QByteArray(Requests::MonikerMethod),
            [responseHandler = std::move(responseHandler),
             errorHandler = std::move(errorHandler)](const QJsonRpcProtocol::Response &response) {
                if (response.errorCode.isDouble())
                    errorHandler(ResponseError{ response.errorCode.toInt(),
                                                response.errorMessage.toUtf8(), response.data });
                else
                    decodeAndCall<std::variant<QList<Moniker>, std::nullptr_t>>(
                            response.data, responseHandler, errorHandler);
            },
            params);
}

void ProtocolGen::registerCancelNotificationHandler(
        const std::function<void(const QByteArray &, const CancelParams &)> &handler)
{
    typedRpc()->registerNotificationHandler<QLspSpecification::Notifications::CancelParamsType>(
            QByteArray(QLspSpecification::Notifications::CancelMethod), handler);
}

void ProtocolGen::registerProgressNotificationHandler(
        const std::function<void(const QByteArray &, const ProgressParams &)> &handler)
{
    typedRpc()->registerNotificationHandler<QLspSpecification::Notifications::ProgressParamsType>(
            QByteArray(QLspSpecification::Notifications::ProgressMethod), handler);
}

void ProtocolGen::registerInitializeRequestHandler(
        const std::function<void(const QByteArray &, const InitializeParams &,
                                 LSPResponse<InitializeResult> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::InitializeParamsType,
                                     QLspSpecification::Responses::InitializeResponseType>(
                    QByteArray(QLspSpecification::Requests::InitializeMethod), handler);
}

void ProtocolGen::registerInitializedNotificationHandler(
        const std::function<void(const QByteArray &, const InitializedParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<QLspSpecification::Notifications::InitializedParamsType>(
                    QByteArray(QLspSpecification::Notifications::InitializedMethod), handler);
}

void ProtocolGen::registerShutdownRequestHandler(
        const std::function<void(const QByteArray &, const std::nullptr_t &,
                                 LSPResponse<std::nullptr_t> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ShutdownParamsType,
                                     QLspSpecification::Responses::ShutdownResponseType>(
                    QByteArray(QLspSpecification::Requests::ShutdownMethod), handler);
}

void ProtocolGen::registerExitNotificationHandler(
        const std::function<void(const QByteArray &, const std::nullptr_t &)> &handler)
{
    typedRpc()->registerNotificationHandler<QLspSpecification::Notifications::ExitParamsType>(
            QByteArray(QLspSpecification::Notifications::ExitMethod), handler);
}

void ProtocolGen::registerLogTraceNotificationHandler(
        const std::function<void(const QByteArray &, const LogTraceParams &)> &handler)
{
    typedRpc()->registerNotificationHandler<QLspSpecification::Notifications::LogTraceParamsType>(
            QByteArray(QLspSpecification::Notifications::LogTraceMethod), handler);
}

void ProtocolGen::registerSetTraceNotificationHandler(
        const std::function<void(const QByteArray &, const SetTraceParams &)> &handler)
{
    typedRpc()->registerNotificationHandler<QLspSpecification::Notifications::SetTraceParamsType>(
            QByteArray(QLspSpecification::Notifications::SetTraceMethod), handler);
}

void ProtocolGen::registerShowMessageNotificationHandler(
        const std::function<void(const QByteArray &, const ShowMessageParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<QLspSpecification::Notifications::ShowMessageParamsType>(
                    QByteArray(QLspSpecification::Notifications::ShowMessageMethod), handler);
}

void ProtocolGen::registerShowMessageRequestRequestHandler(
        const std::function<void(const QByteArray &, const ShowMessageRequestParams &,
                                 LSPResponse<std::variant<MessageActionItem, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ShowMessageRequestParamsType,
                                     QLspSpecification::Responses::ShowMessageRequestResponseType>(
                    QByteArray(QLspSpecification::Requests::ShowMessageRequestMethod), handler);
}

void ProtocolGen::registerShowDocumentRequestHandler(
        const std::function<void(const QByteArray &, const ShowDocumentParams &,
                                 LSPResponse<ShowDocumentResult> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ShowDocumentParamsType,
                                     QLspSpecification::Responses::ShowDocumentResponseType>(
                    QByteArray(QLspSpecification::Requests::ShowDocumentMethod), handler);
}

void ProtocolGen::registerLogMessageNotificationHandler(
        const std::function<void(const QByteArray &, const LogMessageParams &)> &handler)
{
    typedRpc()->registerNotificationHandler<QLspSpecification::Notifications::LogMessageParamsType>(
            QByteArray(QLspSpecification::Notifications::LogMessageMethod), handler);
}

void ProtocolGen::registerWorkDoneProgressCreateRequestHandler(
        const std::function<void(const QByteArray &, const WorkDoneProgressCreateParams &,
                                 LSPResponse<std::nullptr_t> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::WorkDoneProgressCreateParamsType,
                    QLspSpecification::Responses::WorkDoneProgressCreateResponseType>(
                    QByteArray(QLspSpecification::Requests::WorkDoneProgressCreateMethod), handler);
}

void ProtocolGen::registerWorkDoneProgressCancelNotificationHandler(
        const std::function<void(const QByteArray &, const WorkDoneProgressCancelParams &)>
                &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::WorkDoneProgressCancelParamsType>(
                    QByteArray(QLspSpecification::Notifications::WorkDoneProgressCancelMethod),
                    handler);
}

void ProtocolGen::registerTelemetryEventNotificationHandler(
        const std::function<void(const QByteArray &, const QJsonObject &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::TelemetryEventParamsType>(
                    QByteArray(QLspSpecification::Notifications::TelemetryEventMethod), handler);
}

void ProtocolGen::registerRegistrationRequestHandler(
        const std::function<void(const QByteArray &, const RegistrationParams &,
                                 LSPResponse<std::nullptr_t> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::RegistrationParamsType,
                                     QLspSpecification::Responses::RegistrationResponseType>(
                    QByteArray(QLspSpecification::Requests::RegistrationMethod), handler);
}

void ProtocolGen::registerUnregistrationRequestHandler(
        const std::function<void(const QByteArray &, const UnregistrationParams &,
                                 LSPResponse<std::nullptr_t> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::UnregistrationParamsType,
                                     QLspSpecification::Responses::UnregistrationResponseType>(
                    QByteArray(QLspSpecification::Requests::UnregistrationMethod), handler);
}

void ProtocolGen::registerWorkspaceWorkspaceFoldersRequestHandler(
        const std::function<void(
                const QByteArray &, const std::nullptr_t &,
                LSPResponse<std::variant<QList<WorkspaceFolder>, std::nullptr_t>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::WorkspaceWorkspaceFoldersParamsType,
                    QLspSpecification::Responses::WorkspaceWorkspaceFoldersResponseType>(
                    QByteArray(QLspSpecification::Requests::WorkspaceWorkspaceFoldersMethod),
                    handler);
}

void ProtocolGen::registerDidChangeWorkspaceFoldersNotificationHandler(
        const std::function<void(const QByteArray &, const DidChangeWorkspaceFoldersParams &)>
                &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidChangeWorkspaceFoldersParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidChangeWorkspaceFoldersMethod),
                    handler);
}

void ProtocolGen::registerDidChangeConfigurationNotificationHandler(
        const std::function<void(const QByteArray &, const DidChangeConfigurationParams &)>
                &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidChangeConfigurationParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidChangeConfigurationMethod),
                    handler);
}

void ProtocolGen::registerConfigurationRequestHandler(
        const std::function<void(const QByteArray &, const ConfigurationParams &,
                                 LSPResponse<QList<QJsonValue>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ConfigurationParamsType,
                                     QLspSpecification::Responses::ConfigurationResponseType>(
                    QByteArray(QLspSpecification::Requests::ConfigurationMethod), handler);
}

void ProtocolGen::registerDidChangeWatchedFilesNotificationHandler(
        const std::function<void(const QByteArray &, const DidChangeWatchedFilesParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidChangeWatchedFilesParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidChangeWatchedFilesMethod),
                    handler);
}

void ProtocolGen::registerWorkspaceSymbolRequestHandler(
        const std::function<
                void(const QByteArray &, const WorkspaceSymbolParams &,
                     LSPPartialResponse<std::variant<QList<SymbolInformation>, std::nullptr_t>,
                                        QList<SymbolInformation>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::WorkspaceSymbolParamsType,
                                     QLspSpecification::Responses::WorkspaceSymbolResponseType>(
                    QByteArray(QLspSpecification::Requests::WorkspaceSymbolMethod), handler);
}

void ProtocolGen::registerExecuteCommandRequestHandler(
        const std::function<void(const QByteArray &, const ExecuteCommandParams &,
                                 LSPResponse<std::variant<QJsonValue, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ExecuteCommandParamsType,
                                     QLspSpecification::Responses::ExecuteCommandResponseType>(
                    QByteArray(QLspSpecification::Requests::ExecuteCommandMethod), handler);
}

void ProtocolGen::registerApplyWorkspaceEditRequestHandler(
        const std::function<void(const QByteArray &, const ApplyWorkspaceEditParams &,
                                 LSPResponse<ApplyWorkspaceEditResponse> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ApplyWorkspaceEditParamsType,
                                     QLspSpecification::Responses::ApplyWorkspaceEditResponseType>(
                    QByteArray(QLspSpecification::Requests::ApplyWorkspaceEditMethod), handler);
}

void ProtocolGen::registerCreateFilesRequestHandler(
        const std::function<void(const QByteArray &, const CreateFilesParams &,
                                 LSPResponse<std::variant<WorkspaceEdit, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CreateFilesParamsType,
                                     QLspSpecification::Responses::CreateFilesResponseType>(
                    QByteArray(QLspSpecification::Requests::CreateFilesMethod), handler);
}

void ProtocolGen::registerCreateFilesNotificationHandler(
        const std::function<void(const QByteArray &, const CreateFilesParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<QLspSpecification::Notifications::CreateFilesParamsType>(
                    QByteArray(QLspSpecification::Notifications::CreateFilesMethod), handler);
}

void ProtocolGen::registerRenameFilesRequestHandler(
        const std::function<void(const QByteArray &, const RenameFilesParams &,
                                 LSPResponse<std::variant<WorkspaceEdit, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::RenameFilesParamsType,
                                     QLspSpecification::Responses::RenameFilesResponseType>(
                    QByteArray(QLspSpecification::Requests::RenameFilesMethod), handler);
}

void ProtocolGen::registerRenameFilesNotificationHandler(
        const std::function<void(const QByteArray &, const RenameFilesParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<QLspSpecification::Notifications::RenameFilesParamsType>(
                    QByteArray(QLspSpecification::Notifications::RenameFilesMethod), handler);
}

void ProtocolGen::registerDeleteFilesRequestHandler(
        const std::function<void(const QByteArray &, const DeleteFilesParams &,
                                 LSPResponse<std::variant<WorkspaceEdit, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DeleteFilesParamsType,
                                     QLspSpecification::Responses::DeleteFilesResponseType>(
                    QByteArray(QLspSpecification::Requests::DeleteFilesMethod), handler);
}

void ProtocolGen::registerDeleteFilesNotificationHandler(
        const std::function<void(const QByteArray &, const DeleteFilesParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<QLspSpecification::Notifications::DeleteFilesParamsType>(
                    QByteArray(QLspSpecification::Notifications::DeleteFilesMethod), handler);
}

void ProtocolGen::registerDidOpenTextDocumentNotificationHandler(
        const std::function<void(const QByteArray &, const DidOpenTextDocumentParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidOpenTextDocumentParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidOpenTextDocumentMethod),
                    handler);
}

void ProtocolGen::registerDidChangeTextDocumentNotificationHandler(
        const std::function<void(const QByteArray &, const DidChangeTextDocumentParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidChangeTextDocumentParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidChangeTextDocumentMethod),
                    handler);
}

void ProtocolGen::registerWillSaveTextDocumentNotificationHandler(
        const std::function<void(const QByteArray &, const WillSaveTextDocumentParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::WillSaveTextDocumentParamsType>(
                    QByteArray(QLspSpecification::Notifications::WillSaveTextDocumentMethod),
                    handler);
}

void ProtocolGen::registerWillSaveTextDocumentRequestHandler(
        const std::function<void(const QByteArray &, const WillSaveTextDocumentParams &,
                                 LSPResponse<std::variant<QList<TextEdit>, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::WillSaveTextDocumentParamsType,
                    QLspSpecification::Responses::WillSaveTextDocumentResponseType>(
                    QByteArray(QLspSpecification::Requests::WillSaveTextDocumentMethod), handler);
}

void ProtocolGen::registerDidSaveTextDocumentNotificationHandler(
        const std::function<void(const QByteArray &, const DidSaveTextDocumentParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidSaveTextDocumentParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidSaveTextDocumentMethod),
                    handler);
}

void ProtocolGen::registerDidCloseTextDocumentNotificationHandler(
        const std::function<void(const QByteArray &, const DidCloseTextDocumentParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::DidCloseTextDocumentParamsType>(
                    QByteArray(QLspSpecification::Notifications::DidCloseTextDocumentMethod),
                    handler);
}

void ProtocolGen::registerPublishDiagnosticsNotificationHandler(
        const std::function<void(const QByteArray &, const PublishDiagnosticsParams &)> &handler)
{
    typedRpc()
            ->registerNotificationHandler<
                    QLspSpecification::Notifications::PublishDiagnosticsParamsType>(
                    QByteArray(QLspSpecification::Notifications::PublishDiagnosticsMethod),
                    handler);
}

void ProtocolGen::registerCompletionRequestHandler(
        const std::function<
                void(const QByteArray &, const CompletionParams &,
                     LSPPartialResponse<
                             std::variant<QList<CompletionItem>, CompletionList, std::nullptr_t>,
                             std::variant<CompletionList, QList<CompletionItem>>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CompletionParamsType,
                                     QLspSpecification::Responses::CompletionResponseType>(
                    QByteArray(QLspSpecification::Requests::CompletionMethod), handler);
}

void ProtocolGen::registerCompletionItemResolveRequestHandler(
        const std::function<void(const QByteArray &, const CompletionItem &,
                                 LSPResponse<CompletionItem> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::CompletionItemResolveParamsType,
                    QLspSpecification::Responses::CompletionItemResolveResponseType>(
                    QByteArray(QLspSpecification::Requests::CompletionItemResolveMethod), handler);
}

void ProtocolGen::registerHoverRequestHandler(
        const std::function<void(const QByteArray &, const HoverParams &,
                                 LSPResponse<std::variant<Hover, std::nullptr_t>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::HoverParamsType,
                                     QLspSpecification::Responses::HoverResponseType>(
                    QByteArray(QLspSpecification::Requests::HoverMethod), handler);
}

void ProtocolGen::registerSignatureHelpRequestHandler(
        const std::function<void(const QByteArray &, const SignatureHelpParams &,
                                 LSPResponse<std::variant<SignatureHelp, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::SignatureHelpParamsType,
                                     QLspSpecification::Responses::SignatureHelpResponseType>(
                    QByteArray(QLspSpecification::Requests::SignatureHelpMethod), handler);
}

void ProtocolGen::registerDeclarationRequestHandler(
        const std::function<
                void(const QByteArray &, const DeclarationParams &,
                     LSPPartialResponse<std::variant<Location, QList<Location>, QList<LocationLink>,
                                                     std::nullptr_t>,
                                        std::variant<QList<Location>, QList<LocationLink>>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DeclarationParamsType,
                                     QLspSpecification::Responses::DeclarationResponseType>(
                    QByteArray(QLspSpecification::Requests::DeclarationMethod), handler);
}

void ProtocolGen::registerDefinitionRequestHandler(
        const std::function<
                void(const QByteArray &, const DefinitionParams &,
                     LSPPartialResponse<std::variant<Location, QList<Location>, QList<LocationLink>,
                                                     std::nullptr_t>,
                                        std::variant<QList<Location>, QList<LocationLink>>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DefinitionParamsType,
                                     QLspSpecification::Responses::DefinitionResponseType>(
                    QByteArray(QLspSpecification::Requests::DefinitionMethod), handler);
}

void ProtocolGen::registerTypeDefinitionRequestHandler(
        const std::function<
                void(const QByteArray &, const TypeDefinitionParams &,
                     LSPPartialResponse<std::variant<Location, QList<Location>, QList<LocationLink>,
                                                     std::nullptr_t>,
                                        std::variant<QList<Location>, QList<LocationLink>>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::TypeDefinitionParamsType,
                                     QLspSpecification::Responses::TypeDefinitionResponseType>(
                    QByteArray(QLspSpecification::Requests::TypeDefinitionMethod), handler);
}

void ProtocolGen::registerImplementationRequestHandler(
        const std::function<
                void(const QByteArray &, const ImplementationParams &,
                     LSPPartialResponse<std::variant<Location, QList<Location>, QList<LocationLink>,
                                                     std::nullptr_t>,
                                        std::variant<QList<Location>, QList<LocationLink>>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ImplementationParamsType,
                                     QLspSpecification::Responses::ImplementationResponseType>(
                    QByteArray(QLspSpecification::Requests::ImplementationMethod), handler);
}

void ProtocolGen::registerReferenceRequestHandler(
        const std::function<void(const QByteArray &, const ReferenceParams &,
                                 LSPPartialResponse<std::variant<QList<Location>, std::nullptr_t>,
                                                    QList<Location>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ReferenceParamsType,
                                     QLspSpecification::Responses::ReferenceResponseType>(
                    QByteArray(QLspSpecification::Requests::ReferenceMethod), handler);
}

void ProtocolGen::registerDocumentHighlightRequestHandler(
        const std::function<
                void(const QByteArray &, const DocumentHighlightParams &,
                     LSPPartialResponse<std::variant<QList<DocumentHighlight>, std::nullptr_t>,
                                        QList<DocumentHighlight>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DocumentHighlightParamsType,
                                     QLspSpecification::Responses::DocumentHighlightResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentHighlightMethod), handler);
}

void ProtocolGen::registerDocumentSymbolRequestHandler(
        const std::function<void(
                const QByteArray &, const DocumentSymbolParams &,
                LSPPartialResponse<std::variant<QList<DocumentSymbol>, QList<SymbolInformation>,
                                                std::nullptr_t>,
                                   std::variant<QList<DocumentSymbol>, QList<SymbolInformation>>>
                        &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DocumentSymbolParamsType,
                                     QLspSpecification::Responses::DocumentSymbolResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentSymbolMethod), handler);
}

void ProtocolGen::registerCodeActionRequestHandler(
        const std::function<
                void(const QByteArray &, const CodeActionParams &,
                     LSPPartialResponse<
                             std::variant<QList<std::variant<Command, CodeAction>>, std::nullptr_t>,
                             QList<std::variant<Command, CodeAction>>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CodeActionParamsType,
                                     QLspSpecification::Responses::CodeActionResponseType>(
                    QByteArray(QLspSpecification::Requests::CodeActionMethod), handler);
}

void ProtocolGen::registerCodeActionResolveRequestHandler(
        const std::function<void(const QByteArray &, const CodeAction &,
                                 LSPResponse<CodeAction> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CodeActionResolveParamsType,
                                     QLspSpecification::Responses::CodeActionResolveResponseType>(
                    QByteArray(QLspSpecification::Requests::CodeActionResolveMethod), handler);
}

void ProtocolGen::registerCodeLensRequestHandler(
        const std::function<void(const QByteArray &, const CodeLensParams &,
                                 LSPPartialResponse<std::variant<QList<CodeLens>, std::nullptr_t>,
                                                    QList<CodeLens>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CodeLensParamsType,
                                     QLspSpecification::Responses::CodeLensResponseType>(
                    QByteArray(QLspSpecification::Requests::CodeLensMethod), handler);
}

void ProtocolGen::registerCodeLensResolveRequestHandler(
        const std::function<void(const QByteArray &, const CodeLens &, LSPResponse<CodeLens> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CodeLensResolveParamsType,
                                     QLspSpecification::Responses::CodeLensResolveResponseType>(
                    QByteArray(QLspSpecification::Requests::CodeLensResolveMethod), handler);
}

void ProtocolGen::registerCodeLensRefreshRequestHandler(
        const std::function<void(const QByteArray &, const std::nullptr_t &,
                                 LSPResponse<std::nullptr_t> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::CodeLensRefreshParamsType,
                                     QLspSpecification::Responses::CodeLensRefreshResponseType>(
                    QByteArray(QLspSpecification::Requests::CodeLensRefreshMethod), handler);
}

void ProtocolGen::registerDocumentLinkRequestHandler(
        const std::function<
                void(const QByteArray &, const DocumentLinkParams &,
                     LSPPartialResponse<std::variant<QList<DocumentLink>, std::nullptr_t>,
                                        QList<DocumentLink>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DocumentLinkParamsType,
                                     QLspSpecification::Responses::DocumentLinkResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentLinkMethod), handler);
}

void ProtocolGen::registerDocumentLinkResolveRequestHandler(
        const std::function<void(const QByteArray &, const DocumentLink &,
                                 LSPResponse<DocumentLink> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DocumentLinkResolveParamsType,
                                     QLspSpecification::Responses::DocumentLinkResolveResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentLinkResolveMethod), handler);
}

void ProtocolGen::registerDocumentColorRequestHandler(
        const std::function<void(
                const QByteArray &, const DocumentColorParams &,
                LSPPartialResponse<QList<ColorInformation>, QList<ColorInformation>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DocumentColorParamsType,
                                     QLspSpecification::Responses::DocumentColorResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentColorMethod), handler);
}

void ProtocolGen::registerColorPresentationRequestHandler(
        const std::function<void(const QByteArray &, const ColorPresentationParams &,
                                 LSPPartialResponse<QList<ColorPresentation>,
                                                    QList<ColorPresentation>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::ColorPresentationParamsType,
                                     QLspSpecification::Responses::ColorPresentationResponseType>(
                    QByteArray(QLspSpecification::Requests::ColorPresentationMethod), handler);
}

void ProtocolGen::registerDocumentFormattingRequestHandler(
        const std::function<void(const QByteArray &, const DocumentFormattingParams &,
                                 LSPResponse<std::variant<QList<TextEdit>, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::DocumentFormattingParamsType,
                                     QLspSpecification::Responses::DocumentFormattingResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentFormattingMethod), handler);
}

void ProtocolGen::registerDocumentRangeFormattingRequestHandler(
        const std::function<void(const QByteArray &, const DocumentRangeFormattingParams &,
                                 LSPResponse<std::variant<QList<TextEdit>, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::DocumentRangeFormattingParamsType,
                    QLspSpecification::Responses::DocumentRangeFormattingResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentRangeFormattingMethod),
                    handler);
}

void ProtocolGen::registerDocumentOnTypeFormattingRequestHandler(
        const std::function<void(const QByteArray &, const DocumentOnTypeFormattingParams &,
                                 LSPResponse<std::variant<QList<TextEdit>, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::DocumentOnTypeFormattingParamsType,
                    QLspSpecification::Responses::DocumentOnTypeFormattingResponseType>(
                    QByteArray(QLspSpecification::Requests::DocumentOnTypeFormattingMethod),
                    handler);
}

void ProtocolGen::registerRenameRequestHandler(
        const std::function<void(const QByteArray &, const RenameParams &,
                                 LSPResponse<std::variant<WorkspaceEdit, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::RenameParamsType,
                                     QLspSpecification::Responses::RenameResponseType>(
                    QByteArray(QLspSpecification::Requests::RenameMethod), handler);
}

void ProtocolGen::registerPrepareRenameRequestHandler(
        const std::function<
                void(const QByteArray &, const PrepareRenameParams &,
                     LSPResponse<std::variant<Range, RangePlaceHolder, DefaultBehaviorStruct,
                                              std::nullptr_t>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::PrepareRenameParamsType,
                                     QLspSpecification::Responses::PrepareRenameResponseType>(
                    QByteArray(QLspSpecification::Requests::PrepareRenameMethod), handler);
}

void ProtocolGen::registerFoldingRangeRequestHandler(
        const std::function<
                void(const QByteArray &, const FoldingRangeParams &,
                     LSPPartialResponse<std::variant<QList<FoldingRange>, std::nullptr_t>,
                                        QList<FoldingRange>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::FoldingRangeParamsType,
                                     QLspSpecification::Responses::FoldingRangeResponseType>(
                    QByteArray(QLspSpecification::Requests::FoldingRangeMethod), handler);
}

void ProtocolGen::registerSelectionRangeRequestHandler(
        const std::function<
                void(const QByteArray &, const SelectionRangeParams &,
                     LSPPartialResponse<std::variant<QList<SelectionRange>, std::nullptr_t>,
                                        QList<SelectionRange>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::SelectionRangeParamsType,
                                     QLspSpecification::Responses::SelectionRangeResponseType>(
                    QByteArray(QLspSpecification::Requests::SelectionRangeMethod), handler);
}

void ProtocolGen::registerCallHierarchyPrepareRequestHandler(
        const std::function<void(
                const QByteArray &, const CallHierarchyPrepareParams &,
                LSPResponse<std::variant<QList<CallHierarchyItem>, std::nullptr_t>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::CallHierarchyPrepareParamsType,
                    QLspSpecification::Responses::CallHierarchyPrepareResponseType>(
                    QByteArray(QLspSpecification::Requests::CallHierarchyPrepareMethod), handler);
}

void ProtocolGen::registerCallHierarchyIncomingCallsRequestHandler(
        const std::function<void(
                const QByteArray &, const CallHierarchyIncomingCallsParams &,
                LSPPartialResponse<std::variant<QList<CallHierarchyIncomingCall>, std::nullptr_t>,
                                   QList<CallHierarchyIncomingCall>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::CallHierarchyIncomingCallsParamsType,
                    QLspSpecification::Responses::CallHierarchyIncomingCallsResponseType>(
                    QByteArray(QLspSpecification::Requests::CallHierarchyIncomingCallsMethod),
                    handler);
}

void ProtocolGen::registerCallHierarchyOutgoingCallsRequestHandler(
        const std::function<void(
                const QByteArray &, const CallHierarchyOutgoingCallsParams &,
                LSPPartialResponse<std::variant<QList<CallHierarchyOutgoingCall>, std::nullptr_t>,
                                   QList<CallHierarchyOutgoingCall>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::CallHierarchyOutgoingCallsParamsType,
                    QLspSpecification::Responses::CallHierarchyOutgoingCallsResponseType>(
                    QByteArray(QLspSpecification::Requests::CallHierarchyOutgoingCallsMethod),
                    handler);
}

void ProtocolGen::registerSemanticTokensRequestHandler(
        const std::function<void(const QByteArray &, const SemanticTokensParams &,
                                 LSPPartialResponse<std::variant<SemanticTokens, std::nullptr_t>,
                                                    SemanticTokensPartialResult> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::SemanticTokensParamsType,
                                     QLspSpecification::Responses::SemanticTokensResponseType>(
                    QByteArray(QLspSpecification::Requests::SemanticTokensMethod), handler);
}

void ProtocolGen::registerSemanticTokensDeltaRequestHandler(
        const std::function<
                void(const QByteArray &, const SemanticTokensDeltaParams &,
                     LSPPartialResponse<
                             std::variant<SemanticTokens, SemanticTokensDelta, std::nullptr_t>,
                             SemanticTokensDeltaPartialResult> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::SemanticTokensDeltaParamsType,
                                     QLspSpecification::Responses::SemanticTokensDeltaResponseType>(
                    QByteArray(QLspSpecification::Requests::SemanticTokensDeltaMethod), handler);
}

void ProtocolGen::registerSemanticTokensRangeRequestHandler(
        const std::function<void(const QByteArray &, const SemanticTokensRangeParams &,
                                 LSPPartialResponse<std::variant<SemanticTokens, std::nullptr_t>,
                                                    SemanticTokensPartialResult> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::SemanticTokensRangeParamsType,
                                     QLspSpecification::Responses::SemanticTokensRangeResponseType>(
                    QByteArray(QLspSpecification::Requests::SemanticTokensRangeMethod), handler);
}

void ProtocolGen::registerRequestingARefreshOfAllSemanticTokensRequestHandler(
        const std::function<void(const QByteArray &, const std::nullptr_t &,
                                 LSPResponse<std::nullptr_t> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<
                    QLspSpecification::Requests::RequestingARefreshOfAllSemanticTokensParamsType,
                    QLspSpecification::Responses::
                            RequestingARefreshOfAllSemanticTokensResponseType>(
                    QByteArray(QLspSpecification::Requests::
                                       RequestingARefreshOfAllSemanticTokensMethod),
                    handler);
}

void ProtocolGen::registerLinkedEditingRangeRequestHandler(
        const std::function<void(const QByteArray &, const LinkedEditingRangeParams &,
                                 LSPResponse<std::variant<LinkedEditingRanges, std::nullptr_t>> &&)>
                &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::LinkedEditingRangeParamsType,
                                     QLspSpecification::Responses::LinkedEditingRangeResponseType>(
                    QByteArray(QLspSpecification::Requests::LinkedEditingRangeMethod), handler);
}

void ProtocolGen::registerMonikerRequestHandler(
        const std::function<void(const QByteArray &, const MonikerParams &,
                                 LSPPartialResponse<std::variant<QList<Moniker>, std::nullptr_t>,
                                                    QList<Moniker>> &&)> &handler)
{
    typedRpc()
            ->registerRequestHandler<QLspSpecification::Requests::MonikerParamsType,
                                     QLspSpecification::Responses::MonikerResponseType>(
                    QByteArray(QLspSpecification::Requests::MonikerMethod), handler);
}

} // namespace QLspSpecification

QT_END_NAMESPACE
