1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_TOOLING_DISPATCHER_H 17 #define ECMASCRIPT_TOOLING_DISPATCHER_H 18 19 #include <map> 20 #include <memory> 21 22 #include "base/pt_returns.h" 23 24 #include "ecmascript/debugger/js_debugger_interface.h" 25 #include "ecmascript/napi/include/jsnapi.h" 26 #include "libpandabase/macros.h" 27 28 namespace panda::ecmascript::tooling { 29 class ProtocolChannel; 30 class PtBaseReturns; 31 class PtBaseEvents; 32 33 enum class RequestCode : uint8_t { 34 OK = 0, 35 NOK, 36 37 // Json parse errors 38 JSON_PARSE_ERROR, 39 PARSE_ID_ERROR, 40 ID_FORMAT_ERROR, 41 PARSE_METHOD_ERROR, 42 METHOD_FORMAT_ERROR, 43 PARSE_PARAMS_ERROR, 44 PARAMS_FORMAT_ERROR 45 }; 46 47 enum class ResponseCode : uint8_t { OK, NOK }; 48 49 class DispatchRequest { 50 public: 51 explicit DispatchRequest(const std::string &message); 52 ~DispatchRequest(); 53 IsValid()54 bool IsValid() const 55 { 56 return code_ == RequestCode::OK; 57 } GetCallId()58 int32_t GetCallId() const 59 { 60 return callId_; 61 } GetParams()62 const PtJson &GetParams() const 63 { 64 return *params_; 65 } GetDomain()66 const std::string &GetDomain() const 67 { 68 return domain_; 69 } GetMethod()70 const std::string &GetMethod() const 71 { 72 return method_; 73 } 74 75 private: 76 int32_t callId_ = -1; 77 std::string domain_ {}; 78 std::string method_ {}; 79 std::unique_ptr<PtJson> params_ = std::make_unique<PtJson>(); 80 RequestCode code_ {RequestCode::OK}; 81 std::string errorMsg_ {}; 82 }; 83 84 class DispatchResponse { 85 public: IsOk()86 bool IsOk() const 87 { 88 return code_ == ResponseCode::OK; 89 } 90 GetError()91 ResponseCode GetError() const 92 { 93 return code_; 94 } 95 GetMessage()96 const std::string &GetMessage() const 97 { 98 return errorMsg_; 99 } 100 101 static DispatchResponse Create(ResponseCode code, const std::string &msg = ""); 102 static DispatchResponse Create(std::optional<std::string> error); 103 static DispatchResponse Ok(); 104 static DispatchResponse Fail(const std::string &message); 105 106 ~DispatchResponse() = default; 107 108 private: 109 DispatchResponse() = default; 110 111 ResponseCode code_ {ResponseCode::OK}; 112 std::string errorMsg_ {}; 113 }; 114 115 class DispatcherBase { 116 public: DispatcherBase(ProtocolChannel * channel)117 explicit DispatcherBase(ProtocolChannel *channel) : channel_(channel) {} ~DispatcherBase()118 virtual ~DispatcherBase() 119 { 120 channel_ = nullptr; 121 }; 122 virtual void Dispatch(const DispatchRequest &request) = 0; 123 124 protected: 125 void SendResponse(const DispatchRequest &request, const DispatchResponse &response, 126 const PtBaseReturns &result = PtBaseReturns()); 127 128 private: 129 ProtocolChannel *channel_ {nullptr}; 130 131 NO_COPY_SEMANTIC(DispatcherBase); 132 NO_MOVE_SEMANTIC(DispatcherBase); 133 }; 134 135 class Dispatcher { 136 public: 137 explicit Dispatcher(const EcmaVM *vm, ProtocolChannel *channel); 138 ~Dispatcher() = default; 139 void Dispatch(const DispatchRequest &request); 140 141 private: 142 std::unordered_map<std::string, std::unique_ptr<DispatcherBase>> dispatchers_ {}; 143 144 NO_COPY_SEMANTIC(Dispatcher); 145 NO_MOVE_SEMANTIC(Dispatcher); 146 }; 147 } // namespace panda::ecmascript::tooling 148 #endif 149