5#include <llvm/ADT/FunctionExtras.h>
6#include <llvm/Support/Compiler.h>
7#include <llvm/Support/Error.h>
8#include <llvm/Support/JSON.h>
17bool LSPServer::onNotify(llvm::StringRef
Method, llvm::json::Value Params) {
23 Handler->second(std::move(Params));
25 log(
"unhandled notification {0}",
Method);
30bool LSPServer::onCall(llvm::StringRef
Method, llvm::json::Value Params,
31 llvm::json::Value ID) {
35 Handler->second(std::move(Params),
37 this](llvm::Expected<llvm::json::Value> Response)
mutable {
40 Out->reply(std::move(ID), std::move(Response));
42 llvm::Error Err = Response.takeError();
43 log(
"--> reply:{0}({1}) {2:ms}, error: {3}",
Method, ID,
45 Out->reply(std::move(ID), std::move(Err));
53bool LSPServer::onReply(llvm::json::Value ID,
54 llvm::Expected<llvm::json::Value> Result) {
55 log(
"<-- reply({0})", ID);
56 std::optional<Callback<llvm::json::Value>> CB;
58 if (
auto OptI = ID.getAsInteger()) {
59 if (LLVM_UNLIKELY(*OptI > INT_MAX))
60 throw std::logic_error(
"jsonrpc: id is too large (> INT_MAX)");
61 std::lock_guard<std::mutex> Guard(PendingCallsLock);
62 auto I =
static_cast<int>(*OptI);
63 if (PendingCalls.contains(I)) {
64 CB = std::move(PendingCalls[I]);
65 PendingCalls.erase(I);
68 throw std::logic_error(
"jsonrpc: not an integer message ID");
70 if (LLVM_UNLIKELY(!CB)) {
71 elog(
"received a reply with ID {0}, but there was no such call", ID);
77 (*CB)(std::move(Result));
82 std::lock_guard<std::mutex>
_(PendingCallsLock);
84 PendingCalls[Ret] = std::move(CB);
87 if (PendingCalls.size() > MaxPendingCalls) {
88 auto Begin = PendingCalls.begin();
89 auto [ID, OldestCallback] =
90 std::tuple{Begin->first, std::move(Begin->second)};
92 error(
"failed to receive a client reply for request ({0})", ID));
93 elog(
"more than {0} outstanding LSP calls, forgetting about {1}",
95 PendingCalls.erase(Begin);
Whether current platform treats paths case insensitively.
llvm::unique_function< void(llvm::Expected< T >)> Callback
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&...Vals)
void elog(const char *Fmt, Ts &&...Vals)
void log(const char *Fmt, Ts &&...Vals)
HandlerMap< void(JSON)> NotificationHandlers
HandlerMap< void(JSON, Callback< JSON >)> MethodHandlers