================
@@ -54,112 +50,227 @@ class TransportUnhandledContentsError
   std::string m_unhandled_contents;
 };
 
-class TransportInvalidError : public llvm::ErrorInfo<TransportInvalidError> {
+/// A transport is responsible for maintaining the connection to a client
+/// application, and reading/writing structured messages to it.
+///
+/// Transports have limited thread safety requirements:
+///  - Messages will not be sent concurrently.
+///  - Messages MAY be sent while Run() is reading, or its callback is active.
+template <typename Req, typename Resp, typename Evt> class Transport {
 public:
-  static char ID;
-
-  TransportInvalidError() = default;
+  using Message = std::variant<Req, Resp, Evt>;
+
+  virtual ~Transport() = default;
+
+  // Called by transport to send outgoing messages.
+  virtual void Event(const Evt &) = 0;
+  virtual void Request(const Req &) = 0;
+  virtual void Response(const Resp &) = 0;
+
+  /// Implemented to handle incoming messages. (See Run() below).
+  class MessageHandler {
+  public:
+    virtual ~MessageHandler() = default;
+    virtual void OnEvent(const Evt &) = 0;
+    virtual void OnRequest(const Req &) = 0;
+    virtual void OnResponse(const Resp &) = 0;
+  };
+
+  /// Called by server or client to receive messages from the connection.
+  /// The transport should in turn invoke the handler to process messages.
+  /// The MainLoop is used to handle reading from the incoming connection and
+  /// will run until the loop is terminated.
+  virtual llvm::Error Run(MainLoop &, MessageHandler &) = 0;
 
-  void log(llvm::raw_ostream &OS) const override;
-  std::error_code convertToErrorCode() const override;
+protected:
+  template <typename... Ts> inline auto Logv(const char *Fmt, Ts &&...Vals) {
+    Log(llvm::formatv(Fmt, std::forward<Ts>(Vals)...).str());
+  }
+  virtual void Log(llvm::StringRef message) = 0;
 };
 
-/// A transport class that uses JSON for communication.
-class JSONTransport {
+/// A JSONTransport will encode and decode messages using JSON.
+template <typename Req, typename Resp, typename Evt>
+class JSONTransport : public Transport<Req, Resp, Evt> {
 public:
-  using ReadHandleUP = MainLoopBase::ReadHandleUP;
-  template <typename T>
-  using Callback = std::function<void(MainLoopBase &, const 
llvm::Expected<T>)>;
-
-  JSONTransport(lldb::IOObjectSP input, lldb::IOObjectSP output);
-  virtual ~JSONTransport() = default;
-
-  /// Transport is not copyable.
-  /// @{
-  JSONTransport(const JSONTransport &rhs) = delete;
-  void operator=(const JSONTransport &rhs) = delete;
-  /// @}
-
-  /// Writes a message to the output stream.
-  template <typename T> llvm::Error Write(const T &t) {
-    const std::string message = llvm::formatv("{0}", toJSON(t)).str();
-    return WriteImpl(message);
+  using Transport<Req, Resp, Evt>::Transport;
+
+  JSONTransport(lldb::IOObjectSP in, lldb::IOObjectSP out)
+      : m_in(in), m_out(out) {}
+
+  void Event(const Evt &evt) override { Write(evt); }
+  void Request(const Req &req) override { Write(req); }
+  void Response(const Resp &resp) override { Write(resp); }
+
+  /// Run registers the transport with the given MainLoop and handles any
+  /// incoming messages using the given MessageHandler.
+  llvm::Error
+  Run(MainLoop &loop,
+      typename Transport<Req, Resp, Evt>::MessageHandler &handler) override {
+    llvm::Error error = llvm::Error::success();
+    Status status;
+    auto read_handle = loop.RegisterReadObject(
+        m_in,
+        std::bind(&JSONTransport::OnRead, this, &error, std::placeholders::_1,
+                  std::ref(handler)),
+        status);
+    if (status.Fail()) {
+      // This error is only set if the read object handler is invoked, mark it
+      // as consumed if registration of the handler failed.
+      llvm::consumeError(std::move(error));
+      return status.takeError();
+    }
+
+    status = loop.Run();
----------------
ashgti wrote:

Updated to have a register function instead of a `Run` function.

https://github.com/llvm/llvm-project/pull/153121
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to