Chromium Code Reviews| 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..2359c558f0406296b24a3b59169584b3f99ced19 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'): |
|
not at google - send to devlin
2012/02/05 23:42:12
I think you need to document what the available pr
calamity
2012/02/06 11:51:18
Done.
|
| + 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)) |
|
not at google - send to devlin
2012/02/05 23:42:12
(ditto)
I see now why you are appending a differe
calamity
2012/02/06 11:51:18
Done.
|
| 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): |
|
not at google - send to devlin
2012/02/05 23:42:12
is_choice no longer needed
calamity
2012/02/06 11:51:18
I think I'll need something eventually in order to
not at google - send to devlin
2012/02/06 13:14:48
Yeah, see the other couple of comments I've made r
|
| self.name = name |
|
not at google - send to devlin
2012/02/05 23:42:12
I think for self-documentation sake, this should s
calamity
2012/02/06 11:51:18
Done.
|
| + 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': |
|
not at google - send to devlin
2012/02/05 23:42:12
extra space
calamity
2012/02/06 11:51:18
Done.
|
| + 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': |
|
not at google - send to devlin
2012/02/05 23:42:12
We should remove support for "double" and fix up t
calamity
2012/02/06 11:51:18
Done.
|
| 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) |
|
not at google - send to devlin
2012/02/05 23:42:12
doesn't this overwrite the same (and incorrect) ke
calamity
2012/02/06 11:51:18
Done.
|
| + 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): |
|
not at google - send to devlin
2012/02/05 23:42:12
document
calamity
2012/02/06 11:51:18
Done.
|
| + return '_'.join([x.lower() |
| + for x in re.findall('[A-Z][a-z_]*', name[0].upper() + name[1:])]) |
|
not at google - send to devlin
2012/02/05 23:42:12
i'll just assume that works...
|
| - 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): |
|
not at google - send to devlin
2012/02/05 23:42:12
document
calamity
2012/02/06 11:51:18
Done.
|
| + prop_type = json.get('type') |
| + if not prop_type: |
| + prop_type = json['$ref'].lower() |
|
not at google - send to devlin
2012/02/05 23:42:12
I think should structure this slightly differently
|
| + prop = Property(name, json) |
| + prop.unix_name = _UnixName('%s_%s' % (name, prop_type)) |
| + return prop |