Home | History | Annotate | Download | only in browser
      1 #!/usr/bin/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.
      5 
      6 import sys
      7 import string
      8 import json
      9 
     10 package = sys.argv[1]
     11 output_cc_path = sys.argv[2]
     12 output_h_path = sys.argv[3]
     13 blink_protocol_path = sys.argv[4]
     14 browser_protocol_path = sys.argv[5] if len(sys.argv) > 5 else None
     15 
     16 template_h = string.Template("""\
     17 // Copyright 2013 The Chromium Authors. All rights reserved.
     18 // Use of this source code is governed by a BSD-style license that can be
     19 // found in the LICENSE file.
     20 
     21 #ifndef ${PACKAGE}_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTS_H_
     22 #define ${PACKAGE}_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTS_H_
     23 
     24 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
     25 // Generated by
     26 //  content/public/browser/devtools_protocol_constants_generator.py from
     27 //  third_party/WebKit/Source/devtools/protocol.json and
     28 //  content/browser/devtools/browser_protocol.json
     29 
     30 #include <string>
     31 
     32 namespace $package {
     33 namespace devtools {
     34 
     35 extern const char kProtocolVersion[];
     36 
     37 bool IsSupportedProtocolVersion(const std::string& version);
     38 
     39 extern const char kResult[];
     40 $contents
     41 
     42 }  // devtools
     43 }  // $package
     44 
     45 #endif  // ${PACKAGE}_BROWSER_DEVTOOLS_DEVTOOLS_PROTOCOL_CONSTANTS_H_
     46 """)
     47 
     48 template_cc = string.Template("""\
     49 // Copyright 2013 The Chromium Authors. All rights reserved.
     50 // Use of this source code is governed by a BSD-style license that can be
     51 // found in the LICENSE file.
     52 
     53 // THIS FILE IS AUTOGENERATED. DO NOT EDIT.
     54 // Generated by
     55 //  content/public/browser/devtools_protocol_constants_generator.py from
     56 //  third_party/WebKit/Source/devtools/protocol.json and
     57 //  content/browser/devtools/browser_protocol.json
     58 
     59 #include "base/strings/string_number_conversions.h"
     60 #include "base/strings/string_util.h"
     61 #include "$package/browser/devtools/devtools_protocol_constants.h"
     62 
     63 namespace $package {
     64 namespace devtools {
     65 
     66 const char kProtocolVersion[] = "$major.$minor";
     67 
     68 bool IsSupportedProtocolVersion(const std::string& version) {
     69   std::vector<std::string> tokens;
     70   Tokenize(version, ".", &tokens);
     71   int major, minor;
     72   return tokens.size() == 2 &&
     73       base::StringToInt(tokens[0], &major) && major == $major &&
     74       base::StringToInt(tokens[1], &minor) && minor <= $minor;
     75 }
     76 
     77 const char kResult[] = "result";
     78 $contents
     79 
     80 }  // devtools
     81 }  // $package
     82 """)
     83 
     84 def Capitalize(s):
     85   return s[:1].capitalize() + s[1:]
     86 
     87 references = []
     88 
     89 def CreateNamespace(domain_name, data, keys, prefixes, name = None):
     90   result = {}
     91   if name:
     92     result["kName"] = name
     93   for i, key in enumerate(keys):
     94     if key in data:
     95       for parameter in data[key]:
     96         parameter_name = parameter["name"];
     97         result[prefixes[i] + Capitalize(parameter_name)] = parameter_name
     98         if "enum" in parameter:
     99           enum_name = Capitalize(parameter_name)
    100           result[enum_name] = {}
    101           for enum in parameter["enum"]:
    102             result[enum_name]["kEnum" + Capitalize(enum)] = enum
    103         reference = ""
    104         if "$ref" in parameter:
    105           reference = parameter["$ref"]
    106         if "items" in parameter and "$ref" in parameter["items"]:
    107           reference = parameter["items"]["$ref"]
    108         if reference:
    109           if not "." in reference:
    110             reference = domain_name + "." + reference
    111           references.append(reference)
    112   return result
    113 
    114 def IsHandledInBrowser(item):
    115   return "handlers" in item and "browser" in item["handlers"]
    116 
    117 def FormatContents(tree, indent, format_string):
    118   outer = dict((key, value) for key, value in tree.iteritems()
    119                 if not isinstance(value, dict))
    120   inner = dict((key, value) for key, value in tree.iteritems()
    121               if isinstance(value, dict))
    122   body = ""
    123   body += "".join(indent + format_string.format(key, value)
    124                  for (key, value) in sorted(outer.items()))
    125   body += "".join(FormatNamespace(key, value, indent, format_string)
    126                  for (key, value) in sorted(inner.items()))
    127   return body
    128 
    129 def FormatNamespace(title, tree, indent, format_string):
    130   if (not tree):
    131     return ""
    132   body = '\n' + indent + "namespace " + title + " {\n"
    133   body += FormatContents(tree, indent + "  ", format_string)
    134   body += indent + "} // " + title + "\n"
    135   return body
    136 
    137 def CreateHeader(tree, output_file):
    138   contents = FormatContents(tree, "", "extern const char {0}[];\n")
    139   output_file.write(template_h.substitute({
    140       "contents": contents,
    141       "package": package,
    142       "PACKAGE": package.upper()
    143   }))
    144 
    145 def CreateBody(tree, version, output_file):
    146   contents = FormatContents(tree, "", "const char {0}[] = \"{1}\";\n")
    147   output_file.write(template_cc.substitute({
    148       "major": version["major"],
    149       "minor": version["minor"],
    150       "contents": contents,
    151       "package": package
    152   }))
    153 
    154 blink_protocol_data = open(blink_protocol_path).read()
    155 blink_protocol = json.loads(blink_protocol_data)
    156 blink_version = blink_protocol["version"]
    157 
    158 domains = blink_protocol["domains"]
    159 
    160 if browser_protocol_path:
    161   browser_protocol_data = open(browser_protocol_path).read()
    162   browser_protocol = json.loads(browser_protocol_data)
    163   domains = domains + browser_protocol["domains"]
    164 
    165 namespace_tree = {}
    166 
    167 for domain in domains:
    168   domain_value = {}
    169   domain_namespace_name = Capitalize(domain["domain"])
    170   if "commands" in domain:
    171     for command in domain["commands"]:
    172       if (IsHandledInBrowser(command)):
    173         domain_value[command["name"]] = CreateNamespace(domain["domain"],
    174             command, ["parameters", "returns"], ["kParam", "kResponse"],
    175             domain_namespace_name + "." + command["name"])
    176 
    177   if "events" in domain:
    178     for event in domain["events"]:
    179       if IsHandledInBrowser(event):
    180         domain_value[event["name"]] = CreateNamespace(domain["domain"],
    181             event, ["parameters"], ["kParam"],
    182             domain_namespace_name + "." + event["name"])
    183   if domain_value:
    184     namespace_tree[domain_namespace_name] = domain_value
    185 
    186 while (references):
    187   reference = references.pop();
    188   path = reference.split(".");
    189   parent_namespace = namespace_tree;
    190   for path_segment in path[0:-1]:
    191     if path_segment not in parent_namespace:
    192       parent_namespace[path_segment] = {}
    193     parent_namespace = parent_namespace[path_segment]
    194   if (path[-1] not in parent_namespace):
    195     try:
    196       domain = [d for d in domains if d["domain"] == path[0]][0]
    197       ref_type = [t for t in domain["types"] if t["id"] == path[1]][0]
    198       parent_namespace[ref_type["id"]] = CreateNamespace(path[0],
    199           ref_type, ["properties"], ["kParam"])
    200     except IndexError:
    201       sys.stderr.write("Failed to resolve type [{0}].\n".format(reference))
    202       sys.exit(1)
    203 
    204 for (namespace_name, namespace) in namespace_tree.items():
    205   namespace["kName"] = namespace_name
    206 
    207 with open(output_cc_path, "w") as f:
    208   CreateBody(namespace_tree, blink_version, f)
    209 
    210 with open(output_h_path, "w") as f:
    211   CreateHeader(namespace_tree, f)
    212