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

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

Issue 10701012: JSON Schema Compiler: Added event compilation. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Synced. Created 8 years, 5 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
« no previous file with comments | « tools/json_schema_compiler/h_generator.py ('k') | tools/json_schema_compiler/model_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 24 matching lines...) Expand all
35 """An API namespace. 35 """An API namespace.
36 36
37 Properties: 37 Properties:
38 - |name| the name of the namespace 38 - |name| the name of the namespace
39 - |unix_name| the unix_name of the namespace 39 - |unix_name| the unix_name of the namespace
40 - |source_file| the file that contained the namespace definition 40 - |source_file| the file that contained the namespace definition
41 - |source_file_dir| the directory component of |source_file| 41 - |source_file_dir| the directory component of |source_file|
42 - |source_file_filename| the filename component of |source_file| 42 - |source_file_filename| the filename component of |source_file|
43 - |types| a map of type names to their model.Type 43 - |types| a map of type names to their model.Type
44 - |functions| a map of function names to their model.Function 44 - |functions| a map of function names to their model.Function
45 - |events| a map of event names to their model.Function
45 - |properties| a map of property names to their model.Property 46 - |properties| a map of property names to their model.Property
46 """ 47 """
47 def __init__(self, json, source_file): 48 def __init__(self, json, source_file):
48 self.name = json['namespace'] 49 self.name = json['namespace']
49 self.unix_name = UnixName(self.name) 50 self.unix_name = UnixName(self.name)
50 self.source_file = source_file 51 self.source_file = source_file
51 self.source_file_dir, self.source_file_filename = os.path.split(source_file) 52 self.source_file_dir, self.source_file_filename = os.path.split(source_file)
52 self.parent = None 53 self.parent = None
53 _AddTypes(self, json) 54 _AddTypes(self, json)
54 _AddFunctions(self, json) 55 _AddFunctions(self, json)
56 _AddEvents(self, json)
55 _AddProperties(self, json) 57 _AddProperties(self, json)
56 58
57 class Type(object): 59 class Type(object):
58 """A Type defined in the json. 60 """A Type defined in the json.
59 61
60 Properties: 62 Properties:
61 - |name| the type name 63 - |name| the type name
62 - |description| the description of the type (if provided) 64 - |description| the description of the type (if provided)
63 - |properties| a map of property unix_names to their model.Property 65 - |properties| a map of property unix_names to their model.Property
64 - |functions| a map of function names to their model.Function 66 - |functions| a map of function names to their model.Function
(...skipping 30 matching lines...) Expand all
95 97
96 additional_properties_key = 'additionalProperties' 98 additional_properties_key = 'additionalProperties'
97 additional_properties = json.get(additional_properties_key) 99 additional_properties = json.get(additional_properties_key)
98 if additional_properties: 100 if additional_properties:
99 self.properties[additional_properties_key] = Property( 101 self.properties[additional_properties_key] = Property(
100 self, 102 self,
101 additional_properties_key, 103 additional_properties_key,
102 additional_properties, 104 additional_properties,
103 is_additional_properties=True) 105 is_additional_properties=True)
104 106
105 class Callback(object):
106 """A callback parameter to a Function.
107
108 Properties:
109 - |params| the parameters to this callback.
110 """
111 def __init__(self, parent, json):
112 params = json['parameters']
113 self.parent = parent
114 self.description = json.get('description')
115 self.optional = json.get('optional', False)
116 self.params = []
117 if len(params) == 0:
118 return
119 elif len(params) == 1:
120 param = params[0]
121 self.params.append(Property(self, param['name'], param,
122 from_client=True))
123 else:
124 raise ParseException(
125 self,
126 "Callbacks can have at most a single parameter")
127
128 class Function(object): 107 class Function(object):
129 """A Function defined in the API. 108 """A Function defined in the API.
130 109
131 Properties: 110 Properties:
132 - |name| the function name 111 - |name| the function name
133 - |params| a list of parameters to the function (order matters). A separate 112 - |params| a list of parameters to the function (order matters). A separate
134 parameter is used for each choice of a 'choices' parameter. 113 parameter is used for each choice of a 'choices' parameter.
135 - |description| a description of the function (if provided) 114 - |description| a description of the function (if provided)
136 - |callback| the callback parameter to the function. There should be exactly 115 - |callback| the callback parameter to the function. There should be exactly
137 one 116 one
138 """ 117 """
139 def __init__(self, parent, json): 118 def __init__(self, parent, json, from_json=False, from_client=False):
140 self.name = json['name'] 119 self.name = json['name']
141 self.params = [] 120 self.params = []
142 self.description = json.get('description') 121 self.description = json.get('description')
143 self.callback = None 122 self.callback = None
144 self.parent = parent 123 self.parent = parent
145 self.nocompile = json.get('nocompile') 124 self.nocompile = json.get('nocompile')
146 for param in json['parameters']: 125 for param in json.get('parameters', []):
147 if param.get('type') == 'function': 126 if param.get('type') == 'function':
148 if self.callback: 127 if self.callback:
149 raise ParseException(self, self.name + " has more than one callback") 128 raise ParseException(self, self.name + " has more than one callback")
150 self.callback = Callback(self, param) 129 self.callback = Function(self, param, from_client=True)
151 else: 130 else:
152 self.params.append(Property(self, param['name'], param, 131 self.params.append(Property(self, param['name'], param,
153 from_json=True)) 132 from_json=from_json, from_client=from_client))
154 133
155 class Property(object): 134 class Property(object):
156 """A property of a type OR a parameter to a function. 135 """A property of a type OR a parameter to a function.
157 136
158 Properties: 137 Properties:
159 - |name| name of the property as in the json. This shouldn't change since 138 - |name| name of the property as in the json. This shouldn't change since
160 it is the key used to access DictionaryValues 139 it is the key used to access DictionaryValues
161 - |unix_name| the unix_style_name of the property. Used as variable name 140 - |unix_name| the unix_style_name of the property. Used as variable name
162 - |optional| a boolean representing whether the property is optional 141 - |optional| a boolean representing whether the property is optional
163 - |description| a description of the property (if provided) 142 - |description| a description of the property (if provided)
164 - |type_| the model.PropertyType of this property 143 - |type_| the model.PropertyType of this property
165 - |ref_type| the type that the REF property is referencing. Can be used to 144 - |ref_type| the type that the REF property is referencing. Can be used to
166 map to its model.Type 145 map to its model.Type
167 - |item_type| a model.Property representing the type of each element in an 146 - |item_type| a model.Property representing the type of each element in an
168 ARRAY 147 ARRAY
169 - |properties| the properties of an OBJECT parameter 148 - |properties| the properties of an OBJECT parameter
149 - |from_client| indicates that instances of the Type can originate from the
150 users of generated code, such as top-level types and function results
151 - |from_json| indicates that instances of the Type can originate from the
152 JSON (as described by the schema), such as top-level types and function
153 parameters
170 """ 154 """
171 155
172 def __init__(self, parent, name, json, is_additional_properties=False, 156 def __init__(self, parent, name, json, is_additional_properties=False,
173 from_json=False, from_client=False): 157 from_json=False, from_client=False):
174 """
175 Parameters:
176 - |from_json| indicates that instances of the Type can originate from the
177 JSON (as described by the schema), such as top-level types and function
178 parameters
179 - |from_client| indicates that instances of the Type can originate from the
180 users of generated code, such as top-level types and function results
181 """
182 self.name = name 158 self.name = name
183 self._unix_name = UnixName(self.name) 159 self._unix_name = UnixName(self.name)
184 self._unix_name_used = False 160 self._unix_name_used = False
185 self.optional = json.get('optional', False) 161 self.optional = json.get('optional', False)
186 self.functions = [] 162 self.functions = []
187 self.has_value = False 163 self.has_value = False
188 self.description = json.get('description') 164 self.description = json.get('description')
189 self.parent = parent 165 self.parent = parent
166 self.from_json = from_json
167 self.from_client = from_client
190 _AddProperties(self, json) 168 _AddProperties(self, json)
191 if is_additional_properties: 169 if is_additional_properties:
192 self.type_ = PropertyType.ADDITIONAL_PROPERTIES 170 self.type_ = PropertyType.ADDITIONAL_PROPERTIES
193 elif '$ref' in json: 171 elif '$ref' in json:
194 self.ref_type = json['$ref'] 172 self.ref_type = json['$ref']
195 self.type_ = PropertyType.REF 173 self.type_ = PropertyType.REF
196 elif 'enum' in json and json.get('type') == 'string': 174 elif 'enum' in json and json.get('type') == 'string':
197 # Non-string enums (as in the case of [legalValues=(1,2)]) should fall 175 # Non-string enums (as in the case of [legalValues=(1,2)]) should fall
198 # through to the next elif. 176 # through to the next elif.
199 self.enum_values = [] 177 self.enum_values = []
(...skipping 13 matching lines...) Expand all
213 elif json_type == 'number': 191 elif json_type == 'number':
214 self.type_ = PropertyType.DOUBLE 192 self.type_ = PropertyType.DOUBLE
215 elif json_type == 'array': 193 elif json_type == 'array':
216 self.item_type = Property(self, name + "Element", json['items'], 194 self.item_type = Property(self, name + "Element", json['items'],
217 from_json=from_json, 195 from_json=from_json,
218 from_client=from_client) 196 from_client=from_client)
219 self.type_ = PropertyType.ARRAY 197 self.type_ = PropertyType.ARRAY
220 elif json_type == 'object': 198 elif json_type == 'object':
221 self.type_ = PropertyType.OBJECT 199 self.type_ = PropertyType.OBJECT
222 # 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
223 self.from_json = from_json
224 self.from_client = from_client
225 type_ = Type(self, self.name, json) 201 type_ = Type(self, self.name, json)
226 # self.properties will already have some value from |_AddProperties|. 202 # self.properties will already have some value from |_AddProperties|.
227 self.properties.update(type_.properties) 203 self.properties.update(type_.properties)
228 self.functions = type_.functions 204 self.functions = type_.functions
229 elif json_type == 'binary': 205 elif json_type == 'binary':
230 self.type_ = PropertyType.BINARY 206 self.type_ = PropertyType.BINARY
231 else: 207 else:
232 raise ParseException(self, 'type ' + json_type + ' not recognized') 208 raise ParseException(self, 'type ' + json_type + ' not recognized')
233 elif 'choices' in json: 209 elif 'choices' in json:
234 if not json['choices']: 210 if not json['choices'] or len(json['choices']) == 0:
235 raise ParseException(self, 'Choices has no choices') 211 raise ParseException(self, 'Choices has no choices')
236 self.choices = {} 212 self.choices = {}
237 self.type_ = PropertyType.CHOICES 213 self.type_ = PropertyType.CHOICES
238 for choice_json in json['choices']: 214 for choice_json in json['choices']:
239 choice = Property(self, self.name, choice_json, 215 choice = Property(self, self.name, choice_json,
240 from_json=from_json, 216 from_json=from_json,
241 from_client=from_client) 217 from_client=from_client)
242 # A choice gets its unix_name set in 218 choice.unix_name = UnixName(self.name + choice.type_.name)
243 # cpp_type_generator.GetExpandedChoicesInParams
244 choice._unix_name = None
245 # The existence of any single choice is optional 219 # The existence of any single choice is optional
246 choice.optional = True 220 choice.optional = True
247 self.choices[choice.type_] = choice 221 self.choices[choice.type_] = choice
248 elif 'value' in json: 222 elif 'value' in json:
249 self.has_value = True 223 self.has_value = True
250 self.value = json['value'] 224 self.value = json['value']
251 if type(self.value) == int: 225 if type(self.value) == int:
252 self.type_ = PropertyType.INTEGER 226 self.type_ = PropertyType.INTEGER
253 else: 227 else:
254 # TODO(kalman): support more types as necessary. 228 # TODO(kalman): support more types as necessary.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 311
338 def _AddTypes(model, json): 312 def _AddTypes(model, json):
339 """Adds Type objects to |model| contained in the 'types' field of |json|. 313 """Adds Type objects to |model| contained in the 'types' field of |json|.
340 """ 314 """
341 model.types = {} 315 model.types = {}
342 for type_json in json.get('types', []): 316 for type_json in json.get('types', []):
343 type_ = Type(model, type_json['id'], type_json) 317 type_ = Type(model, type_json['id'], type_json)
344 model.types[type_.name] = type_ 318 model.types[type_.name] = type_
345 319
346 def _AddFunctions(model, json): 320 def _AddFunctions(model, json):
347 """Adds Function objects to |model| contained in the 'types' field of |json|. 321 """Adds Function objects to |model| contained in the 'functions' field of
322 |json|.
348 """ 323 """
349 model.functions = {} 324 model.functions = {}
350 for function_json in json.get('functions', []): 325 for function_json in json.get('functions', []):
351 function = Function(model, function_json) 326 function = Function(model, function_json, from_json=True)
352 model.functions[function.name] = function 327 model.functions[function.name] = function
353 328
329 def _AddEvents(model, json):
330 """Adds Function objects to |model| contained in the 'events' field of |json|.
331 """
332 model.events = {}
333 for event_json in json.get('events', []):
334 event = Function(model, event_json, from_client=True)
335 model.events[event.name] = event
336
354 def _AddProperties(model, json, from_json=False, from_client=False): 337 def _AddProperties(model, json, from_json=False, from_client=False):
355 """Adds model.Property objects to |model| contained in the 'properties' field 338 """Adds model.Property objects to |model| contained in the 'properties' field
356 of |json|. 339 of |json|.
357 """ 340 """
358 model.properties = {} 341 model.properties = {}
359 for name, property_json in json.get('properties', {}).items(): 342 for name, property_json in json.get('properties', {}).items():
360 # TODO(calamity): support functions (callbacks) as properties. The model 343 # TODO(calamity): support functions (callbacks) as properties. The model
361 # doesn't support it yet because the h/cc generators don't -- this is 344 # doesn't support it yet because the h/cc generators don't -- this is
362 # because we'd need to hook it into a base::Callback or something. 345 # because we'd need to hook it into a base::Callback or something.
363 # 346 #
364 # However, pragmatically it's not necessary to support them anyway, since 347 # However, pragmatically it's not necessary to support them anyway, since
365 # the instances of functions-on-properties in the extension APIs are all 348 # the instances of functions-on-properties in the extension APIs are all
366 # handled in pure Javascript on the render process (and .: never reach 349 # handled in pure Javascript on the render process (and .: never reach
367 # C++ let alone the browser). 350 # C++ let alone the browser).
368 if property_json.get('type') == 'function': 351 if property_json.get('type') == 'function':
369 continue 352 continue
370 model.properties[name] = Property( 353 model.properties[name] = Property(
371 model, 354 model,
372 name, 355 name,
373 property_json, 356 property_json,
374 from_json=from_json, 357 from_json=from_json,
375 from_client=from_client) 358 from_client=from_client)
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/h_generator.py ('k') | tools/json_schema_compiler/model_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698