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 "tooling/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() const54 bool IsValid() const 55 { 56 return code_ == RequestCode::OK; 57 } GetCallId() const58 int32_t GetCallId() const 59 { 60 return callId_; 61 } GetParams() const62 const PtJson &GetParams() const 63 { 64 return *params_; 65 } GetDomain() const66 const std::string &GetDomain() const 67 { 68 return domain_; 69 } GetMethod() const70 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_ {}; JsonParseError()82 void JsonParseError() 83 { 84 code_ = RequestCode::JSON_PARSE_ERROR; 85 LOG_DEBUGGER(ERROR) << "json parse error"; 86 } JsonFormatError(std::unique_ptr<PtJson>& json)87 void JsonFormatError(std::unique_ptr<PtJson>& json) 88 { 89 code_ = RequestCode::PARAMS_FORMAT_ERROR; 90 LOG_DEBUGGER(ERROR) << "json parse format error"; 91 json->ReleaseRoot(); 92 } 93 }; 94 95 class DispatchResponse { 96 public: IsOk() const97 bool IsOk() const 98 { 99 return code_ == ResponseCode::OK; 100 } 101 GetError() const102 ResponseCode GetError() const 103 { 104 return code_; 105 } 106 GetMessage() const107 const std::string &GetMessage() const 108 { 109 return errorMsg_; 110 } 111 112 static DispatchResponse Create(ResponseCode code, const std::string &msg = ""); 113 static DispatchResponse Create(std::optional<std::string> error); 114 static DispatchResponse Ok(); 115 static DispatchResponse Fail(const std::string &message); 116 117 ~DispatchResponse() = default; 118 119 private: 120 DispatchResponse() = default; 121 122 ResponseCode code_ {ResponseCode::OK}; 123 std::string errorMsg_ {}; 124 }; 125 126 class DispatcherBase { 127 public: DispatcherBase(ProtocolChannel *channel)128 explicit DispatcherBase(ProtocolChannel *channel) : channel_(channel) {} ~DispatcherBase()129 virtual ~DispatcherBase() 130 { 131 channel_ = nullptr; 132 }; 133 virtual void Dispatch(const DispatchRequest &request) = 0; 134 135 protected: 136 void SendResponse(const DispatchRequest &request, const DispatchResponse &response, 137 const PtBaseReturns &result = PtBaseReturns()); 138 139 private: 140 ProtocolChannel *channel_ {nullptr}; 141 142 NO_COPY_SEMANTIC(DispatcherBase); 143 NO_MOVE_SEMANTIC(DispatcherBase); 144 }; 145 146 class Dispatcher { 147 public: 148 explicit Dispatcher(const EcmaVM *vm, ProtocolChannel *channel); 149 ~Dispatcher() = default; 150 void Dispatch(const DispatchRequest &request); 151 152 private: 153 std::unordered_map<std::string, std::unique_ptr<DispatcherBase>> dispatchers_ {}; 154 155 NO_COPY_SEMANTIC(Dispatcher); 156 NO_MOVE_SEMANTIC(Dispatcher); 157 }; 158 } // namespace panda::ecmascript::tooling 159 #endif 160