OLD | NEW |
| (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 "{{config.protocol.package}}/{{domain.domain}}.h" | |
8 | |
9 #include "{{config.protocol.package}}/Protocol.h" | |
10 | |
11 {% for namespace in config.protocol.namespace %} | |
12 namespace {{namespace}} { | |
13 {% endfor %} | |
14 namespace {{domain.domain}} { | |
15 | |
16 // ------------- Enum values from types. | |
17 | |
18 const char Metainfo::domainName[] = "{{domain.domain}}"; | |
19 const char Metainfo::commandPrefix[] = "{{domain.domain}}."; | |
20 const char Metainfo::version[] = "{{domain.version}}"; | |
21 {% for type in domain.types %} | |
22 {% if "enum" in type %} | |
23 | |
24 namespace {{type.id}}Enum { | |
25 {% for literal in type.enum %} | |
26 const char* {{ literal | dash_to_camelcase}} = "{{literal}}"; | |
27 {% endfor %} | |
28 } // namespace {{type.id}}Enum | |
29 {% if type.exported %} | |
30 | |
31 namespace API { | |
32 namespace {{type.id}}Enum { | |
33 {% for literal in type.enum %} | |
34 const char* {{ literal | dash_to_camelcase}} = "{{literal}}"; | |
35 {% endfor %} | |
36 } // namespace {{type.id}}Enum | |
37 } // namespace API | |
38 {% endif %} | |
39 {% endif %} | |
40 {% for property in type.properties %} | |
41 {% if "enum" in property %} | |
42 | |
43 {% for literal in property.enum %} | |
44 const char* {{type.id}}::{{property.name | to_title_case}}Enum::{{literal | dash
_to_camelcase}} = "{{literal}}"; | |
45 {% endfor %} | |
46 {% endif %} | |
47 {% endfor %} | |
48 {% if not (type.type == "object") or not ("properties" in type) %}{% continu
e %}{% endif %} | |
49 | |
50 std::unique_ptr<{{type.id}}> {{type.id}}::parse(protocol::Value* value, ErrorSup
port* errors) | |
51 { | |
52 if (!value || value->type() != protocol::Value::TypeObject) { | |
53 errors->addError("object expected"); | |
54 return nullptr; | |
55 } | |
56 | |
57 std::unique_ptr<{{type.id}}> result(new {{type.id}}()); | |
58 protocol::DictionaryValue* object = DictionaryValue::cast(value); | |
59 errors->push(); | |
60 {% for property in type.properties %} | |
61 protocol::Value* {{property.name}}Value = object->get("{{property.name}}"); | |
62 {% if property.optional %} | |
63 if ({{property.name}}Value) { | |
64 errors->setName("{{property.name}}"); | |
65 result->m_{{property.name}} = ValueConversions<{{resolve_type(property).
raw_type}}>::parse({{property.name}}Value, errors); | |
66 } | |
67 {% else %} | |
68 errors->setName("{{property.name}}"); | |
69 result->m_{{property.name}} = ValueConversions<{{resolve_type(property).raw_
type}}>::parse({{property.name}}Value, errors); | |
70 {% endif %} | |
71 {% endfor %} | |
72 errors->pop(); | |
73 if (errors->hasErrors()) | |
74 return nullptr; | |
75 return result; | |
76 } | |
77 | |
78 std::unique_ptr<protocol::DictionaryValue> {{type.id}}::serialize() const | |
79 { | |
80 std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create(
); | |
81 {% for property in type.properties %} | |
82 {% if property.optional %} | |
83 if (m_{{property.name}}.isJust()) | |
84 result->setValue("{{property.name}}", ValueConversions<{{resolve_type(pr
operty).raw_type}}>::serialize(m_{{property.name}}.fromJust())); | |
85 {% else %} | |
86 result->setValue("{{property.name}}", ValueConversions<{{resolve_type(proper
ty).raw_type}}>::serialize({{resolve_type(property).to_raw_type % ("m_" + proper
ty.name)}})); | |
87 {% endif %} | |
88 {% endfor %} | |
89 return result; | |
90 } | |
91 | |
92 std::unique_ptr<{{type.id}}> {{type.id}}::clone() const | |
93 { | |
94 ErrorSupport errors; | |
95 return parse(serialize().get(), &errors); | |
96 } | |
97 {% if type.exported %} | |
98 | |
99 {{config.exported.string_out}} {{type.id}}::toJSONString() const | |
100 { | |
101 String json = serialize()->toJSONString(); | |
102 return {{config.exported.to_string_out % "json"}}; | |
103 } | |
104 | |
105 // static | |
106 std::unique_ptr<API::{{type.id}}> API::{{type.id}}::fromJSONString(const {{confi
g.exported.string_in}}& json) | |
107 { | |
108 ErrorSupport errors; | |
109 std::unique_ptr<Value> value = parseJSON(json); | |
110 if (!value) | |
111 return nullptr; | |
112 return protocol::{{domain.domain}}::{{type.id}}::parse(value.get(), &errors)
; | |
113 } | |
114 {% endif %} | |
115 {% endfor %} | |
116 | |
117 // ------------- Enum values from params. | |
118 | |
119 {% for command in join_arrays(domain, ["commands", "events"]) %} | |
120 {% for param in join_arrays(command, ["parameters", "returns"]) %} | |
121 {% if "enum" in param %} | |
122 | |
123 namespace {{command.name | to_title_case}} { | |
124 namespace {{param.name | to_title_case}}Enum { | |
125 {% for literal in param.enum %} | |
126 const char* {{ literal | to_title_case}} = "{{literal}}"; | |
127 {% endfor %} | |
128 } // namespace {{param.name | to_title_case}}Enum | |
129 } // namespace {{command.name | to_title_case }} | |
130 {% if param.exported %} | |
131 | |
132 namespace API { | |
133 namespace {{command.name | to_title_case}} { | |
134 namespace {{param.name | to_title_case}}Enum { | |
135 {% for literal in param.enum %} | |
136 const char* {{ literal | to_title_case}} = "{{literal}}"; | |
137 {% endfor %} | |
138 } // namespace {{param.name | to_title_case}}Enum | |
139 } // namespace {{command.name | to_title_case }} | |
140 } // namespace API | |
141 {% endif %} | |
142 {% endif %} | |
143 {% endfor %} | |
144 {% endfor %} | |
145 | |
146 // ------------- Frontend notifications. | |
147 {% for event in domain.events %} | |
148 {% if "handlers" in event and not ("renderer" in event["handlers"]) %}{% con
tinue %}{% endif %} | |
149 | |
150 void Frontend::{{event.name}}( | |
151 {%- for parameter in event.parameters %} | |
152 {% if "optional" in parameter -%} | |
153 const Maybe<{{resolve_type(parameter).raw_type}}>& | |
154 {%- else -%} | |
155 {{resolve_type(parameter).pass_type}} | |
156 {%- endif %} {{parameter.name}}{%- if not loop.last -%}, {% endif -%} | |
157 {% endfor -%}) | |
158 { | |
159 std::unique_ptr<protocol::DictionaryValue> jsonMessage = DictionaryValue::cr
eate(); | |
160 jsonMessage->setString("method", "{{domain.domain}}.{{event.name}}"); | |
161 std::unique_ptr<protocol::DictionaryValue> paramsObject = DictionaryValue::c
reate(); | |
162 {% for parameter in event.parameters %} | |
163 {% if "optional" in parameter %} | |
164 if ({{parameter.name}}.isJust()) | |
165 paramsObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_
type(parameter).raw_type}}>::serialize({{parameter.name}}.fromJust())); | |
166 {% else %} | |
167 paramsObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_type
(parameter).raw_type}}>::serialize({{resolve_type(parameter).to_raw_type % param
eter.name}})); | |
168 {% endif %} | |
169 {% endfor %} | |
170 jsonMessage->setObject("params", std::move(paramsObject)); | |
171 if (m_frontendChannel) | |
172 m_frontendChannel->sendProtocolNotification(jsonMessage->toJSONString())
; | |
173 } | |
174 {% endfor %} | |
175 | |
176 void Frontend::flush() | |
177 { | |
178 m_frontendChannel->flushProtocolNotifications(); | |
179 } | |
180 | |
181 // --------------------- Dispatcher. | |
182 | |
183 class DispatcherImpl : public protocol::DispatcherBase { | |
184 public: | |
185 DispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) | |
186 : DispatcherBase(frontendChannel) | |
187 , m_backend(backend) { | |
188 {% for command in domain.commands %} | |
189 {% if "redirect" in command %}{% continue %}{% endif %} | |
190 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{%
continue %}{% endif %} | |
191 m_dispatchMap["{{domain.domain}}.{{command.name}}"] = &DispatcherImpl::{
{command.name}}; | |
192 {% endfor %} | |
193 } | |
194 ~DispatcherImpl() override { } | |
195 void dispatch(int callId, const String& method, std::unique_ptr<protocol::Di
ctionaryValue> messageObject) override; | |
196 | |
197 protected: | |
198 using CallHandler = void (DispatcherImpl::*)(int callId, std::unique_ptr<Dic
tionaryValue> messageObject, ErrorSupport* errors); | |
199 using DispatchMap = protocol::HashMap<String, CallHandler>; | |
200 DispatchMap m_dispatchMap; | |
201 | |
202 {% for command in domain.commands %} | |
203 {% if "redirect" in command %}{% continue %}{% endif %} | |
204 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{%
continue %}{% endif %} | |
205 void {{command.name}}(int callId, std::unique_ptr<DictionaryValue> requestMe
ssageObject, ErrorSupport*); | |
206 {% endfor %} | |
207 | |
208 Backend* m_backend; | |
209 }; | |
210 | |
211 void DispatcherImpl::dispatch(int callId, const String& method, std::unique_ptr<
protocol::DictionaryValue> messageObject) | |
212 { | |
213 protocol::HashMap<String, CallHandler>::iterator it = m_dispatchMap.find(met
hod); | |
214 if (it == m_dispatchMap.end()) { | |
215 reportProtocolError(callId, MethodNotFound, "'" + method + "' wasn't fou
nd", nullptr); | |
216 return; | |
217 } | |
218 | |
219 protocol::ErrorSupport errors; | |
220 (this->*(it->second))(callId, std::move(messageObject), &errors); | |
221 } | |
222 | |
223 {% for command in domain.commands %} | |
224 {% if "redirect" in command %}{% continue %}{% endif %} | |
225 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{%
continue %}{% endif %} | |
226 {% if "async" in command %} | |
227 | |
228 class {{command.name | to_title_case}}CallbackImpl : public Backend::{{command.n
ame | to_title_case}}Callback, public DispatcherBase::Callback { | |
229 public: | |
230 {{command.name | to_title_case}}CallbackImpl(std::unique_ptr<DispatcherBase:
:WeakPtr> backendImpl, int callId) | |
231 : DispatcherBase::Callback(std::move(backendImpl), callId) { } | |
232 | |
233 void sendSuccess( | |
234 {%- for parameter in command.returns -%} | |
235 {%- if "optional" in parameter -%} | |
236 const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}} | |
237 {%- else -%} | |
238 {{resolve_type(parameter).pass_type}} {{parameter.name}} | |
239 {%- endif -%} | |
240 {%- if not loop.last -%}, {% endif -%} | |
241 {%- endfor -%}) override | |
242 { | |
243 std::unique_ptr<protocol::DictionaryValue> resultObject = DictionaryValu
e::create(); | |
244 {% for parameter in command.returns %} | |
245 {% if "optional" in parameter %} | |
246 if ({{parameter.name}}.isJust()) | |
247 resultObject->setValue("{{parameter.name}}", ValueConversions<{{reso
lve_type(parameter).raw_type}}>::serialize({{parameter.name}}.fromJust())); | |
248 {% else %} | |
249 resultObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_
type(parameter).raw_type}}>::serialize({{resolve_type(parameter).to_raw_type % p
arameter.name}})); | |
250 {% endif %} | |
251 {% endfor %} | |
252 sendIfActive(std::move(resultObject), ErrorString()); | |
253 } | |
254 | |
255 void sendFailure(const ErrorString& error) override | |
256 { | |
257 DCHECK(error.length()); | |
258 sendIfActive(nullptr, error); | |
259 } | |
260 | |
261 }; | |
262 {% endif %} | |
263 | |
264 void DispatcherImpl::{{command.name}}(int callId, std::unique_ptr<DictionaryValu
e> requestMessageObject, ErrorSupport* errors) | |
265 { | |
266 {% if "parameters" in command %} | |
267 // Prepare input parameters. | |
268 protocol::DictionaryValue* object = DictionaryValue::cast(requestMessageObje
ct->get("params")); | |
269 errors->push(); | |
270 {% for property in command.parameters %} | |
271 protocol::Value* {{property.name}}Value = object ? object->get("{{property.n
ame}}") : nullptr; | |
272 {% if property.optional %} | |
273 Maybe<{{resolve_type(property).raw_type}}> in_{{property.name}}; | |
274 if ({{property.name}}Value) { | |
275 errors->setName("{{property.name}}"); | |
276 in_{{property.name}} = ValueConversions<{{resolve_type(property).raw_typ
e}}>::parse({{property.name}}Value, errors); | |
277 } | |
278 {% else %} | |
279 errors->setName("{{property.name}}"); | |
280 {{resolve_type(property).type}} in_{{property.name}} = ValueConversions<{{re
solve_type(property).raw_type}}>::parse({{property.name}}Value, errors); | |
281 {% endif %} | |
282 {% endfor %} | |
283 errors->pop(); | |
284 if (errors->hasErrors()) { | |
285 reportProtocolError(callId, InvalidParams, kInvalidRequest, errors); | |
286 return; | |
287 } | |
288 {% endif %} | |
289 {% if "async" in command %} | |
290 std::unique_ptr<{{command.name | to_title_case}}CallbackImpl> callback(new {
{command.name | to_title_case}}CallbackImpl(weakPtr(), callId)); | |
291 {% elif "returns" in command %} | |
292 // Declare output parameters. | |
293 std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create(
); | |
294 {% for property in command.returns %} | |
295 {% if "optional" in property %} | |
296 Maybe<{{resolve_type(property).raw_type}}> out_{{property.name}}; | |
297 {% else %} | |
298 {{resolve_type(property).type}} out_{{property.name}}; | |
299 {% endif %} | |
300 {% endfor %} | |
301 {% endif %} | |
302 | |
303 std::unique_ptr<DispatcherBase::WeakPtr> weak = weakPtr(); | |
304 {% if not("async" in command) %} | |
305 ErrorString error; | |
306 m_backend->{{command.name}}(&error | |
307 {%- for property in command.parameters -%} | |
308 {%- if "optional" in property -%} | |
309 , in_{{property.name}} | |
310 {%- else -%} | |
311 , {{resolve_type(property).to_pass_type % ("in_" + property.name)}} | |
312 {%- endif -%} | |
313 {%- endfor %} | |
314 {%- if "returns" in command %} | |
315 {%- for property in command.returns -%} | |
316 , &out_{{property.name}} | |
317 {%- endfor %} | |
318 {% endif %}); | |
319 {% if "returns" in command and not("async" in command) %} | |
320 if (!error.length()) { | |
321 {% for parameter in command.returns %} | |
322 {% if "optional" in parameter %} | |
323 if (out_{{parameter.name}}.isJust()) | |
324 result->setValue("{{parameter.name}}", ValueConversions<{{resolve_ty
pe(parameter).raw_type}}>::serialize(out_{{parameter.name}}.fromJust())); | |
325 {% else %} | |
326 result->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(p
arameter).raw_type}}>::serialize({{resolve_type(parameter).to_raw_type % ("out_"
+ parameter.name)}})); | |
327 {% endif %} | |
328 {% endfor %} | |
329 } | |
330 if (weak->get()) | |
331 weak->get()->sendResponse(callId, error, std::move(result)); | |
332 {% else %} | |
333 if (weak->get()) | |
334 weak->get()->sendResponse(callId, error); | |
335 {% endif %} | |
336 {%- else %} | |
337 m_backend->{{command.name}}( | |
338 {%- for property in command.parameters -%} | |
339 {%- if "optional" in property -%} | |
340 in_{{property.name}}, | |
341 {%- else -%} | |
342 {{resolve_type(property).to_pass_type % ("in_" + property.name)}}, | |
343 {%- endif -%} | |
344 {%- endfor -%} | |
345 std::move(callback)); | |
346 {% endif %} | |
347 } | |
348 {% endfor %} | |
349 | |
350 // static | |
351 void Dispatcher::wire(UberDispatcher* dispatcher, Backend* backend) | |
352 { | |
353 dispatcher->registerBackend("{{domain.domain}}", wrapUnique(new DispatcherIm
pl(dispatcher->channel(), backend))); | |
354 } | |
355 | |
356 } // {{domain.domain}} | |
357 {% for namespace in config.protocol.namespace %} | |
358 } // namespace {{namespace}} | |
359 {% endfor %} | |
OLD | NEW |