Change next_proto member type.
[chromium-blink-merge.git] / content / browser / devtools / protocol / devtools_protocol_handler_generator.py
blobd3dd9c1796352370160881e5cea184a0382efd37
1 #!/usr/bin/env python
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.
6 import sys
7 import string
8 import json
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]
15 header = """\
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.
21 // Generated by
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
25 """
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"
34 namespace content {
36 class DevToolsProtocolDispatcher;
38 namespace devtools {
40 extern const char kProtocolVersion[];
42 bool IsSupportedProtocolVersion(const std::string& version);
44 template<typename T>
45 base::Value* CreateValue(const T& param) {
46 return new base::FundamentalValue(param);
49 template<class T>
50 base::Value* CreateValue(scoped_ptr<T>& param) {
51 return param.release();
54 template<class T>
55 base::Value* CreateValue(scoped_refptr<T> param) {
56 return param->ToValue().release();
59 template<typename T>
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));
65 return result;
68 template<>
69 base::Value* CreateValue(const std::string& param);
71 ${types}\
73 } // namespace devtools
75 class DevToolsProtocolDispatcher {
76 public:
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);
86 ${setters}\
88 private:
89 using Response = DevToolsProtocolClient::Response;
90 using CommandHandlers = std::map<std::string, CommandHandler>;
92 ${methods}\
94 Notifier notifier_;
95 DevToolsProtocolClient client_;
96 CommandHandlers command_handlers_;
97 ${fields}\
100 } // namespace content
102 #endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_
103 """)
105 tmpl_typedef = string.Template("""\
106 namespace ${domain} {
107 typedef ${param_type} ${declared_name};
108 } // namespace ${domain}
109 """)
111 tmpl_struct = string.Template("""\
112 namespace ${domain} {
113 template<int MASK>
114 struct ${declared_name}Builder
115 : base::RefCounted<${declared_name}Builder<MASK>> {
116 public:
117 enum {
118 kAllSet = 0,
119 ${fields_enum}\
122 ${methods}\
124 static scoped_refptr<${declared_name}Builder<kNoneSet>> Create() {
125 return new ${declared_name}Builder<kNoneSet>();
128 scoped_ptr<base::DictionaryValue> ToValue() {
129 COMPILE_ASSERT(MASK == kAllSet, required_properties_missing);
130 return make_scoped_ptr(dict_->DeepCopy());
133 private:
134 friend struct ${declared_name}Builder<0>;
136 ${declared_name}Builder() : dict_(new base::DictionaryValue()) {
139 template<class T> T* ThisAs() {
140 COMPILE_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}
150 """)
152 tmpl_builder_setter_req = string.Template("""\
153 scoped_refptr<${declared_name}Builder<MASK & ~k${Param}>>
154 set_${param}(${pass_type} ${param}) {
155 COMPILE_ASSERT(MASK & k${Param}, already_set);
156 dict_->Set("${proto_param}", CreateValue(${param}));
157 return ThisAs<${declared_name}Builder<MASK & ~k${Param}>>();
159 """)
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}));
165 return this;
167 """)
169 tmpl_builder_enum = string.Template("""\
170 k${Param} = 1 << ${ordinal},
171 """)
173 tmpl_builder_none_set = string.Template("""\
174 kNoneSet = ${all_fields}
175 """)
177 tmpl_enum = string.Template("""\
178 namespace ${domain} {
179 namespace ${subdomain} {
180 ${values}\
181 } // namespace ${subdomain}
182 } // namespace ${domain}
183 """)
185 tmpl_enum_value = string.Template("""\
186 extern const char k${Param}${Value}[];
187 """)
189 tmpl_enum_value_def = string.Template("""\
190 const char k${Param}${Value}[] = "${value}";
191 """)
193 tmpl_handler = string.Template("""\
194 namespace ${domain} {
195 class ${Domain}Handler;
196 } // namespace domain
197 """)
199 tmpl_client = string.Template("""\
200 namespace ${domain} {
201 class Client : public DevToolsProtocolClient {
202 public:
203 explicit Client(const RawMessageCallback& raw_message_callback);
204 virtual ~Client();
206 ${methods}\
208 } // namespace ${domain}
209 """)
211 tmpl_event = string.Template("""\
212 void ${Command}(
213 scoped_refptr<${Command}Params> params);
214 """)
216 tmpl_response = string.Template("""\
217 void Send${Command}Response(
218 DevToolsCommandId command_id,
219 scoped_refptr<${Command}Response> params);
220 """)
222 tmpl_setter = string.Template("""\
223 void Set${Domain}Handler(
224 devtools::${domain}::${Domain}Handler* ${domain}_handler);
225 """)
227 tmpl_callback = string.Template("""\
228 bool On${Domain}${Command}(
229 DevToolsCommandId command_id,
230 scoped_ptr<base::DictionaryValue> params);
231 """)
233 tmpl_field = string.Template("""\
234 devtools::${domain}::${Domain}Handler* ${domain}_handler_;
235 """)
237 template_cc = string.Template(header + """\
239 #include "content/browser/devtools/protocol/devtools_protocol_handler.h"
241 #include "base/bind.h"
242 #include "base/strings/string_number_conversions.h"
243 ${includes}\
245 namespace content {
247 DevToolsProtocolDispatcher::DevToolsProtocolDispatcher(
248 const Notifier& notifier)
249 : notifier_(notifier),
250 client_(notifier),
251 ${fields_init} {
254 DevToolsProtocolDispatcher::~DevToolsProtocolDispatcher() {
257 DevToolsProtocolDispatcher::CommandHandler
258 DevToolsProtocolDispatcher::FindCommandHandler(const std::string& method) {
259 CommandHandlers::iterator it = command_handlers_.find(method);
260 return it == command_handlers_.end() ? CommandHandler() : it->second;
263 ${methods}\
265 namespace devtools {
267 const char kProtocolVersion[] = "${major}.${minor}";
269 bool IsSupportedProtocolVersion(const std::string& version) {
270 std::vector<std::string> tokens;
271 Tokenize(version, ".", &tokens);
272 int major, minor;
273 return tokens.size() == 2 &&
274 base::StringToInt(tokens[0], &major) && major == ${major} &&
275 base::StringToInt(tokens[1], &minor) && minor <= ${minor};
278 template<>
279 base::Value* CreateValue(const std::string& param) {
280 return new base::StringValue(param);
283 ${types}\
285 } // namespace devtools
287 } // namespace content
288 """)
290 tmpl_include = string.Template("""\
291 #include "content/browser/devtools/protocol/${domain}_handler.h"
292 """)
294 tmpl_field_init = string.Template("${domain}_handler_(nullptr)")
296 tmpl_setter_impl = string.Template("""\
297 void DevToolsProtocolDispatcher::Set${Domain}Handler(
298 devtools::${domain}::${Domain}Handler* ${domain}_handler) {
299 DCHECK(!${domain}_handler_);
300 ${domain}_handler_ = ${domain}_handler;
301 ${initializations}\
303 """)
305 tmpl_register = string.Template("""\
306 command_handlers_["${Domain}.${command}"] =
307 base::Bind(
308 &DevToolsProtocolDispatcher::On${Domain}${Command},
309 base::Unretained(this));
310 """)
312 tmpl_init_client = string.Template("""\
313 ${domain}_handler_->SetClient(make_scoped_ptr(
314 new devtools::${domain}::Client(notifier_)));
315 """)
317 tmpl_callback_impl = string.Template("""\
318 bool DevToolsProtocolDispatcher::On${Domain}${Command}(
319 DevToolsCommandId command_id,
320 scoped_ptr<base::DictionaryValue> params) {
321 ${prep}\
322 Response response = ${domain}_handler_->${Command}(${args});
323 scoped_ptr<base::DictionaryValue> protocol_response;
324 if (client_.SendError(command_id, response))
325 return true;
326 if (response.IsFallThrough())
327 return false;
328 scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
329 ${wrap}\
330 client_.SendSuccess(command_id, result.Pass());
331 return true;
333 """)
335 tmpl_wrap = string.Template("""\
336 result->Set("${proto_param}", devtools::CreateValue(out_${param}));
337 """)
339 tmpl_callback_async_impl = string.Template("""\
340 bool DevToolsProtocolDispatcher::On${Domain}${Command}(
341 DevToolsCommandId command_id,
342 scoped_ptr<base::DictionaryValue> params) {
343 ${prep}\
344 Response response = ${domain}_handler_->${Command}(${args});
345 if (client_.SendError(command_id, response))
346 return true;
347 return !response.IsFallThrough();
349 """)
351 tmpl_prep_req = string.Template("""\
352 ${param_type} in_${param}${init};
353 if (!params || !params->Get${Type}("${proto_param}", &in_${param})) {
354 client_.SendError(command_id, Response::InvalidParams("${proto_param}"));
355 return true;
357 """)
359 tmpl_prep_req_list = string.Template("""\
360 base::ListValue* list_${param} = nullptr;
361 if (!params || !params->GetList("${proto_param}", &list_${param})) {
362 client_.SendError(command_id, Response::InvalidParams("${proto_param}"));
363 return true;
365 std::vector<${item_type}> in_${param};
366 for (base::ListValue::const_iterator it =
367 list_${param}->begin(); it != list_${param}->end(); ++it) {
368 ${item_type} item${item_init};
369 if (!(*it)->GetAs${ItemType}(&item)) {
370 client_.SendError(command_id, Response::InvalidParams("${proto_param}"));
371 return true;
373 in_${param}.push_back(item);
375 """)
377 tmpl_prep_opt = string.Template("""\
378 ${param_type} in_${param}${init};
379 bool ${param}_found = params && params->Get${Type}(
380 "${proto_param}",
381 &in_${param});
382 """)
384 tmpl_prep_output = string.Template("""\
385 ${param_type} out_${param}${init};
386 """)
388 tmpl_arg_req = string.Template("in_${param}")
390 tmpl_arg_opt = string.Template(
391 "${param}_found ? &in_${param} : nullptr")
393 tmpl_client_impl = string.Template("""\
394 namespace ${domain} {
396 Client::Client(const RawMessageCallback& raw_message_callback)
397 : DevToolsProtocolClient(raw_message_callback) {
400 Client::~Client() {
403 ${methods}\
405 } // namespace ${domain}
406 """)
408 tmpl_event_impl = string.Template("""\
409 void Client::${Command}(
410 scoped_refptr<${Command}Params> params) {
411 SendNotification("${Domain}.${command}",
412 params->ToValue().Pass());
414 """)
416 tmpl_response_impl = string.Template("""\
417 void Client::Send${Command}Response(
418 DevToolsCommandId command_id,
419 scoped_refptr<${Command}Response> params) {
420 SendSuccess(command_id, params->ToValue().Pass());
422 """)
424 tmpl_typename = string.Template("devtools::${domain}::${declared_name}")
426 def Capitalize(s):
427 return s[:1].upper() + s[1:]
429 def Uncamelcase(s):
430 result = ""
431 for i, c in enumerate(s):
432 if c.isupper():
433 if (i > 0) and ((i < len(s)-1) and s[i+1].islower() or s[i-1].islower()):
434 result += "_"
435 result += c.lower()
436 else:
437 result += c
438 return result
440 types = {}
441 blink_protocol = json.loads(open(blink_protocol_path, "r").read())
442 browser_protocol = json.loads(open(browser_protocol_path, "r").read())
443 type_decls = []
444 type_impls = []
445 handler_methods = []
446 handler_method_impls = []
448 all_domains = blink_protocol["domains"] + browser_protocol["domains"]
450 for json_domain in all_domains:
451 if "types" in json_domain:
452 for json_type in json_domain["types"]:
453 types["%s.%s" % (json_domain["domain"], json_type["id"])] = json_type
455 def DeclareStruct(json_properties, mapping):
456 methods = []
457 fields_enum = []
458 enum_items = []
459 req_fields_num = 0
460 for json_prop in json_properties:
461 prop_map = mapping.copy()
462 prop_map["proto_param"] = json_prop["name"]
463 prop_map["param"] = Uncamelcase(json_prop["name"])
464 prop_map["Param"] = Capitalize(json_prop["name"])
465 ResolveType(json_prop, prop_map)
466 prop_map["declared_name"] = mapping["declared_name"]
467 if json_prop.get("optional"):
468 methods.append(tmpl_builder_setter_opt.substitute(prop_map))
469 else:
470 methods.append(tmpl_builder_setter_req.substitute(prop_map))
471 enum_items.append("k%s" % prop_map["Param"]);
472 fields_enum.append(tmpl_builder_enum.substitute(prop_map,
473 ordinal = req_fields_num))
474 req_fields_num += 1
476 all_fields = "kAllSet"
477 if len(enum_items) > 0:
478 all_fields = " | ".join(enum_items)
479 fields_enum.append(tmpl_builder_none_set.substitute(mapping,
480 all_fields = all_fields))
481 type_decls.append(tmpl_struct.substitute(mapping,
482 methods = "\n".join(methods),
483 fields_enum = "".join(fields_enum)))
485 def ResolveRef(json, mapping):
486 dot_pos = json["$ref"].find(".")
487 if dot_pos == -1:
488 domain_name = mapping["Domain"]
489 type_name = json["$ref"]
490 else:
491 domain_name = json["$ref"][:dot_pos]
492 type_name = json["$ref"][dot_pos + 1:]
493 json_type = types["%s.%s" % (domain_name, type_name)]
494 mapping["declared_name"] = Capitalize(type_name)
495 mapping["Domain"] = domain_name
496 mapping["domain"] = Uncamelcase(domain_name)
497 mapping["param_type"] = tmpl_typename.substitute(mapping)
498 if json_type.get("enum"):
499 # TODO(vkuzkokov) Implement. Approximate template:
500 # namespace ${domain} { const char k${declared_name}${Value}; }
501 raise Exception("Named enumerations are not implemented")
502 ResolveType(json_type, mapping)
503 if not "___struct_declared" in json_type:
504 json_type["___struct_declared"] = True;
505 if (json_type.get("type") == "object") and ("properties" in json_type):
506 DeclareStruct(json_type["properties"], mapping)
507 else:
508 type_decls.append(tmpl_typedef.substitute(mapping))
510 def ResolveArray(json, mapping):
511 items_map = mapping.copy()
512 ResolveType(json["items"], items_map)
513 mapping["param_type"] = "std::vector<%s>" % items_map["param_type"]
514 mapping["Type"] = "List"
515 mapping["pass_type"] = "const %s&" % mapping["param_type"]
516 mapping["prep_req"] = tmpl_prep_req_list.substitute(mapping,
517 item_type = items_map["param_type"],
518 item_init = items_map["init"],
519 ItemType = items_map["Type"])
520 mapping["arg_out"] = "&out_%s" % mapping["param"]
522 def ResolveObject(json, mapping):
523 mapping["Type"] = "Dictionary"
524 if "properties" in json:
525 if not "declared_name" in mapping:
526 mapping["declared_name"] = ("%s%s" %
527 (mapping["Command"], Capitalize(mapping["proto_param"])))
528 mapping["param_type"] = ("scoped_refptr<%s>" %
529 tmpl_typename.substitute(mapping))
530 DeclareStruct(json["properties"], mapping)
531 else:
532 mapping["param_type"] = ("scoped_refptr<%s>" %
533 tmpl_typename.substitute(mapping))
534 mapping["pass_type"] = mapping["param_type"]
535 mapping["arg_out"] = "&out_%s" % mapping["param"]
536 else:
537 mapping["param_type"] = "base::DictionaryValue"
538 mapping["pass_type"] = "scoped_ptr<base::DictionaryValue>"
539 mapping["arg_out"] = "out_%s.get()" % mapping["param"]
541 def ResolvePrimitive(json, mapping):
542 jsonrpc_type = json["type"]
543 if jsonrpc_type == "boolean":
544 mapping["param_type"] = "bool"
545 mapping["Type"] = "Boolean"
546 mapping["init"] = " = false"
547 elif jsonrpc_type == "integer":
548 mapping["param_type"] = "int"
549 mapping["Type"] = "Integer"
550 mapping["init"] = " = 0"
551 elif jsonrpc_type == "number":
552 mapping["param_type"] = "double"
553 mapping["Type"] = "Double"
554 mapping["init"] = " = 0.0"
555 elif jsonrpc_type == "string":
556 mapping["param_type"] = "std::string"
557 mapping["pass_type"] = "const std::string&"
558 mapping["Type"] = "String"
559 if "enum" in json:
560 values = []
561 value_defs = []
562 if "declared_name" in mapping:
563 mapping["subdomain"] = Uncamelcase(mapping["declared_name"])
564 else:
565 mapping["subdomain"] = Uncamelcase(mapping["command"])
566 mapping["Param"] = Capitalize(mapping["proto_param"])
567 for enum_value in json["enum"]:
568 values.append(tmpl_enum_value.substitute(mapping,
569 Value = Capitalize(enum_value)))
570 value_defs.append(tmpl_enum_value_def.substitute(mapping,
571 value = enum_value,
572 Value = Capitalize(enum_value)))
573 type_decls.append(tmpl_enum.substitute(mapping,
574 values = "".join(values)))
575 type_impls.append(tmpl_enum.substitute(mapping,
576 values = "".join(value_defs)))
577 else:
578 raise Exception("Unknown type: %s" % json_type)
579 mapping["prep_req"] = tmpl_prep_req.substitute(mapping)
580 if jsonrpc_type != "string":
581 mapping["pass_type"] = mapping["param_type"]
582 mapping["arg_out"] = "&out_%s" % mapping["param"]
584 def ResolveType(json, mapping):
585 mapping["init"] = ""
586 if "$ref" in json:
587 ResolveRef(json, mapping)
588 elif "type" in json:
589 jsonrpc_type = json["type"]
590 if jsonrpc_type == "array":
591 ResolveArray(json, mapping)
592 elif jsonrpc_type == "object":
593 ResolveObject(json, mapping)
594 else:
595 ResolvePrimitive(json, mapping)
596 else:
597 raise Exception("Unknown type at %s.%s %s" %
598 (mapping["Domain"], mapping["command"], mapping["proto_param"]))
600 setters = []
601 fields = []
603 includes = []
604 fields_init = []
606 for json_domain in all_domains:
607 domain_map = {}
608 domain_map["Domain"] = json_domain["domain"]
609 domain_map["domain"] = Uncamelcase(json_domain["domain"])
611 initializations = []
612 client_methods = []
613 client_method_impls = []
614 domain_empty = True
615 domain_needs_client = False
617 if "commands" in json_domain:
618 for json_command in json_domain["commands"]:
619 if (not ("handlers" in json_command) or
620 not ("browser" in json_command["handlers"])):
621 continue
622 domain_empty = False
624 command_map = domain_map.copy()
625 command_map["command"] = json_command["name"]
626 command_map["Command"] = Capitalize(json_command["name"])
628 prep = []
629 args = []
631 if "parameters" in json_command:
632 for json_param in json_command["parameters"]:
633 param_map = command_map.copy()
634 param_map["proto_param"] = json_param["name"]
635 param_map["param"] = Uncamelcase(json_param["name"])
636 ResolveType(json_param, param_map)
637 if json_param.get("optional"):
638 if param_map["Type"] in ["List", "Dictionary"]:
639 # TODO(vkuzkokov) Implement transformation of base::ListValue
640 # to std::vector and base::DictonaryValue to struct.
641 raise Exception(
642 "Optional array and object parameters are not implemented")
643 prep.append(tmpl_prep_opt.substitute(param_map))
644 args.append(tmpl_arg_opt.substitute(param_map))
645 else:
646 prep.append(param_map["prep_req"])
647 args.append(tmpl_arg_req.substitute(param_map))
649 if json_command.get("async"):
650 domain_needs_client = True
651 json_returns = []
652 if "returns" in json_command:
653 json_returns = json_command["returns"]
654 command_map["declared_name"] = "%sResponse" % command_map["Command"]
655 DeclareStruct(json_returns, command_map)
656 # TODO(vkuzkokov) Pass async callback instance similar to how
657 # InspectorBackendDispatcher does it. This, however, can work
658 # only if Blink and Chrome are in the same repo.
659 args.insert(0, "command_id")
660 handler_method_impls.append(
661 tmpl_callback_async_impl.substitute(command_map,
662 prep = "".join(prep),
663 args = "\n " + ",\n ".join(args)))
664 client_methods.append(tmpl_response.substitute(command_map))
665 client_method_impls.append(tmpl_response_impl.substitute(command_map))
666 else:
667 wrap = []
668 if "returns" in json_command:
669 for json_param in json_command["returns"]:
670 param_map = command_map.copy()
671 param_map["proto_param"] = json_param["name"]
672 param_map["param"] = Uncamelcase(json_param["name"])
673 if json_param.get("optional"):
674 # TODO(vkuzkokov) Implement Optional<T> for value types.
675 raise Exception("Optional return values are not implemented")
676 ResolveType(json_param, param_map)
677 prep.append(tmpl_prep_output.substitute(param_map))
678 args.append(param_map["arg_out"])
679 wrap.append(tmpl_wrap.substitute(param_map))
680 args_str = ""
681 if len(args) > 0:
682 args_str = "\n " + ",\n ".join(args)
683 handler_method_impls.append(tmpl_callback_impl.substitute(command_map,
684 prep = "".join(prep),
685 args = args_str,
686 wrap = "".join(wrap)))
688 initializations.append(tmpl_register.substitute(command_map))
689 handler_methods.append(tmpl_callback.substitute(command_map))
691 if "events" in json_domain:
692 for json_event in json_domain["events"]:
693 if (not ("handlers" in json_event) or
694 not ("browser" in json_event["handlers"])):
695 continue
696 domain_empty = False
697 domain_needs_client = True
699 event_map = domain_map.copy()
700 event_map["command"] = json_event["name"]
701 event_map["Command"] = Capitalize(json_event["name"])
703 json_parameters = []
704 if "parameters" in json_event:
705 json_parameters = json_event["parameters"]
706 event_map["declared_name"] = "%sParams" % event_map["Command"]
707 DeclareStruct(json_parameters, event_map);
709 client_methods.append(tmpl_event.substitute(event_map))
710 client_method_impls.append(tmpl_event_impl.substitute(event_map))
712 if domain_empty:
713 continue
714 type_decls.append(tmpl_handler.substitute(domain_map))
715 setters.append(tmpl_setter.substitute(domain_map))
716 fields.append(tmpl_field.substitute(domain_map))
717 includes.append(tmpl_include.substitute(domain_map))
718 fields_init.append(tmpl_field_init.substitute(domain_map))
719 if domain_needs_client:
720 type_decls.append(tmpl_client.substitute(domain_map,
721 methods = "".join(client_methods)))
722 initializations.append(tmpl_init_client.substitute(domain_map))
723 type_impls.append(tmpl_client_impl.substitute(domain_map,
724 methods = "\n".join(client_method_impls)))
725 handler_method_impls.append(tmpl_setter_impl.substitute(domain_map,
726 initializations = "".join(initializations)))
729 output_h_file = open(output_h_path, "w")
730 output_cc_file = open(output_cc_path, "w")
732 output_h_file.write(template_h.substitute({},
733 types = "\n".join(type_decls),
734 setters = "".join(setters),
735 methods = "".join(handler_methods),
736 fields = "".join(fields)))
737 output_h_file.close()
739 output_cc_file.write(template_cc.substitute({},
740 major = blink_protocol["version"]["major"],
741 minor = blink_protocol["version"]["minor"],
742 includes = "".join(sorted(includes)),
743 fields_init = ",\n ".join(fields_init),
744 methods = "\n".join(handler_method_impls),
745 types = "\n".join(type_impls)))
746 output_cc_file.close()