Skip to content

Commit 36d0fec

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 36d0fec

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
@@ -7,10 +7,12 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "DAP.h"
10+
#include "Handler/RequestHandler.h"
1011
#include "Handler/ResponseHandler.h"
1112
#include "JSONUtils.h"
1213
#include "LLDBUtils.h"
1314
#include "OutputRedirector.h"
15+
#include "Protocol.h"
1416
#include "Transport.h"
1517
#include "lldb/API/SBBreakpoint.h"
1618
#include "lldb/API/SBCommandInterpreter.h"
@@ -24,6 +26,7 @@
2426
#include "lldb/lldb-defines.h"
2527
#include "lldb/lldb-enumerations.h"
2628
#include "llvm/ADT/ArrayRef.h"
29+
#include "llvm/ADT/STLExtras.h"
2730
#include "llvm/ADT/ScopeExit.h"
2831
#include "llvm/ADT/StringExtras.h"
2932
#include "llvm/ADT/Twine.h"
@@ -39,6 +42,7 @@
3942
#include <fstream>
4043
#include <memory>
4144
#include <mutex>
45+
#include <string>
4246
#include <utility>
4347

4448
#if defined(_WIN32)
@@ -684,59 +688,66 @@ void DAP::SetTarget(const lldb::SBTarget target) {
684688
}
685689

686690
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);
691+
if (const auto *req = std::get_if<protocol::Request>(&M)) {
692+
auto new_handler_pos = request_handlers.find(req->command);
694693
if (new_handler_pos != request_handlers.end()) {
695-
(*new_handler_pos->second)(object);
694+
(*new_handler_pos->second)(*req);
696695
return true; // Success
697696
}
698697

699698
if (log)
700-
*log << "error: unhandled command \"" << command.data() << "\""
699+
*log << "error: unhandled command \"" << req->command << "\""
701700
<< std::endl;
702701
return false; // Fail
703702
}
704703

705-
if (packet_type == "response") {
706-
auto id = GetInteger<int64_t>(object, "request_seq").value_or(0);
707-
704+
if (const auto *resp = std::get_if<protocol::Response>(&M)) {
708705
std::unique_ptr<ResponseHandler> response_handler;
709706
{
710707
std::lock_guard<std::mutex> locker(call_mutex);
711-
auto inflight = inflight_reverse_requests.find(id);
708+
auto inflight = inflight_reverse_requests.find(resp->request_seq);
712709
if (inflight != inflight_reverse_requests.end()) {
713710
response_handler = std::move(inflight->second);
714711
inflight_reverse_requests.erase(inflight);
715712
}
716713
}
717714

718715
if (!response_handler)
719-
response_handler = std::make_unique<UnknownResponseHandler>("", id);
716+
response_handler =
717+
std::make_unique<UnknownResponseHandler>("", resp->request_seq);
720718

721719
// 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);
720+
if (resp->success) {
721+
(*response_handler)(resp->rawBody);
728722
} else {
729-
llvm::StringRef message = GetString(object, "message");
730-
if (message.empty()) {
731-
message = "Unknown error, response failed";
723+
std::string message = "Unknown error, response failed";
724+
if (resp->message) {
725+
message = std::visit(
726+
llvm::makeVisitor(
727+
[](const std::string &message) -> std::string {
728+
return message;
729+
},
730+
[](const protocol::Response::Message &message) -> std::string {
731+
switch (message) {
732+
case protocol::Response::Message::cancelled:
733+
return "cancelled";
734+
case protocol::Response::Message::notStopped:
735+
return "notStopped";
736+
}
737+
}),
738+
*resp->message);
732739
}
740+
733741
(*response_handler)(llvm::createStringError(
734742
std::error_code(-1, std::generic_category()), message));
735743
}
736744

737745
return true;
738746
}
739747

748+
if (log)
749+
*log << "Unsupported protocol message" << std::endl;
750+
740751
return false;
741752
}
742753

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)