| #!/usr/bin/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 |
| |
| package = sys.argv[1] |
| output_cc_path = sys.argv[2] |
| output_h_path = sys.argv[3] |
| blink_protocol_path = sys.argv[4] |
| |
| template_h = string.Template("""\ |
| // Copyright 2013 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. |
| |
| #ifndef ${PACKAGE}_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTS_H_ |
| #define ${PACKAGE}_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTS_H_ |
| |
| // THIS FILE IS AUTOGENERATED. DO NOT EDIT. |
| // Generated by |
| // chrome/browser/devtools/devtools_protocol_constants_generator.py from |
| // gen/blink/core/inspector/protocol.json |
| |
| #include <string> |
| |
| namespace $package { |
| namespace devtools { |
| |
| extern const char kProtocolVersion[]; |
| |
| bool IsSupportedProtocolVersion(const std::string& version); |
| |
| extern const char kResult[]; |
| $contents |
| |
| } // devtools |
| } // $package |
| |
| #endif // ${PACKAGE}_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTS_H_ |
| """) |
| |
| template_cc = string.Template("""\ |
| // Copyright 2013 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 |
| // chrome/browser/devtools/devtools_protocol_constants_generator.py from |
| // gen/blink/core/inspector/protocol.json |
| |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_split.h" |
| #include "base/strings/string_util.h" |
| #include "$package/browser/devtools/devtools_protocol_constants.h" |
| |
| namespace $package { |
| namespace devtools { |
| |
| const char kProtocolVersion[] = "$major.$minor"; |
| |
| bool IsSupportedProtocolVersion(const std::string& version) { |
| std::vector<base::StringPiece> tokens = base::SplitStringPiece( |
| version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
| int major, minor; |
| return tokens.size() == 2 && |
| base::StringToInt(tokens[0], &major) && major == $major && |
| base::StringToInt(tokens[1], &minor) && minor <= $minor; |
| } |
| |
| const char kResult[] = "result"; |
| $contents |
| |
| } // devtools |
| } // $package |
| """) |
| |
| def Capitalize(s): |
| return s[:1].capitalize() + s[1:] |
| |
| def ToIdentifier(s): |
| return "".join([Capitalize(part) for part in s.split("-")]) |
| |
| references = [] |
| |
| def CreateNamespace(domain_name, data, keys, prefixes, name = None): |
| result = {} |
| if name: |
| result["kName"] = name |
| for i, key in enumerate(keys): |
| if key in data: |
| for parameter in data[key]: |
| parameter_name = parameter["name"]; |
| result[prefixes[i] + Capitalize(parameter_name)] = parameter_name |
| if "enum" in parameter: |
| enum_name = Capitalize(parameter_name) |
| result[enum_name] = {} |
| for enum in parameter["enum"]: |
| result[enum_name]["kEnum" + ToIdentifier(enum)] = enum |
| reference = "" |
| if "$ref" in parameter: |
| reference = parameter["$ref"] |
| if "items" in parameter and "$ref" in parameter["items"]: |
| reference = parameter["items"]["$ref"] |
| if reference: |
| if not "." in reference: |
| reference = domain_name + "." + reference |
| references.append(reference) |
| return result |
| |
| def FormatContents(tree, indent, format_string): |
| outer = dict((key, value) for key, value in tree.iteritems() |
| if not isinstance(value, dict)) |
| inner = dict((key, value) for key, value in tree.iteritems() |
| if isinstance(value, dict)) |
| body = "" |
| body += "".join(indent + format_string.format(key, value) |
| for (key, value) in sorted(outer.items())) |
| body += "".join(FormatNamespace(key, value, indent, format_string) |
| for (key, value) in sorted(inner.items())) |
| return body |
| |
| def FormatNamespace(title, tree, indent, format_string): |
| if (not tree): |
| return "" |
| body = '\n' + indent + "namespace " + title + " {\n" |
| body += FormatContents(tree, indent + " ", format_string) |
| body += indent + "} // " + title + "\n" |
| return body |
| |
| def CreateHeader(tree, output_file): |
| contents = FormatContents(tree, "", "extern const char {0}[];\n") |
| output_file.write(template_h.substitute({ |
| "contents": contents, |
| "package": package, |
| "PACKAGE": package.upper() |
| })) |
| |
| def CreateBody(tree, version, output_file): |
| contents = FormatContents(tree, "", "const char {0}[] = \"{1}\";\n") |
| output_file.write(template_cc.substitute({ |
| "major": version["major"], |
| "minor": version["minor"], |
| "contents": contents, |
| "package": package |
| })) |
| |
| blink_protocol_data = open(blink_protocol_path).read() |
| blink_protocol = json.loads(blink_protocol_data) |
| blink_version = blink_protocol["version"] |
| |
| domains = blink_protocol["domains"] |
| |
| namespace_tree = {} |
| |
| for domain in domains: |
| domain_value = {} |
| domain_namespace_name = Capitalize(domain["domain"]) |
| if "commands" in domain: |
| for command in domain["commands"]: |
| domain_value[command["name"]] = CreateNamespace(domain["domain"], |
| command, ["parameters", "returns"], ["kParam", "kResponse"], |
| domain_namespace_name + "." + command["name"]) |
| |
| if "events" in domain: |
| for event in domain["events"]: |
| domain_value[event["name"]] = CreateNamespace(domain["domain"], |
| event, ["parameters"], ["kParam"], |
| domain_namespace_name + "." + event["name"]) |
| if domain_value: |
| namespace_tree[domain_namespace_name] = domain_value |
| |
| while (references): |
| reference = references.pop(); |
| path = reference.split("."); |
| parent_namespace = namespace_tree; |
| for path_segment in path[0:-1]: |
| if path_segment not in parent_namespace: |
| parent_namespace[path_segment] = {} |
| parent_namespace = parent_namespace[path_segment] |
| if (path[-1] not in parent_namespace): |
| try: |
| domain = [d for d in domains if d["domain"] == path[0]][0] |
| ref_type = [t for t in domain["types"] if t["id"] == path[1]][0] |
| parent_namespace[ref_type["id"]] = CreateNamespace(path[0], |
| ref_type, ["properties"], ["kParam"]) |
| except IndexError: |
| sys.stderr.write("Failed to resolve type [{0}].\n".format(reference)) |
| sys.exit(1) |
| |
| for (namespace_name, namespace) in namespace_tree.items(): |
| namespace["kName"] = namespace_name |
| |
| with open(output_cc_path, "w") as f: |
| CreateBody(namespace_tree, blink_version, f) |
| |
| with open(output_h_path, "w") as f: |
| CreateHeader(namespace_tree, f) |