|
12 | 12 | #include "JSONUtils.h"
|
13 | 13 | #include "LLDBUtils.h"
|
14 | 14 | #include "OutputRedirector.h"
|
| 15 | +#include "Transport.h" |
15 | 16 | #include "lldb/API/SBBreakpoint.h"
|
16 | 17 | #include "lldb/API/SBCommandInterpreter.h"
|
17 | 18 | #include "lldb/API/SBCommandReturnObject.h"
|
@@ -67,7 +68,7 @@ DAP::DAP(llvm::StringRef client_name, llvm::StringRef path, std::ofstream *log,
|
67 | 68 | lldb::IOObjectSP input, lldb::IOObjectSP output, ReplMode repl_mode,
|
68 | 69 | std::vector<std::string> pre_init_commands)
|
69 | 70 | : client_name(client_name), debug_adapter_path(path), log(log),
|
70 |
| - input(std::move(input)), output(std::move(output)), |
| 71 | + transport(client_name, std::move(input), std::move(output)), |
71 | 72 | broadcaster("lldb-dap"), exception_breakpoints(),
|
72 | 73 | pre_init_commands(std::move(pre_init_commands)),
|
73 | 74 | focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false),
|
@@ -221,52 +222,27 @@ void DAP::StopEventHandlers() {
|
221 | 222 | }
|
222 | 223 | }
|
223 | 224 |
|
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 |
| - |
234 | 225 | // Serialize the JSON value into a string and send the JSON packet to
|
235 | 226 | // the "out" stream.
|
236 | 227 | void 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; |
| 228 | + // FIXME: Instead of parsing the output message from JSON, pass the `Message` |
| 229 | + // as parameter to `SendJSON`. |
| 230 | + protocol::Message M; |
| 231 | + llvm::json::Path::Root root; |
| 232 | + if (!protocol::fromJSON(json, M, root)) { |
| 233 | + if (log) { |
| 234 | + std::string error; |
| 235 | + llvm::raw_string_ostream OS(error); |
| 236 | + root.printErrorContext(json, OS); |
| 237 | + *log << "encoding failure: " << error << "\n"; |
| 238 | + } |
| 239 | + return; |
| 240 | + } |
| 241 | + auto status = transport.Write(log, M); |
| 242 | + if (status.Fail() && log) |
| 243 | + *log << llvm::formatv("failed to send {0}: {1}\n", llvm::json::Value(M), |
| 244 | + status.AsCString()) |
| 245 | + .str(); |
270 | 246 | }
|
271 | 247 |
|
272 | 248 | // "OutputEvent": {
|
@@ -693,29 +669,10 @@ void DAP::SetTarget(const lldb::SBTarget target) {
|
693 | 669 | }
|
694 | 670 | }
|
695 | 671 |
|
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) { |
| 672 | +bool DAP::HandleObject(const protocol::Message &M) { |
| 673 | + // FIXME: Directly handle `Message` instead of serializing to JSON. |
| 674 | + llvm::json::Value v = toJSON(M); |
| 675 | + llvm::json::Object object = *v.getAsObject(); |
719 | 676 | const auto packet_type = GetString(object, "type");
|
720 | 677 | if (packet_type == "request") {
|
721 | 678 | const auto command = GetString(object, "command");
|
@@ -818,19 +775,16 @@ llvm::Error DAP::Loop() {
|
818 | 775 | StopEventHandlers();
|
819 | 776 | });
|
820 | 777 | while (!disconnecting) {
|
821 |
| - llvm::json::Object object; |
822 |
| - lldb_dap::PacketStatus status = GetNextObject(object); |
823 |
| - |
824 |
| - if (status == lldb_dap::PacketStatus::EndOfFile) { |
825 |
| - break; |
826 |
| - } |
827 |
| - |
828 |
| - if (status != lldb_dap::PacketStatus::Success) { |
829 |
| - return llvm::createStringError(llvm::inconvertibleErrorCode(), |
830 |
| - "failed to send packet"); |
| 778 | + auto next = transport.Read(log); |
| 779 | + if (auto Err = next.takeError()) { |
| 780 | + // On EOF, simply break out of the loop. |
| 781 | + std::error_code ec = llvm::errorToErrorCode(std::move(Err)); |
| 782 | + if (ec == Transport::kEOF) |
| 783 | + break; |
| 784 | + return llvm::errorCodeToError(ec); |
831 | 785 | }
|
832 | 786 |
|
833 |
| - if (!HandleObject(object)) { |
| 787 | + if (!HandleObject(*next)) { |
834 | 788 | return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
835 | 789 | "unhandled packet");
|
836 | 790 | }
|
|
0 commit comments