Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: third_party/WebKit/Source/platform/inspector_protocol/Dispatcher_cpp.template

Issue 2012753003: DevTools: consolidate protocol generators for front-end, backend and type builder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // This file is generated
2
3 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6
7 #include "platform/inspector_protocol/{{class_name}}.h"
8
9 #include "platform/inspector_protocol/Collections.h"
10 #include "platform/inspector_protocol/FrontendChannel.h"
11 #include "platform/inspector_protocol/Parser.h"
12
13 namespace blink {
14 namespace protocol {
15
16 using protocol::Maybe;
17
18 class DispatcherImpl;
19
20 class DispatcherImplWeakPtr {
21 public:
22 DispatcherImplWeakPtr(DispatcherImpl* dispatcher) : m_dispatcher(dispatcher) { }
23 ~DispatcherImplWeakPtr();
24 DispatcherImpl* get() { return m_dispatcher; }
25 void dispose() { m_dispatcher = nullptr; }
26 private:
27 DispatcherImpl* m_dispatcher;
28 };
29
30 class DispatcherImpl : public Dispatcher {
31 public:
32 DispatcherImpl(FrontendChannel* frontendChannel)
33 : m_frontendChannel(frontendChannel)
34 {% for domain in api.domains %}
35 , m_{{domain.domain | lower}}Agent(0)
36 {% endfor %}
37 {
38 {% for domain in api.domains %}
39 {% for command in domain.commands %}
40 {% if "redirect" in command %}{% continue %}{% endif %}
41 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
42 m_dispatchMap.set("{{domain.domain}}.{{command.name}}", &DispatcherImpl: :{{domain.domain}}_{{command.name}});
43 {% endfor %}
44 {% endfor %}
45
46 // Initialize common errors.
47 m_commonErrors.resize(LastEntry);
48 m_commonErrors[ParseError] = -32700;
49 m_commonErrors[InvalidRequest] = -32600;
50 m_commonErrors[MethodNotFound] = -32601;
51 m_commonErrors[InvalidParams] = -32602;
52 m_commonErrors[InternalError] = -32603;
53 m_commonErrors[ServerError] = -32000;
54 }
55
56 ~DispatcherImpl() { clearFrontend(); }
57
58 virtual void clearFrontend()
59 {
60 m_frontendChannel = nullptr;
61 for (auto& weak : m_weakPtrs)
62 weak.first->dispose();
63 m_weakPtrs.clear();
64 }
65
66 std::unique_ptr<DispatcherImplWeakPtr> weakPtr()
67 {
68 std::unique_ptr<DispatcherImplWeakPtr> weak(new DispatcherImplWeakPtr(th is));
69 m_weakPtrs.add(weak.get());
70 return weak;
71 }
72
73 virtual void dispatch(const String16& message);
74 virtual void reportProtocolError(int callId, CommonErrorCode, const String16 & errorMessage, ErrorSupport* errors) const;
75 using Dispatcher::reportProtocolError;
76
77 void sendResponse(int callId, const ErrorString& invocationError, ErrorSuppo rt* errors, std::unique_ptr<protocol::DictionaryValue> result);
78
79 {% for domain in api.domains %}
80 virtual void registerAgent(blink::protocol::{{domain.domain}}::Backend* agen t) { DCHECK(!m_{{domain.domain | lower}}Agent); m_{{domain.domain | lower}}Agent = agent; }
81 {% endfor %}
82
83 private:
84 friend class DispatcherCallbackBase;
85 friend class DispatcherImplWeakPtr;
86 using CallHandler = void (DispatcherImpl::*)(int callId, std::unique_ptr<Dic tionaryValue> messageObject, ErrorSupport* errors);
87 using DispatchMap = protocol::HashMap<String16, CallHandler>;
88
89 {% for domain in api.domains %}
90 {% for command in domain.commands %}
91 {% if "redirect" in command %}{% continue %}{% endif %}
92 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
93 void {{domain.domain}}_{{command.name}}(int callId, std::unique_ptr<Dictiona ryValue> requestMessageObject, ErrorSupport*);
94 {% endfor %}
95 {% endfor %}
96
97 FrontendChannel* m_frontendChannel;
98
99 {% for domain in api.domains %}
100 {{domain.domain}}::Backend* m_{{domain.domain | lower}}Agent;
101 {% endfor %}
102
103 void sendResponse(int callId, ErrorString invocationError, std::unique_ptr<p rotocol::DictionaryValue> result)
104 {
105 sendResponse(callId, invocationError, nullptr, std::move(result));
106 }
107
108 void sendResponse(int callId, ErrorString invocationError)
109 {
110 sendResponse(callId, invocationError, nullptr, DictionaryValue::create() );
111 }
112
113 static const char kInvalidRequest[];
114
115 DispatchMap m_dispatchMap;
116 protocol::Vector<int> m_commonErrors;
117 protocol::HashSet<DispatcherImplWeakPtr*> m_weakPtrs;
118 };
119
120 class PLATFORM_EXPORT DispatcherCallbackBase : public protocol::BackendCallback {
121 public:
122 DispatcherCallbackBase(std::unique_ptr<DispatcherImplWeakPtr> backendImpl, i nt callId)
123 : m_backendImpl(std::move(backendImpl)), m_callId(callId) { }
124 virtual ~DispatcherCallbackBase() { }
125 void dispose() { m_backendImpl = nullptr; }
126
127 protected:
128 void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError)
129 {
130 if (!m_backendImpl->get())
131 return;
132 m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, s td::move(partialMessage));
133 m_backendImpl = nullptr;
134 }
135
136 private:
137 std::unique_ptr<DispatcherImplWeakPtr> m_backendImpl;
138 int m_callId;
139 };
140
141 DispatcherImplWeakPtr::~DispatcherImplWeakPtr()
142 {
143 if (m_dispatcher)
144 m_dispatcher->m_weakPtrs.remove(this);
145 }
146
147 const char DispatcherImpl::kInvalidRequest[] = "Invalid request";
148
149 {% for domain in api.domains %}
150 {% for command in domain.commands %}
151 {% if "redirect" in command %}{% continue %}{% endif %}
152 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
153
154 {% if "async" in command %}
155
156 class PLATFORM_EXPORT {{domain.domain}}{{command.name | to_title_case}}Callback : public {{domain.domain}}::Backend::{{command.name | to_title_case}}Callback, p ublic DispatcherCallbackBase {
157 public:
158 {{domain.domain}}{{command.name | to_title_case}}Callback(std::unique_ptr<Di spatcherImplWeakPtr> backendImpl, int callId)
159 : DispatcherCallbackBase(std::move(backendImpl), callId) { }
160
161 void sendSuccess(
162 {%- for parameter in command.returns -%}
163 {%- if "optional" in parameter -%}
164 const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}}
165 {%- else -%}
166 {{resolve_type(parameter).pass_type}} {{parameter.name}}
167 {%- endif -%}
168 {%- if not loop.last -%}, {% endif -%}
169 {%- endfor -%}) override
170 {
171 std::unique_ptr<protocol::DictionaryValue> resultObject = DictionaryValu e::create();
172 {% for parameter in command.returns %}
173 {% if "optional" in parameter %}
174 if ({{parameter.name}}.isJust())
175 resultObject->setValue("{{parameter.name}}", toValue({{parameter.nam e}}.fromJust()));
176 {% else %}
177 resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(para meter).to_raw_type % parameter.name}}));
178 {% endif %}
179 {% endfor %}
180 sendIfActive(std::move(resultObject), ErrorString());
181 }
182
183 void sendFailure(const ErrorString& error) override
184 {
185 DCHECK(error.length());
186 sendIfActive(nullptr, error);
187 }
188 };
189 {% endif %}
190
191 void DispatcherImpl::{{domain.domain}}_{{command.name}}(int callId, std::unique_ ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors)
192 {
193 if (!m_{{domain.domain | lower}}Agent)
194 errors->addError("{{domain.domain}} handler is not available.");
195
196 if (errors->hasErrors()) {
197 reportProtocolError(callId, InvalidParams, kInvalidRequest, errors);
198 return;
199 }
200 {% if "parameters" in command %}
201
202 // Prepare input parameters.
203 protocol::DictionaryValue* object = DictionaryValue::cast(requestMessageObje ct->get("params"));
204 errors->push();
205 {% for property in command.parameters %}
206 protocol::Value* {{property.name}}Value = object ? object->get("{{property.n ame}}") : nullptr;
207 {% if property.optional %}
208 Maybe<{{resolve_type(property).raw_type}}> in_{{property.name}};
209 if ({{property.name}}Value) {
210 errors->setName("{{property.name}}");
211 in_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::p arse({{property.name}}Value, errors);
212 }
213 {% else %}
214 errors->setName("{{property.name}}");
215 {{resolve_type(property).type}} in_{{property.name}} = FromValue<{{resolve_t ype(property).raw_type}}>::parse({{property.name}}Value, errors);
216 {% endif %}
217 {% endfor %}
218 errors->pop();
219 if (errors->hasErrors()) {
220 reportProtocolError(callId, InvalidParams, kInvalidRequest, errors);
221 return;
222 }
223 {% endif %}
224
225 {% if "async" in command %}
226 std::unique_ptr<{{domain.domain}}{{command.name | to_title_case}}Callback> c allback(new {{domain.domain}}{{command.name | to_title_case}}Callback(weakPtr(), callId));
227 {% elif "returns" in command %}
228 // Declare output parameters.
229 std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create( );
230 {% for property in command.returns %}
231 {% if "optional" in property %}
232 Maybe<{{resolve_type(property).raw_type}}> out_{{property.name}};
233 {% else %}
234 {{resolve_type(property).type}} out_{{property.name}};
235 {% endif %}
236 {% endfor %}
237 {% endif %}
238
239 std::unique_ptr<DispatcherImplWeakPtr> weak = weakPtr();
240 ErrorString error;
241 m_{{domain.domain | lower}}Agent->{{command.name}}(&error
242 {%- for property in command.parameters -%}
243 {%- if "optional" in property -%}
244 , in_{{property.name}}
245 {%- else -%}
246 , {{resolve_type(property).to_pass_type % ("in_" + property.name)}}
247 {%- endif -%}
248 {%- endfor %}
249 {%- if "async" in command -%}
250 , std::move(callback)
251 {%- elif "returns" in command %}
252 {%- for property in command.returns -%}
253 , &out_{{property.name}}
254 {%- endfor %}
255 {% endif %});
256 {% if "returns" in command and not("async" in command) %}
257 if (!error.length()) {
258 {% for parameter in command.returns %}
259 {% if "optional" in parameter %}
260 if (out_{{parameter.name}}.isJust())
261 result->setValue("{{parameter.name}}", toValue(out_{{parameter.name} }.fromJust()));
262 {% else %}
263 result->setValue("{{parameter.name}}", toValue({{resolve_type(parameter) .to_raw_type % ("out_" + parameter.name)}}));
264 {% endif %}
265 {% endfor %}
266 }
267 if (weak->get())
268 weak->get()->sendResponse(callId, error, std::move(result));
269 {% elif not("async" in command) %}
270 if (weak->get())
271 weak->get()->sendResponse(callId, error);
272 {% endif %}
273 }
274 {% endfor %}
275 {% endfor %}
276
277 std::unique_ptr<Dispatcher> Dispatcher::create(FrontendChannel* frontendChannel)
278 {
279 return wrapUnique(new DispatcherImpl(frontendChannel));
280 }
281
282 void DispatcherImpl::dispatch(const String16& message)
283 {
284 int callId = 0;
285 std::unique_ptr<protocol::Value> parsedMessage = parseJSON(message);
286 DCHECK(parsedMessage);
287 std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue:: cast(std::move(parsedMessage));
288 DCHECK(messageObject);
289
290 protocol::Value* callIdValue = messageObject->get("id");
291 bool success = callIdValue->asNumber(&callId);
292 DCHECK(success);
293
294 protocol::Value* methodValue = messageObject->get("method");
295 String16 method;
296 success = methodValue && methodValue->asString(&method);
297 DCHECK(success);
298
299 protocol::HashMap<String16, CallHandler>::iterator it = m_dispatchMap.find(m ethod);
300 if (it == m_dispatchMap.end()) {
301 reportProtocolError(callId, MethodNotFound, "'" + method + "' wasn't fou nd");
302 return;
303 }
304
305 protocol::ErrorSupport errors;
306 ((*this).*(*it->second))(callId, std::move(messageObject), &errors);
307 }
308
309 void DispatcherImpl::sendResponse(int callId, const ErrorString& invocationError , ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result)
310 {
311 if (invocationError.length() || (errors && errors->hasErrors())) {
312 reportProtocolError(callId, ServerError, invocationError, errors);
313 return;
314 }
315
316 std::unique_ptr<protocol::DictionaryValue> responseMessage = DictionaryValue ::create();
317 responseMessage->setNumber("id", callId);
318 responseMessage->setObject("result", std::move(result));
319 if (m_frontendChannel)
320 m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONS tring());
321 }
322
323 void Dispatcher::reportProtocolError(int callId, CommonErrorCode code, const Str ing16& errorMessage) const
324 {
325 ErrorSupport errors;
326 reportProtocolError(callId, code, errorMessage, &errors);
327 }
328
329 void DispatcherImpl::reportProtocolError(int callId, CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) const
330 {
331 DCHECK(code >=0);
332 DCHECK((unsigned)code < m_commonErrors.size());
333 DCHECK(m_commonErrors[code]);
334 std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create() ;
335 error->setNumber("code", m_commonErrors[code]);
336 error->setString("message", errorMessage);
337 DCHECK(error);
338 if (errors && errors->hasErrors())
339 error->setString("data", errors->errors());
340 std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create ();
341 message->setObject("error", std::move(error));
342 message->setNumber("id", callId);
343 if (m_frontendChannel)
344 m_frontendChannel->sendProtocolResponse(callId, message->toJSONString()) ;
345 }
346
347 bool Dispatcher::getCommandName(const String16& message, String16* result)
348 {
349 std::unique_ptr<protocol::Value> value = parseJSON(message);
350 if (!value)
351 return false;
352
353 protocol::DictionaryValue* object = DictionaryValue::cast(value.get());
354 if (!object)
355 return false;
356
357 if (!object->getString("method", result))
358 return false;
359
360 return true;
361 }
362
363 } // namespace protocol
364 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698