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(ResponseHandlersMutex);
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.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
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.
LLVM_ABI_FOR_TEST void reply(llvm::json::Value Id, llvm::Expected< llvm::json::Value > Result)
LLVM_ABI_FOR_TEST llvm::Error run(MessageHandler &Handler)
Start executing the JSON-RPC transport.
LLVM_ABI_FOR_TEST void notify(StringRef Method, llvm::json::Value Params)
The following methods are used to send a message to the LSP client.
LLVM_ABI_FOR_TEST 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.