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

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

Issue 11827026: Overhaul JSON Schema Compiler to support a number of features required to (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 11 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
« no previous file with comments | « tools/json_schema_compiler/cpp_util.py ('k') | tools/json_schema_compiler/idl_schema.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 from code import Code 5 from code import Code
6 from model import PropertyType 6 from model import PropertyType, Type
7 import cpp_util 7 import cpp_util
8 import schema_util 8 import schema_util
9 9
10 class HGenerator(object): 10 class HGenerator(object):
11 """A .h generator for a namespace. 11 """A .h generator for a namespace.
12 """ 12 """
13 def __init__(self, namespace, cpp_type_generator): 13 def __init__(self, namespace, cpp_type_generator):
14 self._cpp_type_generator = cpp_type_generator 14 self._type_helper = cpp_type_generator
15 self._namespace = namespace 15 self._namespace = namespace
16 self._target_namespace = ( 16 self._target_namespace = (
17 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) 17 self._type_helper.GetCppNamespaceName(self._namespace))
18 18
19 def Generate(self): 19 def Generate(self):
20 """Generates a Code object with the .h for a single namespace. 20 """Generates a Code object with the .h for a single namespace.
21 """ 21 """
22 c = Code() 22 c = Code()
23 (c.Append(cpp_util.CHROMIUM_LICENSE) 23 (c.Append(cpp_util.CHROMIUM_LICENSE)
24 .Append() 24 .Append()
25 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) 25 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file)
26 .Append() 26 .Append()
27 ) 27 )
28 28
29 ifndef_name = cpp_util.GenerateIfndefName(self._namespace.source_file_dir, 29 ifndef_name = cpp_util.GenerateIfndefName(self._namespace.source_file_dir,
30 self._target_namespace) 30 self._target_namespace)
31 (c.Append('#ifndef %s' % ifndef_name) 31 (c.Append('#ifndef %s' % ifndef_name)
32 .Append('#define %s' % ifndef_name) 32 .Append('#define %s' % ifndef_name)
33 .Append() 33 .Append()
34 .Append('#include <map>')
34 .Append('#include <string>') 35 .Append('#include <string>')
35 .Append('#include <vector>') 36 .Append('#include <vector>')
36 .Append() 37 .Append()
37 .Append('#include "base/basictypes.h"') 38 .Append('#include "base/basictypes.h"')
38 .Append('#include "base/logging.h"') 39 .Append('#include "base/logging.h"')
39 .Append('#include "base/memory/linked_ptr.h"') 40 .Append('#include "base/memory/linked_ptr.h"')
40 .Append('#include "base/memory/scoped_ptr.h"') 41 .Append('#include "base/memory/scoped_ptr.h"')
41 .Append('#include "base/values.h"') 42 .Append('#include "base/values.h"')
42 .Append('#include "tools/json_schema_compiler/any.h"')
43 .Append() 43 .Append()
44 ) 44 )
45 45
46 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) 46 c.Concat(self._type_helper.GetRootNamespaceStart())
47 # TODO(calamity): These forward declarations should be #includes to allow 47 # TODO(calamity): These forward declarations should be #includes to allow
48 # $ref types from other files to be used as required params. This requires 48 # $ref types from other files to be used as required params. This requires
49 # some detangling of windows and tabs which will currently lead to circular 49 # some detangling of windows and tabs which will currently lead to circular
50 # #includes. 50 # #includes.
51 forward_declarations = ( 51 forward_declarations = (
52 self._cpp_type_generator.GenerateForwardDeclarations()) 52 self._type_helper.GenerateForwardDeclarations())
53 if not forward_declarations.IsEmpty(): 53 if not forward_declarations.IsEmpty():
54 (c.Append() 54 (c.Append()
55 .Concat(forward_declarations) 55 .Cblock(forward_declarations)
56 .Append()
57 ) 56 )
58 57
59 c.Concat(self._cpp_type_generator.GetNamespaceStart()) 58 c.Concat(self._type_helper.GetNamespaceStart())
60 c.Append() 59 c.Append()
61 if self._namespace.properties: 60 if self._namespace.properties:
62 (c.Append('//') 61 (c.Append('//')
63 .Append('// Properties') 62 .Append('// Properties')
64 .Append('//') 63 .Append('//')
65 .Append() 64 .Append()
66 ) 65 )
67 for property in self._namespace.properties.values(): 66 for property in self._namespace.properties.values():
68 property_code = self._cpp_type_generator.GeneratePropertyValues( 67 property_code = self._type_helper.GeneratePropertyValues(
69 property, 68 property,
70 'extern const %(type)s %(name)s;') 69 'extern const %(type)s %(name)s;')
71 if property_code: 70 if property_code:
72 c.Concat(property_code).Append() 71 c.Cblock(property_code)
73 if self._namespace.types: 72 if self._namespace.types:
74 (c.Append('//') 73 (c.Append('//')
75 .Append('// Types') 74 .Append('// Types')
76 .Append('//') 75 .Append('//')
77 .Append() 76 .Append()
77 .Cblock(self._GenerateTypes(self._FieldDependencyOrder(),
78 is_toplevel=True,
79 generate_typedefs=True))
78 ) 80 )
79 for type_ in self._FieldDependencyOrder():
80 (c.Concat(self._GenerateType(type_))
81 .Append()
82 )
83 if self._namespace.functions: 81 if self._namespace.functions:
84 (c.Append('//') 82 (c.Append('//')
85 .Append('// Functions') 83 .Append('// Functions')
86 .Append('//') 84 .Append('//')
87 .Append() 85 .Append()
88 ) 86 )
89 for function in self._namespace.functions.values(): 87 for function in self._namespace.functions.values():
90 (c.Concat(self._GenerateFunction(function)) 88 c.Cblock(self._GenerateFunction(function))
91 .Append()
92 )
93 if self._namespace.events: 89 if self._namespace.events:
94 (c.Append('//') 90 (c.Append('//')
95 .Append('// Events') 91 .Append('// Events')
96 .Append('//') 92 .Append('//')
97 .Append() 93 .Append()
98 ) 94 )
99 for event in self._namespace.events.values(): 95 for event in self._namespace.events.values():
100 (c.Concat(self._GenerateEvent(event)) 96 c.Cblock(self._GenerateEvent(event))
101 .Append() 97 (c.Concat(self._type_helper.GetNamespaceEnd())
102 ) 98 .Cblock(self._type_helper.GetRootNamespaceEnd())
103 (c.Concat(self._cpp_type_generator.GetNamespaceEnd())
104 .Concat(self._cpp_type_generator.GetRootNamespaceEnd())
105 .Append()
106 .Append('#endif // %s' % ifndef_name) 99 .Append('#endif // %s' % ifndef_name)
107 .Append() 100 .Append()
108 ) 101 )
109 return c 102 return c
110 103
111 def _FieldDependencyOrder(self): 104 def _FieldDependencyOrder(self):
112 """Generates the list of types in the current namespace in an order in which 105 """Generates the list of types in the current namespace in an order in which
113 depended-upon types appear before types which depend on them. 106 depended-upon types appear before types which depend on them.
114 """ 107 """
115 dependency_order = [] 108 dependency_order = []
116 109
117 def ExpandType(path, type_): 110 def ExpandType(path, type_):
118 if type_ in path: 111 if type_ in path:
119 raise ValueError("Illegal circular dependency via cycle " + 112 raise ValueError("Illegal circular dependency via cycle " +
120 ", ".join(map(lambda x: x.name, path + [type_]))) 113 ", ".join(map(lambda x: x.name, path + [type_])))
121 for prop in type_.properties.values(): 114 for prop in type_.properties.values():
122 if (prop.type_ == PropertyType.REF and 115 if (prop.type_ == PropertyType.REF and
123 schema_util.GetNamespace(prop.ref_type) == self._namespace.name): 116 schema_util.GetNamespace(prop.ref_type) == self._namespace.name):
124 ExpandType(path + [type_], self._namespace.types[prop.ref_type]) 117 ExpandType(path + [type_], self._namespace.types[prop.ref_type])
125 if not type_ in dependency_order: 118 if not type_ in dependency_order:
126 dependency_order.append(type_) 119 dependency_order.append(type_)
127 120
128 for type_ in self._namespace.types.values(): 121 for type_ in self._namespace.types.values():
129 ExpandType([], type_) 122 ExpandType([], type_)
130 return dependency_order 123 return dependency_order
131 124
132 def _GenerateEnumDeclaration(self, enum_name, prop, values): 125 def _GenerateEnumDeclaration(self, enum_name, type_):
133 """Generate the declaration of a C++ enum for the given property and 126 """Generate the declaration of a C++ enum.
134 values.
135 """ 127 """
136 c = Code() 128 c = Code()
137 c.Sblock('enum %s {' % enum_name) 129 c.Sblock('enum %s {' % enum_name)
138 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') 130 c.Append(self._type_helper.GetEnumNoneValue(type_) + ',')
139 for value in values: 131 for value in type_.enum_values:
140 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') 132 c.Append(self._type_helper.GetEnumValue(type_, value) + ',')
141 (c.Eblock('};') 133 return c.Eblock('};')
142 .Append()
143 )
144 return c
145 134
146 def _GenerateFields(self, props): 135 def _GenerateFields(self, props):
147 """Generates the field declarations when declaring a type. 136 """Generates the field declarations when declaring a type.
148 """ 137 """
149 c = Code() 138 c = Code()
150 # Generate the enums needed for any fields with "choices" 139 needs_blank_line = False
151 for prop in props: 140 for prop in props:
152 if prop.type_ == PropertyType.CHOICES: 141 if needs_blank_line:
153 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop)
154 c.Append('%s %s_type;' % (enum_name, prop.unix_name))
155 c.Append() 142 c.Append()
156 143 needs_blank_line = True
157 for prop in self._cpp_type_generator.ExpandParams(props):
158 if prop.description: 144 if prop.description:
159 c.Comment(prop.description) 145 c.Comment(prop.description)
146 # ANY is a base::Value which is abstract and cannot be a direct member, so
147 # we always need to wrap it in a scoped_ptr.
148 is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY
160 (c.Append('%s %s;' % ( 149 (c.Append('%s %s;' % (
161 self._cpp_type_generator.GetCompiledType(prop, wrap_optional=True), 150 self._type_helper.GetCppType(prop.type_, is_ptr=is_ptr),
162 prop.unix_name)) 151 prop.unix_name))
163 .Append()
164 ) 152 )
165 return c 153 return c
166 154
167 def _GenerateType(self, type_): 155 def _GenerateType(self, type_, is_toplevel=False, generate_typedefs=False):
168 """Generates a struct for a type. 156 """Generates a struct for |type_|.
157
158 |is_toplevel| implies that the type was declared in the "types" field
159 of an API schema. This determines the correct function
160 modifier(s).
161 |generate_typedefs| controls whether primitive types should be generated as
162 a typedef. This may not always be desired. If false,
163 primitive types are ignored.
169 """ 164 """
170 classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name)) 165 classname = cpp_util.Classname(schema_util.StripSchemaNamespace(type_.name))
171 c = Code() 166 c = Code()
172 167
173 if type_.functions: 168 if type_.functions:
174 c.Sblock('namespace %(classname)s {') 169 # Wrap functions within types in the type's namespace.
170 (c.Append('namespace %s {' % classname)
171 .Append()
172 )
175 for function in type_.functions.values(): 173 for function in type_.functions.values():
176 (c.Concat(self._GenerateFunction(function)) 174 c.Cblock(self._GenerateFunction(function))
177 .Append() 175 c.Append('} // namespace %s' % classname)
176 elif type_.property_type == PropertyType.ARRAY:
177 if generate_typedefs and type_.description:
178 c.Comment(type_.description)
179 c.Cblock(self._GenerateType(type_.item_type))
180 if generate_typedefs:
181 (c.Append('typedef std::vector<%s > %s;' % (
182 self._type_helper.GetCppType(type_.item_type),
183 classname))
178 ) 184 )
179 c.Eblock('}') 185 elif type_.property_type == PropertyType.STRING:
180 elif type_.type_ == PropertyType.ARRAY: 186 if generate_typedefs:
181 if type_.description: 187 if type_.description:
182 c.Comment(type_.description) 188 c.Comment(type_.description)
183 c.Append('typedef std::vector<%(item_type)s> %(classname)s;') 189 c.Append('typedef std::string %(classname)s;')
184 c.Substitute({'classname': classname, 'item_type': 190 elif type_.property_type == PropertyType.ENUM:
185 self._cpp_type_generator.GetCompiledType(type_.item_type,
186 wrap_optional=True)})
187 elif type_.type_ == PropertyType.STRING:
188 if type_.description:
189 c.Comment(type_.description)
190 c.Append('typedef std::string %(classname)s;')
191 elif type_.type_ == PropertyType.ENUM:
192 if type_.description: 191 if type_.description:
193 c.Comment(type_.description) 192 c.Comment(type_.description)
194 c.Sblock('enum %(classname)s {') 193 c.Sblock('enum %(classname)s {')
195 c.Append('%s,' % self._cpp_type_generator.GetEnumNoneValue(type_)) 194 c.Append('%s,' % self._type_helper.GetEnumNoneValue(type_))
196 for value in type_.enum_values: 195 for value in type_.enum_values:
197 c.Append('%s,' % self._cpp_type_generator.GetEnumValue(type_, value)) 196 c.Append('%s,' % self._type_helper.GetEnumValue(type_, value))
197 # Top level enums are in a namespace scope so the methods shouldn't be
198 # static. On the other hand, those declared inline (e.g. in an object) do.
199 maybe_static = '' if is_toplevel else 'static '
198 (c.Eblock('};') 200 (c.Eblock('};')
199 .Append() 201 .Append()
200 .Append('scoped_ptr<base::Value> CreateEnumValue(%s %s);' % 202 .Append('%sstd::string ToString(%s as_enum);' %
201 (classname, classname.lower())) 203 (maybe_static, classname))
202 .Append('std::string ToString(%s enum_param);' % classname) 204 .Append('%s%s Parse%s(const std::string& as_string);' %
203 .Append('%s From%sString(const std::string& enum_string);' % 205 (maybe_static, classname, classname))
204 (classname, classname))
205 ) 206 )
206 else: 207 elif type_.property_type == PropertyType.OBJECT:
207 if type_.description: 208 if type_.description:
208 c.Comment(type_.description) 209 c.Comment(type_.description)
209 (c.Sblock('struct %(classname)s {') 210 (c.Sblock('struct %(classname)s {')
211 .Append('%(classname)s();')
210 .Append('~%(classname)s();') 212 .Append('~%(classname)s();')
213 )
214 if type_.origin.from_json:
215 (c.Append()
216 .Comment('Populates a %s object from a base::Value. Returns'
217 ' whether |out| was successfully populated.' % classname)
218 .Append('static bool Populate(const base::Value& value, '
219 '%(classname)s* out);')
220 )
221 if type_.origin.from_client:
222 (c.Append()
223 .Comment('Returns a new base::DictionaryValue representing the'
224 ' serialized form of this %s object.' % classname)
225 .Append('scoped_ptr<base::DictionaryValue> ToValue() const;')
226 )
227 properties = type_.properties.values()
228 (c.Append()
229 .Cblock(self._GenerateTypes(p.type_ for p in properties))
230 .Cblock(self._GenerateFields(properties)))
231 if type_.additional_properties is not None:
232 # Most additionalProperties actually have type "any", which is better
233 # modelled as a DictionaryValue rather than a map of string -> Value.
234 if type_.additional_properties.property_type == PropertyType.ANY:
235 c.Append('base::DictionaryValue additional_properties;')
236 else:
237 (c.Cblock(self._GenerateType(type_.additional_properties))
238 .Append('std::map<std::string, %s> additional_properties;' %
239 cpp_util.PadForGenerics(
240 self._type_helper.GetCppType(type_.additional_properties,
241 is_in_container=True)))
242 )
243 (c.Eblock()
244 .Sblock(' private:')
245 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
246 .Eblock('};')
247 )
248 elif type_.property_type == PropertyType.CHOICES:
249 if type_.description:
250 c.Comment(type_.description)
251 # Choices are modelled with optional fields for each choice. Exactly one
252 # field of the choice is guaranteed to be set by the compiler.
253 (c.Sblock('struct %(classname)s {')
211 .Append('%(classname)s();') 254 .Append('%(classname)s();')
212 .Append() 255 .Append('~%(classname)s();')
213 .Concat(self._GeneratePropertyStructures(type_.properties.values())) 256 .Append())
214 .Concat(self._GenerateFields(type_.properties.values())) 257 c.Cblock(self._GenerateTypes(type_.choices))
215 ) 258 if type_.origin.from_json:
216 if type_.from_json:
217 (c.Comment('Populates a %s object from a base::Value. Returns' 259 (c.Comment('Populates a %s object from a base::Value. Returns'
218 ' whether |out| was successfully populated.' % classname) 260 ' whether |out| was successfully populated.' % classname)
219 .Append('static bool Populate(const base::Value& value, ' 261 .Append('static bool Populate(const base::Value& value, '
220 '%(classname)s* out);') 262 '%(classname)s* out);')
221 .Append() 263 .Append()
222 ) 264 )
223 265 if type_.origin.from_client:
224 if type_.from_client: 266 (c.Comment('Returns a new base::Value representing the'
225 (c.Comment('Returns a new base::DictionaryValue representing the' 267 ' serialized form of this %s object.' % classname)
226 ' serialized form of this %s object. Passes ' 268 .Append('scoped_ptr<base::Value> ToValue() const;')
227 'ownership to caller.' % classname) 269 .Append()
228 .Append('scoped_ptr<base::DictionaryValue> ToValue() const;')
229 ) 270 )
230 271 c.Append('// Choices:')
231 (c.Eblock() 272 for choice_type in type_.choices:
232 .Sblock(' private:') 273 c.Append('%s as_%s;' % (
233 .Concat(self._GeneratePrivatePropertyStructures( 274 self._type_helper.GetCppType(choice_type, is_ptr=True),
234 type_.properties.values())) 275 choice_type.unix_name))
235 .Append() 276 c.Eblock('};')
236 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
237 .Eblock('};')
238 )
239 c.Substitute({'classname': classname}) 277 c.Substitute({'classname': classname})
240 return c 278 return c
241 279
242 def _GenerateEvent(self, event): 280 def _GenerateEvent(self, event):
243 """Generates the namespaces for an event. 281 """Generates the namespaces for an event.
244 """ 282 """
245 c = Code() 283 c = Code()
246 (c.Sblock('namespace %s {' % cpp_util.Classname(event.name)) 284 # TODO(kalman): use event.unix_name not Classname.
247 .Concat(self._GenerateCreateCallbackArguments(event, 285 event_namespace = cpp_util.Classname(event.name)
248 generate_to_json=True)) 286 (c.Append('namespace %s {' % event_namespace)
249 .Eblock('};') 287 .Append()
288 .Concat(self._GenerateCreateCallbackArguments(event))
289 .Eblock('} // namespace %s' % event_namespace)
250 ) 290 )
251 return c 291 return c
252 292
253 def _GenerateFunction(self, function): 293 def _GenerateFunction(self, function):
254 """Generates the namespaces and structs for a function. 294 """Generates the namespaces and structs for a function.
255 """ 295 """
256 c = Code() 296 c = Code()
257 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) 297 # TODO(kalman): Use function.unix_name not Classname here.
258 .Concat(self._GenerateFunctionParams(function)) 298 function_namespace = cpp_util.Classname(function.name)
259 .Append() 299 (c.Append('namespace %s {' % function_namespace)
300 .Append()
301 .Cblock(self._GenerateFunctionParams(function))
260 ) 302 )
261 if function.callback: 303 if function.callback:
262 (c.Concat(self._GenerateFunctionResults(function.callback)) 304 c.Cblock(self._GenerateFunctionResults(function.callback))
263 .Append() 305 c.Append('} // namespace %s' % function_namespace)
264 )
265 c.Eblock('};')
266
267 return c 306 return c
268 307
269 def _GenerateFunctionParams(self, function): 308 def _GenerateFunctionParams(self, function):
270 """Generates the struct for passing parameters from JSON to a function. 309 """Generates the struct for passing parameters from JSON to a function.
271 """ 310 """
311 if not function.params:
312 return Code()
313
272 c = Code() 314 c = Code()
273 315 (c.Sblock('struct Params {')
274 if function.params: 316 .Append('static scoped_ptr<Params> Create(const base::ListValue& args);')
275 (c.Sblock('struct Params {') 317 .Append('~Params();')
276 .Concat(self._GeneratePropertyStructures(function.params)) 318 .Append()
277 .Concat(self._GenerateFields(function.params)) 319 .Cblock(self._GenerateTypes(p.type_ for p in function.params))
278 .Append('~Params();') 320 .Cblock(self._GenerateFields(function.params))
279 .Append() 321 .Eblock()
280 .Append('static scoped_ptr<Params> Create(' 322 .Sblock(' private:')
281 'const base::ListValue& args);') 323 .Append('Params();')
282 .Eblock() 324 .Append()
283 .Sblock(' private:') 325 .Append('DISALLOW_COPY_AND_ASSIGN(Params);')
284 .Append('Params();') 326 .Eblock('};')
285 .Append() 327 )
286 .Append('DISALLOW_COPY_AND_ASSIGN(Params);')
287 .Eblock('};')
288 )
289
290 return c 328 return c
291 329
292 def _GeneratePropertyStructures(self, props): 330 def _GenerateTypes(self, types, is_toplevel=False, generate_typedefs=False):
293 """Generate the structures required by a property such as OBJECT classes 331 """Generate the structures required by a property such as OBJECT classes
294 and enums. 332 and enums.
295 """ 333 """
296 c = Code() 334 c = Code()
297 for prop in props: 335 for type_ in types:
298 if prop.type_ == PropertyType.OBJECT: 336 c.Cblock(self._GenerateType(type_,
299 c.Concat(self._GenerateType(prop)) 337 is_toplevel=is_toplevel,
300 c.Append() 338 generate_typedefs=generate_typedefs))
301 elif prop.type_ == PropertyType.ARRAY:
302 c.Concat(self._GeneratePropertyStructures([prop.item_type]))
303 c.Append()
304 elif prop.type_ == PropertyType.CHOICES:
305 c.Concat(self._GenerateEnumDeclaration(
306 self._cpp_type_generator.GetChoicesEnumType(prop),
307 prop,
308 [choice.type_.name for choice in prop.choices.values()]))
309 c.Concat(self._GeneratePropertyStructures(prop.choices.values()))
310 elif prop.type_ == PropertyType.ENUM:
311 enum_name = self._cpp_type_generator.GetCompiledType(prop)
312 c.Concat(self._GenerateEnumDeclaration(
313 enum_name,
314 prop,
315 prop.enum_values))
316 create_enum_value = ('scoped_ptr<base::Value> CreateEnumValue(%s %s);' %
317 (enum_name, prop.unix_name))
318 enum_to_string = 'std::string ToString(%s enum_param);' % enum_name
319 enum_from_string = ('%s From%sString(const std::string& enum_string);' %
320 (enum_name, enum_name))
321 # If the property is from the UI then we're in a struct so this function
322 # should be static. If it's from the client, then we're just in a
323 # namespace so we can't have the static keyword.
324 if prop.from_json:
325 create_enum_value = 'static %s' % create_enum_value
326 enum_to_string = 'static %s' % enum_to_string
327 enum_from_string = 'static %s' % enum_from_string
328 (c.Append(create_enum_value)
329 .Append(enum_to_string)
330 .Append(enum_from_string))
331 return c 339 return c
332 340
333 def _GeneratePrivatePropertyStructures(self, props): 341 def _GenerateCreateCallbackArguments(self, function):
334 """Generate the private structures required by a property such as OBJECT 342 """Generates functions for passing parameters to a callback.
335 classes and enums.
336 """
337 c = Code()
338 for prop in props:
339 if prop.type_ == PropertyType.ARRAY:
340 c.Concat(self._GeneratePrivatePropertyStructures([prop.item_type]))
341 c.Append()
342 elif prop.type_ == PropertyType.CHOICES:
343 # We only need GetChoiceValue() if there is a ToValue() method.
344 if prop.from_client:
345 c.Append('scoped_ptr<base::Value> Get%sChoiceValue() const;' % (
346 cpp_util.Classname(prop.name)))
347 return c
348
349 def _GenerateCreateCallbackArguments(self, function, generate_to_json=False):
350 """Generates functions for passing paramaters to a callback.
351 """ 343 """
352 c = Code() 344 c = Code()
353 params = function.params 345 params = function.params
354 c.Concat(self._GeneratePropertyStructures(params)) 346 c.Cblock(self._GenerateTypes((p.type_ for p in params), is_toplevel=True))
355 347
356 param_lists = self._cpp_type_generator.GetAllPossibleParameterLists(params) 348 declaration_list = []
357 for param_list in param_lists: 349 for param in params:
358 declaration_list = [] 350 if param.description:
359 for param in param_list: 351 c.Comment(param.description)
360 if param.description: 352 declaration_list.append(cpp_util.GetParameterDeclaration(
361 c.Comment(param.description) 353 param, self._type_helper.GetCppType(param.type_)))
362 declaration_list.append('const %s' % cpp_util.GetParameterDeclaration( 354 c.Append('scoped_ptr<base::ListValue> Create(%s);' %
363 param, self._cpp_type_generator.GetCompiledType(param))) 355 ', '.join(declaration_list))
364 c.Append('scoped_ptr<base::ListValue> Create(%s);' %
365 ', '.join(declaration_list))
366 if generate_to_json:
367 c.Append('std::string ToJson(%s);' % ', '.join(declaration_list))
368 return c 356 return c
369 357
370 def _GenerateFunctionResults(self, callback): 358 def _GenerateFunctionResults(self, callback):
371 """Generates namespace for passing a function's result back. 359 """Generates namespace for passing a function's result back.
372 """ 360 """
373 c = Code() 361 c = Code()
374 (c.Sblock('namespace Results {') 362 (c.Append('namespace Results {')
375 .Concat(self._GenerateCreateCallbackArguments(callback)) 363 .Append()
376 .Eblock('};') 364 .Concat(self._GenerateCreateCallbackArguments(callback))
365 .Append('} // namespace Results')
377 ) 366 )
378 return c 367 return c
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/cpp_util.py ('k') | tools/json_schema_compiler/idl_schema.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698