12 #include "llvm/Support/Errno.h"
17 using namespace clang;
18 using namespace clangd;
22 json::Object encodeError(Error
E) {
29 return Error::success();
34 {
"message", std::move(
Message)},
35 {
"code", int64_t(
Code)},
39 Error decodeError(
const json::Object &O) {
41 std::string(O.getString(
"message").getValueOr(
"Unspecified error"));
42 if (
auto Code = O.getInteger(
"code"))
43 return make_error<LSPError>(std::move(Msg),
ErrorCode(*
Code));
44 return make_error<StringError>(std::move(Msg), inconvertibleErrorCode());
49 void connection_handler(xpc_connection_t clientConnection);
56 void notify(StringRef Method, json::Value Params)
override {
57 sendMessage(json::Object{
60 {
"params", std::move(Params)},
63 void call(StringRef Method, json::Value Params, json::Value ID)
override {
64 sendMessage(json::Object{
66 {
"id", std::move(ID)},
68 {
"params", std::move(Params)},
71 void reply(json::Value ID, Expected<json::Value> Result)
override {
73 sendMessage(json::Object{
75 {
"id", std::move(ID)},
76 {
"result", std::move(*Result)},
79 sendMessage(json::Object{
81 {
"id", std::move(ID)},
82 {
"error", encodeError(Result.takeError())},
87 Error loop(MessageHandler &Handler)
override;
91 friend void xpcClosure::connection_handler(xpc_connection_t clientConnection);
94 bool handleMessage(json::Value
Message, MessageHandler &Handler);
95 void sendMessage(json::Value
Message) {
97 xpc_connection_send_message(clientConnection, response);
98 xpc_release(response);
100 void resetClientConnection(xpc_connection_t newClientConnection) {
101 clientConnection = newClientConnection;
103 xpc_connection_t clientConnection;
106 bool XPCTransport::handleMessage(json::Value
Message, MessageHandler &Handler) {
109 if (!Object ||
Object->getString(
"jsonrpc") != Optional<StringRef>(
"2.0")) {
110 elog(
"Not a JSON-RPC 2.0 message: {0:2}",
Message);
114 Optional<json::Value> ID;
115 if (
auto *I =
Object->get(
"id"))
120 elog(
"No method and no response ID: {0:2}",
Message);
123 if (
auto *Err =
Object->getObject(
"error"))
124 return Handler.onReply(std::move(*ID), decodeError(*Err));
126 json::Value Result =
nullptr;
127 if (
auto *R =
Object->get(
"result"))
128 Result = std::move(*R);
129 return Handler.onReply(std::move(*ID), std::move(Result));
132 json::Value Params =
nullptr;
133 if (
auto *P =
Object->get(
"params"))
134 Params = std::move(*P);
137 return Handler.onCall(*Method, std::move(Params), std::move(*ID));
139 return Handler.onNotify(*Method, std::move(Params));
145 XPCTransport *TransportObject =
nullptr;
148 void connection_handler(xpc_connection_t clientConnection) {
149 xpc_connection_set_target_queue(clientConnection, dispatch_get_main_queue());
151 xpc_transaction_begin();
153 TransportObject->resetClientConnection(clientConnection);
155 xpc_connection_set_event_handler(clientConnection, ^(xpc_object_t message) {
156 if (message == XPC_ERROR_CONNECTION_INVALID) {
158 log(
"Received XPC_ERROR_CONNECTION_INVALID message - returning from the "
163 if (xpc_get_type(message) != XPC_TYPE_DICTIONARY) {
164 log(
"Received XPC message of unknown type - returning from the "
169 const json::Value Doc =
xpcToJson(message);
170 if (Doc == json::Value(
nullptr)) {
171 log(
"XPC message was converted to Null JSON message - returning from the "
176 vlog(
"<<< {0}\n", Doc);
178 if (!TransportObject->handleMessage(std::move(Doc), *HandlerPtr)) {
179 log(
"Received exit notification - cancelling connection.");
180 xpc_connection_cancel(xpc_dictionary_get_remote_connection(message));
181 xpc_transaction_end();
185 xpc_connection_resume(clientConnection);
189 Error XPCTransport::loop(MessageHandler &Handler) {
190 assert(xpcClosure::TransportObject ==
nullptr &&
191 "TransportObject has already been set.");
196 xpcClosure::TransportObject =
this;
198 assert(xpcClosure::HandlerPtr ==
nullptr &&
199 "HandlerPtr has already been set.");
200 xpcClosure::HandlerPtr = &Handler;
202 xpc_main(xpcClosure::connection_handler);
204 return errorCodeToError(std::make_error_code(std::errc::io_error));
213 return std::make_unique<XPCTransport>();