Index: tools/json_schema_compiler/model.py |
diff --git a/tools/json_schema_compiler/model.py b/tools/json_schema_compiler/model.py |
index 2c356fff20d06f0815e7a2662586bdacbfa77e01..99ad6286c335d977cc001a97152bf4f066ccb678 100644 |
--- a/tools/json_schema_compiler/model.py |
+++ b/tools/json_schema_compiler/model.py |
@@ -3,6 +3,7 @@ |
# found in the LICENSE file. |
import os.path |
+import re |
class Model(object): |
"""Model of all namespaces that comprise an API. |
@@ -14,7 +15,7 @@ class Model(object): |
"""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'): |
+ if not json.get('compile', False): |
return None |
namespace = Namespace(json, source_file) |
self.namespaces[namespace.name] = namespace |
@@ -34,7 +35,7 @@ class Namespace(object): |
type_ = Type(type_json) |
self.types[type_.name] = type_ |
for function_json in json['functions']: |
- if not function_json.get('nocompile'): |
+ if function_json.get('compile', True): |
function = Function(function_json) |
self.functions[function.name] = function |
@@ -53,11 +54,16 @@ class Callback(object): |
""" |
def __init__(self, json): |
params = json['parameters'] |
+ self.params = [] |
if len(params) == 0: |
- self.param = None |
+ return |
elif len(params) == 1: |
param = params[0] |
- self.param = Property(param['name'], param) |
+ if param.get('choices'): |
+ for choice in param['choices']: |
+ self.params.append(_Choice('callback', choice)) |
+ else: |
+ self.params.append(Property(param['name'], param)) |
else: |
raise AssertionError("Callbacks can have at most a single parameter") |
@@ -72,11 +78,14 @@ class Function(object): |
self.type_dependencies = {} |
for param in json['parameters']: |
if param.get('type') == 'function': |
- assert (not self.callback), "Function has more than one callback" |
+ assert (not self.callback), self.name + " has more than one callback" |
self.callback = Callback(param) |
+ elif param.get('choices'): |
+ for choice in param['choices']: |
+ self.params.append(_Choice(self.name, choice)) |
else: |
self.params.append(Property(param['name'], param)) |
- assert (self.callback), "Function does not support callback" |
+ assert (self.callback), self.name + " does not support callback" |
# TODO(calamity): handle Enum/choices |
class Property(object): |
@@ -85,11 +94,11 @@ class Property(object): |
Members will change based on PropertyType. Check self.type_ to determine which |
members actually exist. |
""" |
- def __init__(self, name, json): |
+ def __init__(self, name, json, is_choice=False): |
self.name = name |
+ self.unix_name = _UnixName(self.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 |
@@ -97,11 +106,13 @@ class Property(object): |
json_type = json['type'] |
if json_type == 'string': |
self.type_ = PropertyType.STRING |
+ elif json_type == 'any': |
+ self.type_ = PropertyType.ANY |
elif json_type == 'boolean': |
self.type_ = PropertyType.BOOLEAN |
elif json_type == 'integer': |
self.type_ = PropertyType.INTEGER |
- elif json_type == 'double': |
+ elif json_type == 'double' or json_type == 'number': |
self.type_ = PropertyType.DOUBLE |
elif json_type == 'array': |
self.item_type = Property(name + "_inner", json['items']) |
@@ -110,25 +121,49 @@ class Property(object): |
self.properties = {} |
self.type_ = PropertyType.OBJECT |
for key, val in json['properties'].items(): |
- self.properties[key] = Property(key, val) |
+ if 'choices' in val: |
+ for choice in val['choices']: |
+ self.properties[key] = _Choice(self.name, choice) |
+ else: |
+ self.properties[key] = Property(key, val) |
else: |
raise NotImplementedError(json_type) |
- elif 'choices' in json: |
- self.type_ = PropertyType.CHOICES |
- self.choices = {} |
+ else: |
+ raise NotImplementedError(json) |
class PropertyType(object): |
"""Enum of different types of properties/parameters. |
""" |
class _Info(object): |
- def __init__(self, is_fundamental): |
+ def __init__(self, is_fundamental, name): |
self.is_fundamental = is_fundamental |
+ self.name = name |
+ |
+ def __repr__(self): |
+ return self.name |
- INTEGER = _Info(True) |
- DOUBLE = _Info(True) |
- BOOLEAN = _Info(True) |
- STRING = _Info(True) |
- ARRAY = _Info(False) |
- REF = _Info(False) |
- CHOICES = _Info(False) |
- OBJECT = _Info(False) |
+ INTEGER = _Info(True, "INTEGER") |
+ DOUBLE = _Info(True, "DOUBLE") |
+ BOOLEAN = _Info(True, "BOOLEAN") |
+ STRING = _Info(True, "STRING") |
+ ARRAY = _Info(False, "ARRAY") |
+ REF = _Info(False, "REF") |
+ CHOICE = _Info(False, "CHOICE") |
+ OBJECT = _Info(False, "OBJECT") |
+ ANY = _Info(False, "ANY") |
+ |
+def _UnixName(name): |
+ """Returns the unix_style name for a given string. |
+ """ |
+ return '_'.join([x.lower() |
+ for x in re.findall('[A-Z][a-z_]*', name[0].upper() + name[1:])]) |
+ |
+def _Choice(name, json): |
+ """Creates a 'choice' type Property. |
+ """ |
+ prop_type = json.get('type') |
+ if not prop_type: |
+ prop_type = json['$ref'].lower() |
+ prop = Property(name, json, is_choice=True) |
+ prop.unix_name = _UnixName('%s_%s' % (name, prop_type)) |
+ return prop |