Index: tools/json_schema_compiler/model.py |
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2c356fff20d06f0815e7a2662586bdacbfa77e01 |
--- /dev/null |
+++ b/tools/json_schema_compiler/model.py |
@@ -0,0 +1,134 @@ |
+# Copyright (c) 2012 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 os.path |
+ |
+class Model(object): |
+ """Model of all namespaces that comprise an API. |
+ """ |
+ def __init__(self): |
+ self.namespaces = {} |
+ |
+ def AddNamespace(self, json, source_file): |
+ """Add a namespace's json to the model if it has a "compile" property set |
+ to true. Returns the new namespace or None if a namespace wasn't added. |
+ """ |
+ if not json.get('compile'): |
+ return None |
+ namespace = Namespace(json, source_file) |
+ self.namespaces[namespace.name] = namespace |
+ return namespace |
+ |
+class Namespace(object): |
+ """An API namespace. |
+ """ |
+ def __init__(self, json, source_file): |
+ self.name = json['namespace'] |
+ self.source_file = source_file |
+ self.source_file_dir, self.source_file_filename = os.path.split(source_file) |
+ self.type_dependencies = {} |
+ self.types = {} |
+ self.functions = {} |
+ for type_json in json['types']: |
+ type_ = Type(type_json) |
+ self.types[type_.name] = type_ |
+ for function_json in json['functions']: |
+ if not function_json.get('nocompile'): |
+ function = Function(function_json) |
+ self.functions[function.name] = function |
+ |
+class Type(object): |
+ """A Type defined in the json. |
+ """ |
+ def __init__(self, json): |
+ self.name = json['id'] |
+ self.description = json.get('description') |
+ self.properties = {} |
+ for prop_name, prop_json in json['properties'].items(): |
+ self.properties[prop_name] = Property(prop_name, prop_json) |
+ |
+class Callback(object): |
+ """A callback parameter to a Function. |
+ """ |
+ def __init__(self, json): |
+ params = json['parameters'] |
+ if len(params) == 0: |
+ self.param = None |
+ elif len(params) == 1: |
+ param = params[0] |
+ self.param = Property(param['name'], param) |
+ else: |
+ raise AssertionError("Callbacks can have at most a single parameter") |
+ |
+class Function(object): |
+ """A Function defined in the API. |
+ """ |
+ def __init__(self, json): |
+ self.name = json['name'] |
+ self.params = [] |
+ self.description = json['description'] |
+ self.callback = None |
+ self.type_dependencies = {} |
+ for param in json['parameters']: |
+ if param.get('type') == 'function': |
+ assert (not self.callback), "Function has more than one callback" |
+ self.callback = Callback(param) |
+ else: |
+ self.params.append(Property(param['name'], param)) |
+ assert (self.callback), "Function does not support callback" |
+ |
+# TODO(calamity): handle Enum/choices |
+class Property(object): |
+ """A property of a type OR a parameter to a function. |
+ |
+ Members will change based on PropertyType. Check self.type_ to determine which |
+ members actually exist. |
+ """ |
+ def __init__(self, name, json): |
+ self.name = name |
+ self.optional = json.get('optional', False) |
+ self.description = json.get('description') |
+ # TODO(calamity) maybe check for circular refs? could that be a problem? |
+ if '$ref' in json: |
+ self.ref_type = json['$ref'] |
+ self.type_ = PropertyType.REF |
+ elif 'type' in json: |
+ json_type = json['type'] |
+ if json_type == 'string': |
+ self.type_ = PropertyType.STRING |
+ elif json_type == 'boolean': |
+ self.type_ = PropertyType.BOOLEAN |
+ elif json_type == 'integer': |
+ self.type_ = PropertyType.INTEGER |
+ elif json_type == 'double': |
+ self.type_ = PropertyType.DOUBLE |
+ elif json_type == 'array': |
+ self.item_type = Property(name + "_inner", json['items']) |
+ self.type_ = PropertyType.ARRAY |
+ elif json_type == 'object': |
+ self.properties = {} |
+ self.type_ = PropertyType.OBJECT |
+ for key, val in json['properties'].items(): |
+ self.properties[key] = Property(key, val) |
+ else: |
+ raise NotImplementedError(json_type) |
+ elif 'choices' in json: |
+ self.type_ = PropertyType.CHOICES |
+ self.choices = {} |
+ |
+class PropertyType(object): |
+ """Enum of different types of properties/parameters. |
+ """ |
+ class _Info(object): |
+ def __init__(self, is_fundamental): |
+ self.is_fundamental = is_fundamental |
+ |
+ INTEGER = _Info(True) |
+ DOUBLE = _Info(True) |
+ BOOLEAN = _Info(True) |
+ STRING = _Info(True) |
+ ARRAY = _Info(False) |
+ REF = _Info(False) |
+ CHOICES = _Info(False) |
+ OBJECT = _Info(False) |