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#include "dispatcher.h"
17e509ee18Sopenharmony_ci
18e509ee18Sopenharmony_ci#include "agent/debugger_impl.h"
19e509ee18Sopenharmony_ci#include "agent/runtime_impl.h"
20e509ee18Sopenharmony_ci#ifdef ECMASCRIPT_SUPPORT_HEAPPROFILER
21e509ee18Sopenharmony_ci#include "agent/heapprofiler_impl.h"
22e509ee18Sopenharmony_ci#endif
23e509ee18Sopenharmony_ci#ifdef ECMASCRIPT_SUPPORT_CPUPROFILER
24e509ee18Sopenharmony_ci#include "agent/profiler_impl.h"
25e509ee18Sopenharmony_ci#endif
26e509ee18Sopenharmony_ci#include "agent/tracing_impl.h"
27e509ee18Sopenharmony_ci#include "agent/css_impl.h"
28e509ee18Sopenharmony_ci#include "agent/dom_impl.h"
29e509ee18Sopenharmony_ci#include "agent/overlay_impl.h"
30e509ee18Sopenharmony_ci#include "agent/page_impl.h"
31e509ee18Sopenharmony_ci#include "agent/target_impl.h"
32e509ee18Sopenharmony_ci#include "protocol_channel.h"
33e509ee18Sopenharmony_ci
34e509ee18Sopenharmony_cinamespace panda::ecmascript::tooling {
35e509ee18Sopenharmony_ciDispatchRequest::DispatchRequest(const std::string &message)
36e509ee18Sopenharmony_ci{
37e509ee18Sopenharmony_ci    std::unique_ptr<PtJson> json = PtJson::Parse(message);
38e509ee18Sopenharmony_ci    if (json == nullptr) {
39e509ee18Sopenharmony_ci        JsonParseError();
40e509ee18Sopenharmony_ci        return;
41e509ee18Sopenharmony_ci    }
42e509ee18Sopenharmony_ci    if (!json->IsObject()) {
43e509ee18Sopenharmony_ci        JsonFormatError(json);
44e509ee18Sopenharmony_ci        return;
45e509ee18Sopenharmony_ci    }
46e509ee18Sopenharmony_ci
47e509ee18Sopenharmony_ci    Result ret;
48e509ee18Sopenharmony_ci    int32_t callId;
49e509ee18Sopenharmony_ci    ret = json->GetInt("id", &callId);
50e509ee18Sopenharmony_ci    if (ret != Result::SUCCESS) {
51e509ee18Sopenharmony_ci        code_ = RequestCode::PARSE_ID_ERROR;
52e509ee18Sopenharmony_ci        LOG_DEBUGGER(ERROR) << "parse id error";
53e509ee18Sopenharmony_ci        return;
54e509ee18Sopenharmony_ci    }
55e509ee18Sopenharmony_ci    callId_ = callId;
56e509ee18Sopenharmony_ci
57e509ee18Sopenharmony_ci    std::string wholeMethod;
58e509ee18Sopenharmony_ci    ret = json->GetString("method", &wholeMethod);
59e509ee18Sopenharmony_ci    if (ret != Result::SUCCESS || wholeMethod.empty()) {
60e509ee18Sopenharmony_ci        code_ = RequestCode::PARSE_METHOD_ERROR;
61e509ee18Sopenharmony_ci        LOG_DEBUGGER(ERROR) << "parse method error";
62e509ee18Sopenharmony_ci        return;
63e509ee18Sopenharmony_ci    }
64e509ee18Sopenharmony_ci    std::string::size_type length = wholeMethod.length();
65e509ee18Sopenharmony_ci    std::string::size_type indexPoint = wholeMethod.find_first_of('.', 0);
66e509ee18Sopenharmony_ci    if (indexPoint == std::string::npos || indexPoint == 0 || indexPoint == length - 1) {
67e509ee18Sopenharmony_ci        code_ = RequestCode::METHOD_FORMAT_ERROR;
68e509ee18Sopenharmony_ci        LOG_DEBUGGER(ERROR) << "method format error: " << wholeMethod;
69e509ee18Sopenharmony_ci        return;
70e509ee18Sopenharmony_ci    }
71e509ee18Sopenharmony_ci    domain_ = wholeMethod.substr(0, indexPoint);
72e509ee18Sopenharmony_ci    method_ = wholeMethod.substr(indexPoint + 1, length);
73e509ee18Sopenharmony_ci
74e509ee18Sopenharmony_ci    LOG_DEBUGGER(DEBUG) << "id: " << callId_ << ", domain: " << domain_ << ", method: " << method_;
75e509ee18Sopenharmony_ci
76e509ee18Sopenharmony_ci    std::unique_ptr<PtJson> params;
77e509ee18Sopenharmony_ci    ret = json->GetObject("params", &params);
78e509ee18Sopenharmony_ci    if (ret == Result::NOT_EXIST) {
79e509ee18Sopenharmony_ci        return;
80e509ee18Sopenharmony_ci    }
81e509ee18Sopenharmony_ci    if (ret == Result::TYPE_ERROR) {
82e509ee18Sopenharmony_ci        code_ = RequestCode::PARAMS_FORMAT_ERROR;
83e509ee18Sopenharmony_ci        LOG_DEBUGGER(ERROR) << "params format error";
84e509ee18Sopenharmony_ci        return;
85e509ee18Sopenharmony_ci    }
86e509ee18Sopenharmony_ci    params_ = std::move(params);
87e509ee18Sopenharmony_ci}
88e509ee18Sopenharmony_ci
89e509ee18Sopenharmony_ciDispatchRequest::~DispatchRequest()
90e509ee18Sopenharmony_ci{
91e509ee18Sopenharmony_ci    params_->ReleaseRoot();
92e509ee18Sopenharmony_ci}
93e509ee18Sopenharmony_ci
94e509ee18Sopenharmony_ciDispatchResponse DispatchResponse::Create(ResponseCode code, const std::string &msg)
95e509ee18Sopenharmony_ci{
96e509ee18Sopenharmony_ci    DispatchResponse response;
97e509ee18Sopenharmony_ci    response.code_ = code;
98e509ee18Sopenharmony_ci    response.errorMsg_ = msg;
99e509ee18Sopenharmony_ci    return response;
100e509ee18Sopenharmony_ci}
101e509ee18Sopenharmony_ci
102e509ee18Sopenharmony_ciDispatchResponse DispatchResponse::Create(std::optional<std::string> error)
103e509ee18Sopenharmony_ci{
104e509ee18Sopenharmony_ci    DispatchResponse response;
105e509ee18Sopenharmony_ci    if (error.has_value()) {
106e509ee18Sopenharmony_ci        response.code_ = ResponseCode::NOK;
107e509ee18Sopenharmony_ci        response.errorMsg_ = error.value();
108e509ee18Sopenharmony_ci    }
109e509ee18Sopenharmony_ci    return response;
110e509ee18Sopenharmony_ci}
111e509ee18Sopenharmony_ci
112e509ee18Sopenharmony_ciDispatchResponse DispatchResponse::Ok()
113e509ee18Sopenharmony_ci{
114e509ee18Sopenharmony_ci    return DispatchResponse();
115e509ee18Sopenharmony_ci}
116e509ee18Sopenharmony_ci
117e509ee18Sopenharmony_ciDispatchResponse DispatchResponse::Fail(const std::string &message)
118e509ee18Sopenharmony_ci{
119e509ee18Sopenharmony_ci    DispatchResponse response;
120e509ee18Sopenharmony_ci    response.code_ = ResponseCode::NOK;
121e509ee18Sopenharmony_ci    response.errorMsg_ = message;
122e509ee18Sopenharmony_ci    return response;
123e509ee18Sopenharmony_ci}
124e509ee18Sopenharmony_ci
125e509ee18Sopenharmony_civoid DispatcherBase::SendResponse(const DispatchRequest &request, const DispatchResponse &response,
126e509ee18Sopenharmony_ci                                  const PtBaseReturns &result)
127e509ee18Sopenharmony_ci{
128e509ee18Sopenharmony_ci    if (channel_ != nullptr) {
129e509ee18Sopenharmony_ci        channel_->SendResponse(request, response, result);
130e509ee18Sopenharmony_ci    }
131e509ee18Sopenharmony_ci}
132e509ee18Sopenharmony_ci
133e509ee18Sopenharmony_ciDispatcher::Dispatcher(const EcmaVM *vm, ProtocolChannel *channel)
134e509ee18Sopenharmony_ci{
135e509ee18Sopenharmony_ci    // profiler
136e509ee18Sopenharmony_ci#ifdef ECMASCRIPT_SUPPORT_CPUPROFILER
137e509ee18Sopenharmony_ci    auto profiler = std::make_unique<ProfilerImpl>(vm, channel);
138e509ee18Sopenharmony_ci    dispatchers_["Profiler"] =
139e509ee18Sopenharmony_ci        std::make_unique<ProfilerImpl::DispatcherImpl>(channel, std::move(profiler));
140e509ee18Sopenharmony_ci#endif
141e509ee18Sopenharmony_ci#ifdef ECMASCRIPT_SUPPORT_HEAPPROFILER
142e509ee18Sopenharmony_ci    auto heapProfiler = std::make_unique<HeapProfilerImpl>(vm, channel);
143e509ee18Sopenharmony_ci    dispatchers_["HeapProfiler"] =
144e509ee18Sopenharmony_ci        std::make_unique<HeapProfilerImpl::DispatcherImpl>(channel, std::move(heapProfiler));
145e509ee18Sopenharmony_ci#endif
146e509ee18Sopenharmony_ci#ifdef ECMASCRIPT_SUPPORT_TRACING
147e509ee18Sopenharmony_ci    auto tracing = std::make_unique<TracingImpl>(vm, channel);
148e509ee18Sopenharmony_ci    dispatchers_["Tracing"] =
149e509ee18Sopenharmony_ci        std::make_unique<TracingImpl::DispatcherImpl>(channel, std::move(tracing));
150e509ee18Sopenharmony_ci#endif
151e509ee18Sopenharmony_ci
152e509ee18Sopenharmony_ci    // debugger
153e509ee18Sopenharmony_ci    auto runtime = std::make_unique<RuntimeImpl>(vm, channel);
154e509ee18Sopenharmony_ci    auto debugger = std::make_unique<DebuggerImpl>(vm, channel, runtime.get());
155e509ee18Sopenharmony_ci    dispatchers_["Runtime"] =
156e509ee18Sopenharmony_ci        std::make_unique<RuntimeImpl::DispatcherImpl>(channel, std::move(runtime));
157e509ee18Sopenharmony_ci    dispatchers_["Debugger"] =
158e509ee18Sopenharmony_ci        std::make_unique<DebuggerImpl::DispatcherImpl>(channel, std::move(debugger));
159e509ee18Sopenharmony_ci
160e509ee18Sopenharmony_ci    auto dom = std::make_unique<DomImpl>();
161e509ee18Sopenharmony_ci    dispatchers_["DOM"] =
162e509ee18Sopenharmony_ci        std::make_unique<DomImpl::DispatcherImpl>(channel, std::move(dom));
163e509ee18Sopenharmony_ci
164e509ee18Sopenharmony_ci    auto css = std::make_unique<CssImpl>();
165e509ee18Sopenharmony_ci    dispatchers_["CSS"] =
166e509ee18Sopenharmony_ci        std::make_unique<CssImpl::DispatcherImpl>(channel, std::move(css));
167e509ee18Sopenharmony_ci
168e509ee18Sopenharmony_ci    auto overlay = std::make_unique<OverlayImpl>();
169e509ee18Sopenharmony_ci    dispatchers_["Overlay"] =
170e509ee18Sopenharmony_ci        std::make_unique<OverlayImpl::DispatcherImpl>(channel, std::move(overlay));
171e509ee18Sopenharmony_ci
172e509ee18Sopenharmony_ci    auto target = std::make_unique<TargetImpl>();
173e509ee18Sopenharmony_ci    dispatchers_["Target"] =
174e509ee18Sopenharmony_ci        std::make_unique<TargetImpl::DispatcherImpl>(channel, std::move(target));
175e509ee18Sopenharmony_ci
176e509ee18Sopenharmony_ci    auto page = std::make_unique<PageImpl>();
177e509ee18Sopenharmony_ci    dispatchers_["Page"] =
178e509ee18Sopenharmony_ci        std::make_unique<PageImpl::DispatcherImpl>(channel, std::move(page));
179e509ee18Sopenharmony_ci}
180e509ee18Sopenharmony_ci
181e509ee18Sopenharmony_civoid Dispatcher::Dispatch(const DispatchRequest &request)
182e509ee18Sopenharmony_ci{
183e509ee18Sopenharmony_ci    if (!request.IsValid()) {
184e509ee18Sopenharmony_ci        LOG_DEBUGGER(ERROR) << "Unknown request";
185e509ee18Sopenharmony_ci        return;
186e509ee18Sopenharmony_ci    }
187e509ee18Sopenharmony_ci    const std::string &domain = request.GetDomain();
188e509ee18Sopenharmony_ci    auto dispatcher = dispatchers_.find(domain);
189e509ee18Sopenharmony_ci    if (dispatcher != dispatchers_.end()) {
190e509ee18Sopenharmony_ci        dispatcher->second->Dispatch(request);
191e509ee18Sopenharmony_ci    } else {
192e509ee18Sopenharmony_ci        if (domain == "Test") {
193e509ee18Sopenharmony_ci            if (request.GetMethod() == "fail") {
194e509ee18Sopenharmony_ci                LOG_DEBUGGER(FATAL) << "Test fail";
195e509ee18Sopenharmony_ci                UNREACHABLE();
196e509ee18Sopenharmony_ci            }
197e509ee18Sopenharmony_ci            LOG_DEBUGGER(INFO) << "Test success";
198e509ee18Sopenharmony_ci        } else {
199e509ee18Sopenharmony_ci            LOG_DEBUGGER(ERROR) << "unknown domain: " << domain;
200e509ee18Sopenharmony_ci        }
201e509ee18Sopenharmony_ci    }
202e509ee18Sopenharmony_ci}
203e509ee18Sopenharmony_ci}  // namespace panda::ecmascript::tooling
204