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

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

Issue 1702673002: DevTools: migrate remote debugging protocol generators to jinja2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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/JSONParser.h"
10 #include "platform/inspector_protocol/FrontendChannel.h"
11 #include "wtf/text/CString.h"
12
13 namespace blink {
14 namespace protocol {
15
16 using protocol::OptionalValue;
17
18 class DispatcherImpl : public Dispatcher {
19 public:
20 DispatcherImpl(FrontendChannel* frontendChannel)
21 : m_frontendChannel(frontendChannel)
22 {% for domain in api.domains %}
23 , m_{{domain.domain | lower}}Agent(0)
24 {% endfor %}
25 {
26 {% for domain in api.domains %}
27 {% for command in domain.commands %}
28 {% if "redirect" in command %}{% continue %}{% endif %}
29 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
30 m_dispatchMap.add("{{domain.domain}}.{{command.name}}", &DispatcherImpl: :{{domain.domain}}_{{command.name}});
31 {% endfor %}
32 {% endfor %}
33
34 // Initialize common errors.
35 m_commonErrors.insert(ParseError, -32700);
36 m_commonErrors.insert(InvalidRequest, -32600);
37 m_commonErrors.insert(MethodNotFound, -32601);
38 m_commonErrors.insert(InvalidParams, -32602);
39 m_commonErrors.insert(InternalError, -32603);
40 m_commonErrors.insert(ServerError, -32000);
41 }
42
43 virtual void clearFrontend() { m_frontendChannel = 0; }
44 virtual void dispatch(int sessionId, const String& message);
45 virtual void reportProtocolError(int sessionId, int callId, CommonErrorCode, const String& errorMessage, PassRefPtr<JSONValue> data) const;
46 using Dispatcher::reportProtocolError;
47
48 void sendResponse(int sessionId, int callId, const ErrorString& invocationEr ror, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result);
49 bool isActive() { return m_frontendChannel; }
50
51 {% for domain in api.domains %}
52 virtual void registerAgent({{domain.domain}}CommandHandler* agent) { ASSERT( !m_{{domain.domain | lower}}Agent); m_{{domain.domain | lower}}Agent = agent; }
53 {% endfor %}
54
55 private:
56 using CallHandler = void (DispatcherImpl::*)(int sessionId, int callId, JSON Object* messageObject, JSONArray* protocolErrors);
57 using DispatchMap = HashMap<String, CallHandler>;
58
59 {% for domain in api.domains %}
60 {% for command in domain.commands %}
61 {% if "redirect" in command %}{% continue %}{% endif %}
62 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
63 void {{domain.domain}}_{{command.name}}(int sessionId, int callId, JSONObjec t* requestMessageObject, JSONArray* protocolErrors);
64 {% endfor %}
65 {% endfor %}
66
67 FrontendChannel* m_frontendChannel;
68
69 {% for domain in api.domains %}
70 {{domain.domain}}CommandHandler* m_{{domain.domain | lower}}Agent;
71 {% endfor %}
72
73 template<typename R, typename V, typename V0>
74 static R getPropertyValueImpl(JSONObject* object, const char* name, bool* va lueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONVal ue*, V*), const char* type_name);
75
76 static OptionalValue<int> getInteger(JSONObject* object, const char* name, b ool isOptional, JSONArray* protocolErrors);
77 static OptionalValue<double> getNumber(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
78 static OptionalValue<String> getString(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
79 static OptionalValue<bool> getBoolean(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
80 static PassRefPtr<JSONObject> getObject(JSONObject* object, const char* name , bool isOptional, JSONArray* protocolErrors);
81 static PassRefPtr<JSONArray> getArray(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors);
82
83 void sendResponse(int sessionId, int callId, ErrorString invocationError, Pa ssRefPtr<JSONObject> result)
84 {
85 sendResponse(sessionId, callId, invocationError, RefPtr<JSONValue>(), re sult);
86 }
87
88 void sendResponse(int sessionId, int callId, ErrorString invocationError)
89 {
90 sendResponse(sessionId, callId, invocationError, RefPtr<JSONValue>(), JS ONObject::create());
91 }
92
93 static const char InvalidParamsFormatString[];
94
95 DispatchMap m_dispatchMap;
96 Vector<int> m_commonErrors;
97 };
98
99 const char DispatcherImpl::InvalidParamsFormatString[] = "Some arguments of meth od '%s' can't be processed";
100 {% for domain in api.domains %}
101 {% for command in domain.commands %}
102 {% if "redirect" in command %}{% continue %}{% endif %}
103 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %}
104
105 {% if "async" in command %}
106 Dispatcher::{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Cal lback::{{command.name | to_title_case}}Callback(PassRefPtr<DispatcherImpl> backe ndImpl, int sessionId, int id) : CallbackBase(backendImpl, sessionId, id) { }
107
108 void Dispatcher::{{domain.domain}}CommandHandler::{{command.name | to_title_case }}Callback::sendSuccess(
109 {%- for parameter in command.returns -%}
110 {%- if "optional" in parameter -%}
111 {{resolve_type(parameter).optional_pass_type}} {{parameter.name}}
112 {%- else -%}
113 {{resolve_type(parameter).pass_type}} {{parameter.name}}
114 {%- endif -%}
115 {%- if not loop.last -%}, {% endif -%}
116 {% endfor %})
117 {
118 RefPtr<JSONObject> resultObject = JSONObject::create();
119 {% for parameter in command.returns %}
120 {% if "optional" in parameter %}
121 {{resolve_type(parameter).optional_type}} opt_{{parameter.name}} = {{paramet er.name}};
122 if (hasValue({{parameter.name}}))
123 resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(para meter).from_optional_out % ("opt_" + parameter.name)}}));
124 {% else %}
125 resultObject->setValue("{{parameter.name}}", toValue({{parameter.name}}));
126 {% endif %}
127 {% endfor %}
128 sendIfActive(resultObject.release(), ErrorString(), PassRefPtr<JSONValue>()) ;
129 }
130 {% endif %}
131
132 void DispatcherImpl::{{domain.domain}}_{{command.name}}(int sessionId, int callI d, JSONObject* requestMessageObject, JSONArray* protocolErrors)
133 {
134 if (!m_{{domain.domain | lower}}Agent)
135 protocolErrors->pushString("Inspector handler is not available.");
136
137 if (protocolErrors->length()) {
138 reportProtocolError(sessionId, callId, InvalidParams, String::format(Inv alidParamsFormatString, "{{domain.domain}}.{{command.name}}"), protocolErrors);
139 return;
140 }
141
142 {% if "parameters" in command %}
143 // Prepare input parameters.
144 RefPtr<JSONObject> paramsContainer = requestMessageObject->getObject("params ");
145 JSONObject* paramsContainerPtr = paramsContainer.get();
146 {% for property in command.parameters %}
147 {{resolve_type(property).optional_type}} in_{{property.name}} = {{resolve_ty pe(property).json_getter % ("paramsContainerPtr, \"" + property.name + "\", " + ("true" if "optional" in property else "false") + ", protocolErrors")}};
148 {% endfor %}
149 {% endif %}
150
151 if (protocolErrors->length()) {
152 reportProtocolError(sessionId, callId, InvalidParams, String::format(Inv alidParamsFormatString, "{{domain.domain}}.{{command.name}}"), protocolErrors);
153 return;
154 }
155
156 {% if "async" in command %}
157 RefPtr<{{domain.domain}}CommandHandler::{{command.name | to_title_case}}Call back> callback = adoptRef(new {{domain.domain}}CommandHandler::{{command.name | to_title_case}}Callback(this, sessionId, callId));
158 {% elif "returns" in command %}
159 // Declare output parameters.
160 RefPtr<JSONObject> result = JSONObject::create();
161 {% for property in command.returns %}
162 {% if "optional" in property %}
163 {{resolve_type(property).optional_type}} out_{{property.name}};
164 {% else %}
165 {{resolve_type(property).type}} out_{{property.name}};
166 {% endif %}
167 {% endfor %}
168 {% endif %}
169
170 ErrorString error;
171 m_{{domain.domain | lower}}Agent->{{command.name}}(&error
172 {%- for property in command.parameters -%}
173 {%- if "optional" in property -%}
174 , {{resolve_type(property).to_pass_type % ("in_" + property.name)}}
175 {%- else -%}
176 , {{resolve_type(property).from_optional_out % ("in_" + property.name)}}
177 {%- endif -%}
178 {%- endfor %}
179 {%- if "async" in command -%}
180 , callback.release()
181 {%- elif "returns" in command %}
182 {%- for property in command.returns -%}
183 , &out_{{property.name}}
184 {%- endfor %}
185 {% endif %});
186 {% if "returns" in command and not("async" in command) %}
187 if (!error.length()) {
188 {% for parameter in command.returns %}
189 {% if "optional" in parameter %}
190 if (hasValue(out_{{parameter.name}}))
191 result->setValue("{{parameter.name}}", toValue({{resolve_type(parame ter).from_optional_out % ("out_" + parameter.name)}}));
192 {% else %}
193 result->setValue("{{parameter.name}}", toValue(out_{{resolve_type(parame ter).to_pass_type % parameter.name}}));
194 {% endif %}
195 {% endfor %}
196 }
197 sendResponse(sessionId, callId, error, result);
198 {% elif not("async" in command) %}
199 sendResponse(sessionId, callId, error);
200 {% endif %}
201 }
202 {% endfor %}
203 {% endfor %}
204
205 PassRefPtr<Dispatcher> Dispatcher::create(FrontendChannel* frontendChannel)
206 {
207 return adoptRef(new DispatcherImpl(frontendChannel));
208 }
209
210 void DispatcherImpl::dispatch(int sessionId, const String& message)
211 {
212 RefPtr<Dispatcher> protect(this);
213 int callId = 0;
214 RefPtr<JSONValue> parsedMessage = parseJSON(message);
215 ASSERT(parsedMessage);
216 RefPtr<JSONObject> messageObject = parsedMessage->asObject();
217 ASSERT(messageObject);
218
219 RefPtr<JSONValue> callIdValue = messageObject->get("id");
220 bool success = callIdValue->asNumber(&callId);
221 ASSERT_UNUSED(success, success);
222
223 RefPtr<JSONValue> methodValue = messageObject->get("method");
224 String method;
225 success = methodValue && methodValue->asString(&method);
226 ASSERT_UNUSED(success, success);
227
228 HashMap<String, CallHandler>::iterator it = m_dispatchMap.find(method);
229 if (it == m_dispatchMap.end()) {
230 reportProtocolError(sessionId, callId, MethodNotFound, "'" + method + "' wasn't found");
231 return;
232 }
233
234 RefPtr<JSONArray> protocolErrors = JSONArray::create();
235 ((*this).*it->value)(sessionId, callId, messageObject.get(), protocolErrors. get());
236 }
237
238 void DispatcherImpl::sendResponse(int sessionId, int callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result)
239 {
240 if (invocationError.length()) {
241 reportProtocolError(sessionId, callId, ServerError, invocationError, err orData);
242 return;
243 }
244
245 RefPtr<JSONObject> responseMessage = JSONObject::create();
246 responseMessage->setNumber("id", callId);
247 responseMessage->setObject("result", result);
248 if (m_frontendChannel)
249 m_frontendChannel->sendProtocolResponse(sessionId, callId, responseMessa ge.release());
250 }
251
252 void Dispatcher::reportProtocolError(int sessionId, int callId, CommonErrorCode code, const String& errorMessage) const
253 {
254 reportProtocolError(sessionId, callId, code, errorMessage, PassRefPtr<JSONVa lue>());
255 }
256
257 void DispatcherImpl::reportProtocolError(int sessionId, int callId, CommonErrorC ode code, const String& errorMessage, PassRefPtr<JSONValue> data) const
258 {
259 ASSERT(code >=0);
260 ASSERT((unsigned)code < m_commonErrors.size());
261 ASSERT(m_commonErrors[code]);
262 RefPtr<JSONObject> error = JSONObject::create();
263 error->setNumber("code", m_commonErrors[code]);
264 error->setString("message", errorMessage);
265 ASSERT(error);
266 if (data)
267 error->setValue("data", data);
268 RefPtr<JSONObject> message = JSONObject::create();
269 message->setObject("error", error);
270 message->setNumber("id", callId);
271 if (m_frontendChannel)
272 m_frontendChannel->sendProtocolResponse(sessionId, callId, message.relea se());
273 }
274
275 template<typename R, typename V, typename V0>
276 R DispatcherImpl::getPropertyValueImpl(JSONObject* object, const char* name, boo l* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JS ONValue*, V*), const char* type_name)
277 {
278 ASSERT(protocolErrors);
279
280 if (valueFound)
281 *valueFound = false;
282
283 V value = initial_value;
284
285 if (!object) {
286 if (!valueFound) {
287 // Required parameter in missing params container.
288 protocolErrors->pushString(String::format("'params' object must cont ain required parameter '%s' with type '%s'.", name, type_name));
289 }
290 return value;
291 }
292
293 JSONObject::const_iterator end = object->end();
294 JSONObject::const_iterator valueIterator = object->find(name);
295
296 if (valueIterator == end) {
297 if (!valueFound)
298 protocolErrors->pushString(String::format("Parameter '%s' with type '%s' was not found.", name, type_name));
299 return value;
300 }
301
302 if (!as_method(valueIterator->value.get(), &value))
303 protocolErrors->pushString(String::format("Parameter '%s' has wrong type . It must be '%s'.", name, type_name));
304 else
305 if (valueFound)
306 *valueFound = true;
307 return value;
308 }
309
310 struct AsMethodBridges {
311 static bool asInteger(JSONValue* value, int* output) { return value->asNumbe r(output); }
312 static bool asNumber(JSONValue* value, double* output) { return value->asNum ber(output); }
313 static bool asString(JSONValue* value, String* output) { return value->asStr ing(output); }
314 static bool asBoolean(JSONValue* value, bool* output) { return value->asBool ean(output); }
315 static bool asObject(JSONValue* value, RefPtr<JSONObject>* output) { return value->asObject(output); }
316 static bool asArray(JSONValue* value, RefPtr<JSONArray>* output) { return va lue->asArray(output); }
317 };
318
319 OptionalValue<int> DispatcherImpl::getInteger(JSONObject* object, const char* na me, bool isOptional, JSONArray* protocolErrors)
320 {
321 bool valueFound = false;
322 int result = getPropertyValueImpl<int, int, int>(object, name, isOptional ? &valueFound : 0, protocolErrors, 0, AsMethodBridges::asInteger, "Number");
323 return valueFound || !isOptional ? OptionalValue<int>(result) : OptionalValu e<int>();
324 }
325
326 OptionalValue<double> DispatcherImpl::getNumber(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
327 {
328 bool valueFound = false;
329 double result = getPropertyValueImpl<double, double, double>(object, name, i sOptional ? &valueFound : 0, protocolErrors, 0, AsMethodBridges::asNumber, "Numb er");
330 return valueFound || !isOptional ? OptionalValue<double>(result) : OptionalV alue<double>();
331 }
332
333 OptionalValue<String> DispatcherImpl::getString(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
334 {
335 bool valueFound = false;
336 String result = getPropertyValueImpl<String, String, String>(object, name, i sOptional ? &valueFound : 0, protocolErrors, "", AsMethodBridges::asString, "Str ing");
337 return valueFound || !isOptional ? OptionalValue<String>(result) : OptionalV alue<String>();
338 }
339
340 OptionalValue<bool> DispatcherImpl::getBoolean(JSONObject* object, const char* n ame, bool isOptional, JSONArray* protocolErrors)
341 {
342 bool valueFound = false;
343 bool result = getPropertyValueImpl<bool, bool, bool>(object, name, isOptiona l ? &valueFound : 0, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean ");
344 return valueFound || !isOptional ? OptionalValue<bool>(result) : OptionalVal ue<bool>();
345 }
346
347 PassRefPtr<JSONObject> DispatcherImpl::getObject(JSONObject* object, const char* name, bool isOptional, JSONArray* protocolErrors)
348 {
349 bool valueFound = false;
350 return getPropertyValueImpl<PassRefPtr<JSONObject>, RefPtr<JSONObject>, JSON Object*>(object, name, isOptional ? &valueFound : 0, protocolErrors, 0, AsMethod Bridges::asObject, "Object");
351 }
352
353 PassRefPtr<JSONArray> DispatcherImpl::getArray(JSONObject* object, const char* n ame, bool isOptional, JSONArray* protocolErrors)
354 {
355 bool valueFound = false;
356 return getPropertyValueImpl<PassRefPtr<JSONArray>, RefPtr<JSONArray>, JSONAr ray*>(object, name, isOptional ? &valueFound : 0, protocolErrors, 0, AsMethodBri dges::asArray, "Array");
357 }
358
359 bool Dispatcher::getCommandName(const String& message, String* result)
360 {
361 RefPtr<JSONValue> value = parseJSON(message);
362 if (!value)
363 return false;
364
365 RefPtr<JSONObject> object = value->asObject();
366 if (!object)
367 return false;
368
369 if (!object->getString("method", result))
370 return false;
371
372 return true;
373 }
374
375 Dispatcher::CallbackBase::CallbackBase(PassRefPtr<DispatcherImpl> backendImpl, i nt sessionId, int id)
376 : m_backendImpl(backendImpl), m_sessionId(sessionId), m_id(id), m_alreadySen t(false) { }
377
378 Dispatcher::CallbackBase::~CallbackBase() { }
379
380 void Dispatcher::CallbackBase::sendFailure(const ErrorString& error)
381 {
382 ASSERT(error.length());
383 sendIfActive(nullptr, error, PassRefPtr<JSONValue>());
384 }
385
386 bool Dispatcher::CallbackBase::isActive()
387 {
388 return !m_alreadySent && m_backendImpl->isActive();
389 }
390
391 void Dispatcher::CallbackBase::sendIfActive(PassRefPtr<JSONObject> partialMessag e, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData)
392 {
393 if (m_alreadySent)
394 return;
395 m_backendImpl->sendResponse(m_sessionId, m_id, invocationError, errorData, p artialMessage);
396 m_alreadySent = true;
397 }
398
399 } // namespace protocol
400 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698