[Lldb-commits] [lldb] [lldb-dap] Creating well defined structures for DAP messages. (PR #129155)
Adrian Vogelsgesang via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 28 21:08:10 PST 2025
================
@@ -0,0 +1,231 @@
+//===-- Protocol.cpp ------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Protocol.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/JSON.h"
+#include <optional>
+#include <utility>
+
+using namespace llvm;
+
+static bool mapRaw(const json::Value &Params, StringLiteral Prop,
+ std::optional<json::Value> &V, json::Path P) {
+ const auto *O = Params.getAsObject();
+ if (!O) {
+ P.report("expected object");
+ return false;
+ }
+ if (const json::Value *E = O->get(Prop))
+ V = std::move(Params);
+ return true;
+}
+
+namespace lldb_dap {
+namespace protocol {
+
+enum class MessageType { request, response, event };
+
+bool fromJSON(const json::Value &Params, MessageType &M, json::Path P) {
+ auto rawType = Params.getAsString();
+ if (!rawType) {
+ P.report("expected a string");
+ return false;
+ }
+ std::optional<MessageType> type =
+ StringSwitch<std::optional<MessageType>>(*rawType)
+ .Case("request", MessageType::request)
+ .Case("response", MessageType::response)
+ .Case("event", MessageType::event)
+ .Default(std::nullopt);
+ if (!type) {
+ P.report("unexpected value, expected 'request', 'response' or 'event'");
+ return false;
+ }
+ M = *type;
+ return true;
+}
+
+json::Value toJSON(const Request &R) {
+ json::Object Result{
+ {"type", "request"},
+ {"seq", R.seq},
+ {"command", R.command},
+ };
+
+ if (R.rawArguments)
+ Result.insert({"arguments", R.rawArguments});
+
+ return std::move(Result);
+}
+
+bool fromJSON(json::Value const &Params, Request &R, json::Path P) {
+ json::ObjectMapper O(Params, P);
+ if (!O)
+ return false;
+
+ MessageType type;
+ if (!O.map("type", type) || !O.map("command", R.command) ||
+ !O.map("seq", R.seq))
+ return false;
+
+ if (type != MessageType::request) {
+ P.field("type").report("expected to be 'request'");
+ return false;
+ }
+
+ if (R.command.empty()) {
+ P.field("command").report("expected to not be ''");
+ return false;
+ }
+
+ if (!R.seq) {
+ P.field("seq").report("expected to not be '0'");
+ return false;
+ }
+
+ return mapRaw(Params, "arguments", R.rawArguments, P);
+}
+
+json::Value toJSON(const Response &R) {
+ json::Object Result{{"type", "response"},
+ {"req", 0},
+ {"command", R.command},
+ {"request_seq", R.request_seq},
+ {"success", R.success}};
+
+ if (R.message)
+ Result.insert({"message", R.message});
----------------
vogelsgesang wrote:
Should we assert that the message is only set if the command failed? At least the protocol seems to support the message field only for failed requests
> Contains the raw error in short form **if `success` is false.**
(emphasis mine)
```suggestion
if (R.message) {
assert(!R.success);
Result.insert({"message", R.message});
}
```
https://github.com/llvm/llvm-project/pull/129155
More information about the lldb-commits
mailing list