2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
10 blink_protocol_path
= sys
.argv
[1]
11 browser_protocol_path
= sys
.argv
[2]
12 output_cc_path
= sys
.argv
[3]
13 output_h_path
= sys
.argv
[4]
16 // Copyright 2014 The Chromium Authors. All rights reserved.
17 // Use of this source code is governed by a BSD-style license that can be
18 // found in the LICENSE file.
20 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
22 // content/public/browser/devtools_protocol_handler_generator.py from
23 // third_party/WebKit/Source/devtools/protocol.json and
24 // content/browser/devtools/browser_protocol.json
27 template_h
= string
.Template(header
+ """\
29 #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_
30 #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_
32 #include "content/browser/devtools/protocol/devtools_protocol_client.h"
36 class DevToolsProtocolDispatcher;
40 extern const char kProtocolVersion[];
42 bool IsSupportedProtocolVersion(const std::string& version);
45 base::Value* CreateValue(const T& param) {
46 return new base::FundamentalValue(param);
50 base::Value* CreateValue(scoped_ptr<T>& param) {
51 return param.release();
55 base::Value* CreateValue(scoped_refptr<T> param) {
56 return param->ToValue().release();
60 base::Value* CreateValue(const std::vector<T> param) {
61 base::ListValue* result = new base::ListValue();
62 for (auto& item : param) {
63 result->Append(CreateValue(item));
69 base::Value* CreateValue(const std::string& param);
73 } // namespace devtools
75 class DevToolsProtocolDispatcher {
77 using Notifier = DevToolsProtocolClient::RawMessageCallback;
78 using CommandHandler =
79 base::Callback<bool(int, scoped_ptr<base::DictionaryValue>)>;
81 explicit DevToolsProtocolDispatcher(const Notifier& notifier);
82 ~DevToolsProtocolDispatcher();
84 CommandHandler FindCommandHandler(const std::string& method);
89 using Response = DevToolsProtocolClient::Response;
90 using CommandHandlers = std::map<std::string, CommandHandler>;
95 DevToolsProtocolClient client_;
96 CommandHandlers command_handlers_;
100 } // namespace content
102 #endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_
105 tmpl_typedef
= string
.Template("""\
106 namespace ${domain} {
107 typedef ${param_type} ${declared_name};
108 } // namespace ${domain}
111 tmpl_struct
= string
.Template("""\
112 namespace ${domain} {
114 struct ${declared_name}Builder
115 : base::RefCounted<${declared_name}Builder<MASK>> {
124 static scoped_refptr<${declared_name}Builder<kNoneSet>> Create() {
125 return new ${declared_name}Builder<kNoneSet>();
128 scoped_ptr<base::DictionaryValue> ToValue() {
129 static_assert(MASK == kAllSet, "required properties missing");
130 return make_scoped_ptr(dict_->DeepCopy());
134 friend struct ${declared_name}Builder<0>;
136 ${declared_name}Builder() : dict_(new base::DictionaryValue()) {
139 template<class T> T* ThisAs() {
140 static_assert(sizeof(*this) == sizeof(T), "cannot cast");
141 return reinterpret_cast<T*>(this);
144 scoped_ptr<base::DictionaryValue> dict_;
147 typedef ${declared_name}Builder<0> ${declared_name};
149 } // namespace ${domain}
152 tmpl_builder_setter_req
= string
.Template("""\
153 scoped_refptr<${declared_name}Builder<MASK & ~k${Param}>>
154 set_${param}(${pass_type} ${param}) {
155 static_assert(MASK & k${Param}, "already set");
156 dict_->Set("${proto_param}", CreateValue(${param}));
157 return ThisAs<${declared_name}Builder<MASK & ~k${Param}>>();
161 tmpl_builder_setter_opt
= string
.Template("""\
162 scoped_refptr<${declared_name}Builder<MASK>>
163 set_${param}(${pass_type} ${param}) {
164 dict_->Set("${proto_param}", CreateValue(${param}));
169 tmpl_builder_enum
= string
.Template("""\
170 k${Param} = 1 << ${ordinal},
173 tmpl_builder_none_set
= string
.Template("""\
174 kNoneSet = ${all_fields}
177 tmpl_named_enum
= string
.Template("""\
178 namespace ${domain} {
180 } // namespace ${domain}
183 tmpl_inline_enum
= string
.Template("""\
184 namespace ${domain} {
185 namespace ${subdomain} {
187 } // namespace ${subdomain}
188 } // namespace ${domain}
191 tmpl_enum_value
= string
.Template("""\
192 extern const char k${Enum}${Value}[];
195 tmpl_enum_value_def
= string
.Template("""\
196 const char k${Enum}${Value}[] = "${value}";
199 tmpl_handler
= string
.Template("""\
200 namespace ${domain} {
201 class ${Domain}Handler;
202 } // namespace domain
205 tmpl_client
= string
.Template("""\
206 namespace ${domain} {
207 class Client : public DevToolsProtocolClient {
209 explicit Client(const RawMessageCallback& raw_message_callback);
214 } // namespace ${domain}
217 tmpl_event
= string
.Template("""\
219 scoped_refptr<${Command}Params> params);
222 tmpl_response
= string
.Template("""\
223 void Send${Command}Response(
224 DevToolsCommandId command_id,
225 scoped_refptr<${Command}Response> params);
228 tmpl_setter
= string
.Template("""\
229 void Set${Domain}Handler(
230 devtools::${domain}::${Domain}Handler* ${domain}_handler);
233 tmpl_callback
= string
.Template("""\
234 bool On${Domain}${Command}(
235 DevToolsCommandId command_id,
236 scoped_ptr<base::DictionaryValue> params);
239 tmpl_field
= string
.Template("""\
240 devtools::${domain}::${Domain}Handler* ${domain}_handler_;
243 template_cc
= string
.Template(header
+ """\
245 #include "base/bind.h"
246 #include "base/strings/string_number_conversions.h"
247 #include "base/strings/string_split.h"
252 DevToolsProtocolDispatcher::DevToolsProtocolDispatcher(
253 const Notifier& notifier)
254 : notifier_(notifier),
259 DevToolsProtocolDispatcher::~DevToolsProtocolDispatcher() {
262 DevToolsProtocolDispatcher::CommandHandler
263 DevToolsProtocolDispatcher::FindCommandHandler(const std::string& method) {
264 CommandHandlers::iterator it = command_handlers_.find(method);
265 return it == command_handlers_.end() ? CommandHandler() : it->second;
272 const char kProtocolVersion[] = "${major}.${minor}";
274 bool IsSupportedProtocolVersion(const std::string& version) {
275 std::vector<base::StringPiece> tokens = base::SplitStringPiece(
276 version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
278 return tokens.size() == 2 &&
279 base::StringToInt(tokens[0], &major) && major == ${major} &&
280 base::StringToInt(tokens[1], &minor) && minor <= ${minor};
284 base::Value* CreateValue(const std::string& param) {
285 return new base::StringValue(param);
290 } // namespace devtools
292 } // namespace content
295 tmpl_include
= string
.Template("""\
296 #include "content/browser/devtools/protocol/${domain}_handler.h"
299 tmpl_field_init
= string
.Template("${domain}_handler_(nullptr)")
301 tmpl_setter_impl
= string
.Template("""\
302 void DevToolsProtocolDispatcher::Set${Domain}Handler(
303 devtools::${domain}::${Domain}Handler* ${domain}_handler) {
304 DCHECK(!${domain}_handler_);
305 ${domain}_handler_ = ${domain}_handler;
310 tmpl_register
= string
.Template("""\
311 command_handlers_["${Domain}.${command}"] =
313 &DevToolsProtocolDispatcher::On${TargetDomain}${Command},
314 base::Unretained(this));
317 tmpl_init_client
= string
.Template("""\
318 ${domain}_handler_->SetClient(make_scoped_ptr(
319 new devtools::${domain}::Client(notifier_)));
322 tmpl_callback_impl
= string
.Template("""\
323 bool DevToolsProtocolDispatcher::On${Domain}${Command}(
324 DevToolsCommandId command_id,
325 scoped_ptr<base::DictionaryValue> params) {
327 Response response = ${domain}_handler_->${Command}(${args});
328 scoped_ptr<base::DictionaryValue> protocol_response;
329 if (client_.SendError(command_id, response))
331 if (response.IsFallThrough())
333 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
335 client_.SendSuccess(command_id, result.Pass());
340 tmpl_wrap
= string
.Template("""\
341 result->Set("${proto_param}", devtools::CreateValue(out_${param}));
344 tmpl_callback_async_impl
= string
.Template("""\
345 bool DevToolsProtocolDispatcher::On${Domain}${Command}(
346 DevToolsCommandId command_id,
347 scoped_ptr<base::DictionaryValue> params) {
349 Response response = ${domain}_handler_->${Command}(${args});
350 if (client_.SendError(command_id, response))
352 return !response.IsFallThrough();
356 tmpl_prep_req
= string
.Template("""\
357 ${raw_type} in_${param}${init};
358 if (!params || !params->Get${Type}("${proto_param}", &in_${param})) {
359 client_.SendError(command_id, Response::InvalidParams("${proto_param}"));
364 tmpl_prep_req_list
= string
.Template("""\
365 base::ListValue* list_${param} = nullptr;
366 if (!params || !params->GetList("${proto_param}", &list_${param})) {
367 client_.SendError(command_id, Response::InvalidParams("${proto_param}"));
370 std::vector<${item_type}> in_${param};
371 for (base::ListValue::const_iterator it =
372 list_${param}->begin(); it != list_${param}->end(); ++it) {
373 ${item_raw_type} item;
374 if (!(*it)->GetAs${ItemType}(&item)) {
375 client_.SendError(command_id, Response::InvalidParams("${proto_param}"));
378 in_${param}.push_back(${item_pass});
382 tmpl_prep_opt
= string
.Template("""\
383 ${raw_type} in_${param}${init};
384 bool ${param}_found = params && params->Get${Type}(
389 tmpl_prep_output
= string
.Template("""\
390 ${param_type} out_${param}${init};
393 tmpl_arg_name
= string
.Template("in_${param}")
395 tmpl_arg_req
= string
.Template("${param_pass}")
397 tmpl_arg_opt
= string
.Template(
398 "${param}_found ? ${param_pass} : nullptr")
400 tmpl_object_pass
= string
.Template(
401 "make_scoped_ptr<base::DictionaryValue>(${name}->DeepCopy())")
403 tmpl_client_impl
= string
.Template("""\
404 namespace ${domain} {
406 Client::Client(const RawMessageCallback& raw_message_callback)
407 : DevToolsProtocolClient(raw_message_callback) {
415 } // namespace ${domain}
418 tmpl_event_impl
= string
.Template("""\
419 void Client::${Command}(
420 scoped_refptr<${Command}Params> params) {
421 SendNotification("${Domain}.${command}",
422 params->ToValue().Pass());
426 tmpl_response_impl
= string
.Template("""\
427 void Client::Send${Command}Response(
428 DevToolsCommandId command_id,
429 scoped_refptr<${Command}Response> params) {
430 SendSuccess(command_id, params->ToValue().Pass());
434 tmpl_typename
= string
.Template("devtools::${domain}::${declared_name}")
437 return s
[:1].upper() + s
[1:]
441 for i
, c
in enumerate(s
):
443 if (i
> 0) and ((i
< len(s
)-1) and s
[i
+1].islower() or s
[i
-1].islower()):
451 blink_protocol
= json
.loads(open(blink_protocol_path
, "r").read())
452 browser_protocol
= json
.loads(open(browser_protocol_path
, "r").read())
456 handler_method_impls
= []
460 all_domains
= blink_protocol
["domains"] + browser_protocol
["domains"]
462 for json_domain
in all_domains
:
463 if "types" in json_domain
:
464 for json_type
in json_domain
["types"]:
465 types
["%s.%s" % (json_domain
["domain"], json_type
["id"])] = json_type
467 def DeclareStruct(json_properties
, mapping
):
472 for json_prop
in json_properties
:
473 prop_map
= mapping
.copy()
474 prop_map
["proto_param"] = json_prop
["name"]
475 prop_map
["param"] = Uncamelcase(json_prop
["name"])
476 prop_map
["Param"] = Capitalize(json_prop
["name"])
477 prop_map
["subdomain"] = Uncamelcase(prop_map
["declared_name"])
478 del prop_map
["declared_name"]
479 ResolveType(json_prop
, prop_map
)
480 prop_map
["declared_name"] = mapping
["declared_name"]
481 if json_prop
.get("optional"):
482 methods
.append(tmpl_builder_setter_opt
.substitute(prop_map
))
484 methods
.append(tmpl_builder_setter_req
.substitute(prop_map
))
485 enum_items
.append("k%s" % prop_map
["Param"]);
486 fields_enum
.append(tmpl_builder_enum
.substitute(prop_map
,
487 ordinal
= req_fields_num
))
490 all_fields
= "kAllSet"
491 if len(enum_items
) > 0:
492 all_fields
= " | ".join(enum_items
)
493 fields_enum
.append(tmpl_builder_none_set
.substitute(mapping
,
494 all_fields
= all_fields
))
495 type_decls
.append(tmpl_struct
.substitute(mapping
,
496 methods
= "\n".join(methods
),
497 fields_enum
= "".join(fields_enum
)))
499 def DeclareEnum(json
, mapping
):
502 tmpl_enum
= tmpl_inline_enum
503 if "declared_name" in mapping
:
504 mapping
["Enum"] = mapping
["declared_name"]
505 tmpl_enum
= tmpl_named_enum
507 mapping
["Enum"] = Capitalize(mapping
["proto_param"])
509 for enum_value
in json
["enum"]:
510 values
.append(tmpl_enum_value
.substitute(mapping
,
511 Value
= Capitalize(enum_value
)))
512 value_defs
.append(tmpl_enum_value_def
.substitute(mapping
,
514 Value
= Capitalize(enum_value
)))
515 type_decls
.append(tmpl_enum
.substitute(mapping
,
516 values
= "".join(values
)))
517 type_impls
.append(tmpl_enum
.substitute(mapping
,
518 values
= "".join(value_defs
)))
520 def ResolveRef(json
, mapping
):
521 dot_pos
= json
["$ref"].find(".")
523 domain_name
= mapping
["Domain"]
524 type_name
= json
["$ref"]
526 domain_name
= json
["$ref"][:dot_pos
]
527 type_name
= json
["$ref"][dot_pos
+ 1:]
528 json_type
= types
["%s.%s" % (domain_name
, type_name
)]
529 mapping
["declared_name"] = Capitalize(type_name
)
530 mapping
["Domain"] = domain_name
531 mapping
["domain"] = Uncamelcase(domain_name
)
532 mapping
["param_type"] = tmpl_typename
.substitute(mapping
)
533 ResolveType(json_type
, mapping
)
534 if not "___type_declared" in json_type
:
535 json_type
["___type_declared"] = True;
536 if (json_type
.get("type") == "object") and ("properties" in json_type
):
537 DeclareStruct(json_type
["properties"], mapping
)
539 if ("enum" in json_type
):
540 DeclareEnum(json_type
, mapping
)
541 type_decls
.append(tmpl_typedef
.substitute(mapping
))
543 def ResolveArray(json
, mapping
):
544 items_map
= mapping
.copy()
545 ResolveType(json
["items"], items_map
)
546 if items_map
["Type"] == "List":
547 # TODO(dgozman) Implement this.
548 raise Exception("Nested arrays are not implemented")
549 mapping
["param_type"] = "std::vector<%s>" % items_map
["param_type"]
550 mapping
["Type"] = "List"
551 mapping
["pass_type"] = "const %s&" % mapping
["param_type"]
552 mapping
["storage_type"] = "std::vector<%s>" % items_map
["storage_type"]
553 mapping
["raw_type"] = mapping
["storage_type"]
554 mapping
["prep_req"] = tmpl_prep_req_list
.substitute(mapping
,
555 item_type
= items_map
["storage_type"],
556 item_init
= items_map
["init"],
557 item_raw_type
= items_map
["raw_type"],
558 item_pass
= items_map
["pass_template"].substitute(name
="item", opt
=""),
559 ItemType
= items_map
["Type"])
560 mapping
["arg_out"] = "&out_%s" % mapping
["param"]
562 def ResolveObject(json
, mapping
):
563 mapping
["Type"] = "Dictionary"
564 mapping
["storage_type"] = "scoped_ptr<base::DictionaryValue>"
565 mapping
["raw_type"] = "base::DictionaryValue*"
566 mapping
["pass_template"] = tmpl_object_pass
567 if "properties" in json
:
568 if not "declared_name" in mapping
:
569 mapping
["declared_name"] = ("%s%s" %
570 (mapping
["Command"], Capitalize(mapping
["proto_param"])))
571 mapping
["param_type"] = ("scoped_refptr<%s>" %
572 tmpl_typename
.substitute(mapping
))
573 DeclareStruct(json
["properties"], mapping
)
575 mapping
["param_type"] = ("scoped_refptr<%s>" %
576 tmpl_typename
.substitute(mapping
))
577 mapping
["pass_type"] = mapping
["param_type"]
578 mapping
["arg_out"] = "&out_%s" % mapping
["param"]
580 mapping
["param_type"] = "base::DictionaryValue"
581 mapping
["pass_type"] = "scoped_ptr<base::DictionaryValue>"
582 mapping
["arg_out"] = "out_%s.get()" % mapping
["param"]
583 mapping
["prep_req"] = tmpl_prep_req
.substitute(mapping
)
585 def ResolvePrimitive(json
, mapping
):
586 jsonrpc_type
= json
["type"]
587 if jsonrpc_type
== "boolean":
588 mapping
["param_type"] = "bool"
589 mapping
["Type"] = "Boolean"
590 mapping
["init"] = " = false"
591 elif jsonrpc_type
== "integer":
592 mapping
["param_type"] = "int"
593 mapping
["Type"] = "Integer"
594 mapping
["init"] = " = 0"
595 elif jsonrpc_type
== "number":
596 mapping
["param_type"] = "double"
597 mapping
["Type"] = "Double"
598 mapping
["init"] = " = 0.0"
599 elif jsonrpc_type
== "string":
600 mapping
["param_type"] = "std::string"
601 mapping
["pass_type"] = "const std::string&"
602 mapping
["Type"] = "String"
603 if "enum" in json
and not "declared_name" in mapping
:
604 if not "subdomain" in mapping
:
605 mapping
["subdomain"] = Uncamelcase(mapping
["command"])
606 DeclareEnum(json
, mapping
)
608 raise Exception("Unknown type: %s" % json_type
)
609 mapping
["storage_type"] = mapping
["param_type"]
610 mapping
["raw_type"] = mapping
["param_type"]
611 mapping
["prep_req"] = tmpl_prep_req
.substitute(mapping
)
612 if jsonrpc_type
!= "string":
613 mapping
["pass_type"] = mapping
["param_type"]
614 mapping
["arg_out"] = "&out_%s" % mapping
["param"]
616 def ResolveType(json
, mapping
):
618 mapping
["pass_template"] = string
.Template("${opt}${name}")
620 ResolveRef(json
, mapping
)
622 jsonrpc_type
= json
["type"]
623 if jsonrpc_type
== "array":
624 ResolveArray(json
, mapping
)
625 elif jsonrpc_type
== "object":
626 ResolveObject(json
, mapping
)
628 ResolvePrimitive(json
, mapping
)
630 raise Exception("Unknown type at %s.%s %s" %
631 (mapping
["Domain"], mapping
["command"], mapping
["proto_param"]))
639 for json_domain
in all_domains
:
641 domain_map
["Domain"] = json_domain
["domain"]
642 domain_map
["domain"] = Uncamelcase(json_domain
["domain"])
646 client_method_impls
= []
648 domain_needs_client
= False
650 if "commands" in json_domain
:
651 for json_command
in json_domain
["commands"]:
652 if (not ("handlers" in json_command
) or
653 not ("browser" in json_command
["handlers"])):
657 command_map
= domain_map
.copy()
658 command_map
["command"] = json_command
["name"]
659 command_map
["Command"] = Capitalize(json_command
["name"])
661 if "redirect" in json_command
:
662 redirect_domain
= json_command
["redirect"]
663 if not (redirect_domain
in redirects
):
664 redirects
[redirect_domain
] = []
665 command_map
["TargetDomain"] = redirect_domain
666 redirects
[redirect_domain
].append(tmpl_register
.substitute(command_map
))
669 command_map
["TargetDomain"] = command_map
["Domain"]
673 if "parameters" in json_command
:
674 for json_param
in json_command
["parameters"]:
675 param_map
= command_map
.copy()
676 param_map
["proto_param"] = json_param
["name"]
677 param_map
["param"] = Uncamelcase(json_param
["name"])
678 ResolveType(json_param
, param_map
)
679 if json_param
.get("optional"):
680 if param_map
["Type"] in ["List"]:
681 # TODO(vkuzkokov) Implement transformation of base::ListValue
682 # to std::vector and base::DictonaryValue to struct.
684 "Optional array parameters are not implemented")
685 prep
.append(tmpl_prep_opt
.substitute(param_map
))
686 param_pass
= param_map
["pass_template"].substitute(
687 name
=tmpl_arg_name
.substitute(param_map
),
690 tmpl_arg_opt
.substitute(param_map
, param_pass
=param_pass
))
692 prep
.append(param_map
["prep_req"])
693 param_pass
= param_map
["pass_template"].substitute(
694 name
=tmpl_arg_name
.substitute(param_map
),
697 tmpl_arg_req
.substitute(param_map
, param_pass
=param_pass
))
699 if json_command
.get("async"):
700 domain_needs_client
= True
702 if "returns" in json_command
:
703 json_returns
= json_command
["returns"]
704 command_map
["declared_name"] = "%sResponse" % command_map
["Command"]
705 DeclareStruct(json_returns
, command_map
)
706 # TODO(vkuzkokov) Pass async callback instance similar to how
707 # InspectorBackendDispatcher does it. This, however, can work
708 # only if Blink and Chrome are in the same repo.
709 args
.insert(0, "command_id")
710 handler_method_impls
.append(
711 tmpl_callback_async_impl
.substitute(command_map
,
712 prep
= "".join(prep
),
713 args
= "\n " + ",\n ".join(args
)))
714 client_methods
.append(tmpl_response
.substitute(command_map
))
715 client_method_impls
.append(tmpl_response_impl
.substitute(command_map
))
718 if "returns" in json_command
:
719 for json_param
in json_command
["returns"]:
720 param_map
= command_map
.copy()
721 param_map
["proto_param"] = json_param
["name"]
722 param_map
["param"] = Uncamelcase(json_param
["name"])
723 if json_param
.get("optional"):
724 # TODO(vkuzkokov) Implement Optional<T> for value types.
725 raise Exception("Optional return values are not implemented")
726 ResolveType(json_param
, param_map
)
727 prep
.append(tmpl_prep_output
.substitute(param_map
))
728 args
.append(param_map
["arg_out"])
729 wrap
.append(tmpl_wrap
.substitute(param_map
))
732 args_str
= "\n " + ",\n ".join(args
)
733 handler_method_impls
.append(tmpl_callback_impl
.substitute(command_map
,
734 prep
= "".join(prep
),
736 wrap
= "".join(wrap
)))
738 initializations
.append(tmpl_register
.substitute(command_map
))
739 handler_methods
.append(tmpl_callback
.substitute(command_map
))
741 if "events" in json_domain
:
742 for json_event
in json_domain
["events"]:
743 if (not ("handlers" in json_event
) or
744 not ("browser" in json_event
["handlers"])):
747 domain_needs_client
= True
749 event_map
= domain_map
.copy()
750 event_map
["command"] = json_event
["name"]
751 event_map
["Command"] = Capitalize(json_event
["name"])
754 if "parameters" in json_event
:
755 json_parameters
= json_event
["parameters"]
756 event_map
["declared_name"] = "%sParams" % event_map
["Command"]
757 DeclareStruct(json_parameters
, event_map
);
759 client_methods
.append(tmpl_event
.substitute(event_map
))
760 client_method_impls
.append(tmpl_event_impl
.substitute(event_map
))
764 type_decls
.append(tmpl_handler
.substitute(domain_map
))
765 setters
.append(tmpl_setter
.substitute(domain_map
))
766 fields
.append(tmpl_field
.substitute(domain_map
))
767 includes
.append(tmpl_include
.substitute(domain_map
))
768 fields_init
.append(tmpl_field_init
.substitute(domain_map
))
769 if domain_needs_client
:
770 type_decls
.append(tmpl_client
.substitute(domain_map
,
771 methods
= "".join(client_methods
)))
772 initializations
.append(tmpl_init_client
.substitute(domain_map
))
773 type_impls
.append(tmpl_client_impl
.substitute(domain_map
,
774 methods
= "\n".join(client_method_impls
)))
775 domain_map
["initializations"] = "".join(initializations
)
776 domain_maps
.append(domain_map
)
778 for domain_map
in domain_maps
:
779 domain
= domain_map
["Domain"]
780 if domain
in redirects
:
781 domain_map
["initializations"] += "".join(redirects
[domain
])
782 handler_method_impls
.append(tmpl_setter_impl
.substitute(domain_map
))
784 output_h_file
= open(output_h_path
, "w")
785 output_cc_file
= open(output_cc_path
, "w")
787 output_h_file
.write(template_h
.substitute({},
788 types
= "\n".join(type_decls
),
789 setters
= "".join(setters
),
790 methods
= "".join(handler_methods
),
791 fields
= "".join(fields
)))
792 output_h_file
.close()
794 output_cc_file
.write(template_cc
.substitute({},
795 major
= blink_protocol
["version"]["major"],
796 minor
= blink_protocol
["version"]["minor"],
797 includes
= "".join(sorted(includes
)),
798 fields_init
= ",\n ".join(fields_init
),
799 methods
= "\n".join(handler_method_impls
),
800 types
= "\n".join(type_impls
)))
801 output_cc_file
.close()