@@ -109,9 +109,10 @@ using OutgoingRequest =
109
109
110
110
// / An `OutgoingRequestCallback` is invoked when an outgoing request to the
111
111
// / client receives a response in turn. It is passed the original request's ID,
112
- // / as well as the result JSON.
112
+ // / as well as the response result.
113
+ template <typename T>
113
114
using OutgoingRequestCallback =
114
- std::function<void (llvm::json::Value, llvm::Expected<llvm::json::Value >)>;
115
+ std::function<void (llvm::json::Value, llvm::Expected<T >)>;
115
116
116
117
// / A handler used to process the incoming transport messages.
117
118
class MessageHandler {
@@ -185,21 +186,37 @@ class MessageHandler {
185
186
186
187
// / Create an OutgoingRequest function that, when called, sends a request with
187
188
// / the given method via the transport. Should the outgoing request be
188
- // / met with a response, the response callback is invoked to handle that
189
- // / response.
190
- template <typename T>
191
- OutgoingRequest<T> outgoingRequest (llvm::StringLiteral method,
192
- OutgoingRequestCallback callback) {
193
- return [&, method, callback](const T ¶ms, llvm::json::Value id) {
189
+ // / met with a response, the result JSON is parsed and the response callback
190
+ // / is invoked.
191
+ template <typename Param, typename Result>
192
+ OutgoingRequest<Param>
193
+ outgoingRequest (llvm::StringLiteral method,
194
+ OutgoingRequestCallback<Result> callback) {
195
+ return [&, method, callback](const Param ¶m, llvm::json::Value id) {
196
+ auto callbackWrapper = [method, callback = std::move (callback)](
197
+ llvm::json::Value id,
198
+ llvm::Expected<llvm::json::Value> value) {
199
+ if (!value)
200
+ return callback (std::move (id), value.takeError ());
201
+
202
+ std::string responseName = llvm::formatv (" reply:{0}({1})" , method, id);
203
+ llvm::Expected<Result> result =
204
+ parse<Result>(*value, responseName, " response" );
205
+ if (!result)
206
+ return callback (std::move (id), result.takeError ());
207
+
208
+ return callback (std::move (id), *result);
209
+ };
210
+
194
211
{
195
212
std::lock_guard<std::mutex> lock (responseHandlersMutex);
196
213
responseHandlers.insert (
197
- {debugString (id), std::make_pair (method.str (), callback )});
214
+ {debugString (id), std::make_pair (method.str (), callbackWrapper )});
198
215
}
199
216
200
217
std::lock_guard<std::mutex> transportLock (transportOutputMutex);
201
218
Logger::info (" --> {0}({1})" , method, id);
202
- transport.call (method, llvm::json::Value (params ), id);
219
+ transport.call (method, llvm::json::Value (param ), id);
203
220
};
204
221
}
205
222
@@ -213,7 +230,8 @@ class MessageHandler {
213
230
214
231
// / A pair of (1) the original request's method name, and (2) the callback
215
232
// / function to be invoked for responses.
216
- using ResponseHandlerTy = std::pair<std::string, OutgoingRequestCallback>;
233
+ using ResponseHandlerTy =
234
+ std::pair<std::string, OutgoingRequestCallback<llvm::json::Value>>;
217
235
// / A mapping from request/response ID to response handler.
218
236
llvm::StringMap<ResponseHandlerTy> responseHandlers;
219
237
// / Mutex to guard insertion into the response handler map.
0 commit comments