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

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: Added more testing for event compilation. 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
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 additional_properties, 104 additional_properties,
103 is_additional_properties=True) 105 is_additional_properties=True)
104 106
105 class Callback(object): 107 class Callback(object):
106 """A callback parameter to a Function. 108 """A callback parameter to a Function.
107 109
108 Properties: 110 Properties:
109 - |params| the parameters to this callback. 111 - |params| the parameters to this callback.
110 """ 112 """
111 def __init__(self, parent, json): 113 def __init__(self, parent, json):
112 params = json['parameters'] 114 params = json.get('parameters', [])
113 self.parent = parent 115 self.parent = parent
114 self.params = [] 116 self.params = []
115 if len(params) == 0: 117 if len(params) == 0:
116 return 118 return
117 elif len(params) == 1: 119 elif len(params) == 1:
118 param = params[0] 120 param = params[0]
119 self.params.append(Property(self, param['name'], param, 121 self.params.append(Property(self, param['name'], param,
120 from_client=True)) 122 from_client=True))
121 else: 123 else:
122 raise ParseException( 124 raise ParseException(
123 self, 125 self,
124 "Callbacks can have at most a single parameter") 126 "Callbacks can have at most a single parameter")
125 127
126 class Function(object): 128 class Function(object):
127 """A Function defined in the API. 129 """A Function defined in the API.
128 130
129 Properties: 131 Properties:
130 - |name| the function name 132 - |name| the function name
131 - |params| a list of parameters to the function (order matters). A separate 133 - |params| a list of parameters to the function (order matters). A separate
132 parameter is used for each choice of a 'choices' parameter. 134 parameter is used for each choice of a 'choices' parameter.
133 - |description| a description of the function (if provided) 135 - |description| a description of the function (if provided)
134 - |callback| the callback parameter to the function. There should be exactly 136 - |callback| the callback parameter to the function. There should be exactly
135 one 137 one
136 """ 138 """
137 def __init__(self, parent, json): 139 def __init__(self, parent, json, from_json=False, from_client=False):
138 self.name = json['name'] 140 self.name = json['name']
139 self.params = [] 141 self.params = []
140 self.description = json.get('description') 142 self.description = json.get('description')
141 self.callback = None 143 self.callback = None
142 self.parent = parent 144 self.parent = parent
143 self.nocompile = json.get('nocompile') 145 self.nocompile = json.get('nocompile')
144 for param in json['parameters']: 146 for param in json['parameters']:
145 if param.get('type') == 'function': 147 if param.get('type') == 'function':
146 if self.callback: 148 if self.callback:
147 raise ParseException(self, self.name + " has more than one callback") 149 raise ParseException(self, self.name + " has more than one callback")
148 self.callback = Callback(self, param) 150 self.callback = Callback(self, param)
149 else: 151 else:
150 self.params.append(Property(self, param['name'], param, 152 self.params.append(Property(self, param['name'], param,
151 from_json=True)) 153 from_json=from_json, from_client=from_client))
152 154
153 class Property(object): 155 class Property(object):
154 """A property of a type OR a parameter to a function. 156 """A property of a type OR a parameter to a function.
155 157
156 Properties: 158 Properties:
157 - |name| name of the property as in the json. This shouldn't change since 159 - |name| name of the property as in the json. This shouldn't change since
158 it is the key used to access DictionaryValues 160 it is the key used to access DictionaryValues
159 - |unix_name| the unix_style_name of the property. Used as variable name 161 - |unix_name| the unix_style_name of the property. Used as variable name
160 - |optional| a boolean representing whether the property is optional 162 - |optional| a boolean representing whether the property is optional
161 - |description| a description of the property (if provided) 163 - |description| a description of the property (if provided)
162 - |type_| the model.PropertyType of this property 164 - |type_| the model.PropertyType of this property
163 - |ref_type| the type that the REF property is referencing. Can be used to 165 - |ref_type| the type that the REF property is referencing. Can be used to
164 map to its model.Type 166 map to its model.Type
165 - |item_type| a model.Property representing the type of each element in an 167 - |item_type| a model.Property representing the type of each element in an
166 ARRAY 168 ARRAY
167 - |properties| the properties of an OBJECT parameter 169 - |properties| the properties of an OBJECT parameter
170 - |from_client| indicates that instances of the Type can originate from the
171 users of generated code, such as top-level types and function results
172 - |from_json| indicates that instances of the Type can originate from the
173 JSON (as described by the schema), such as top-level types and function
174 parameters
168 """ 175 """
169 176
170 def __init__(self, parent, name, json, is_additional_properties=False, 177 def __init__(self, parent, name, json, is_additional_properties=False,
171 from_json=False, from_client=False): 178 from_json=False, from_client=False):
172 """
173 Parameters:
174 - |from_json| indicates that instances of the Type can originate from the
175 JSON (as described by the schema), such as top-level types and function
176 parameters
177 - |from_client| indicates that instances of the Type can originate from the
178 users of generated code, such as top-level types and function results
179 """
180 self.name = name 179 self.name = name
181 self._unix_name = UnixName(self.name) 180 self._unix_name = UnixName(self.name)
182 self._unix_name_used = False 181 self._unix_name_used = False
183 self.optional = json.get('optional', False) 182 self.optional = json.get('optional', False)
184 self.has_value = False 183 self.has_value = False
185 self.description = json.get('description') 184 self.description = json.get('description')
186 self.parent = parent 185 self.parent = parent
186 self.from_json = from_json
187 self.from_client = from_client
187 _AddProperties(self, json) 188 _AddProperties(self, json)
188 if is_additional_properties: 189 if is_additional_properties:
189 self.type_ = PropertyType.ADDITIONAL_PROPERTIES 190 self.type_ = PropertyType.ADDITIONAL_PROPERTIES
190 elif '$ref' in json: 191 elif '$ref' in json:
191 self.ref_type = json['$ref'] 192 self.ref_type = json['$ref']
192 self.type_ = PropertyType.REF 193 self.type_ = PropertyType.REF
193 elif 'enum' in json: 194 elif 'enum' in json:
194 self.enum_values = [] 195 self.enum_values = []
195 for value in json['enum']: 196 for value in json['enum']:
196 self.enum_values.append(value) 197 self.enum_values.append(value)
(...skipping 11 matching lines...) Expand all
208 elif json_type == 'number': 209 elif json_type == 'number':
209 self.type_ = PropertyType.DOUBLE 210 self.type_ = PropertyType.DOUBLE
210 elif json_type == 'array': 211 elif json_type == 'array':
211 self.item_type = Property(self, name + "Element", json['items'], 212 self.item_type = Property(self, name + "Element", json['items'],
212 from_json=from_json, 213 from_json=from_json,
213 from_client=from_client) 214 from_client=from_client)
214 self.type_ = PropertyType.ARRAY 215 self.type_ = PropertyType.ARRAY
215 elif json_type == 'object': 216 elif json_type == 'object':
216 self.type_ = PropertyType.OBJECT 217 self.type_ = PropertyType.OBJECT
217 # These members are read when this OBJECT Property is used as a Type 218 # These members are read when this OBJECT Property is used as a Type
218 self.from_json = from_json
219 self.from_client = from_client
220 type_ = Type(self, self.name, json) 219 type_ = Type(self, self.name, json)
221 # self.properties will already have some value from |_AddProperties|. 220 # self.properties will already have some value from |_AddProperties|.
222 self.properties.update(type_.properties) 221 self.properties.update(type_.properties)
223 self.functions = type_.functions 222 self.functions = type_.functions
224 elif json_type == 'binary': 223 elif json_type == 'binary':
225 self.type_ = PropertyType.BINARY 224 self.type_ = PropertyType.BINARY
226 else: 225 else:
227 raise ParseException(self, 'type ' + json_type + ' not recognized') 226 raise ParseException(self, 'type ' + json_type + ' not recognized')
228 elif 'choices' in json: 227 elif 'choices' in json:
229 if not json['choices']: 228 if not json['choices']:
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 331
333 def _AddTypes(model, json): 332 def _AddTypes(model, json):
334 """Adds Type objects to |model| contained in the 'types' field of |json|. 333 """Adds Type objects to |model| contained in the 'types' field of |json|.
335 """ 334 """
336 model.types = {} 335 model.types = {}
337 for type_json in json.get('types', []): 336 for type_json in json.get('types', []):
338 type_ = Type(model, type_json['id'], type_json) 337 type_ = Type(model, type_json['id'], type_json)
339 model.types[type_.name] = type_ 338 model.types[type_.name] = type_
340 339
341 def _AddFunctions(model, json): 340 def _AddFunctions(model, json):
342 """Adds Function objects to |model| contained in the 'types' field of |json|. 341 """Adds Function objects to |model| contained in the 'functions' field of
342 |json|.
343 """ 343 """
344 model.functions = {} 344 model.functions = {}
345 for function_json in json.get('functions', []): 345 for function_json in json.get('functions', []):
346 function = Function(model, function_json) 346 function = Function(model, function_json, from_json=True)
347 model.functions[function.name] = function 347 model.functions[function.name] = function
348 348
349 def _AddEvents(model, json):
350 """Adds Function objects to |model| contained in the 'events' field of |json|.
351 """
352 model.events = {}
353 for event_json in json.get('events', []):
354 event = Function(model, event_json, from_client=True)
355 model.events[event.name] = event
356
349 def _AddProperties(model, json, from_json=False, from_client=False): 357 def _AddProperties(model, json, from_json=False, from_client=False):
350 """Adds model.Property objects to |model| contained in the 'properties' field 358 """Adds model.Property objects to |model| contained in the 'properties' field
351 of |json|. 359 of |json|.
352 """ 360 """
353 model.properties = {} 361 model.properties = {}
354 for name, property_json in json.get('properties', {}).items(): 362 for name, property_json in json.get('properties', {}).items():
355 # TODO(calamity): support functions (callbacks) as properties. The model 363 # TODO(calamity): support functions (callbacks) as properties. The model
356 # doesn't support it yet because the h/cc generators don't -- this is 364 # doesn't support it yet because the h/cc generators don't -- this is
357 # because we'd need to hook it into a base::Callback or something. 365 # because we'd need to hook it into a base::Callback or something.
358 # 366 #
359 # However, pragmatically it's not necessary to support them anyway, since 367 # However, pragmatically it's not necessary to support them anyway, since
360 # the instances of functions-on-properties in the extension APIs are all 368 # the instances of functions-on-properties in the extension APIs are all
361 # handled in pure Javascript on the render process (and .: never reach 369 # handled in pure Javascript on the render process (and .: never reach
362 # C++ let alone the browser). 370 # C++ let alone the browser).
363 if property_json.get('type') == 'function': 371 if property_json.get('type') == 'function':
364 continue 372 continue
365 model.properties[name] = Property( 373 model.properties[name] = Property(
366 model, 374 model,
367 name, 375 name,
368 property_json, 376 property_json,
369 from_json=from_json, 377 from_json=from_json,
370 from_client=from_client) 378 from_client=from_client)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698