1212#include " JSONUtils.h"
1313#include " LLDBUtils.h"
1414#include " OutputRedirector.h"
15+ #include " Transport.h"
1516#include " lldb/API/SBBreakpoint.h"
1617#include " lldb/API/SBCommandInterpreter.h"
1718#include " lldb/API/SBCommandReturnObject.h"
@@ -63,11 +64,10 @@ const char DEV_NULL[] = "/dev/null";
6364
6465namespace lldb_dap {
6566
66- DAP::DAP (llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
67- lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
68- std::vector<std::string> pre_init_commands)
69- : client_name(client_name), debug_adapter_path(path), log(log),
70- input (std::move(input)), output(std::move(output)),
67+ DAP::DAP (llvm::StringRef path, std::ofstream *log,
68+ const ReplMode default_repl_mode,
69+ std::vector<std::string> pre_init_commands, Transport &transport)
70+ : debug_adapter_path(path), log(log), transport(transport),
7171 broadcaster (" lldb-dap" ), exception_breakpoints(),
7272 pre_init_commands(std::move(pre_init_commands)),
7373 focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false ), is_attach(false ),
@@ -78,7 +78,7 @@ DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
7878 configuration_done_sent(false ), waiting_for_run_in_terminal(false ),
7979 progress_event_reporter(
8080 [&](const ProgressEvent &event) { SendJSON (event.ToJSON ()); }),
81- reverse_request_seq (0 ), repl_mode(repl_mode ) {}
81+ reverse_request_seq (0 ), repl_mode(default_repl_mode ) {}
8282
8383DAP::~DAP () = default ;
8484
@@ -221,52 +221,21 @@ void DAP::StopEventHandlers() {
221221 }
222222}
223223
224- // Send the JSON in "json_str" to the "out" stream. Correctly send the
225- // "Content-Length:" field followed by the length, followed by the raw
226- // JSON bytes.
227- void DAP::SendJSON (const std::string &json_str) {
228- output.write_full (" Content-Length: " );
229- output.write_full (llvm::utostr (json_str.size ()));
230- output.write_full (" \r\n\r\n " );
231- output.write_full (json_str);
232- }
233-
234224// Serialize the JSON value into a string and send the JSON packet to
235225// the "out" stream.
236226void DAP::SendJSON (const llvm::json::Value &json) {
237- std::string json_str;
238- llvm::raw_string_ostream strm (json_str);
239- strm << json;
240- static std::mutex mutex;
241- std::lock_guard<std::mutex> locker (mutex);
242- SendJSON (json_str);
243-
244- DAP_LOG (log, " ({0}) <-- {1}" , client_name, json_str);
245- }
246-
247- // Read a JSON packet from the "in" stream.
248- std::string DAP::ReadJSON () {
249- std::string length_str;
250- std::string json_str;
251- int length;
252-
253- if (!input.read_expected (log, " Content-Length: " ))
254- return json_str;
255-
256- if (!input.read_line (log, length_str))
257- return json_str;
258-
259- if (!llvm::to_integer (length_str, length))
260- return json_str;
261-
262- if (!input.read_expected (log, " \r\n " ))
263- return json_str;
264-
265- if (!input.read_full (log, length, json_str))
266- return json_str;
267-
268- DAP_LOG (log, " ({0}) --> {1}" , client_name, json_str);
269- return json_str;
227+ // FIXME: Instead of parsing the output message from JSON, pass the `Message`
228+ // as parameter to `SendJSON`.
229+ protocol::Message message;
230+ llvm::json::Path::Root root;
231+ if (!fromJSON (json, message, root)) {
232+ DAP_LOG_ERROR (log, root.getError (), " ({1}) encoding failed: {0}" ,
233+ transport.GetClientName ());
234+ return ;
235+ }
236+ if (llvm::Error err = transport.Write (message))
237+ DAP_LOG_ERROR (log, std::move (err), " ({1}) write failed: {0}" ,
238+ transport.GetClientName ());
270239}
271240
272241// "OutputEvent": {
@@ -693,29 +662,10 @@ void DAP::SetTarget(const lldb::SBTarget target) {
693662 }
694663}
695664
696- PacketStatus DAP::GetNextObject (llvm::json::Object &object) {
697- std::string json = ReadJSON ();
698- if (json.empty ())
699- return PacketStatus::EndOfFile;
700-
701- llvm::StringRef json_sref (json);
702- llvm::Expected<llvm::json::Value> json_value = llvm::json::parse (json_sref);
703- if (!json_value) {
704- DAP_LOG_ERROR (log, json_value.takeError (),
705- " ({1}) failed to parse JSON: {0}" , client_name);
706- return PacketStatus::JSONMalformed;
707- }
708-
709- llvm::json::Object *object_ptr = json_value->getAsObject ();
710- if (!object_ptr) {
711- DAP_LOG (log, " ({0}) error: json packet isn't a object" , client_name);
712- return PacketStatus::JSONNotObject;
713- }
714- object = *object_ptr;
715- return PacketStatus::Success;
716- }
717-
718- bool DAP::HandleObject (const llvm::json::Object &object) {
665+ 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 ();
719669 const auto packet_type = GetString (object, " type" );
720670 if (packet_type == " request" ) {
721671 const auto command = GetString (object, " command" );
@@ -726,7 +676,8 @@ bool DAP::HandleObject(const llvm::json::Object &object) {
726676 return true ; // Success
727677 }
728678
729- DAP_LOG (log, " ({0}) error: unhandled command '{1}'" , client_name, command);
679+ DAP_LOG (log, " ({0}) error: unhandled command '{1}'" ,
680+ transport.GetClientName (), command);
730681 return false ; // Fail
731682 }
732683
@@ -749,9 +700,8 @@ bool DAP::HandleObject(const llvm::json::Object &object) {
749700 // Result should be given, use null if not.
750701 if (GetBoolean (object, " success" ).value_or (false )) {
751702 llvm::json::Value Result = nullptr ;
752- if (auto *B = object.get (" body" )) {
703+ if (auto *B = object.get (" body" ))
753704 Result = std::move (*B);
754- }
755705 (*response_handler)(Result);
756706 } else {
757707 llvm::StringRef message = GetString (object, " message" );
@@ -818,19 +768,15 @@ llvm::Error DAP::Loop() {
818768 StopEventHandlers ();
819769 });
820770 while (!disconnecting) {
821- llvm::json::Object object;
822- lldb_dap::PacketStatus status = GetNextObject (object);
771+ llvm::Expected<std::optional<protocol::Message>> next = transport.Read ();
772+ if (!next)
773+ return next.takeError ();
823774
824- if (status == lldb_dap::PacketStatus::EndOfFile) {
775+ // nullopt on EOF
776+ if (!*next)
825777 break ;
826- }
827-
828- if (status != lldb_dap::PacketStatus::Success) {
829- return llvm::createStringError (llvm::inconvertibleErrorCode (),
830- " failed to send packet" );
831- }
832778
833- if (!HandleObject (object )) {
779+ if (!HandleObject (**next )) {
834780 return llvm::createStringError (llvm::inconvertibleErrorCode (),
835781 " unhandled packet" );
836782 }
0 commit comments