| #!/usr/bin/env python |
| # Copyright 2014 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import sys |
| import string |
| import json |
| |
| blink_protocol_path = sys.argv[1] |
| browser_protocol_path = sys.argv[2] |
| output_cc_path = sys.argv[3] |
| output_h_path = sys.argv[4] |
| |
| header = """\ |
| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // THIS FILE IS AUTOGENERATED. DO NOT EDIT. |
| // Generated by |
| // content/public/browser/devtools_protocol_handler_generator.py from |
| // third_party/WebKit/Source/devtools/protocol.json and |
| // content/browser/devtools/browser_protocol.json |
| """ |
| |
| template_h = string.Template(header + """\ |
| |
| #ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_ |
| #define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_ |
| |
| #include "content/browser/devtools/protocol/devtools_protocol_client.h" |
| |
| namespace content { |
| |
| class DevToolsProtocolDispatcher; |
| |
| namespace devtools { |
| |
| extern const char kProtocolVersion[]; |
| |
| bool IsSupportedProtocolVersion(const std::string& version); |
| |
| template<typename T> |
| base::Value* CreateValue(const T& param) { |
| return new base::FundamentalValue(param); |
| } |
| |
| template<class T> |
| base::Value* CreateValue(scoped_ptr<T>& param) { |
| return param.release(); |
| } |
| |
| template<class T> |
| base::Value* CreateValue(scoped_refptr<T> param) { |
| return param->ToValue().release(); |
| } |
| |
| template<typename T> |
| base::Value* CreateValue(const std::vector<T> param) { |
| base::ListValue* result = new base::ListValue(); |
| for (auto& item : param) { |
| result->Append(CreateValue(item)); |
| } |
| return result; |
| } |
| |
| template<> |
| base::Value* CreateValue(const std::string& param); |
| |
| ${types}\ |
| |
| } // namespace devtools |
| |
| class DevToolsProtocolDispatcher { |
| public: |
| using Notifier = DevToolsProtocolClient::RawMessageCallback; |
| using CommandHandler = |
| base::Callback<bool(int, scoped_ptr<base::DictionaryValue>)>; |
| |
| explicit DevToolsProtocolDispatcher(const Notifier& notifier); |
| ~DevToolsProtocolDispatcher(); |
| |
| CommandHandler FindCommandHandler(const std::string& method); |
| |
| ${setters}\ |
| |
| private: |
| using Response = DevToolsProtocolClient::Response; |
| using CommandHandlers = std::map<std::string, CommandHandler>; |
| |
| ${methods}\ |
| |
| Notifier notifier_; |
| DevToolsProtocolClient client_; |
| CommandHandlers command_handlers_; |
| ${fields}\ |
| }; |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_DEVTOOLS_PROTOCOL_DISPATCHER_H_ |
| """) |
| |
| tmpl_typedef = string.Template("""\ |
| namespace ${domain} { |
| typedef ${param_type} ${declared_name}; |
| } // namespace ${domain} |
| """) |
| |
| tmpl_struct = string.Template("""\ |
| namespace ${domain} { |
| template<int MASK> |
| struct ${declared_name}Builder |
| : base::RefCounted<${declared_name}Builder<MASK>> { |
| public: |
| enum { |
| kAllSet = 0, |
| ${fields_enum}\ |
| }; |
| |
| ${methods}\ |
| |
| static scoped_refptr<${declared_name}Builder<kNoneSet>> Create() { |
| return new ${declared_name}Builder<kNoneSet>(); |
| } |
| |
| scoped_ptr<base::DictionaryValue> ToValue() { |
| static_assert(MASK == kAllSet, "required properties missing"); |
| return make_scoped_ptr(dict_->DeepCopy()); |
| } |
| |
| private: |
| friend struct ${declared_name}Builder<0>; |
| |
| ${declared_name}Builder() : dict_(new base::DictionaryValue()) { |
| } |
| |
| template<class T> T* ThisAs() { |
| static_assert(sizeof(*this) == sizeof(T), "cannot cast"); |
| return reinterpret_cast<T*>(this); |
| } |
| |
| scoped_ptr<base::DictionaryValue> dict_; |
| }; |
| |
| typedef ${declared_name}Builder<0> ${declared_name}; |
| |
| } // namespace ${domain} |
| """) |
| |
| tmpl_builder_setter_req = string.Template("""\ |
| scoped_refptr<${declared_name}Builder<MASK & ~k${Param}>> |
| set_${param}(${pass_type} ${param}) { |
| static_assert(MASK & k${Param}, "already set"); |
| dict_->Set("${proto_param}", CreateValue(${param})); |
| return ThisAs<${declared_name}Builder<MASK & ~k${Param}>>(); |
| } |
| """) |
| |
| tmpl_builder_setter_opt = string.Template("""\ |
| scoped_refptr<${declared_name}Builder<MASK>> |
| set_${param}(${pass_type} ${param}) { |
| dict_->Set("${proto_param}", CreateValue(${param})); |
| return this; |
| } |
| """) |
| |
| tmpl_builder_enum = string.Template("""\ |
| k${Param} = 1 << ${ordinal}, |
| """) |
| |
| tmpl_builder_none_set = string.Template("""\ |
| kNoneSet = ${all_fields} |
| """) |
| |
| tmpl_named_enum = string.Template("""\ |
| namespace ${domain} { |
| ${values}\ |
| } // namespace ${domain} |
| """) |
| |
| tmpl_inline_enum = string.Template("""\ |
| namespace ${domain} { |
| namespace ${subdomain} { |
| ${values}\ |
| } // namespace ${subdomain} |
| } // namespace ${domain} |
| """) |
| |
| tmpl_enum_value = string.Template("""\ |
| extern const char k${Enum}${Value}[]; |
| """) |
| |
| tmpl_enum_value_def = string.Template("""\ |
| const char k${Enum}${Value}[] = "${value}"; |
| """) |
| |
| tmpl_handler = string.Template("""\ |
| namespace ${domain} { |
| class ${Domain}Handler; |
| } // namespace domain |
| """) |
| |
| tmpl_client = string.Template("""\ |
| namespace ${domain} { |
| class Client : public DevToolsProtocolClient { |
| public: |
| explicit Client(const RawMessageCallback& raw_message_callback); |
| ~Client() override; |
| |
| ${methods}\ |
| }; |
| } // namespace ${domain} |
| """) |
| |
| tmpl_event = string.Template("""\ |
| void ${Command}( |
| scoped_refptr<${Command}Params> params); |
| """) |
| |
| tmpl_response = string.Template("""\ |
| void Send${Command}Response( |
| DevToolsCommandId command_id, |
| scoped_refptr<${Command}Response> params); |
| """) |
| |
| tmpl_setter = string.Template("""\ |
| void Set${Domain}Handler( |
| devtools::${domain}::${Domain}Handler* ${domain}_handler); |
| """) |
| |
| tmpl_callback = string.Template("""\ |
| bool On${Domain}${Command}( |
| DevToolsCommandId command_id, |
| scoped_ptr<base::DictionaryValue> params); |
| """) |
| |
| tmpl_field = string.Template("""\ |
| devtools::${domain}::${Domain}Handler* ${domain}_handler_; |
| """) |
| |
| template_cc = string.Template(header + """\ |
| |
| #include "content/browser/devtools/protocol/devtools_protocol_handler.h" |
| |
| #include "base/bind.h" |
| #include "base/strings/string_number_conversions.h" |
| ${includes}\ |
| |
| namespace content { |
| |
| DevToolsProtocolDispatcher::DevToolsProtocolDispatcher( |
| const Notifier& notifier) |
| : notifier_(notifier), |
| client_(notifier), |
| ${fields_init} { |
| } |
| |
| DevToolsProtocolDispatcher::~DevToolsProtocolDispatcher() { |
| } |
| |
| DevToolsProtocolDispatcher::CommandHandler |
| DevToolsProtocolDispatcher::FindCommandHandler(const std::string& method) { |
| CommandHandlers::iterator it = command_handlers_.find(method); |
| return it == command_handlers_.end() ? CommandHandler() : it->second; |
| } |
| |
| ${methods}\ |
| |
| namespace devtools { |
| |
| const char kProtocolVersion[] = "${major}.${minor}"; |
| |
| bool IsSupportedProtocolVersion(const std::string& version) { |
| std::vector<std::string> tokens; |
| Tokenize(version, ".", &tokens); |
| int major, minor; |
| return tokens.size() == 2 && |
| base::StringToInt(tokens[0], &major) && major == ${major} && |
| base::StringToInt(tokens[1], &minor) && minor <= ${minor}; |
| } |
| |
| template<> |
| base::Value* CreateValue(const std::string& param) { |
| return new base::StringValue(param); |
| } |
| |
| ${types}\ |
| |
| } // namespace devtools |
| |
| } // namespace content |
| """) |
| |
| tmpl_include = string.Template("""\ |
| #include "content/browser/devtools/protocol/${domain}_handler.h" |
| """) |
| |
| tmpl_field_init = string.Template("${domain}_handler_(nullptr)") |
| |
| tmpl_setter_impl = string.Template("""\ |
| void DevToolsProtocolDispatcher::Set${Domain}Handler( |
| devtools::${domain}::${Domain}Handler* ${domain}_handler) { |
| DCHECK(!${domain}_handler_); |
| ${domain}_handler_ = ${domain}_handler; |
| ${initializations}\ |
| } |
| """) |
| |
| tmpl_register = string.Template("""\ |
| command_handlers_["${Domain}.${command}"] = |
| base::Bind( |
| &DevToolsProtocolDispatcher::On${TargetDomain}${Command}, |
| base::Unretained(this)); |
| """) |
| |
| tmpl_init_client = string.Template("""\ |
| ${domain}_handler_->SetClient(make_scoped_ptr( |
| new devtools::${domain}::Client(notifier_))); |
| """) |
| |
| tmpl_callback_impl = string.Template("""\ |
| bool DevToolsProtocolDispatcher::On${Domain}${Command}( |
| DevToolsCommandId command_id, |
| scoped_ptr<base::DictionaryValue> params) { |
| ${prep}\ |
| Response response = ${domain}_handler_->${Command}(${args}); |
| scoped_ptr<base::DictionaryValue> protocol_response; |
| if (client_.SendError(command_id, response)) |
| return true; |
| if (response.IsFallThrough()) |
| return false; |
| scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue()); |
| ${wrap}\ |
| client_.SendSuccess(command_id, result.Pass()); |
| return true; |
| } |
| """) |
| |
| tmpl_wrap = string.Template("""\ |
| result->Set("${proto_param}", devtools::CreateValue(out_${param})); |
| """) |
| |
| tmpl_callback_async_impl = string.Template("""\ |
| bool DevToolsProtocolDispatcher::On${Domain}${Command}( |
| DevToolsCommandId command_id, |
| scoped_ptr<base::DictionaryValue> params) { |
| ${prep}\ |
| Response response = ${domain}_handler_->${Command}(${args}); |
| if (client_.SendError(command_id, response)) |
| return true; |
| return !response.IsFallThrough(); |
| } |
| """) |
| |
| tmpl_prep_req = string.Template("""\ |
| ${raw_type} in_${param}${init}; |
| if (!params || !params->Get${Type}("${proto_param}", &in_${param})) { |
| client_.SendError(command_id, Response::InvalidParams("${proto_param}")); |
| return true; |
| } |
| """) |
| |
| tmpl_prep_req_list = string.Template("""\ |
| base::ListValue* list_${param} = nullptr; |
| if (!params || !params->GetList("${proto_param}", &list_${param})) { |
| client_.SendError(command_id, Response::InvalidParams("${proto_param}")); |
| return true; |
| } |
| std::vector<${item_type}> in_${param}; |
| for (base::ListValue::const_iterator it = |
| list_${param}->begin(); it != list_${param}->end(); ++it) { |
| ${item_raw_type} item; |
| if (!(*it)->GetAs${ItemType}(&item)) { |
| client_.SendError(command_id, Response::InvalidParams("${proto_param}")); |
| return true; |
| } |
| in_${param}.push_back(${item_pass}); |
| } |
| """) |
| |
| tmpl_prep_opt = string.Template("""\ |
| ${raw_type} in_${param}${init}; |
| bool ${param}_found = params && params->Get${Type}( |
| "${proto_param}", |
| &in_${param}); |
| """) |
| |
| tmpl_prep_output = string.Template("""\ |
| ${param_type} out_${param}${init}; |
| """) |
| |
| tmpl_arg_name = string.Template("in_${param}") |
| |
| tmpl_arg_req = string.Template("${param_pass}") |
| |
| tmpl_arg_opt = string.Template( |
| "${param}_found ? ${param_pass} : nullptr") |
| |
| tmpl_object_pass = string.Template( |
| "make_scoped_ptr<base::DictionaryValue>(${name}->DeepCopy())") |
| |
| tmpl_client_impl = string.Template("""\ |
| namespace ${domain} { |
| |
| Client::Client(const RawMessageCallback& raw_message_callback) |
| : DevToolsProtocolClient(raw_message_callback) { |
| } |
| |
| Client::~Client() { |
| } |
| |
| ${methods}\ |
| |
| } // namespace ${domain} |
| """) |
| |
| tmpl_event_impl = string.Template("""\ |
| void Client::${Command}( |
| scoped_refptr<${Command}Params> params) { |
| SendNotification("${Domain}.${command}", |
| params->ToValue().Pass()); |
| } |
| """) |
| |
| tmpl_response_impl = string.Template("""\ |
| void Client::Send${Command}Response( |
| DevToolsCommandId command_id, |
| scoped_refptr<${Command}Response> params) { |
| SendSuccess(command_id, params->ToValue().Pass()); |
| } |
| """) |
| |
| tmpl_typename = string.Template("devtools::${domain}::${declared_name}") |
| |
| def Capitalize(s): |
| return s[:1].upper() + s[1:] |
| |
| def Uncamelcase(s): |
| result = "" |
| for i, c in enumerate(s): |
| if c.isupper(): |
| if (i > 0) and ((i < len(s)-1) and s[i+1].islower() or s[i-1].islower()): |
| result += "_" |
| result += c.lower() |
| else: |
| result += c |
| return result |
| |
| types = {} |
| blink_protocol = json.loads(open(blink_protocol_path, "r").read()) |
| browser_protocol = json.loads(open(browser_protocol_path, "r").read()) |
| type_decls = [] |
| type_impls = [] |
| handler_methods = [] |
| handler_method_impls = [] |
| domain_maps = [] |
| redirects = {} |
| |
| all_domains = blink_protocol["domains"] + browser_protocol["domains"] |
| |
| for json_domain in all_domains: |
| if "types" in json_domain: |
| for json_type in json_domain["types"]: |
| types["%s.%s" % (json_domain["domain"], json_type["id"])] = json_type |
| |
| def DeclareStruct(json_properties, mapping): |
| methods = [] |
| fields_enum = [] |
| enum_items = [] |
| req_fields_num = 0 |
| for json_prop in json_properties: |
| prop_map = mapping.copy() |
| prop_map["proto_param"] = json_prop["name"] |
| prop_map["param"] = Uncamelcase(json_prop["name"]) |
| prop_map["Param"] = Capitalize(json_prop["name"]) |
| prop_map["subdomain"] = Uncamelcase(prop_map["declared_name"]) |
| del prop_map["declared_name"] |
| ResolveType(json_prop, prop_map) |
| prop_map["declared_name"] = mapping["declared_name"] |
| if json_prop.get("optional"): |
| methods.append(tmpl_builder_setter_opt.substitute(prop_map)) |
| else: |
| methods.append(tmpl_builder_setter_req.substitute(prop_map)) |
| enum_items.append("k%s" % prop_map["Param"]); |
| fields_enum.append(tmpl_builder_enum.substitute(prop_map, |
| ordinal = req_fields_num)) |
| req_fields_num += 1 |
| |
| all_fields = "kAllSet" |
| if len(enum_items) > 0: |
| all_fields = " | ".join(enum_items) |
| fields_enum.append(tmpl_builder_none_set.substitute(mapping, |
| all_fields = all_fields)) |
| type_decls.append(tmpl_struct.substitute(mapping, |
| methods = "\n".join(methods), |
| fields_enum = "".join(fields_enum))) |
| |
| def DeclareEnum(json, mapping): |
| values = [] |
| value_defs = [] |
| tmpl_enum = tmpl_inline_enum |
| if "declared_name" in mapping: |
| mapping["Enum"] = mapping["declared_name"] |
| tmpl_enum = tmpl_named_enum |
| else: |
| mapping["Enum"] = Capitalize(mapping["proto_param"]) |
| |
| for enum_value in json["enum"]: |
| values.append(tmpl_enum_value.substitute(mapping, |
| Value = Capitalize(enum_value))) |
| value_defs.append(tmpl_enum_value_def.substitute(mapping, |
| value = enum_value, |
| Value = Capitalize(enum_value))) |
| type_decls.append(tmpl_enum.substitute(mapping, |
| values = "".join(values))) |
| type_impls.append(tmpl_enum.substitute(mapping, |
| values = "".join(value_defs))) |
| |
| def ResolveRef(json, mapping): |
| dot_pos = json["$ref"].find(".") |
| if dot_pos == -1: |
| domain_name = mapping["Domain"] |
| type_name = json["$ref"] |
| else: |
| domain_name = json["$ref"][:dot_pos] |
| type_name = json["$ref"][dot_pos + 1:] |
| json_type = types["%s.%s" % (domain_name, type_name)] |
| mapping["declared_name"] = Capitalize(type_name) |
| mapping["Domain"] = domain_name |
| mapping["domain"] = Uncamelcase(domain_name) |
| mapping["param_type"] = tmpl_typename.substitute(mapping) |
| ResolveType(json_type, mapping) |
| if not "___type_declared" in json_type: |
| json_type["___type_declared"] = True; |
| if (json_type.get("type") == "object") and ("properties" in json_type): |
| DeclareStruct(json_type["properties"], mapping) |
| else: |
| if ("enum" in json_type): |
| DeclareEnum(json_type, mapping) |
| type_decls.append(tmpl_typedef.substitute(mapping)) |
| |
| def ResolveArray(json, mapping): |
| items_map = mapping.copy() |
| ResolveType(json["items"], items_map) |
| if items_map["Type"] == "List": |
| # TODO(dgozman) Implement this. |
| raise Exception("Nested arrays are not implemented") |
| mapping["param_type"] = "std::vector<%s>" % items_map["param_type"] |
| mapping["Type"] = "List" |
| mapping["pass_type"] = "const %s&" % mapping["param_type"] |
| mapping["storage_type"] = "std::vector<%s>" % items_map["storage_type"] |
| mapping["raw_type"] = mapping["storage_type"] |
| mapping["prep_req"] = tmpl_prep_req_list.substitute(mapping, |
| item_type = items_map["storage_type"], |
| item_init = items_map["init"], |
| item_raw_type = items_map["raw_type"], |
| item_pass = items_map["pass_template"].substitute(name="item", opt=""), |
| ItemType = items_map["Type"]) |
| mapping["arg_out"] = "&out_%s" % mapping["param"] |
| |
| def ResolveObject(json, mapping): |
| mapping["Type"] = "Dictionary" |
| mapping["storage_type"] = "scoped_ptr<base::DictionaryValue>" |
| mapping["raw_type"] = "base::DictionaryValue*" |
| mapping["pass_template"] = tmpl_object_pass |
| if "properties" in json: |
| if not "declared_name" in mapping: |
| mapping["declared_name"] = ("%s%s" % |
| (mapping["Command"], Capitalize(mapping["proto_param"]))) |
| mapping["param_type"] = ("scoped_refptr<%s>" % |
| tmpl_typename.substitute(mapping)) |
| DeclareStruct(json["properties"], mapping) |
| else: |
| mapping["param_type"] = ("scoped_refptr<%s>" % |
| tmpl_typename.substitute(mapping)) |
| mapping["pass_type"] = mapping["param_type"] |
| mapping["arg_out"] = "&out_%s" % mapping["param"] |
| else: |
| mapping["param_type"] = "base::DictionaryValue" |
| mapping["pass_type"] = "scoped_ptr<base::DictionaryValue>" |
| mapping["arg_out"] = "out_%s.get()" % mapping["param"] |
| mapping["prep_req"] = tmpl_prep_req.substitute(mapping) |
| |
| def ResolvePrimitive(json, mapping): |
| jsonrpc_type = json["type"] |
| if jsonrpc_type == "boolean": |
| mapping["param_type"] = "bool" |
| mapping["Type"] = "Boolean" |
| mapping["init"] = " = false" |
| elif jsonrpc_type == "integer": |
| mapping["param_type"] = "int" |
| mapping["Type"] = "Integer" |
| mapping["init"] = " = 0" |
| elif jsonrpc_type == "number": |
| mapping["param_type"] = "double" |
| mapping["Type"] = "Double" |
| mapping["init"] = " = 0.0" |
| elif jsonrpc_type == "string": |
| mapping["param_type"] = "std::string" |
| mapping["pass_type"] = "const std::string&" |
| mapping["Type"] = "String" |
| if "enum" in json and not "declared_name" in mapping: |
| if not "subdomain" in mapping: |
| mapping["subdomain"] = Uncamelcase(mapping["command"]) |
| DeclareEnum(json, mapping) |
| else: |
| raise Exception("Unknown type: %s" % json_type) |
| mapping["storage_type"] = mapping["param_type"] |
| mapping["raw_type"] = mapping["param_type"] |
| mapping["prep_req"] = tmpl_prep_req.substitute(mapping) |
| if jsonrpc_type != "string": |
| mapping["pass_type"] = mapping["param_type"] |
| mapping["arg_out"] = "&out_%s" % mapping["param"] |
| |
| def ResolveType(json, mapping): |
| mapping["init"] = "" |
| mapping["pass_template"] = string.Template("${opt}${name}") |
| if "$ref" in json: |
| ResolveRef(json, mapping) |
| elif "type" in json: |
| jsonrpc_type = json["type"] |
| if jsonrpc_type == "array": |
| ResolveArray(json, mapping) |
| elif jsonrpc_type == "object": |
| ResolveObject(json, mapping) |
| else: |
| ResolvePrimitive(json, mapping) |
| else: |
| raise Exception("Unknown type at %s.%s %s" % |
| (mapping["Domain"], mapping["command"], mapping["proto_param"])) |
| |
| setters = [] |
| fields = [] |
| |
| includes = [] |
| fields_init = [] |
| |
| for json_domain in all_domains: |
| domain_map = {} |
| domain_map["Domain"] = json_domain["domain"] |
| domain_map["domain"] = Uncamelcase(json_domain["domain"]) |
| |
| initializations = [] |
| client_methods = [] |
| client_method_impls = [] |
| domain_empty = True |
| domain_needs_client = False |
| |
| if "commands" in json_domain: |
| for json_command in json_domain["commands"]: |
| if (not ("handlers" in json_command) or |
| not ("browser" in json_command["handlers"])): |
| continue |
| domain_empty = False |
| |
| command_map = domain_map.copy() |
| command_map["command"] = json_command["name"] |
| command_map["Command"] = Capitalize(json_command["name"]) |
| |
| if "redirect" in json_command: |
| redirect_domain = json_command["redirect"] |
| if not (redirect_domain in redirects): |
| redirects[redirect_domain] = [] |
| command_map["TargetDomain"] = redirect_domain |
| redirects[redirect_domain].append(tmpl_register.substitute(command_map)) |
| continue |
| |
| command_map["TargetDomain"] = command_map["Domain"] |
| prep = [] |
| args = [] |
| |
| if "parameters" in json_command: |
| for json_param in json_command["parameters"]: |
| param_map = command_map.copy() |
| param_map["proto_param"] = json_param["name"] |
| param_map["param"] = Uncamelcase(json_param["name"]) |
| ResolveType(json_param, param_map) |
| if json_param.get("optional"): |
| if param_map["Type"] in ["List"]: |
| # TODO(vkuzkokov) Implement transformation of base::ListValue |
| # to std::vector and base::DictonaryValue to struct. |
| raise Exception( |
| "Optional array parameters are not implemented") |
| prep.append(tmpl_prep_opt.substitute(param_map)) |
| param_pass = param_map["pass_template"].substitute( |
| name=tmpl_arg_name.substitute(param_map), |
| opt="&") |
| args.append( |
| tmpl_arg_opt.substitute(param_map, param_pass=param_pass)) |
| else: |
| prep.append(param_map["prep_req"]) |
| param_pass = param_map["pass_template"].substitute( |
| name=tmpl_arg_name.substitute(param_map), |
| opt="") |
| args.append( |
| tmpl_arg_req.substitute(param_map, param_pass=param_pass)) |
| |
| if json_command.get("async"): |
| domain_needs_client = True |
| json_returns = [] |
| if "returns" in json_command: |
| json_returns = json_command["returns"] |
| command_map["declared_name"] = "%sResponse" % command_map["Command"] |
| DeclareStruct(json_returns, command_map) |
| # TODO(vkuzkokov) Pass async callback instance similar to how |
| # InspectorBackendDispatcher does it. This, however, can work |
| # only if Blink and Chrome are in the same repo. |
| args.insert(0, "command_id") |
| handler_method_impls.append( |
| tmpl_callback_async_impl.substitute(command_map, |
| prep = "".join(prep), |
| args = "\n " + ",\n ".join(args))) |
| client_methods.append(tmpl_response.substitute(command_map)) |
| client_method_impls.append(tmpl_response_impl.substitute(command_map)) |
| else: |
| wrap = [] |
| if "returns" in json_command: |
| for json_param in json_command["returns"]: |
| param_map = command_map.copy() |
| param_map["proto_param"] = json_param["name"] |
| param_map["param"] = Uncamelcase(json_param["name"]) |
| if json_param.get("optional"): |
| # TODO(vkuzkokov) Implement Optional<T> for value types. |
| raise Exception("Optional return values are not implemented") |
| ResolveType(json_param, param_map) |
| prep.append(tmpl_prep_output.substitute(param_map)) |
| args.append(param_map["arg_out"]) |
| wrap.append(tmpl_wrap.substitute(param_map)) |
| args_str = "" |
| if len(args) > 0: |
| args_str = "\n " + ",\n ".join(args) |
| handler_method_impls.append(tmpl_callback_impl.substitute(command_map, |
| prep = "".join(prep), |
| args = args_str, |
| wrap = "".join(wrap))) |
| |
| initializations.append(tmpl_register.substitute(command_map)) |
| handler_methods.append(tmpl_callback.substitute(command_map)) |
| |
| if "events" in json_domain: |
| for json_event in json_domain["events"]: |
| if (not ("handlers" in json_event) or |
| not ("browser" in json_event["handlers"])): |
| continue |
| domain_empty = False |
| domain_needs_client = True |
| |
| event_map = domain_map.copy() |
| event_map["command"] = json_event["name"] |
| event_map["Command"] = Capitalize(json_event["name"]) |
| |
| json_parameters = [] |
| if "parameters" in json_event: |
| json_parameters = json_event["parameters"] |
| event_map["declared_name"] = "%sParams" % event_map["Command"] |
| DeclareStruct(json_parameters, event_map); |
| |
| client_methods.append(tmpl_event.substitute(event_map)) |
| client_method_impls.append(tmpl_event_impl.substitute(event_map)) |
| |
| if domain_empty: |
| continue |
| type_decls.append(tmpl_handler.substitute(domain_map)) |
| setters.append(tmpl_setter.substitute(domain_map)) |
| fields.append(tmpl_field.substitute(domain_map)) |
| includes.append(tmpl_include.substitute(domain_map)) |
| fields_init.append(tmpl_field_init.substitute(domain_map)) |
| if domain_needs_client: |
| type_decls.append(tmpl_client.substitute(domain_map, |
| methods = "".join(client_methods))) |
| initializations.append(tmpl_init_client.substitute(domain_map)) |
| type_impls.append(tmpl_client_impl.substitute(domain_map, |
| methods = "\n".join(client_method_impls))) |
| domain_map["initializations"] = "".join(initializations) |
| domain_maps.append(domain_map) |
| |
| for domain_map in domain_maps: |
| domain = domain_map["Domain"] |
| if domain in redirects: |
| domain_map["initializations"] += "".join(redirects[domain]) |
| handler_method_impls.append(tmpl_setter_impl.substitute(domain_map)) |
| |
| output_h_file = open(output_h_path, "w") |
| output_cc_file = open(output_cc_path, "w") |
| |
| output_h_file.write(template_h.substitute({}, |
| types = "\n".join(type_decls), |
| setters = "".join(setters), |
| methods = "".join(handler_methods), |
| fields = "".join(fields))) |
| output_h_file.close() |
| |
| output_cc_file.write(template_cc.substitute({}, |
| major = blink_protocol["version"]["major"], |
| minor = blink_protocol["version"]["minor"], |
| includes = "".join(sorted(includes)), |
| fields_init = ",\n ".join(fields_init), |
| methods = "\n".join(handler_method_impls), |
| types = "\n".join(type_impls))) |
| output_cc_file.close() |