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 "ecmascript/napi/include/jsnapi.h" 23 #include "ecmascript/tooling/backend/js_debugger_interface.h" 24 #include "ecmascript/tooling/base/pt_returns.h" 25 #include "libpandabase/macros.h" 26 27 namespace panda::ecmascript::tooling { 28 class ProtocolChannel; 29 class PtBaseReturns; 30 class PtBaseEvents; 31 32 enum class RequestCode : uint8_t { 33 OK = 0, 34 NOK, 35 36 // Json parse errors 37 JSON_PARSE_ERROR, 38 PARSE_ID_ERROR, 39 ID_FORMAT_ERROR, 40 PARSE_METHOD_ERROR, 41 METHOD_FORMAT_ERROR, 42 PARSE_PARAMS_ERROR, 43 PARAMS_FORMAT_ERROR 44 }; 45 46 enum class ResponseCode : uint8_t { OK, NOK }; 47 48 class DispatchRequest { 49 public: 50 explicit DispatchRequest(const std::string &message); 51 ~DispatchRequest(); 52 IsValid()53 bool IsValid() const 54 { 55 return code_ == RequestCode::OK; 56 } GetCallId()57 int32_t GetCallId() const 58 { 59 return callId_; 60 } GetParams()61 const PtJson &GetParams() const 62 { 63 return *params_; 64 } GetDomain()65 const std::string &GetDomain() const 66 { 67 return domain_; 68 } GetMethod()69 const std::string &GetMethod() const 70 { 71 return method_; 72 } 73 74 private: 75 int32_t callId_ = -1; 76 std::string domain_ {}; 77 std::string method_ {}; 78 std::unique_ptr<PtJson> params_ = std::make_unique<PtJson>(); 79 RequestCode code_ {RequestCode::OK}; 80 std::string errorMsg_ {}; 81 }; 82 83 class DispatchResponse { 84 public: IsOk()85 bool IsOk() const 86 { 87 return code_ == ResponseCode::OK; 88 } 89 GetError()90 ResponseCode GetError() const 91 { 92 return code_; 93 } 94 GetMessage()95 const std::string &GetMessage() const 96 { 97 return errorMsg_; 98 } 99 100 static DispatchResponse Create(ResponseCode code, const std::string &msg = ""); 101 static DispatchResponse Create(std::optional<std::string> error); 102 static DispatchResponse Ok(); 103 static DispatchResponse Fail(const std::string &message); 104 105 ~DispatchResponse() = default; 106 107 private: 108 DispatchResponse() = default; 109 110 ResponseCode code_ {ResponseCode::OK}; 111 std::string errorMsg_ {}; 112 }; 113 114 class DispatcherBase { 115 public: DispatcherBase(ProtocolChannel * channel)116 explicit DispatcherBase(ProtocolChannel *channel) : channel_(channel) {} ~DispatcherBase()117 virtual ~DispatcherBase() 118 { 119 channel_ = nullptr; 120 }; 121 virtual void Dispatch(const DispatchRequest &request) = 0; 122 123 protected: 124 void SendResponse(const DispatchRequest &request, const DispatchResponse &response, 125 const PtBaseReturns &result = PtBaseReturns()); 126 127 private: 128 ProtocolChannel *channel_ {nullptr}; 129 130 NO_COPY_SEMANTIC(DispatcherBase); 131 NO_MOVE_SEMANTIC(DispatcherBase); 132 }; 133 134 class Dispatcher { 135 public: 136 explicit Dispatcher(const EcmaVM *vm, ProtocolChannel *channel); 137 ~Dispatcher() = default; 138 void Dispatch(const DispatchRequest &request); 139 140 private: 141 std::unordered_map<std::string, std::unique_ptr<DispatcherBase>> dispatchers_ {}; 142 143 NO_COPY_SEMANTIC(Dispatcher); 144 NO_MOVE_SEMANTIC(Dispatcher); 145 }; 146 } // namespace panda::ecmascript::tooling 147 #endif 148