| 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 |