//===--- ProtocolHandlers.cpp - LSP callbacks -----------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "ProtocolHandlers.h" #include "ClangdLSPServer.h" #include "ClangdServer.h" #include "DraftStore.h" using namespace clang; using namespace clangd; namespace { struct InitializeHandler : Handler { InitializeHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { Callbacks.onInitialize(ID, Output); } private: ProtocolCallbacks &Callbacks; }; struct ShutdownHandler : Handler { ShutdownHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { Callbacks.onShutdown(Output); } private: ProtocolCallbacks &Callbacks; }; struct TextDocumentDidOpenHandler : Handler { TextDocumentDidOpenHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleNotification(llvm::yaml::MappingNode *Params) override { auto DOTDP = DidOpenTextDocumentParams::parse(Params, Output); if (!DOTDP) { Output.log("Failed to decode DidOpenTextDocumentParams!\n"); return; } Callbacks.onDocumentDidOpen(*DOTDP, Output); } private: ProtocolCallbacks &Callbacks; }; struct TextDocumentDidChangeHandler : Handler { TextDocumentDidChangeHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleNotification(llvm::yaml::MappingNode *Params) override { auto DCTDP = DidChangeTextDocumentParams::parse(Params, Output); if (!DCTDP || DCTDP->contentChanges.size() != 1) { Output.log("Failed to decode DidChangeTextDocumentParams!\n"); return; } Callbacks.onDocumentDidChange(*DCTDP, Output); } private: ProtocolCallbacks &Callbacks; }; struct TextDocumentDidCloseHandler : Handler { TextDocumentDidCloseHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleNotification(llvm::yaml::MappingNode *Params) override { auto DCTDP = DidCloseTextDocumentParams::parse(Params, Output); if (!DCTDP) { Output.log("Failed to decode DidCloseTextDocumentParams!\n"); return; } Callbacks.onDocumentDidClose(*DCTDP, Output); } private: ProtocolCallbacks &Callbacks; }; struct TextDocumentOnTypeFormattingHandler : Handler { TextDocumentOnTypeFormattingHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { auto DOTFP = DocumentOnTypeFormattingParams::parse(Params, Output); if (!DOTFP) { Output.log("Failed to decode DocumentOnTypeFormattingParams!\n"); return; } Callbacks.onDocumentOnTypeFormatting(*DOTFP, ID, Output); } private: ProtocolCallbacks &Callbacks; }; struct TextDocumentRangeFormattingHandler : Handler { TextDocumentRangeFormattingHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { auto DRFP = DocumentRangeFormattingParams::parse(Params, Output); if (!DRFP) { Output.log("Failed to decode DocumentRangeFormattingParams!\n"); return; } Callbacks.onDocumentRangeFormatting(*DRFP, ID, Output); } private: ProtocolCallbacks &Callbacks; }; struct TextDocumentFormattingHandler : Handler { TextDocumentFormattingHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { auto DFP = DocumentFormattingParams::parse(Params, Output); if (!DFP) { Output.log("Failed to decode DocumentFormattingParams!\n"); return; } Callbacks.onDocumentFormatting(*DFP, ID, Output); } private: ProtocolCallbacks &Callbacks; }; struct CodeActionHandler : Handler { CodeActionHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { auto CAP = CodeActionParams::parse(Params, Output); if (!CAP) { Output.log("Failed to decode CodeActionParams!\n"); return; } Callbacks.onCodeAction(*CAP, ID, Output); } private: ProtocolCallbacks &Callbacks; }; struct CompletionHandler : Handler { CompletionHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { auto TDPP = TextDocumentPositionParams::parse(Params, Output); if (!TDPP) { Output.log("Failed to decode TextDocumentPositionParams!\n"); return; } Callbacks.onCompletion(*TDPP, ID, Output); } private: ProtocolCallbacks &Callbacks; }; struct GotoDefinitionHandler : Handler { GotoDefinitionHandler(JSONOutput &Output, ProtocolCallbacks &Callbacks) : Handler(Output), Callbacks(Callbacks) {} void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override { auto TDPP = TextDocumentPositionParams::parse(Params, Output); if (!TDPP) { Output.log("Failed to decode TextDocumentPositionParams!\n"); return; } Callbacks.onGoToDefinition(*TDPP, ID, Output); } private: ProtocolCallbacks &Callbacks; }; } // namespace void clangd::regiterCallbackHandlers(JSONRPCDispatcher &Dispatcher, JSONOutput &Out, ProtocolCallbacks &Callbacks) { Dispatcher.registerHandler( "initialize", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "shutdown", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/didOpen", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/didClose", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/didChange", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/rangeFormatting", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/onTypeFormatting", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/formatting", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/codeAction", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/completion", llvm::make_unique(Out, Callbacks)); Dispatcher.registerHandler( "textDocument/definition", llvm::make_unique(Out, Callbacks)); }