AngelscriptDebuggerServer/src/DebugAdapterProtocol/BaseProtocol.hpp

142 lines
4.7 KiB
C++

#ifndef ANGELSCRIPTDEBUGGER_BASEPROTOCOL_HPP
#define ANGELSCRIPTDEBUGGER_BASEPROTOCOL_HPP
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include <nlohmann/json.hpp>
#include "Utils.hpp"
namespace DebugAdapterProtocol {
static size_t current_sequence = 0;
struct ProtocolMessage {
explicit ProtocolMessage(std::string t) : seq(current_sequence++), type(std::move(t)) {}
ProtocolMessage(std::string t, size_t s) : seq(s), type(std::move(t)) {}
size_t seq;
std::string type{"event"};
static ProtocolMessage* FromJson(nlohmann::json& j);
[[nodiscard]] virtual nlohmann::json ToJson() const { return {{"seq", seq}, {"type", type}}; }
virtual ~ProtocolMessage() = default;
};
struct RequestArguments {
RequestArguments(){};
explicit RequestArguments(nlohmann::json&) {}
virtual ~RequestArguments() = default;
virtual nlohmann::json ToJson() const { return nlohmann::json ::object(); }
};
struct Request : public ProtocolMessage {
Request() : ProtocolMessage("request") {}
virtual std::string GetCommand() const = 0;
virtual std::optional<RequestArguments*> GetArguments() const = 0;
static ProtocolMessage* FromJson(nlohmann::json& j);
[[nodiscard]] nlohmann::json ToJson() const override {
auto o = ProtocolMessage::ToJson();
o["command"] = GetCommand();
if (GetArguments().has_value()) {
o["body"] = GetArguments().value()->ToJson();
}
return o;
}
};
template <class T>
concept IsRequestArguments = std::is_base_of<RequestArguments, T>::value;
template <IsRequestArguments T, const char* S> struct DefinedRequest : public Request {
std::optional<T*> arguments;
static ProtocolMessage* FromJson(nlohmann::json& j);
~DefinedRequest() override {
if (arguments.has_value()) {
delete arguments.value();
}
}
[[nodiscard]] std::string GetCommand() const override { return S; }
[[nodiscard]] std::optional<RequestArguments*> GetArguments() const override { return arguments; }
};
struct EventBody {
EventBody() = default;
explicit EventBody(nlohmann::json&) {}
virtual ~EventBody() = default;
[[nodiscard]] virtual nlohmann::json ToJson() const { return nlohmann::json::object(); };
};
template <class T>
concept IsEventBody = std::is_base_of<EventBody, T>::value;
template <IsEventBody T, const char* S> struct Event : public ProtocolMessage {
Event() : ProtocolMessage("event") {}
explicit Event(T* b) : ProtocolMessage("event"), body(b) {}
std::optional<T*> body;
~Event() override {
if (body.has_value()) {
delete body.value();
}
}
[[nodiscard]] nlohmann::json ToJson() const override {
auto o = ProtocolMessage::ToJson();
o["event"] = S;
if (body.has_value()) {
o["body"] = body.value()->ToJson();
}
return o;
}
};
struct ResponseBody {
ResponseBody() = default;
explicit ResponseBody(nlohmann::json&) {}
virtual ~ResponseBody() = default;
[[nodiscard]] virtual nlohmann::json ToJson() const { return nlohmann::json::object(); };
};
template <class T>
concept IsResponseBody = std::is_base_of<ResponseBody, T>::value;
struct Response : public ProtocolMessage {
Response(size_t seq) : ProtocolMessage("response", seq), request_seq(seq) {}
size_t request_seq;
bool success = true;
std::optional<std::string> message;
virtual std::string GetCommand() const = 0;
virtual std::optional<ResponseBody*> GetBody() const = 0;
};
template <IsResponseBody T, const char* S> struct DefinedResponse : public Response {
DefinedResponse(size_t seq) : Response(seq) {}
std::optional<T*> body;
[[nodiscard]] std::string GetCommand() const override { return S; }
[[nodiscard]] std::optional<ResponseBody*> GetBody() const override { return body; }
[[nodiscard]] nlohmann::json ToJson() const override {
auto o = ProtocolMessage::ToJson();
o["request_seq"] = request_seq;
o["success"] = success;
o["command"] = GetCommand();
JsonSerializeOptional(o, message);
if (body.has_value()) {
o["body"] = body.value()->ToJson();
}
return o;
}
};
}
#endif // ANGELSCRIPTDEBUGGER_BASEPROTOCOL_HPP