| 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..bc4a725f3f45edd0afcb9964bb1cbf2694a67581 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)
|
| - else:
|
| + 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,45 @@ 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, "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):
|
| + return '_'.join([x.lower()
|
| + for x in re.findall('[A-Z][a-z_]*', name[0].upper() + name[1:])])
|
|
|
| - INTEGER = _Info(True)
|
| - DOUBLE = _Info(True)
|
| - BOOLEAN = _Info(True)
|
| - STRING = _Info(True)
|
| - ARRAY = _Info(False)
|
| - REF = _Info(False)
|
| - CHOICES = _Info(False)
|
| - OBJECT = _Info(False)
|
| +def _Choice(name, json):
|
| + prop_type = json.get('type')
|
| + if not prop_type:
|
| + prop_type = json['$ref'].lower()
|
| + prop = Property(name, json)
|
| + prop.unix_name = _UnixName('%s_%s' % (name, prop_type))
|
| + return prop
|
|
|