Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: tools/json_schema_compiler/model.py

Issue 9309044: Supporting more APIs with json_schema_compiler (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: a few comments, fixes Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import os.path 5 import os.path
6 import re
6 7
7 class Model(object): 8 class Model(object):
8 """Model of all namespaces that comprise an API. 9 """Model of all namespaces that comprise an API.
9 """ 10 """
10 def __init__(self): 11 def __init__(self):
11 self.namespaces = {} 12 self.namespaces = {}
12 13
13 def AddNamespace(self, json, source_file): 14 def AddNamespace(self, json, source_file):
14 """Add a namespace's json to the model if it has a "compile" property set 15 """Add a namespace's json to the model if it has a "compile" property set
15 to true. Returns the new namespace or None if a namespace wasn't added. 16 to true. Returns the new namespace or None if a namespace wasn't added.
16 """ 17 """
17 if not json.get('compile'): 18 if not json.get('compile', False):
18 return None 19 return None
19 namespace = Namespace(json, source_file) 20 namespace = Namespace(json, source_file)
20 self.namespaces[namespace.name] = namespace 21 self.namespaces[namespace.name] = namespace
21 return namespace 22 return namespace
22 23
23 class Namespace(object): 24 class Namespace(object):
24 """An API namespace. 25 """An API namespace.
25 """ 26 """
26 def __init__(self, json, source_file): 27 def __init__(self, json, source_file):
27 self.name = json['namespace'] 28 self.name = json['namespace']
28 self.source_file = source_file 29 self.source_file = source_file
29 self.source_file_dir, self.source_file_filename = os.path.split(source_file) 30 self.source_file_dir, self.source_file_filename = os.path.split(source_file)
30 self.type_dependencies = {} 31 self.type_dependencies = {}
31 self.types = {} 32 self.types = {}
32 self.functions = {} 33 self.functions = {}
33 for type_json in json['types']: 34 for type_json in json['types']:
34 type_ = Type(type_json) 35 type_ = Type(type_json)
35 self.types[type_.name] = type_ 36 self.types[type_.name] = type_
36 for function_json in json['functions']: 37 for function_json in json['functions']:
37 if not function_json.get('nocompile'): 38 if function_json.get('compile', True):
38 function = Function(function_json) 39 function = Function(function_json)
39 self.functions[function.name] = function 40 self.functions[function.name] = function
40 41
41 class Type(object): 42 class Type(object):
42 """A Type defined in the json. 43 """A Type defined in the json.
43 """ 44 """
44 def __init__(self, json): 45 def __init__(self, json):
45 self.name = json['id'] 46 self.name = json['id']
46 self.description = json.get('description') 47 self.description = json.get('description')
47 self.properties = {} 48 self.properties = {}
48 for prop_name, prop_json in json['properties'].items(): 49 for prop_name, prop_json in json['properties'].items():
49 self.properties[prop_name] = Property(prop_name, prop_json) 50 self.properties[prop_name] = Property(prop_name, prop_json)
50 51
51 class Callback(object): 52 class Callback(object):
52 """A callback parameter to a Function. 53 """A callback parameter to a Function.
53 """ 54 """
54 def __init__(self, json): 55 def __init__(self, json):
55 params = json['parameters'] 56 params = json['parameters']
57 self.params = []
56 if len(params) == 0: 58 if len(params) == 0:
57 self.param = None 59 return
58 elif len(params) == 1: 60 elif len(params) == 1:
59 param = params[0] 61 param = params[0]
60 self.param = Property(param['name'], param) 62 if param.get('choices'):
63 for choice in param['choices']:
64 self.params.append(_Choice('callback', choice))
65 else:
66 self.params.append(Property(param['name'], param))
61 else: 67 else:
62 raise AssertionError("Callbacks can have at most a single parameter") 68 raise AssertionError("Callbacks can have at most a single parameter")
63 69
64 class Function(object): 70 class Function(object):
65 """A Function defined in the API. 71 """A Function defined in the API.
66 """ 72 """
67 def __init__(self, json): 73 def __init__(self, json):
68 self.name = json['name'] 74 self.name = json['name']
69 self.params = [] 75 self.params = []
70 self.description = json['description'] 76 self.description = json['description']
71 self.callback = None 77 self.callback = None
72 self.type_dependencies = {} 78 self.type_dependencies = {}
73 for param in json['parameters']: 79 for param in json['parameters']:
74 if param.get('type') == 'function': 80 if param.get('type') == 'function':
75 assert (not self.callback), "Function has more than one callback" 81 assert (not self.callback), self.name + " has more than one callback"
76 self.callback = Callback(param) 82 self.callback = Callback(param)
83 elif param.get('choices'):
84 for choice in param['choices']:
85 self.params.append(_Choice(self.name, choice))
77 else: 86 else:
78 self.params.append(Property(param['name'], param)) 87 self.params.append(Property(param['name'], param))
79 assert (self.callback), "Function does not support callback" 88 assert (self.callback), self.name + " does not support callback"
80 89
81 # TODO(calamity): handle Enum/choices 90 # TODO(calamity): handle Enum/choices
82 class Property(object): 91 class Property(object):
83 """A property of a type OR a parameter to a function. 92 """A property of a type OR a parameter to a function.
84 93
85 Members will change based on PropertyType. Check self.type_ to determine which 94 Members will change based on PropertyType. Check self.type_ to determine which
86 members actually exist. 95 members actually exist.
87 """ 96 """
88 def __init__(self, name, json): 97 def __init__(self, name, json, is_choice=False):
89 self.name = name 98 self.name = name
99 self.unix_name = _UnixName(self.name)
90 self.optional = json.get('optional', False) 100 self.optional = json.get('optional', False)
91 self.description = json.get('description') 101 self.description = json.get('description')
92 # TODO(calamity) maybe check for circular refs? could that be a problem?
93 if '$ref' in json: 102 if '$ref' in json:
94 self.ref_type = json['$ref'] 103 self.ref_type = json['$ref']
95 self.type_ = PropertyType.REF 104 self.type_ = PropertyType.REF
96 elif 'type' in json: 105 elif 'type' in json:
97 json_type = json['type'] 106 json_type = json['type']
98 if json_type == 'string': 107 if json_type == 'string':
99 self.type_ = PropertyType.STRING 108 self.type_ = PropertyType.STRING
109 elif json_type == 'any':
110 self.type_ = PropertyType.ANY
100 elif json_type == 'boolean': 111 elif json_type == 'boolean':
101 self.type_ = PropertyType.BOOLEAN 112 self.type_ = PropertyType.BOOLEAN
102 elif json_type == 'integer': 113 elif json_type == 'integer':
103 self.type_ = PropertyType.INTEGER 114 self.type_ = PropertyType.INTEGER
104 elif json_type == 'double': 115 elif json_type == 'double' or json_type == 'number':
105 self.type_ = PropertyType.DOUBLE 116 self.type_ = PropertyType.DOUBLE
106 elif json_type == 'array': 117 elif json_type == 'array':
107 self.item_type = Property(name + "_inner", json['items']) 118 self.item_type = Property(name + "_inner", json['items'])
108 self.type_ = PropertyType.ARRAY 119 self.type_ = PropertyType.ARRAY
109 elif json_type == 'object': 120 elif json_type == 'object':
110 self.properties = {} 121 self.properties = {}
111 self.type_ = PropertyType.OBJECT 122 self.type_ = PropertyType.OBJECT
112 for key, val in json['properties'].items(): 123 for key, val in json['properties'].items():
113 self.properties[key] = Property(key, val) 124 if 'choices' in val:
125 for choice in val['choices']:
126 self.properties[key] = _Choice(self.name, choice)
127 else:
128 self.properties[key] = Property(key, val)
114 else: 129 else:
115 raise NotImplementedError(json_type) 130 raise NotImplementedError(json_type)
116 elif 'choices' in json: 131 else:
117 self.type_ = PropertyType.CHOICES 132 raise NotImplementedError(json)
118 self.choices = {}
119 133
120 class PropertyType(object): 134 class PropertyType(object):
121 """Enum of different types of properties/parameters. 135 """Enum of different types of properties/parameters.
122 """ 136 """
123 class _Info(object): 137 class _Info(object):
124 def __init__(self, is_fundamental): 138 def __init__(self, is_fundamental, name):
125 self.is_fundamental = is_fundamental 139 self.is_fundamental = is_fundamental
140 self.name = name
126 141
127 INTEGER = _Info(True) 142 def __repr__(self):
128 DOUBLE = _Info(True) 143 return self.name
129 BOOLEAN = _Info(True) 144
130 STRING = _Info(True) 145 INTEGER = _Info(True, "INTEGER")
131 ARRAY = _Info(False) 146 DOUBLE = _Info(True, "DOUBLE")
132 REF = _Info(False) 147 BOOLEAN = _Info(True, "BOOLEAN")
133 CHOICES = _Info(False) 148 STRING = _Info(True, "STRING")
134 OBJECT = _Info(False) 149 ARRAY = _Info(False, "ARRAY")
150 REF = _Info(False, "REF")
151 CHOICE = _Info(False, "CHOICE")
152 OBJECT = _Info(False, "OBJECT")
153 ANY = _Info(False, "ANY")
154
155 def _UnixName(name):
156 """Returns the unix_style name for a given string.
157 """
158 return '_'.join([x.lower()
159 for x in re.findall('[A-Z][a-z_]*', name[0].upper() + name[1:])])
160
161 def _Choice(name, json):
162 """Creates a 'choice' type Property.
163 """
164 prop_type = json.get('type')
165 if not prop_type:
166 prop_type = json['$ref'].lower()
167 prop = Property(name, json, is_choice=True)
168 prop.unix_name = _UnixName('%s_%s' % (name, prop_type))
169 return prop
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698