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 |