16#include <system_error>
33 Reply(
const llvm::json::Value &Id, StringRef Method, JSONTransport &Transport,
34 std::mutex &TransportOutputMutex);
36 Reply &operator=(Reply &&) =
delete;
37 Reply(
const Reply &) =
delete;
38 Reply &operator=(
const Reply &) =
delete;
40 void operator()(llvm::Expected<llvm::json::Value> Reply);
44 std::atomic<bool> Replied = {
false};
46 JSONTransport *Transport;
47 std::mutex &TransportOutputMutex;
54 TransportOutputMutex(TransportOutputMutex) {}
56Reply::Reply(Reply &&
Other)
59 TransportOutputMutex(
Other.TransportOutputMutex) {
60 Other.Transport =
nullptr;
64 if (Replied.exchange(
true)) {
66 assert(
false &&
"must reply to each call only once!");
69 assert(Transport &&
"expected valid transport to reply to");
71 std::lock_guard<std::mutex> TransportLock(TransportOutputMutex);
74 Transport->
reply(std::move(Id), std::move(Reply));
78 Transport->
reply(std::move(Id), std::move(
Error));
94 auto It = NotificationHandlers.find(
Method);
95 if (It != NotificationHandlers.end())
96 It->second(std::move(
Value));
105 Reply Reply(Id,
Method, Transport, TransportOutputMutex);
107 auto It = MethodHandlers.find(
Method);
108 if (It != MethodHandlers.end()) {
109 It->second(std::move(Params), std::move(Reply));
121 ResponseHandlerTy ResponseHandler;
123 std::lock_guard<std::mutex> responseHandlersLock(ResponseHandlerTy);
125 if (It != ResponseHandlers.end()) {
126 ResponseHandler = std::move(It->second);
127 ResponseHandlers.erase(It);
132 if (ResponseHandler.second) {
133 Logger::info(
"--> reply:{0}({1})", ResponseHandler.first, Id);
134 ResponseHandler.second(std::move(Id), std::move(Result));
137 "received a reply with ID {0}, but there was no such outgoing request",
154 Message = LspError.message;
155 Code = LspError.code;
162 {
"message", std::move(Message)},
163 {
"code", int64_t(Code)},
169 StringRef Msg = O.getString(
"message").value_or(
"Unspecified error");
170 if (std::optional<int64_t> Code = O.getInteger(
"code"))
180 {
"params", std::move(Params)},
187 {
"id", std::move(Id)},
189 {
"params", std::move(Params)},
197 {
"id", std::move(Id)},
198 {
"result", std::move(*Result)},
204 {
"id", std::move(Id)},
211 while (!In->isEndOfInput()) {
212 if (In->hasError()) {
214 std::error_code(errno, std::system_category()));
219 if (!handleMessage(std::move(*Doc), Handler))
233 Out <<
"Content-Length: " <<
OutputBuffer.size() <<
"\r\n\r\n"
244 Object->getString(
"jsonrpc") != std::optional<StringRef>(
"2.0"))
248 std::optional<llvm::json::Value> Id;
251 std::optional<StringRef>
Method =
Object->getString(
"method");
257 if (
auto *Err =
Object->getObject(
"error"))
262 Result = std::move(*R);
263 return Handler.
onReply(std::move(*Id), std::move(Result));
269 Params = std::move(*
P);
272 return Handler.
onCall(*
Method, std::move(Params), std::move(*Id));
281 static constexpr int BufSize = 128;
286 if (!std::fgets(&Out[
Size], BufSize, In))
293 size_t Read = std::strlen(&Out[
Size]);
309 unsigned long long ContentLength = 0;
329 if (ContentLength == 0 || ContentLength > 1 << 30)
332 Json.resize(ContentLength);
333 for (
size_t Pos = 0,
Read; Pos < ContentLength; Pos +=
Read) {
334 Read = std::fread(&Json[Pos], 1, ContentLength - Pos, In);
360 if (LineRef ==
"// -----")
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Mark last scratch load
This file defines the SmallString class.
static llvm::json::Object encodeError(llvm::Error Error)
Encode the given error as a JSON object.
LogicalResult readLine(std::FILE *In, SmallVectorImpl< char > &Out)
Tries to read a line up to and including .
llvm::Error decodeError(const llvm::json::Object &O)
Decode the given JSON object into an error.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
An Object is a JSON object, which maps strings to heterogenous JSON values.
A Value is an JSON value of unknown type.
const json::Object * getAsObject() const
A transport class that performs the JSON-RPC communication with the LSP client.
void reply(llvm::json::Value Id, llvm::Expected< llvm::json::Value > Result)
llvm::Error run(MessageHandler &Handler)
Start executing the JSON-RPC transport.
void notify(StringRef Method, llvm::json::Value Params)
The following methods are used to send a message to the LSP client.
void call(StringRef Method, llvm::json::Value Params, llvm::json::Value Id)
This class models an LSP error as an llvm::Error.
static void error(const char *Fmt, Ts &&...Vals)
static void debug(const char *Fmt, Ts &&...Vals)
Initiate a log message at various severity levels.
static void info(const char *Fmt, Ts &&...Vals)
A handler used to process the incoming transport messages.
bool onNotify(StringRef Method, llvm::json::Value Value)
bool onCall(StringRef Method, llvm::json::Value Params, llvm::json::Value Id)
bool onReply(llvm::json::Value Id, llvm::Expected< llvm::json::Value > Result)
A raw_ostream that writes to an SmallVector or SmallString.
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
This is an optimization pass for GlobalISel generic memory operations.
bool succeeded(LogicalResult Result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
bool failed(LogicalResult Result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
LogicalResult failure(bool IsFailure=true)
Utility function to generate a LogicalResult.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
static std::string debugString(T &&Op)
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
void consumeError(Error Err)
Consume a Error without doing anything.
Implement std::hash so that hash_code can be used in STL containers.
This class represents an efficient way to signal success or failure.