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