nixd
Loading...
Searching...
No Matches
LSPServer.h
Go to the documentation of this file.
1#pragma once
2
6
7#include <llvm/ADT/StringRef.h>
8#include <llvm/Support/Error.h>
9#include <llvm/Support/JSON.h>
10
11#include <memory>
12
13namespace lspserver {
14
15/// LSPServer wraps inputs & outputs, associate message IDs between calls/reply,
16/// and provide type-safe interfaces.
17class LSPServer : public MessageHandler {
18private:
19 std::unique_ptr<InboundPort> In;
20 std::unique_ptr<OutboundPort> Out;
21
22 bool onNotify(llvm::StringRef Method, llvm::json::Value) override;
23 bool onCall(llvm::StringRef Method, llvm::json::Value Params,
24 llvm::json::Value ID) override;
25 bool onReply(llvm::json::Value ID,
26 llvm::Expected<llvm::json::Value> Result) override;
27
28 std::mutex PendingCallsLock;
29
30 /// Calls to the client sent, and waiting for the response.
31 /// The callback function will be invoked when we get the result.
32 ///
33 /// If the call has no response for a long time, it should be removed and
34 /// associated an error.
35 std::map<int, Callback<llvm::json::Value>> PendingCalls;
36
37 /// Number of maximum callbacks stored in the structure.
38 /// Give an error to the oldest callback (least ID) while exceeding this
39 /// value.
40 static constexpr int MaxPendingCalls = 100;
41
42 int TopID = 1;
43
44 /// Allocate an "ID" (as returned value) for this callback.
45 int bindReply(Callback<llvm::json::Value>);
46
47 void callMethod(llvm::StringRef Method, llvm::json::Value Params,
49 llvm::json::Value ID(bindReply(std::move(CB)));
50 log("--> call {0}({1})", Method, ID.getAsInteger());
51 O->call(Method, Params, ID);
52 }
53
54protected:
56 template <class T>
57 llvm::unique_function<void(const T &)>
58 mkOutNotifiction(llvm::StringRef Method, OutboundPort *O = nullptr) {
59 if (!O)
60 O = Out.get();
61 return [=](const T &Params) {
62 log("--> notify {0}", Method);
63 O->notify(Method, Params);
64 };
65 }
66
67 template <class ParamTy, class ResponseTy>
68 llvm::unique_function<void(const ParamTy &, Callback<ResponseTy>)>
69 mkOutMethod(llvm::StringRef Method, OutboundPort *O = nullptr) {
70 if (!O)
71 O = Out.get();
72 return [=, this](const ParamTy &Params, Callback<ResponseTy> Reply) {
73 callMethod(
75 [=, Reply = std::move(Reply)](
76 llvm::Expected<llvm::json::Value> Response) mutable {
77 if (!Response)
78 return Reply(Response.takeError());
79 Reply(
80 parseParam<ResponseTy>(std::move(*Response), Method, "reply"));
81 },
82 O);
83 };
84 }
85
86public:
87 LSPServer(std::unique_ptr<InboundPort> In, std::unique_ptr<OutboundPort> Out)
88 : In(std::move(In)), Out(std::move(Out)){};
89
90 /// \brief Close the inbound port.
91 void closeInbound() { In->close(); }
92 void run();
93
94 void switchStreamStyle(JSONStreamStyle Style) { In->StreamStyle = Style; }
95};
96
97} // namespace lspserver
HandlerRegistry Registry
Definition LSPServer.h:55
LSPServer(std::unique_ptr< InboundPort > In, std::unique_ptr< OutboundPort > Out)
Definition LSPServer.h:87
llvm::unique_function< void(const ParamTy &, Callback< ResponseTy >) mkOutMethod)(llvm::StringRef Method, OutboundPort *O=nullptr)
Definition LSPServer.h:69
void closeInbound()
Close the inbound port.
Definition LSPServer.h:91
void switchStreamStyle(JSONStreamStyle Style)
Definition LSPServer.h:94
llvm::unique_function< void(const T &) mkOutNotifiction)(llvm::StringRef Method, OutboundPort *O=nullptr)
Definition LSPServer.h:58
void notify(llvm::StringRef Method, llvm::json::Value Params)
void call(llvm::StringRef Method, llvm::json::Value Params, llvm::json::Value ID)
Whether current platform treats paths case insensitively.
Definition Connection.h:11
llvm::unique_function< void(llvm::Expected< T >)> Callback
Definition Function.h:14
bool fromJSON(const llvm::json::Value &, URIForFile &, llvm::json::Path)
void log(const char *Fmt, Ts &&...Vals)
Definition Logger.h:58