OLD | NEW |
---|---|
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 copy | 5 import copy |
6 import os.path | 6 import os.path |
7 import re | 7 import re |
8 | 8 |
9 class ParseException(Exception): | 9 class ParseException(Exception): |
10 """Thrown when data in the model is invalid. | 10 """Thrown when data in the model is invalid. |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 class Property(object): | 143 class Property(object): |
144 """A property of a type OR a parameter to a function. | 144 """A property of a type OR a parameter to a function. |
145 | 145 |
146 Properties: | 146 Properties: |
147 - |name| name of the property as in the json. This shouldn't change since | 147 - |name| name of the property as in the json. This shouldn't change since |
148 it is the key used to access DictionaryValues | 148 it is the key used to access DictionaryValues |
149 - |unix_name| the unix_style_name of the property. Used as variable name | 149 - |unix_name| the unix_style_name of the property. Used as variable name |
150 - |optional| a boolean representing whether the property is optional | 150 - |optional| a boolean representing whether the property is optional |
151 - |description| a description of the property (if provided) | 151 - |description| a description of the property (if provided) |
152 - |type_| the model.PropertyType of this property | 152 - |type_| the model.PropertyType of this property |
153 - |compiled_type| the model.PropertyType that this property should be | |
154 compiled to from the JSON. Defaults to type_. | |
153 - |ref_type| the type that the REF property is referencing. Can be used to | 155 - |ref_type| the type that the REF property is referencing. Can be used to |
154 map to its model.Type | 156 map to its model.Type |
155 - |item_type| a model.Property representing the type of each element in an | 157 - |item_type| a model.Property representing the type of each element in an |
156 ARRAY | 158 ARRAY |
157 - |properties| the properties of an OBJECT parameter | 159 - |properties| the properties of an OBJECT parameter |
158 - |from_client| indicates that instances of the Type can originate from the | 160 - |from_client| indicates that instances of the Type can originate from the |
159 users of generated code, such as top-level types and function results | 161 users of generated code, such as top-level types and function results |
160 - |from_json| indicates that instances of the Type can originate from the | 162 - |from_json| indicates that instances of the Type can originate from the |
161 JSON (as described by the schema), such as top-level types and function | 163 JSON (as described by the schema), such as top-level types and function |
162 parameters | 164 parameters |
163 """ | 165 """ |
164 | 166 |
165 def __init__(self, parent, name, json, is_additional_properties=False, | 167 def __init__(self, parent, name, json, is_additional_properties=False, |
166 from_json=False, from_client=False): | 168 from_json=False, from_client=False): |
167 self.name = name | 169 self.name = name |
168 self._unix_name = UnixName(self.name) | 170 self._unix_name = UnixName(self.name) |
169 self._unix_name_used = False | 171 self._unix_name_used = False |
170 self.optional = json.get('optional', False) | 172 self.optional = json.get('optional', False) |
171 self.functions = {} | 173 self.functions = {} |
172 self.has_value = False | 174 self.has_value = False |
173 self.description = json.get('description') | 175 self.description = json.get('description') |
174 self.parent = parent | 176 self.parent = parent |
175 self.from_json = from_json | 177 self.from_json = from_json |
176 self.from_client = from_client | 178 self.from_client = from_client |
177 self.instance_of = json.get('isInstanceOf', None) | 179 self.instance_of = json.get('isInstanceOf', None) |
178 _AddProperties(self, json) | 180 _AddProperties(self, json) |
179 if is_additional_properties: | 181 if is_additional_properties: |
180 self.type_ = PropertyType.ADDITIONAL_PROPERTIES | 182 self.type_ = PropertyType.ADDITIONAL_PROPERTIES |
183 self.compiled_type = self.type_ | |
not at google - send to devlin
2012/07/31 06:37:41
a lot of repetitive assigning to compiled_type. Co
mitchellwrosen
2012/07/31 17:50:25
Okay. I was originally thinking that a compiled_ty
| |
181 elif '$ref' in json: | 184 elif '$ref' in json: |
182 self.ref_type = json['$ref'] | 185 self.ref_type = json['$ref'] |
183 self.type_ = PropertyType.REF | 186 self.type_ = PropertyType.REF |
187 self.compiled_type = self.type_ | |
184 elif 'enum' in json and json.get('type') == 'string': | 188 elif 'enum' in json and json.get('type') == 'string': |
185 # Non-string enums (as in the case of [legalValues=(1,2)]) should fall | 189 # Non-string enums (as in the case of [legalValues=(1,2)]) should fall |
186 # through to the next elif. | 190 # through to the next elif. |
187 self.enum_values = [] | 191 self.enum_values = [] |
188 for value in json['enum']: | 192 for value in json['enum']: |
189 self.enum_values.append(value) | 193 self.enum_values.append(value) |
190 self.type_ = PropertyType.ENUM | 194 self.type_ = PropertyType.ENUM |
195 self.compiled_type = self.type_ | |
191 elif 'type' in json: | 196 elif 'type' in json: |
192 json_type = json['type'] | 197 self.type_ = self._JsonTypeToPropertyType(json['type']) |
193 if json_type == 'string': | 198 if self.type_ == PropertyType.ARRAY: |
194 self.type_ = PropertyType.STRING | |
195 elif json_type == 'any': | |
196 self.type_ = PropertyType.ANY | |
197 elif json_type == 'boolean': | |
198 self.type_ = PropertyType.BOOLEAN | |
199 elif json_type == 'integer': | |
200 self.type_ = PropertyType.INTEGER | |
201 elif json_type == 'number': | |
202 self.type_ = PropertyType.DOUBLE | |
203 elif json_type == 'array': | |
204 self.item_type = Property(self, name + "Element", json['items'], | 199 self.item_type = Property(self, name + "Element", json['items'], |
205 from_json=from_json, | 200 from_json=from_json, |
206 from_client=from_client) | 201 from_client=from_client) |
207 self.type_ = PropertyType.ARRAY | 202 elif self.type_ == PropertyType.OBJECT: |
208 elif json_type == 'object': | |
209 self.type_ = PropertyType.OBJECT | |
210 # These members are read when this OBJECT Property is used as a Type | 203 # These members are read when this OBJECT Property is used as a Type |
211 type_ = Type(self, self.name, json) | 204 type_ = Type(self, self.name, json) |
212 # self.properties will already have some value from |_AddProperties|. | 205 # self.properties will already have some value from |_AddProperties|. |
213 self.properties.update(type_.properties) | 206 self.properties.update(type_.properties) |
214 self.functions = type_.functions | 207 self.functions = type_.functions |
215 elif json_type == 'function': | 208 if 'compiled_type' in json: |
216 self.type_ = PropertyType.FUNCTION | 209 self.compiled_type = self._JsonTypeToPropertyType(json['compiled_type']) |
217 elif json_type == 'binary': | |
218 self.type_ = PropertyType.BINARY | |
219 else: | 210 else: |
220 raise ParseException(self, 'type ' + json_type + ' not recognized') | 211 self.compiled_type = self.type_ |
221 elif 'choices' in json: | 212 elif 'choices' in json: |
222 if not json['choices'] or len(json['choices']) == 0: | 213 if not json['choices'] or len(json['choices']) == 0: |
223 raise ParseException(self, 'Choices has no choices') | 214 raise ParseException(self, 'Choices has no choices') |
224 self.choices = {} | 215 self.choices = {} |
225 self.type_ = PropertyType.CHOICES | 216 self.type_ = PropertyType.CHOICES |
217 self.compiled_type = self.type_ | |
226 for choice_json in json['choices']: | 218 for choice_json in json['choices']: |
227 choice = Property(self, self.name, choice_json, | 219 choice = Property(self, self.name, choice_json, |
228 from_json=from_json, | 220 from_json=from_json, |
229 from_client=from_client) | 221 from_client=from_client) |
230 choice.unix_name = UnixName(self.name + choice.type_.name) | 222 choice.unix_name = UnixName(self.name + choice.type_.name) |
231 # The existence of any single choice is optional | 223 # The existence of any single choice is optional |
232 choice.optional = True | 224 choice.optional = True |
233 self.choices[choice.type_] = choice | 225 self.choices[choice.type_] = choice |
234 elif 'value' in json: | 226 elif 'value' in json: |
235 self.has_value = True | 227 self.has_value = True |
236 self.value = json['value'] | 228 self.value = json['value'] |
237 if type(self.value) == int: | 229 if type(self.value) == int: |
238 self.type_ = PropertyType.INTEGER | 230 self.type_ = PropertyType.INTEGER |
231 self.compiled_type = self.type_ | |
239 else: | 232 else: |
240 # TODO(kalman): support more types as necessary. | 233 # TODO(kalman): support more types as necessary. |
241 raise ParseException( | 234 raise ParseException( |
242 self, '"%s" is not a supported type' % type(self.value)) | 235 self, '"%s" is not a supported type' % type(self.value)) |
243 else: | 236 else: |
244 raise ParseException( | 237 raise ParseException( |
245 self, 'Property has no type, $ref, choices, or value') | 238 self, 'Property has no type, $ref, choices, or value') |
246 | 239 |
240 def _JsonTypeToPropertyType(self, json_type): | |
241 if json_type == 'any': | |
242 return PropertyType.ANY | |
243 if json_type == 'array': | |
244 return PropertyType.ARRAY | |
245 if json_type == 'binary': | |
246 return PropertyType.BINARY | |
247 if json_type == 'boolean': | |
248 return PropertyType.BOOLEAN | |
249 if json_type == 'integer': | |
250 return PropertyType.INTEGER | |
251 if json_type == 'int64': | |
252 return PropertyType.INT_64 | |
253 if json_type == 'function': | |
254 return PropertyType.FUNCTION | |
255 if json_type == 'number': | |
256 return PropertyType.DOUBLE | |
257 if json_type == 'object': | |
258 return PropertyType.OBJECT | |
259 if json_type == 'string': | |
260 return PropertyType.STRING | |
261 raise NotImplementedError('Type %s not recognized' % json_type) | |
not at google - send to devlin
2012/07/31 06:37:41
you could do the old
try:
return {
'any': P
mitchellwrosen
2012/07/31 17:50:25
Yes. My never-written-python-before-in-my-life is
| |
262 | |
247 def GetUnixName(self): | 263 def GetUnixName(self): |
248 """Gets the property's unix_name. Raises AttributeError if not set. | 264 """Gets the property's unix_name. Raises AttributeError if not set. |
249 """ | 265 """ |
250 if not self._unix_name: | 266 if not self._unix_name: |
251 raise AttributeError('No unix_name set on %s' % self.name) | 267 raise AttributeError('No unix_name set on %s' % self.name) |
252 self._unix_name_used = True | 268 self._unix_name_used = True |
253 return self._unix_name | 269 return self._unix_name |
254 | 270 |
255 def SetUnixName(self, unix_name): | 271 def SetUnixName(self, unix_name): |
256 """Set the property's unix_name. Raises AttributeError if the unix_name has | 272 """Set the property's unix_name. Raises AttributeError if the unix_name has |
(...skipping 23 matching lines...) Expand all Loading... | |
280 """ | 296 """ |
281 class _Info(object): | 297 class _Info(object): |
282 def __init__(self, is_fundamental, name): | 298 def __init__(self, is_fundamental, name): |
283 self.is_fundamental = is_fundamental | 299 self.is_fundamental = is_fundamental |
284 self.name = name | 300 self.name = name |
285 | 301 |
286 def __repr__(self): | 302 def __repr__(self): |
287 return self.name | 303 return self.name |
288 | 304 |
289 INTEGER = _Info(True, "INTEGER") | 305 INTEGER = _Info(True, "INTEGER") |
306 INT_64 = _Info(True, "INT_64") | |
not at google - send to devlin
2012/07/31 06:37:41
the c++ type is int64 not int_64 so this should be
mitchellwrosen
2012/07/31 17:50:25
Sure, I actually changed it from INT64 to INT_64 b
| |
290 DOUBLE = _Info(True, "DOUBLE") | 307 DOUBLE = _Info(True, "DOUBLE") |
291 BOOLEAN = _Info(True, "BOOLEAN") | 308 BOOLEAN = _Info(True, "BOOLEAN") |
292 STRING = _Info(True, "STRING") | 309 STRING = _Info(True, "STRING") |
293 ENUM = _Info(False, "ENUM") | 310 ENUM = _Info(False, "ENUM") |
294 ARRAY = _Info(False, "ARRAY") | 311 ARRAY = _Info(False, "ARRAY") |
295 REF = _Info(False, "REF") | 312 REF = _Info(False, "REF") |
296 CHOICES = _Info(False, "CHOICES") | 313 CHOICES = _Info(False, "CHOICES") |
297 OBJECT = _Info(False, "OBJECT") | 314 OBJECT = _Info(False, "OBJECT") |
298 FUNCTION = _Info(False, "FUNCTION") | 315 FUNCTION = _Info(False, "FUNCTION") |
299 BINARY = _Info(False, "BINARY") | 316 BINARY = _Info(False, "BINARY") |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 of |json|. | 369 of |json|. |
353 """ | 370 """ |
354 model.properties = {} | 371 model.properties = {} |
355 for name, property_json in json.get('properties', {}).items(): | 372 for name, property_json in json.get('properties', {}).items(): |
356 model.properties[name] = Property( | 373 model.properties[name] = Property( |
357 model, | 374 model, |
358 name, | 375 name, |
359 property_json, | 376 property_json, |
360 from_json=from_json, | 377 from_json=from_json, |
361 from_client=from_client) | 378 from_client=from_client) |
OLD | NEW |