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

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

Issue 10825029: Added JSON schema compiler support for serialized types (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Indent typo fix Created 8 years, 4 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 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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698