| OLD | NEW |
| (Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 Google Inc. All rights reserved. |
| 3 # |
| 4 # Redistribution and use in source and binary forms, with or without |
| 5 # modification, are permitted provided that the following conditions are |
| 6 # met: |
| 7 # |
| 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above |
| 11 # copyright notice, this list of conditions and the following disclaimer |
| 12 # in the documentation and/or other materials provided with the |
| 13 # distribution. |
| 14 # * Neither the name of Google Inc. nor the names of its |
| 15 # contributors may be used to endorse or promote products derived from |
| 16 # this software without specific prior written permission. |
| 17 # |
| 18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 |
| 30 type_traits = { |
| 31 "any": "*", |
| 32 "string": "string", |
| 33 "integer": "number", |
| 34 "number": "number", |
| 35 "boolean": "boolean", |
| 36 "array": "Array.<*>", |
| 37 "object": "Object", |
| 38 } |
| 39 |
| 40 ref_types = {} |
| 41 |
| 42 |
| 43 def full_qualified_type_id(domain_name, type_id): |
| 44 if type_id.find(".") == -1: |
| 45 return "%s.%s" % (domain_name, type_id) |
| 46 return type_id |
| 47 |
| 48 |
| 49 def param_type(domain_name, param): |
| 50 if "type" in param: |
| 51 if param["type"] == "array": |
| 52 items = param["items"] |
| 53 return "Array.<%s>" % param_type(domain_name, items) |
| 54 else: |
| 55 return type_traits[param["type"]] |
| 56 if "$ref" in param: |
| 57 type_id = full_qualified_type_id(domain_name, param["$ref"]) |
| 58 if type_id in ref_types: |
| 59 return ref_types[type_id] |
| 60 else: |
| 61 print "Type not found: " + type_id |
| 62 return "!! Type not found: " + type_id |
| 63 |
| 64 |
| 65 def generate_protocol_externs(output_path, input_path): |
| 66 input_file = open(input_path, "r") |
| 67 json_string = input_file.read() |
| 68 json_string = json_string.replace(": true", ": True") |
| 69 json_string = json_string.replace(": false", ": False") |
| 70 json_api = eval(json_string)["domains"] |
| 71 |
| 72 output_file = open(output_path, "w") |
| 73 |
| 74 output_file.write( |
| 75 """ |
| 76 var Protocol = {}; |
| 77 /** @typedef {string}*/ |
| 78 Protocol.Error; |
| 79 """) |
| 80 |
| 81 for domain in json_api: |
| 82 domain_name = domain["domain"] |
| 83 if "types" in domain: |
| 84 for type in domain["types"]: |
| 85 type_id = full_qualified_type_id(domain_name, type["id"]) |
| 86 ref_types[type_id] = "%sAgent.%s" % (domain_name, type["id"]) |
| 87 |
| 88 for domain in json_api: |
| 89 domain_name = domain["domain"] |
| 90 output_file.write("\n\n\nvar %sAgent = {};\n" % domain_name) |
| 91 if "types" in domain: |
| 92 for type in domain["types"]: |
| 93 if type["type"] == "object": |
| 94 typedef_args = [] |
| 95 if "properties" in type: |
| 96 for property in type["properties"]: |
| 97 suffix = "" |
| 98 if ("optional" in property): |
| 99 suffix = "|undefined" |
| 100 typedef_args.append("%s:(%s%s)" % (property["name"],
param_type(domain_name, property), suffix)) |
| 101 if (typedef_args): |
| 102 output_file.write("\n/** @typedef {{%s}|null} */\n%sAgen
t.%s;\n" % (", ".join(typedef_args), domain_name, type["id"])) |
| 103 else: |
| 104 output_file.write("\n/** @typedef {Object} */\n%sAgent.%
s;\n" % (domain_name, type["id"])) |
| 105 elif type["type"] == "array": |
| 106 suffix = "" |
| 107 if ("optional" in property): |
| 108 suffix = "|undefined" |
| 109 output_file.write("\n/** @typedef {Array.<%s>%s} */\n%sAgent
.%s;\n" % (param_type(domain_name, type["items"]), suffix, domain_name, type["id
"])) |
| 110 else: |
| 111 output_file.write("\n/** @typedef {%s} */\n%sAgent.%s;\n" %
(type_traits[type["type"]], domain_name, type["id"])) |
| 112 |
| 113 if "commands" in domain: |
| 114 for command in domain["commands"]: |
| 115 output_file.write("\n/**\n") |
| 116 params = [] |
| 117 if ("parameters" in command): |
| 118 for in_param in command["parameters"]: |
| 119 if ("optional" in in_param): |
| 120 params.append("opt_%s" % in_param["name"]) |
| 121 output_file.write(" * @param {%s=} opt_%s\n" % (para
m_type(domain_name, in_param), in_param["name"])) |
| 122 else: |
| 123 params.append(in_param["name"]) |
| 124 output_file.write(" * @param {%s} %s\n" % (param_typ
e(domain_name, in_param), in_param["name"])) |
| 125 returns = ["?Protocol.Error"] |
| 126 if ("returns" in command): |
| 127 for out_param in command["returns"]: |
| 128 if ("optional" in out_param): |
| 129 returns.append("%s=" % param_type(domain_name, out_p
aram)) |
| 130 else: |
| 131 returns.append("%s" % param_type(domain_name, out_pa
ram)) |
| 132 output_file.write(" * @param {function(%s):void=} opt_callback\n
" % ", ".join(returns)) |
| 133 output_file.write(" */\n") |
| 134 params.append("opt_callback") |
| 135 output_file.write("%sAgent.%s = function(%s) {}\n" % (domain_nam
e, command["name"], ", ".join(params))) |
| 136 output_file.write("/** @param {function(%s):void=} opt_callback
*/\n" % ", ".join(returns)) |
| 137 output_file.write("%sAgent.%s.invoke = function(obj, opt_callbac
k) {}\n" % (domain_name, command["name"])) |
| 138 |
| 139 output_file.write("/** @interface */\n") |
| 140 output_file.write("%sAgent.Dispatcher = function() {};\n" % domain_name) |
| 141 if "events" in domain: |
| 142 for event in domain["events"]: |
| 143 params = [] |
| 144 if ("parameters" in event): |
| 145 output_file.write("/**\n") |
| 146 for param in event["parameters"]: |
| 147 if ("optional" in param): |
| 148 params.append("opt_%s" % param["name"]) |
| 149 output_file.write(" * @param {%s=} opt_%s\n" % (para
m_type(domain_name, param), param["name"])) |
| 150 else: |
| 151 params.append(param["name"]) |
| 152 output_file.write(" * @param {%s} %s\n" % (param_typ
e(domain_name, param), param["name"])) |
| 153 output_file.write(" */\n") |
| 154 output_file.write("%sAgent.Dispatcher.prototype.%s = function(%s
) {};\n" % (domain_name, event["name"], ", ".join(params))) |
| 155 output_file.write("/**\n * @param {%sAgent.Dispatcher} dispatcher\n */\n
" % domain_name) |
| 156 output_file.write("InspectorBackend.register%sDispatcher = function(disp
atcher) {}\n" % domain_name) |
| 157 output_file.close() |
| 158 |
| 159 if __name__ == "__main__": |
| 160 import sys |
| 161 import os.path |
| 162 program_name = os.path.basename(__file__) |
| 163 if len(sys.argv) < 4 or sys.argv[1] != "-o": |
| 164 sys.stderr.write("Usage: %s -o OUTPUT_FILE INPUT_FILE\n" % program_name) |
| 165 exit(1) |
| 166 output_path = sys.argv[2] |
| 167 input_path = sys.argv[3] |
| 168 generate_protocol_externs(output_path, input_path) |
| OLD | NEW |