| 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 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 182 self.ref_type = json['$ref'] | 184 self.ref_type = json['$ref'] |
| 183 self.type_ = PropertyType.REF | 185 self.type_ = PropertyType.REF |
| 184 elif 'enum' in json and json.get('type') == 'string': | 186 elif 'enum' in json and json.get('type') == 'string': |
| 185 # Non-string enums (as in the case of [legalValues=(1,2)]) should fall | 187 # Non-string enums (as in the case of [legalValues=(1,2)]) should fall |
| 186 # through to the next elif. | 188 # through to the next elif. |
| 187 self.enum_values = [] | 189 self.enum_values = [] |
| 188 for value in json['enum']: | 190 for value in json['enum']: |
| 189 self.enum_values.append(value) | 191 self.enum_values.append(value) |
| 190 self.type_ = PropertyType.ENUM | 192 self.type_ = PropertyType.ENUM |
| 191 elif 'type' in json: | 193 elif 'type' in json: |
| 192 json_type = json['type'] | 194 self.type_ = self._JsonTypeToPropertyType(json['type']) |
| 193 if json_type == 'string': | 195 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'], | 196 self.item_type = Property(self, name + "Element", json['items'], |
| 205 from_json=from_json, | 197 from_json=from_json, |
| 206 from_client=from_client) | 198 from_client=from_client) |
| 207 self.type_ = PropertyType.ARRAY | 199 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 | 200 # These members are read when this OBJECT Property is used as a Type |
| 211 type_ = Type(self, self.name, json) | 201 type_ = Type(self, self.name, json) |
| 212 # self.properties will already have some value from |_AddProperties|. | 202 # self.properties will already have some value from |_AddProperties|. |
| 213 self.properties.update(type_.properties) | 203 self.properties.update(type_.properties) |
| 214 self.functions = type_.functions | 204 self.functions = type_.functions |
| 215 elif json_type == 'function': | |
| 216 self.type_ = PropertyType.FUNCTION | |
| 217 elif json_type == 'binary': | |
| 218 self.type_ = PropertyType.BINARY | |
| 219 else: | |
| 220 raise ParseException(self, 'type ' + json_type + ' not recognized') | |
| 221 elif 'choices' in json: | 205 elif 'choices' in json: |
| 222 if not json['choices'] or len(json['choices']) == 0: | 206 if not json['choices'] or len(json['choices']) == 0: |
| 223 raise ParseException(self, 'Choices has no choices') | 207 raise ParseException(self, 'Choices has no choices') |
| 224 self.choices = {} | 208 self.choices = {} |
| 225 self.type_ = PropertyType.CHOICES | 209 self.type_ = PropertyType.CHOICES |
| 210 self.compiled_type = self.type_ |
| 226 for choice_json in json['choices']: | 211 for choice_json in json['choices']: |
| 227 choice = Property(self, self.name, choice_json, | 212 choice = Property(self, self.name, choice_json, |
| 228 from_json=from_json, | 213 from_json=from_json, |
| 229 from_client=from_client) | 214 from_client=from_client) |
| 230 choice.unix_name = UnixName(self.name + choice.type_.name) | 215 choice.unix_name = UnixName(self.name + choice.type_.name) |
| 231 # The existence of any single choice is optional | 216 # The existence of any single choice is optional |
| 232 choice.optional = True | 217 choice.optional = True |
| 233 self.choices[choice.type_] = choice | 218 self.choices[choice.type_] = choice |
| 234 elif 'value' in json: | 219 elif 'value' in json: |
| 235 self.has_value = True | 220 self.has_value = True |
| 236 self.value = json['value'] | 221 self.value = json['value'] |
| 237 if type(self.value) == int: | 222 if type(self.value) == int: |
| 238 self.type_ = PropertyType.INTEGER | 223 self.type_ = PropertyType.INTEGER |
| 224 self.compiled_type = self.type_ |
| 239 else: | 225 else: |
| 240 # TODO(kalman): support more types as necessary. | 226 # TODO(kalman): support more types as necessary. |
| 241 raise ParseException( | 227 raise ParseException( |
| 242 self, '"%s" is not a supported type' % type(self.value)) | 228 self, '"%s" is not a supported type' % type(self.value)) |
| 243 else: | 229 else: |
| 244 raise ParseException( | 230 raise ParseException( |
| 245 self, 'Property has no type, $ref, choices, or value') | 231 self, 'Property has no type, $ref, choices, or value') |
| 232 if 'compiled_type' in json: |
| 233 if 'type' in json: |
| 234 self.compiled_type = self._JsonTypeToPropertyType(json['compiled_type']) |
| 235 else: |
| 236 raise ParseException(self, 'Property has compiled_type but no type') |
| 237 else: |
| 238 self.compiled_type = self.type_ |
| 239 |
| 240 def _JsonTypeToPropertyType(self, json_type): |
| 241 try: |
| 242 return { |
| 243 'any': PropertyType.ANY, |
| 244 'array': PropertyType.ARRAY, |
| 245 'binary': PropertyType.BINARY, |
| 246 'boolean': PropertyType.BOOLEAN, |
| 247 'integer': PropertyType.INTEGER, |
| 248 'int64': PropertyType.INT64, |
| 249 'function': PropertyType.FUNCTION, |
| 250 'number': PropertyType.DOUBLE, |
| 251 'object': PropertyType.OBJECT, |
| 252 'string': PropertyType.STRING, |
| 253 }[json_type] |
| 254 except KeyError: |
| 255 raise NotImplementedError('Type %s not recognized' % json_type) |
| 246 | 256 |
| 247 def GetUnixName(self): | 257 def GetUnixName(self): |
| 248 """Gets the property's unix_name. Raises AttributeError if not set. | 258 """Gets the property's unix_name. Raises AttributeError if not set. |
| 249 """ | 259 """ |
| 250 if not self._unix_name: | 260 if not self._unix_name: |
| 251 raise AttributeError('No unix_name set on %s' % self.name) | 261 raise AttributeError('No unix_name set on %s' % self.name) |
| 252 self._unix_name_used = True | 262 self._unix_name_used = True |
| 253 return self._unix_name | 263 return self._unix_name |
| 254 | 264 |
| 255 def SetUnixName(self, unix_name): | 265 def SetUnixName(self, unix_name): |
| (...skipping 24 matching lines...) Expand all Loading... |
| 280 """ | 290 """ |
| 281 class _Info(object): | 291 class _Info(object): |
| 282 def __init__(self, is_fundamental, name): | 292 def __init__(self, is_fundamental, name): |
| 283 self.is_fundamental = is_fundamental | 293 self.is_fundamental = is_fundamental |
| 284 self.name = name | 294 self.name = name |
| 285 | 295 |
| 286 def __repr__(self): | 296 def __repr__(self): |
| 287 return self.name | 297 return self.name |
| 288 | 298 |
| 289 INTEGER = _Info(True, "INTEGER") | 299 INTEGER = _Info(True, "INTEGER") |
| 300 INT64 = _Info(True, "INT64") |
| 290 DOUBLE = _Info(True, "DOUBLE") | 301 DOUBLE = _Info(True, "DOUBLE") |
| 291 BOOLEAN = _Info(True, "BOOLEAN") | 302 BOOLEAN = _Info(True, "BOOLEAN") |
| 292 STRING = _Info(True, "STRING") | 303 STRING = _Info(True, "STRING") |
| 293 ENUM = _Info(False, "ENUM") | 304 ENUM = _Info(False, "ENUM") |
| 294 ARRAY = _Info(False, "ARRAY") | 305 ARRAY = _Info(False, "ARRAY") |
| 295 REF = _Info(False, "REF") | 306 REF = _Info(False, "REF") |
| 296 CHOICES = _Info(False, "CHOICES") | 307 CHOICES = _Info(False, "CHOICES") |
| 297 OBJECT = _Info(False, "OBJECT") | 308 OBJECT = _Info(False, "OBJECT") |
| 298 FUNCTION = _Info(False, "FUNCTION") | 309 FUNCTION = _Info(False, "FUNCTION") |
| 299 BINARY = _Info(False, "BINARY") | 310 BINARY = _Info(False, "BINARY") |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 of |json|. | 363 of |json|. |
| 353 """ | 364 """ |
| 354 model.properties = {} | 365 model.properties = {} |
| 355 for name, property_json in json.get('properties', {}).items(): | 366 for name, property_json in json.get('properties', {}).items(): |
| 356 model.properties[name] = Property( | 367 model.properties[name] = Property( |
| 357 model, | 368 model, |
| 358 name, | 369 name, |
| 359 property_json, | 370 property_json, |
| 360 from_json=from_json, | 371 from_json=from_json, |
| 361 from_client=from_client) | 372 from_client=from_client) |
| OLD | NEW |