Skip to content

Commit f26c9a7

Browse files
committed
[lldb-dap] Updating RequestHandler to encode/decode arguments and response.
This is a work in progress refactor to add explicit types instead of generic 'llvm::json::Value' types to the DAP protocol. This updates RequestHandler to have take the type of the arguments and response body for serialization for requests. The 'source' request is updated to show how the new flow works.
1 parent 5929de8 commit f26c9a7

File tree

8 files changed

+381
-186
lines changed

8 files changed

+381
-186
lines changed

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88

99
#include "DAP.h"
1010
#include "DAPLog.h"
11+
#include "Handler/RequestHandler.h"
1112
#include "Handler/ResponseHandler.h"
1213
#include "JSONUtils.h"
1314
#include "LLDBUtils.h"
1415
#include "OutputRedirector.h"
16+
#include "Protocol.h"
1517
#include "Transport.h"
1618
#include "lldb/API/SBBreakpoint.h"
1719
#include "lldb/API/SBCommandInterpreter.h"
@@ -25,6 +27,7 @@
2527
#include "lldb/lldb-defines.h"
2628
#include "lldb/lldb-enumerations.h"
2729
#include "llvm/ADT/ArrayRef.h"
30+
#include "llvm/ADT/STLExtras.h"
2831
#include "llvm/ADT/ScopeExit.h"
2932
#include "llvm/ADT/StringExtras.h"
3033
#include "llvm/ADT/StringRef.h"
@@ -41,6 +44,7 @@
4144
#include <fstream>
4245
#include <memory>
4346
#include <mutex>
47+
#include <string>
4448
#include <utility>
4549

4650
#if defined(_WIN32)
@@ -663,58 +667,65 @@ void DAP::SetTarget(const lldb::SBTarget target) {
663667
}
664668

665669
bool DAP::HandleObject(const protocol::Message &M) {
666-
// FIXME: Directly handle `Message` instead of serializing to JSON.
667-
llvm::json::Value v = toJSON(M);
668-
llvm::json::Object object = *v.getAsObject();
669-
const auto packet_type = GetString(object, "type");
670-
if (packet_type == "request") {
671-
const auto command = GetString(object, "command");
672-
673-
auto new_handler_pos = request_handlers.find(command);
670+
if (const auto *req = std::get_if<protocol::Request>(&M)) {
671+
auto new_handler_pos = request_handlers.find(req->command);
674672
if (new_handler_pos != request_handlers.end()) {
675-
(*new_handler_pos->second)(object);
673+
(*new_handler_pos->second)(*req);
676674
return true; // Success
677675
}
678676

679677
DAP_LOG(log, "({0}) error: unhandled command '{1}'",
680-
transport.GetClientName(), command);
678+
transport.GetClientName(), req->command);
681679
return false; // Fail
682680
}
683681

684-
if (packet_type == "response") {
685-
auto id = GetInteger<int64_t>(object, "request_seq").value_or(0);
686-
682+
if (const auto *resp = std::get_if<protocol::Response>(&M)) {
687683
std::unique_ptr<ResponseHandler> response_handler;
688684
{
689685
std::lock_guard<std::mutex> locker(call_mutex);
690-
auto inflight = inflight_reverse_requests.find(id);
686+
auto inflight = inflight_reverse_requests.find(resp->request_seq);
691687
if (inflight != inflight_reverse_requests.end()) {
692688
response_handler = std::move(inflight->second);
693689
inflight_reverse_requests.erase(inflight);
694690
}
695691
}
696692

697693
if (!response_handler)
698-
response_handler = std::make_unique<UnknownResponseHandler>("", id);
694+
response_handler =
695+
std::make_unique<UnknownResponseHandler>("", resp->request_seq);
699696

700697
// Result should be given, use null if not.
701-
if (GetBoolean(object, "success").value_or(false)) {
702-
llvm::json::Value Result = nullptr;
703-
if (auto *B = object.get("body"))
704-
Result = std::move(*B);
705-
(*response_handler)(Result);
698+
if (resp->success) {
699+
(*response_handler)(resp->rawBody);
706700
} else {
707-
llvm::StringRef message = GetString(object, "message");
708-
if (message.empty()) {
709-
message = "Unknown error, response failed";
701+
std::string message = "Unknown error, response failed";
702+
if (resp->message) {
703+
message = std::visit(
704+
llvm::makeVisitor(
705+
[](const std::string &message) -> std::string {
706+
return message;
707+
},
708+
[](const protocol::Response::Message &message) -> std::string {
709+
switch (message) {
710+
case protocol::Response::Message::cancelled:
711+
return "cancelled";
712+
case protocol::Response::Message::notStopped:
713+
return "notStopped";
714+
}
715+
}),
716+
*resp->message);
710717
}
718+
711719
(*response_handler)(llvm::createStringError(
712720
std::error_code(-1, std::generic_category()), message));
713721
}
714722

715723
return true;
716724
}
717725

726+
if (log)
727+
*log << "Unsupported protocol message" << std::endl;
728+
718729
return false;
719730
}
720731

lldb/tools/lldb-dap/DAP.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
#include "DAPForward.h"
1313
#include "ExceptionBreakpoint.h"
1414
#include "FunctionBreakpoint.h"
15-
#include "Handler/RequestHandler.h"
16-
#include "Handler/ResponseHandler.h"
1715
#include "InstructionBreakpoint.h"
1816
#include "OutputRedirector.h"
1917
#include "ProgressEvent.h"
@@ -187,7 +185,7 @@ struct DAP {
187185
// the old process here so we can detect this case and keep running.
188186
lldb::pid_t restarting_process_id;
189187
bool configuration_done_sent;
190-
llvm::StringMap<std::unique_ptr<RequestHandler>> request_handlers;
188+
llvm::StringMap<std::unique_ptr<BaseRequestHandler>> request_handlers;
191189
bool waiting_for_run_in_terminal;
192190
ProgressEventReporter progress_event_reporter;
193191
// Keep track of the last stop thread index IDs as threads won't go away

lldb/tools/lldb-dap/DAPForward.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ struct SourceBreakpoint;
1919
struct Watchpoint;
2020
struct InstructionBreakpoint;
2121
struct DAP;
22+
class BaseRequestHandler;
23+
class ResponseHandler;
2224
} // namespace lldb_dap
2325

2426
namespace lldb {

lldb/tools/lldb-dap/Handler/RequestHandler.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "RequestHandler.h"
9+
#include "Handler/RequestHandler.h"
1010
#include "DAP.h"
11+
#include "Handler/ResponseHandler.h"
1112
#include "JSONUtils.h"
1213
#include "LLDBUtils.h"
1314
#include "RunInTerminal.h"
@@ -45,7 +46,7 @@ static uint32_t SetLaunchFlag(uint32_t flags, const llvm::json::Object *obj,
4546

4647
// Both attach and launch take either a sourcePath or a sourceMap
4748
// argument (or neither), from which we need to set the target.source-map.
48-
void RequestHandler::SetSourceMapFromArguments(
49+
void BaseRequestHandler::SetSourceMapFromArguments(
4950
const llvm::json::Object &arguments) const {
5051
const char *sourceMapHelp =
5152
"source must be be an array of two-element arrays, "
@@ -159,7 +160,7 @@ static llvm::Error RunInTerminal(DAP &dap,
159160
}
160161

161162
lldb::SBError
162-
RequestHandler::LaunchProcess(const llvm::json::Object &request) const {
163+
BaseRequestHandler::LaunchProcess(const llvm::json::Object &request) const {
163164
lldb::SBError error;
164165
const auto *arguments = request.getObject("arguments");
165166
auto launchCommands = GetStrings(arguments, "launchCommands");
@@ -228,13 +229,13 @@ RequestHandler::LaunchProcess(const llvm::json::Object &request) const {
228229
return error;
229230
}
230231

231-
void RequestHandler::PrintWelcomeMessage() const {
232+
void BaseRequestHandler::PrintWelcomeMessage() const {
232233
#ifdef LLDB_DAP_WELCOME_MESSAGE
233234
dap.SendOutput(OutputType::Console, LLDB_DAP_WELCOME_MESSAGE);
234235
#endif
235236
}
236237

237-
bool RequestHandler::HasInstructionGranularity(
238+
bool BaseRequestHandler::HasInstructionGranularity(
238239
const llvm::json::Object &arguments) const {
239240
if (std::optional<llvm::StringRef> value = arguments.getString("granularity"))
240241
return value == "instruction";

0 commit comments

Comments
 (0)