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

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

Issue 10639020: Switch the downloads API over to IDL/json_schema_compiler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge 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 | Annotate | Revision Log
OLDNEW
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import itertools 6 import itertools
7 import json 7 import json
8 import os.path 8 import os.path
9 import re 9 import re
10 import sys 10 import sys
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 { 48 {
49 'parameter_name_1': "The comment that followed |parameter_name_1|:", 49 'parameter_name_1': "The comment that followed |parameter_name_1|:",
50 ... 50 ...
51 } 51 }
52 ) 52 )
53 ''' 53 '''
54 54
55 # Escape double quotes. 55 # Escape double quotes.
56 comment = comment.replace('"', '\\"'); 56 comment = comment.replace('"', '\\"');
57 57
58 # Find all the parameter comments of the form "|name|: comment". 58 # Find all the parameter comments of the form '|name|: comment'.
59 parameter_starts = list(re.finditer(r'\n *\|([^|]*)\| *: *', comment)) 59 parameter_starts = list(re.finditer(r'\n *\|([^|]*)\| *: *', comment))
60 60
61 # Get the parent comment (everything before the first parameter comment. 61 # Get the parent comment (everything before the first parameter comment.
62 first_parameter_location = (parameter_starts[0].start() 62 first_parameter_location = (parameter_starts[0].start()
63 if parameter_starts else len(comment)) 63 if parameter_starts else len(comment))
64 parent_comment = comment[:first_parameter_location] 64 parent_comment = comment[:first_parameter_location]
65 parent_comment = parent_comment.replace('\n', '').strip() 65 parent_comment = parent_comment.replace('\n', '').strip()
66 66
67 params = {} 67 params = {}
68 for (cur_param, next_param) in itertools.izip_longest(parameter_starts, 68 for (cur_param, next_param) in itertools.izip_longest(parameter_starts,
(...skipping 28 matching lines...) Expand all
97 97
98 class Param(object): 98 class Param(object):
99 ''' 99 '''
100 Given a Param node representing a function parameter, converts into a Python 100 Given a Param node representing a function parameter, converts into a Python
101 dictionary that the JSON schema compiler expects to see. 101 dictionary that the JSON schema compiler expects to see.
102 ''' 102 '''
103 def __init__(self, param_node): 103 def __init__(self, param_node):
104 self.node = param_node 104 self.node = param_node
105 105
106 def process(self, callbacks): 106 def process(self, callbacks):
107 return Typeref(self.node.GetProperty( 'TYPEREF'), 107 return Typeref(self.node.GetProperty('TYPEREF'),
108 self.node, 108 self.node,
109 { 'name': self.node.GetName() }).process(callbacks) 109 {'name': self.node.GetName()}).process(callbacks)
110 110
111 class Dictionary(object): 111 class Dictionary(object):
112 ''' 112 '''
113 Given an IDL Dictionary node, converts into a Python dictionary that the JSON 113 Given an IDL Dictionary node, converts into a Python dictionary that the JSON
114 schema compiler expects to see. 114 schema compiler expects to see.
115 ''' 115 '''
116 def __init__(self, dictionary_node): 116 def __init__(self, dictionary_node):
117 self.node = dictionary_node 117 self.node = dictionary_node
118 118
119 def process(self, callbacks): 119 def process(self, callbacks):
120 properties = {} 120 properties = {}
121 for node in self.node.children: 121 for node in self.node.children:
122 if node.cls == 'Member': 122 if node.cls == 'Member':
123 k, v = Member(node).process(callbacks) 123 k, v = Member(node).process(callbacks)
124 properties[k] = v 124 properties[k] = v
125 return { 'id': self.node.GetName(), 125 result = {'id': self.node.GetName(),
126 'properties': properties, 126 'properties': properties,
127 'type': 'object' } 127 'type': 'object'}
128 128 if self.node.GetProperty('inline_doc'):
129 class Enum(object): 129 result['inline_doc'] = True
130 ''' 130 return result
131 Given an IDL Enum node, converts into a Python dictionary that the JSON
132 schema compiler expects to see.
133 '''
134 def __init__(self, enum_node):
135 self.node = enum_node
136
137 def process(self, callbacks):
138 enum = []
139 for node in self.node.children:
140 if node.cls == 'EnumItem':
141 name = node.GetName()
142 enum.append(name)
143 else:
144 sys.exit("Did not process %s %s" % (node.cls, node))
145 return { "id" : self.node.GetName(),
146 'enum': enum,
147 'type': 'string' }
148
149 131
150 132
151 class Member(object): 133 class Member(object):
152 ''' 134 '''
153 Given an IDL dictionary or interface member, converts into a name/value pair 135 Given an IDL dictionary or interface member, converts into a name/value pair
154 where the value is a Python dictionary that the JSON schema compiler expects 136 where the value is a Python dictionary that the JSON schema compiler expects
155 to see. 137 to see.
156 ''' 138 '''
157 def __init__(self, member_node): 139 def __init__(self, member_node):
158 self.node = member_node 140 self.node = member_node
159 141
160 def process(self, callbacks): 142 def process(self, callbacks):
161 properties = {} 143 properties = {}
162 name = self.node.GetName() 144 name = self.node.GetName()
163 for property_name in ('OPTIONAL', 'nodoc', 'nocompile'): 145 for property_name in ('OPTIONAL', 'nodoc', 'nocompile'):
164 if self.node.GetProperty(property_name): 146 if self.node.GetProperty(property_name):
165 properties[property_name.lower()] = True 147 properties[property_name.lower()] = True
166 is_function = False 148 is_function = False
167 parameter_comments = {} 149 parameter_comments = {}
168 for node in self.node.children: 150 for node in self.node.children:
169 if node.cls == 'Comment': 151 if node.cls == 'Comment':
170 (parent_comment, parameter_comments) = ProcessComment(node.GetName()) 152 (parent_comment, parameter_comments) = ProcessComment(node.GetName())
171 properties['description'] = parent_comment 153 properties['description'] = parent_comment
172 for node in self.node.children: 154 elif node.cls == 'Callspec':
173 if node.cls == 'Callspec':
174 is_function = True 155 is_function = True
175 name, parameters = Callspec(node, parameter_comments).process(callbacks) 156 name, parameters = Callspec(node, parameter_comments).process(callbacks)
176 properties['parameters'] = parameters 157 properties['parameters'] = parameters
177 properties['name'] = name 158 properties['name'] = name
178 if is_function: 159 if is_function:
179 properties['type'] = 'function' 160 properties['type'] = 'function'
180 else: 161 else:
181 properties = Typeref(self.node.GetProperty('TYPEREF'), 162 properties = Typeref(self.node.GetProperty('TYPEREF'),
182 self.node, properties).process(callbacks) 163 self.node, properties).process(callbacks)
164 enum_values = self.node.GetProperty('legalValues')
165 if enum_values:
166 if properties['type'] == 'integer':
167 enum_values = map(int, enum_values)
168 elif properties['type'] == 'double':
169 enum_values = map(float, enum_values)
170 properties['enum'] = enum_values
183 return name, properties 171 return name, properties
184 172
185 class Typeref(object): 173 class Typeref(object):
186 ''' 174 '''
187 Given a TYPEREF property representing the type of dictionary member or 175 Given a TYPEREF property representing the type of dictionary member or
188 function parameter, converts into a Python dictionary that the JSON schema 176 function parameter, converts into a Python dictionary that the JSON schema
189 compiler expects to see. 177 compiler expects to see.
190 ''' 178 '''
191 def __init__(self, typeref, parent, additional_properties={}): 179 def __init__(self, typeref, parent, additional_properties={}):
192 self.typeref = typeref 180 self.typeref = typeref
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 elif self.typeref is None: 221 elif self.typeref is None:
234 properties['type'] = 'function' 222 properties['type'] = 'function'
235 else: 223 else:
236 if self.typeref in callbacks: 224 if self.typeref in callbacks:
237 properties.update(callbacks[self.typeref]) 225 properties.update(callbacks[self.typeref])
238 else: 226 else:
239 properties['$ref'] = self.typeref 227 properties['$ref'] = self.typeref
240 228
241 return result 229 return result
242 230
231
232 class Enum(object):
233 '''
234 Given an IDL Enum node, converts into a Python dictionary that the JSON
235 schema compiler expects to see.
236 '''
237 def __init__(self, enum_node):
238 self.node = enum_node
239 self.description = ''
240
241 def process(self, callbacks):
242 enum = []
243 for node in self.node.children:
244 if node.cls == 'EnumItem':
245 enum.append(node.GetName())
246 elif node.cls == 'Comment':
247 self.description = ProcessComment(node.GetName())[0]
248 else:
249 sys.exit('Did not process %s %s' % (node.cls, node))
250 result = {'id' : self.node.GetName(),
251 'description': self.description,
252 'type': 'string',
253 'enum': enum}
254 if self.node.GetProperty('inline_doc'):
255 result['inline_doc'] = True
256 return result
257
258
243 class Namespace(object): 259 class Namespace(object):
244 ''' 260 '''
245 Given an IDLNode representing an IDL namespace, converts into a Python 261 Given an IDLNode representing an IDL namespace, converts into a Python
246 dictionary that the JSON schema compiler expects to see. 262 dictionary that the JSON schema compiler expects to see.
247 ''' 263 '''
248 264
249 def __init__(self, namespace_node, nodoc=False): 265 def __init__(self, namespace_node, nodoc=False, permissions=None):
250 self.namespace = namespace_node 266 self.namespace = namespace_node
251 self.nodoc = nodoc 267 self.nodoc = nodoc
252 self.events = [] 268 self.events = []
253 self.functions = [] 269 self.functions = []
254 self.types = [] 270 self.types = []
255 self.callbacks = {} 271 self.callbacks = {}
272 self.permissions = permissions or []
256 273
257 def process(self): 274 def process(self):
258 for node in self.namespace.children: 275 for node in self.namespace.children:
259 cls = node.cls 276 if node.cls == 'Dictionary':
260 if cls == "Dictionary":
261 self.types.append(Dictionary(node).process(self.callbacks)) 277 self.types.append(Dictionary(node).process(self.callbacks))
262 elif cls == "Callback": 278 elif node.cls == 'Callback':
263 k, v = Member(node).process(self.callbacks) 279 k, v = Member(node).process(self.callbacks)
264 self.callbacks[k] = v 280 self.callbacks[k] = v
265 elif cls == "Interface" and node.GetName() == "Functions": 281 elif node.cls == 'Interface' and node.GetName() == 'Functions':
266 self.functions = self.process_interface(node) 282 self.functions = self.process_interface(node)
267 elif cls == "Interface" and node.GetName() == "Events": 283 elif node.cls == 'Interface' and node.GetName() == 'Events':
268 self.events = self.process_interface(node) 284 self.events = self.process_interface(node)
269 elif cls == "Enum": 285 elif node.cls == 'Enum':
270 self.types.append(Enum(node).process(self.callbacks)) 286 self.types.append(Enum(node).process(self.callbacks))
271 else: 287 else:
272 sys.exit("Did not process %s %s" % (node.cls, node)) 288 sys.exit('Did not process %s %s' % (node.cls, node))
273 289 return {'namespace': self.namespace.GetName(),
274 return { 'events': self.events, 290 'nodoc': self.nodoc,
275 'functions': self.functions, 291 'documentation_permissions_required': self.permissions,
276 'types': self.types, 292 'types': self.types,
277 'namespace': self.namespace.GetName(), 293 'functions': self.functions,
278 'nodoc': self.nodoc } 294 'events': self.events}
279 295
280 def process_interface(self, node): 296 def process_interface(self, node):
281 members = [] 297 members = []
282 for member in node.children: 298 for member in node.children:
283 if member.cls == 'Member': 299 if member.cls == 'Member':
284 name, properties = Member(member).process(self.callbacks) 300 name, properties = Member(member).process(self.callbacks)
285 members.append(properties) 301 members.append(properties)
286 return members 302 return members
287 303
288 class IDLSchema(object): 304 class IDLSchema(object):
289 ''' 305 '''
290 Given a list of IDLNodes and IDLAttributes, converts into a Python list 306 Given a list of IDLNodes and IDLAttributes, converts into a Python list
291 of api_defs that the JSON schema compiler expects to see. 307 of api_defs that the JSON schema compiler expects to see.
292 ''' 308 '''
293 309
294 def __init__(self, idl): 310 def __init__(self, idl):
295 self.idl = idl 311 self.idl = idl
296 312
297 def process(self): 313 def process(self):
298 namespaces = [] 314 namespaces = []
315 nodoc = False
316 permissions = None
299 for node in self.idl: 317 for node in self.idl:
300 nodoc = False 318 if node.cls == 'Namespace':
301 cls = node.cls 319 namespace = Namespace(node, nodoc, permissions)
302 if cls == 'Namespace':
303 namespace = Namespace(node, nodoc)
304 namespaces.append(namespace.process()) 320 namespaces.append(namespace.process())
305 elif cls == 'Copyright': 321 elif node.cls == 'Copyright':
306 continue 322 continue
307 elif cls == 'Comment': 323 elif node.cls == 'Comment':
308 continue 324 continue
309 elif cls == 'ExtAttribute': 325 elif node.cls == 'ExtAttribute':
310 if node.name == 'nodoc': 326 if node.name == 'nodoc':
311 nodoc = bool(node.value) 327 nodoc = bool(node.value)
328 elif node.name == 'permissions':
329 permission = node.value.split(',')
312 else: 330 else:
313 continue 331 continue
314 else: 332 else:
315 sys.exit("Did not process %s %s" % (node.cls, node)) 333 sys.exit('Did not process %s %s' % (node.cls, node))
316 schema_util.PrefixSchemasWithNamespace(namespaces) 334 schema_util.PrefixSchemasWithNamespace(namespaces)
317 return namespaces 335 return namespaces
318 336
319 def Load(filename): 337 def Load(filename):
320 ''' 338 '''
321 Given the filename of an IDL file, parses it and returns an equivalent 339 Given the filename of an IDL file, parses it and returns an equivalent
322 Python dictionary in a format that the JSON schema compiler expects to see. 340 Python dictionary in a format that the JSON schema compiler expects to see.
323 ''' 341 '''
324 342
325 f = open(filename, 'r') 343 f = open(filename, 'r')
326 contents = f.read() 344 contents = f.read()
327 f.close() 345 f.close()
328 346
329 idl = idl_parser.IDLParser().ParseData(contents, filename) 347 idl = idl_parser.IDLParser().ParseData(contents, filename)
330 idl_schema = IDLSchema(idl) 348 idl_schema = IDLSchema(idl)
331 return idl_schema.process() 349 return idl_schema.process()
332 350
333 def Main(): 351 def Main():
334 ''' 352 '''
335 Dump a json serialization of parse result for the IDL files whose names 353 Dump a json serialization of parse result for the IDL files whose names
336 were passed in on the command line. 354 were passed in on the command line.
337 ''' 355 '''
338 for filename in sys.argv[1:]: 356 for filename in sys.argv[1:]:
339 schema = Load(filename) 357 schema = Load(filename)
340 print json.dumps(schema, indent=2) 358 print json.dumps(schema, indent=2)
341 359
342 if __name__ == '__main__': 360 if __name__ == '__main__':
343 Main() 361 Main()
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/h_generator.py ('k') | tools/json_schema_compiler/idl_schema_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698