Skip to content

Commit 72956b9

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 2283694 commit 72956b9

File tree

8 files changed

+375
-186
lines changed

8 files changed

+375
-186
lines changed

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "DAP.h"
10+
#include "Handler/RequestHandler.h"
1011
#include "Handler/ResponseHandler.h"
1112
#include "JSONUtils.h"
1213
#include "LLDBUtils.h"
@@ -24,6 +25,7 @@
2425
#include "lldb/lldb-defines.h"
2526
#include "lldb/lldb-enumerations.h"
2627
#include "llvm/ADT/ArrayRef.h"
28+
#include "llvm/ADT/STLExtras.h"
2729
#include "llvm/ADT/ScopeExit.h"
2830
#include "llvm/ADT/StringExtras.h"
2931
#include "llvm/ADT/Twine.h"
@@ -39,6 +41,7 @@
3941
#include <fstream>
4042
#include <memory>
4143
#include <mutex>
44+
#include <string>
4245
#include <utility>
4346

4447
#if defined(_WIN32)
@@ -684,59 +687,61 @@ void DAP::SetTarget(const lldb::SBTarget target) {
684687
}
685688

686689
bool DAP::HandleObject(const protocol::Message &M) {
687-
llvm::json::Value v = toJSON(M);
688-
llvm::json::Object object = *v.getAsObject();
689-
const auto packet_type = GetString(object, "type");
690-
if (packet_type == "request") {
691-
const auto command = GetString(object, "command");
692-
693-
auto new_handler_pos = request_handlers.find(command);
690+
if (const auto *req = std::get_if<protocol::Request>(&M)) {
691+
auto new_handler_pos = request_handlers.find(req->command);
694692
if (new_handler_pos != request_handlers.end()) {
695-
(*new_handler_pos->second)(object);
693+
(*new_handler_pos->second)(*req);
696694
return true; // Success
697695
}
698696

699697
if (log)
700-
*log << "error: unhandled command \"" << command.data() << "\""
698+
*log << "error: unhandled command \"" << req->command << "\""
701699
<< std::endl;
702700
return false; // Fail
703701
}
704702

705-
if (packet_type == "response") {
706-
auto id = GetInteger<int64_t>(object, "request_seq").value_or(0);
707-
703+
if (const auto *resp = std::get_if<protocol::Response>(&M)) {
708704
std::unique_ptr<ResponseHandler> response_handler;
709705
{
710706
std::lock_guard<std::mutex> locker(call_mutex);
711-
auto inflight = inflight_reverse_requests.find(id);
707+
auto inflight = inflight_reverse_requests.find(resp->request_seq);
712708
if (inflight != inflight_reverse_requests.end()) {
713709
response_handler = std::move(inflight->second);
714710
inflight_reverse_requests.erase(inflight);
715711
}
716712
}
717713

718714
if (!response_handler)
719-
response_handler = std::make_unique<UnknownResponseHandler>("", id);
715+
response_handler =
716+
std::make_unique<UnknownResponseHandler>("", resp->request_seq);
720717

721718
// Result should be given, use null if not.
722-
if (GetBoolean(object, "success").value_or(false)) {
723-
llvm::json::Value Result = nullptr;
724-
if (auto *B = object.get("body")) {
725-
Result = std::move(*B);
726-
}
727-
(*response_handler)(Result);
719+
if (resp->success) {
720+
(*response_handler)(resp->rawBody);
728721
} else {
729-
llvm::StringRef message = GetString(object, "message");
730-
if (message.empty()) {
731-
message = "Unknown error, response failed";
722+
std::string message = "Unknown error, response failed";
723+
if (resp->message) {
724+
message = std::visit(
725+
llvm::makeVisitor(
726+
[](const std::string &message) -> std::string {
727+
return message;
728+
},
729+
[](const protocol::Response::Message &message) -> std::string {
730+
return "hi";
731+
}),
732+
*resp->message);
732733
}
734+
733735
(*response_handler)(llvm::createStringError(
734736
std::error_code(-1, std::generic_category()), message));
735737
}
736738

737739
return true;
738740
}
739741

742+
if (log)
743+
*log << "Unsupported protocol message" << std::endl;
744+
740745
return false;
741746
}
742747

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"
@@ -188,7 +186,7 @@ struct DAP {
188186
// the old process here so we can detect this case and keep running.
189187
lldb::pid_t restarting_process_id;
190188
bool configuration_done_sent;
191-
llvm::StringMap<std::unique_ptr<RequestHandler>> request_handlers;
189+
llvm::StringMap<std::unique_ptr<BaseRequestHandler>> request_handlers;
192190
bool waiting_for_run_in_terminal;
193191
ProgressEventReporter progress_event_reporter;
194192
// 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)