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 input_json_path
= sys
.argv
[1]
11 output_cc_path
= sys
.argv
[2]
12 output_h_path
= sys
.argv
[3]
15 // Copyright 2014 The Chromium Authors. All rights reserved.
16 // Use of this source code is governed by a BSD-style license that can be
17 // found in the LICENSE file.
19 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
21 // content/public/browser/devtools_protocol_handler_generator.py from
22 // third_party/WebKit/Source/devtools/protocol.json
25 template_h
= string
.Template(header
+ """\
27 #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_HANDLER_IMPL_H_
28 #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_HANDLER_IMPL_H_
30 #include "content/browser/devtools/devtools_protocol.h"
31 #include "content/browser/devtools/protocol/devtools_protocol_client.h"
35 class DevToolsProtocolHandlerImpl;
41 } // namespace devtools
43 class DevToolsProtocolHandlerImpl : public DevToolsProtocol::Handler {
45 typedef DevToolsProtocolClient::Response Response;
46 typedef DevToolsProtocolClient::ResponseStatus ResponseStatus;
48 DevToolsProtocolHandlerImpl();
49 virtual ~DevToolsProtocolHandlerImpl();
61 } // namespace content
63 #endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_HANDLER_IMPL_H_
66 tmpl_typedef
= string
.Template("""\
68 typedef ${param_type} ${declared_name};
69 } // namespace ${domain}
72 tmpl_struct
= string
.Template("""\
74 struct ${declared_name} {
81 friend class ::content::DevToolsProtocolHandlerImpl;
85 } // namespace ${domain}
88 tmpl_struct_setter
= string
.Template("""\
89 void set_${param}(${pass_type} ${param});
92 tmpl_struct_field
= string
.Template("""\
93 ${param_type} ${param}_;
97 tmpl_enum
= string
.Template("""\
99 namespace ${subdomain} {
101 } // namespace ${subdomain}
102 } // namespace ${domain}
105 tmpl_enum_value
= string
.Template("""\
106 extern const char k${Param}${Value}[];
109 tmpl_enum_value_def
= string
.Template("""\
110 const char k${Param}${Value}[] = "${value}";
113 tmpl_handler
= string
.Template("""\
114 namespace ${domain} {
115 class ${Domain}Handler;
116 } // namespace domain
119 tmpl_client
= string
.Template("""\
120 namespace ${domain} {
121 class Client : public DevToolsProtocolClient {
123 Client(const EventCallback& event_callback,
124 const ResponseCallback& response_callback);
129 } // namespace ${domain}
132 tmpl_event
= string
.Template("""\
134 const ${Command}Params& params);
137 tmpl_response
= string
.Template("""\
138 void Send${Command}Response(
139 scoped_refptr<DevToolsProtocol::Command> command,
140 const ${Command}Response& params);
143 tmpl_setter
= string
.Template("""\
144 void Set${Domain}Handler(
145 devtools::${domain}::${Domain}Handler* ${domain}_handler);
148 tmpl_friend
= string
.Template("""\
149 friend class devtools::${domain}::Client;
152 tmpl_callback
= string
.Template("""\
153 scoped_refptr<DevToolsProtocol::Response>
154 On${Domain}${Command}(
155 scoped_refptr<DevToolsProtocol::Command> command);
158 tmpl_to_value
= string
.Template("""\
159 static base::DictionaryValue* ToValue(
160 const devtools::${domain}::${declared_name}& src);
163 tmpl_field
= string
.Template("""\
164 devtools::${domain}::${Domain}Handler* ${domain}_handler_;
167 template_cc
= string
.Template(header
+ """\
169 #include "content/browser/devtools/protocol/devtools_protocol_handler_impl.h"
171 #include "base/bind.h"
176 DevToolsProtocolHandlerImpl::DevToolsProtocolHandlerImpl()
180 DevToolsProtocolHandlerImpl::~DevToolsProtocolHandlerImpl() {
185 typedef DevToolsProtocolClient::ResponseStatus ResponseStatus;
187 bool CreateCommonResponse(
188 scoped_refptr<DevToolsProtocol::Command> command,
189 const DevToolsProtocolClient::Response& response,
190 scoped_refptr<DevToolsProtocol::Response>* protocol_response) {
191 switch (response.status()) {
192 case ResponseStatus::RESPONSE_STATUS_FALLTHROUGH:
193 *protocol_response = NULL;
195 case ResponseStatus::RESPONSE_STATUS_OK:
197 case ResponseStatus::RESPONSE_STATUS_INVALID_PARAMS:
198 *protocol_response = command->InvalidParamResponse(response.message());
200 case ResponseStatus::RESPONSE_STATUS_INTERNAL_ERROR:
201 *protocol_response = command->InternalErrorResponse(response.message());
203 case ResponseStatus::RESPONSE_STATUS_SERVER_ERROR:
204 *protocol_response = command->ServerErrorResponse(response.message());
218 } // namespace devtools
220 } // namespace content
223 tmpl_include
= string
.Template("""\
224 #include "content/browser/devtools/protocol/${domain}_handler.h"
227 tmpl_field_init
= string
.Template("${domain}_handler_(NULL)")
229 tmpl_setter_impl
= string
.Template("""\
230 void DevToolsProtocolHandlerImpl::Set${Domain}Handler(
231 devtools::${domain}::${Domain}Handler* ${domain}_handler) {
232 DCHECK(!${domain}_handler_);
233 ${domain}_handler_ = ${domain}_handler;
238 tmpl_register
= string
.Template("""\
239 RegisterCommandHandler(
240 "${Domain}.${command}",
242 &DevToolsProtocolHandlerImpl::On${Domain}${Command},
243 base::Unretained(this)));
246 tmpl_init_client
= string
.Template("""\
247 ${domain}_handler_->SetClient(make_scoped_ptr(
248 new devtools::${domain}::Client(
249 base::Bind(&DevToolsProtocolHandlerImpl::SendNotification,
250 base::Unretained(this)),
251 base::Bind(&DevToolsProtocolHandlerImpl::SendAsyncResponse,
252 base::Unretained(this)))));
255 tmpl_callback_impl
= string
.Template("""\
256 scoped_refptr<DevToolsProtocol::Response>
257 DevToolsProtocolHandlerImpl::On${Domain}${Command}(
258 scoped_refptr<DevToolsProtocol::Command> command) {
260 Response response = ${domain}_handler_->${Command}(${args});
261 scoped_refptr<DevToolsProtocol::Response> protocol_response;
262 if (CreateCommonResponse(command, response, &protocol_response))
263 return protocol_response;
264 base::DictionaryValue* dict = new base::DictionaryValue();
266 return command->SuccessResponse(dict);
270 tmpl_callback_async_impl
= string
.Template("""\
271 scoped_refptr<DevToolsProtocol::Response>
272 DevToolsProtocolHandlerImpl::On${Domain}${Command}(
273 scoped_refptr<DevToolsProtocol::Command> command) {
275 return ${domain}_handler_->${Command}(${args});
280 base::DictionaryValue* params = command->params();
283 tmpl_prep_req
= string
.Template("""\
284 ${param_type} in_${param}${init};
286 !params->Get${Type}("${proto_param}", &in_${param}))
287 return command->InvalidParamResponse("${proto_param}");
290 tmpl_prep_req_list
= string
.Template("""\
291 base::ListValue* list_${param} = NULL;
292 if (!params || !params->GetList("${proto_param}", &list_${param}))
293 return command->InvalidParamResponse("${proto_param}");
294 ${param_type} in_${param};
295 for (base::ListValue::const_iterator it =
296 list_${param}->begin(); it != list_${param}->end(); ++it) {
297 ${item_type} item${item_init};
298 if (!(*it)->GetAs${ItemType}(&item))
299 return command->InvalidParamResponse("${proto_param}");
300 in_${param}.push_back(item);
304 tmpl_prep_opt
= string
.Template("""\
305 ${param_type} in_${param}${init};
306 bool ${param}_found = params && params->Get${Type}(
311 tmpl_prep_output
= string
.Template("""\
312 ${param_type} out_${param}${init};
315 tmpl_arg_req
= string
.Template("in_${param}")
317 tmpl_arg_opt
= string
.Template(
318 "${param}_found ?\n &in_${param} : NULL")
320 tmpl_arg_output
= string
.Template("&out_${param}")
322 tmpl_to_value_impl
= string
.Template("""\
324 base::DictionaryValue* DevToolsProtocolHandlerImpl::ToValue(
325 const devtools::${domain}::${declared_name}& src) {
326 base::DictionaryValue* dict = new base::DictionaryValue();
333 tmpl_dcheck
= string
.Template("""\
334 DCHECK(${cond_name});
337 tmpl_struct_impl
= string
.Template("""\
338 namespace ${domain} {
340 ${declared_name}::${declared_name}()${fields} {
345 } // namespace ${domain}
348 tmpl_struct_field_init
= string
.Template("has_${param}_(false)")
350 tmpl_struct_setter_impl
= string
.Template("""\
351 void ${declared_name}::set_${param}(
352 ${pass_type} ${param}) {
353 ${param}_ = ${param};
354 has_${param}_ = true;
358 tmpl_client_impl
= string
.Template("""\
359 namespace ${domain} {
361 Client::Client(const EventCallback& event_callback,
362 const ResponseCallback& response_callback)
363 : DevToolsProtocolClient(event_callback, response_callback) {
371 } // namespace ${domain}
374 tmpl_event_impl
= string
.Template("""\
375 void Client::${Command}(
376 const ${Command}Params& params) {
377 SendNotification("${Domain}.${command}",
378 DevToolsProtocolHandlerImpl::ToValue(params));
382 tmpl_response_impl
= string
.Template("""\
383 void Client::Send${Command}Response(
384 scoped_refptr<DevToolsProtocol::Command> command,
385 const ${Command}Response& params) {
387 command->SuccessResponse(DevToolsProtocolHandlerImpl::ToValue(params)));
391 tmpl_wrap
= string
.Template("""\
392 dict->Set${Type}("${proto_param}", ${var_name});
395 tmpl_wrap_dict
= string
.Template("""\
396 dict->Set("${proto_param}",
397 DevToolsProtocolHandlerImpl::ToValue(${var_name}));
400 tmpl_wrap_obj
= string
.Template("""\
401 dict->Set("${proto_param}", ${var_name});
404 tmpl_wrap_list
= string
.Template("""\
405 base::ListValue* list_${param} = new base::ListValue();
406 for (${param_type}::const_iterator it =
407 ${var_name}.begin(); it != ${var_name}.end(); ++it) {
410 dict->Set("${proto_param}", list_${param});
413 tmpl_append
= string
.Template("""\
414 list_${param}->Append${Type}(*it);
417 tmpl_append_dict
= string
.Template("""\
418 list_${param}->Append(DevToolsProtocolHandlerImpl::ToValue(*it));
421 tmpl_append_obj
= string
.Template("""\
422 list_${param}->Append(*it);
425 tmpl_wrap_opt
= string
.Template("""\
427 dict->Set${Type}("${proto_param}", ${var_name});
430 tmpl_typename
= string
.Template("devtools::${domain}::${declared_name}")
433 return s
[:1].upper() + s
[1:]
440 for i
, c
in enumerate(s
):
442 if (i
> 0) and ((i
< len(s
)-1) and s
[i
+1].islower() or s
[i
-1].islower()):
450 json_api
= json
.loads(open(input_json_path
, "r").read())
454 handler_method_impls
= []
456 for json_domain
in json_api
["domains"]:
457 if "types" in json_domain
:
458 for json_type
in json_domain
["types"]:
459 types
["%s.%s" % (json_domain
["domain"], json_type
["id"])] = json_type
461 def DeclareStruct(json_properties
, mapping
):
468 for json_prop
in json_properties
:
469 prop_map
= mapping
.copy()
470 prop_map
["proto_param"] = json_prop
["name"]
471 prop_map
["param"] = Uncamelcase(json_prop
["name"])
472 prop_map
["var_name"] = "src.%s_" % prop_map
["param"]
473 prop_map
["cond_name"] = "src.has_%s_" % prop_map
["param"]
474 ResolveType(json_prop
, prop_map
)
475 prop_map
["declared_name"] = mapping
["declared_name"]
476 methods
.append(tmpl_struct_setter
.substitute(prop_map
))
477 fields
.append(tmpl_struct_field
.substitute(prop_map
))
478 fields_init
.append(tmpl_struct_field_init
.substitute(prop_map
))
479 method_impls
.append(tmpl_struct_setter_impl
.substitute(prop_map
))
480 if json_prop
.get("optional"):
481 if param_map
["Type"] in ["List", "Dictionary"]:
482 # TODO(vkuzkokov) Implement.
484 "Optional array and object properties are not implemented")
485 wrap
.append(tmpl_wrap_opt
.substitute(prop_map
))
487 dchecks
.append(tmpl_dcheck
.substitute(prop_map
));
488 if not "wrap" in prop_map
:
489 raise Exception("Arrays of arrays are not implemented")
490 wrap
.append(prop_map
["wrap"])
492 type_decls
.append(tmpl_struct
.substitute(mapping
,
493 methods
= "".join(methods
),
494 fields
= "".join(fields
)))
496 if len(fields_init
) > 0:
497 fields_init_str
= "\n : " + (",\n ".join(fields_init
))
498 type_impls
.append(tmpl_struct_impl
.substitute(mapping
,
499 fields
= fields_init_str
,
500 methods
= "\n".join(method_impls
)))
501 handler_methods
.append(tmpl_to_value
.substitute(mapping
))
502 handler_method_impls
.append(tmpl_to_value_impl
.substitute(mapping
,
503 dchecks
= "".join(dchecks
),
504 wrap
= "".join(wrap
)))
506 def ResolveRef(json
, mapping
):
507 dot_pos
= json
["$ref"].find(".")
509 domain_name
= mapping
["Domain"]
510 type_name
= json
["$ref"]
512 domain_name
= json
["$ref"][:dot_pos
]
513 type_name
= json
["$ref"][dot_pos
+ 1:]
514 json_type
= types
["%s.%s" % (domain_name
, type_name
)]
515 mapping
["declared_name"] = Capitalize(type_name
)
516 mapping
["Domain"] = domain_name
517 mapping
["domain"] = Decapitalize(domain_name
)
518 mapping
["param_type"] = tmpl_typename
.substitute(mapping
)
519 if json_type
.get("enum"):
520 # TODO(vkuzkokov) Implement. Approximate template:
521 # namespace ${domain} { const char k${declared_name}${Value}; }
522 raise Exception("Named enumerations are not implemented")
523 ResolveType(json_type
, mapping
)
524 if not "___struct_declared" in json_type
:
525 json_type
["___struct_declared"] = True;
526 if (json_type
.get("type") == "object") and ("properties" in json_type
):
527 DeclareStruct(json_type
["properties"], mapping
)
529 type_decls
.append(tmpl_typedef
.substitute(mapping
))
530 mapping
["param_type"] = tmpl_typename
.substitute(mapping
)
532 def ResolveArray(json
, mapping
):
533 items_map
= mapping
.copy()
534 ResolveType(json
["items"], items_map
)
535 mapping
["param_type"] = "std::vector<%s>" % items_map
["param_type"]
536 mapping
["Type"] = "List"
537 if "append" in items_map
:
538 mapping
["wrap"] = tmpl_wrap_list
.substitute(mapping
,
539 append
= items_map
["append"])
540 mapping
["pass_type"] = "const %s&" % mapping
["param_type"]
541 mapping
["prep_req"] = tmpl_prep_req_list
.substitute(mapping
,
542 item_type
= items_map
["param_type"],
543 item_init
= items_map
["init"],
544 ItemType
= items_map
["Type"])
545 # TODO(vkuzkokov) mapping["append"]: template for array of arrays.
547 def ResolveObject(json
, mapping
):
548 mapping
["Type"] = "Dictionary"
549 if "properties" in json
:
550 if not "declared_name" in mapping
:
551 mapping
["declared_name"] = ("%s%s" %
552 (mapping
["Command"], Capitalize(mapping
["proto_param"])))
553 mapping
["param_type"] = tmpl_typename
.substitute(mapping
)
554 DeclareStruct(json
["properties"], mapping
)
555 mapping
["append"] = tmpl_append_dict
.substitute(mapping
)
556 mapping
["wrap"] = tmpl_wrap_dict
.substitute(mapping
)
557 mapping
["pass_type"] = "const %s&" % mapping
["param_type"]
559 mapping
["param_type"] = "base::DictionaryValue*"
560 mapping
["append"] = tmpl_append_obj
.substitute(mapping
)
561 mapping
["wrap"] = tmpl_wrap_obj
.substitute(mapping
)
562 mapping
["pass_type"] = mapping
["param_type"]
564 def ResolvePrimitive(json
, mapping
):
565 jsonrpc_type
= json
["type"]
566 if jsonrpc_type
== "boolean":
567 mapping
["param_type"] = "bool"
568 mapping
["Type"] = "Boolean"
569 mapping
["init"] = " = false"
570 elif jsonrpc_type
== "integer":
571 mapping
["param_type"] = "int"
572 mapping
["Type"] = "Integer"
573 mapping
["init"] = " = 0"
574 elif jsonrpc_type
== "number":
575 mapping
["param_type"] = "double"
576 mapping
["Type"] = "Double"
577 mapping
["init"] = " = 0.0"
578 elif jsonrpc_type
== "string":
579 mapping
["param_type"] = "std::string"
580 mapping
["pass_type"] = "const std::string&"
581 mapping
["Type"] = "String"
585 if "declared_name" in mapping
:
586 mapping
["subdomain"] = Uncamelcase(mapping
["declared_name"])
588 mapping
["subdomain"] = Uncamelcase(mapping
["command"])
589 mapping
["Param"] = Capitalize(mapping
["proto_param"])
590 for enum_value
in json
["enum"]:
591 values
.append(tmpl_enum_value
.substitute(mapping
,
592 Value
= Capitalize(enum_value
)))
593 value_defs
.append(tmpl_enum_value_def
.substitute(mapping
,
595 Value
= Capitalize(enum_value
)))
596 type_decls
.append(tmpl_enum
.substitute(mapping
,
597 values
= "".join(values
)))
598 type_impls
.append(tmpl_enum
.substitute(mapping
,
599 values
= "".join(value_defs
)))
601 raise Exception("Unknown type: %s" % json_type
)
602 mapping
["wrap"] = tmpl_wrap
.substitute(mapping
)
603 mapping
["append"] = tmpl_append
.substitute(mapping
)
604 mapping
["prep_req"] = tmpl_prep_req
.substitute(mapping
)
605 if jsonrpc_type
!= "string":
606 mapping
["pass_type"] = mapping
["param_type"]
608 def ResolveType(json
, mapping
):
611 ResolveRef(json
, mapping
)
613 jsonrpc_type
= json
["type"]
614 if jsonrpc_type
== "array":
615 ResolveArray(json
, mapping
)
616 elif jsonrpc_type
== "object":
617 ResolveObject(json
, mapping
)
619 ResolvePrimitive(json
, mapping
)
621 raise Exception("Unknown type at %s.%s %s" %
622 (mapping
["Domain"], mapping
["command"], mapping
["proto_param"]))
631 for json_domain
in json_api
["domains"]:
633 domain_map
["Domain"] = json_domain
["domain"]
634 domain_map
["domain"] = Decapitalize(json_domain
["domain"])
638 client_method_impls
= []
640 domain_needs_client
= False
642 if "commands" in json_domain
:
643 for json_command
in json_domain
["commands"]:
644 if (not ("handlers" in json_command
) or
645 not ("browser" in json_command
["handlers"])):
649 command_map
= domain_map
.copy()
650 command_map
["command"] = json_command
["name"]
651 command_map
["Command"] = Capitalize(json_command
["name"])
656 if "parameters" in json_command
:
657 for json_param
in json_command
["parameters"]:
658 param_map
= command_map
.copy()
659 param_map
["proto_param"] = json_param
["name"]
660 param_map
["param"] = Uncamelcase(json_param
["name"])
661 param_map
["var_name"] = "in_%s" % param_map
["param"]
663 ResolveType(json_param
, param_map
)
665 prep
.append(params_prep
)
666 if json_param
.get("optional"):
667 if param_map
["Type"] in ["List", "Dictionary"]:
668 # TODO(vkuzkokov) Implement transformation of base::ListValue
669 # to std::vector and base::DictonaryValue to struct.
671 "Optional array and object parameters are not implemented")
672 prep
.append(tmpl_prep_opt
.substitute(param_map
))
673 args
.append(tmpl_arg_opt
.substitute(param_map
))
675 prep
.append(param_map
["prep_req"])
676 args
.append(tmpl_arg_req
.substitute(param_map
))
678 if json_command
.get("async"):
679 domain_needs_client
= True
681 if "returns" in json_command
:
682 json_returns
= json_command
["returns"]
683 command_map
["declared_name"] = "%sResponse" % command_map
["Command"]
684 DeclareStruct(json_returns
, command_map
)
685 # TODO(vkuzkokov) Pass async callback instance similar to how
686 # InspectorBackendDispatcher does it. This, however, can work
687 # only if Blink and Chrome are in the same repo.
688 args
.append("command")
689 handler_method_impls
.append(
690 tmpl_callback_async_impl
.substitute(command_map
,
691 prep
= "".join(prep
),
692 args
= "\n " + ",\n ".join(args
)))
693 client_methods
.append(tmpl_response
.substitute(command_map
))
694 client_method_impls
.append(tmpl_response_impl
.substitute(command_map
))
697 if "returns" in json_command
:
698 for json_param
in json_command
["returns"]:
699 param_map
= command_map
.copy()
700 param_map
["proto_param"] = json_param
["name"]
701 param_map
["param"] = Uncamelcase(json_param
["name"])
702 param_map
["var_name"] = "out_%s" % param_map
["param"]
704 if json_param
.get("optional"):
705 # TODO(vkuzkokov) Implement Optional<T> for value types.
706 raise Exception("Optional return values are not implemented")
707 ResolveType(json_param
, param_map
)
708 prep
.append(tmpl_prep_output
.substitute(param_map
))
709 args
.append(tmpl_arg_output
.substitute(param_map
))
710 if not "wrap" in param_map
:
711 raise Exception("Arrays of arrays are not implemented")
712 wrap
.append(param_map
["wrap"])
716 args_str
= "\n " + ",\n ".join(args
)
717 handler_method_impls
.append(tmpl_callback_impl
.substitute(command_map
,
718 prep
= "".join(prep
),
720 wrap
= "".join(wrap
)))
722 initializations
.append(tmpl_register
.substitute(command_map
))
723 handler_methods
.append(tmpl_callback
.substitute(command_map
))
725 if "events" in json_domain
:
726 for json_event
in json_domain
["events"]:
727 if (not ("handlers" in json_event
) or
728 not ("browser" in json_event
["handlers"])):
731 domain_needs_client
= True
733 event_map
= domain_map
.copy()
734 event_map
["command"] = json_event
["name"]
735 event_map
["Command"] = Capitalize(json_event
["name"])
738 if "parameters" in json_event
:
739 json_parameters
= json_event
["parameters"]
740 event_map
["declared_name"] = "%sParams" % event_map
["Command"]
741 DeclareStruct(json_parameters
, event_map
);
743 client_methods
.append(tmpl_event
.substitute(event_map
))
744 client_method_impls
.append(tmpl_event_impl
.substitute(event_map
))
748 type_decls
.append(tmpl_handler
.substitute(domain_map
))
749 setters
.append(tmpl_setter
.substitute(domain_map
))
750 fields
.append(tmpl_field
.substitute(domain_map
))
751 includes
.append(tmpl_include
.substitute(domain_map
))
752 fields_init
.append(tmpl_field_init
.substitute(domain_map
))
753 if domain_needs_client
:
754 type_decls
.append(tmpl_client
.substitute(domain_map
,
755 methods
= "".join(client_methods
)))
756 friends
.append(tmpl_friend
.substitute(domain_map
))
757 initializations
.append(tmpl_init_client
.substitute(domain_map
))
758 type_impls
.append(tmpl_client_impl
.substitute(domain_map
,
759 methods
= "\n".join(client_method_impls
)))
760 handler_method_impls
.append(tmpl_setter_impl
.substitute(domain_map
,
761 initializations
= "".join(initializations
)))
764 output_h_file
= open(output_h_path
, "w")
765 output_cc_file
= open(output_cc_path
, "w")
767 output_h_file
.write(template_h
.substitute({},
768 types
= "\n".join(type_decls
),
769 setters
= "".join(setters
),
770 friends
= "".join(friends
),
771 methods
= "".join(handler_methods
),
772 fields
= "".join(fields
)))
773 output_h_file
.close()
775 output_cc_file
.write(template_cc
.substitute({},
776 includes
= "".join(sorted(includes
)),
777 fields_init
= ",\n ".join(fields_init
),
778 methods
= "\n".join(handler_method_impls
),
779 types
= "\n".join(type_impls
)))
780 output_cc_file
.close()