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

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

Issue 9456007: Add wider support to json_schema_compiler (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: reupload Created 8 years, 9 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/cpp_util.py ('k') | tools/json_schema_compiler/model.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 model import PropertyType 5 from model import PropertyType
6 import code 6 import code
7 import cpp_util 7 import cpp_util
8 import os 8 import os
9 9
10 class HGenerator(object): 10 class HGenerator(object):
(...skipping 24 matching lines...) Expand all
35 .Append('#include <vector>') 35 .Append('#include <vector>')
36 .Append() 36 .Append()
37 .Append('#include "base/basictypes.h"') 37 .Append('#include "base/basictypes.h"')
38 .Append('#include "base/memory/linked_ptr.h"') 38 .Append('#include "base/memory/linked_ptr.h"')
39 .Append('#include "base/memory/scoped_ptr.h"') 39 .Append('#include "base/memory/scoped_ptr.h"')
40 .Append('#include "base/values.h"') 40 .Append('#include "base/values.h"')
41 .Append() 41 .Append()
42 ) 42 )
43 43
44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) 44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
45 # TODO(calamity): These forward declarations should be #includes to allow
46 # $ref types from other files to be used as required params. This requires
47 # some detangling of windows and tabs which will currently lead to circular
48 # #includes.
45 forward_declarations = ( 49 forward_declarations = (
46 self._cpp_type_generator.GenerateForwardDeclarations()) 50 self._cpp_type_generator.GenerateForwardDeclarations())
47 if not forward_declarations.IsEmpty(): 51 if not forward_declarations.IsEmpty():
48 (c.Append() 52 (c.Append()
49 .Concat(forward_declarations) 53 .Concat(forward_declarations)
50 .Append() 54 .Append()
51 ) 55 )
52 56
53 (c.Concat(self._cpp_type_generator.GetNamespaceStart()) 57 c.Concat(self._cpp_type_generator.GetNamespaceStart())
54 .Append() 58 c.Append()
55 .Append('//') 59 if self._namespace.types:
56 .Append('// Types') 60 (c.Append('//')
57 .Append('//') 61 .Append('// Types')
58 .Append() 62 .Append('//')
59 )
60 for type_ in self._namespace.types.values():
61 (c.Concat(self._GenerateType(type_))
62 .Append() 63 .Append()
63 ) 64 )
64 (c.Append('//') 65 for type_ in self._namespace.types.values():
65 .Append('// Functions') 66 (c.Concat(self._GenerateType(type_))
66 .Append('//') 67 .Append()
67 .Append() 68 )
68 ) 69 if self._namespace.functions:
69 for function in self._namespace.functions.values(): 70 (c.Append('//')
70 (c.Concat(self._GenerateFunction(function)) 71 .Append('// Functions')
72 .Append('//')
71 .Append() 73 .Append()
72 ) 74 )
75 for function in self._namespace.functions.values():
76 (c.Concat(self._GenerateFunction(function))
77 .Append()
78 )
73 (c.Append() 79 (c.Append()
74 .Concat(self._cpp_type_generator.GetNamespaceEnd()) 80 .Concat(self._cpp_type_generator.GetNamespaceEnd())
75 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) 81 .Concat(self._cpp_type_generator.GetRootNamespaceEnd())
76 .Append() 82 .Append()
77 .Append('#endif // %s' % ifndef_name) 83 .Append('#endif // %s' % ifndef_name)
78 .Append() 84 .Append()
79 ) 85 )
80 return c 86 return c
81 87
82 def _GenerateEnumDeclaration(self, enum_name, prop, values): 88 def _GenerateEnumDeclaration(self, enum_name, prop, values):
89 """Generate the declaration of a C++ enum for the given property and
90 values.
91 """
83 c = code.Code() 92 c = code.Code()
84 c.Sblock('enum %s {' % enum_name) 93 c.Sblock('enum %s {' % enum_name)
85 if prop.optional: 94 if prop.optional:
86 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') 95 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',')
87 for value in values: 96 for value in values:
88 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') 97 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',')
89 (c.Eblock('};') 98 (c.Eblock('};')
90 .Append() 99 .Append()
91 ) 100 )
92 return c 101 return c
93 102
94 def _GenerateFields(self, props): 103 def _GenerateFields(self, props):
95 """Generates the field declarations when declaring a type. 104 """Generates the field declarations when declaring a type.
96 """ 105 """
97 c = code.Code() 106 c = code.Code()
98 # Generate the enums needed for any fields with "choices" 107 # Generate the enums needed for any fields with "choices"
99 for prop in props: 108 for prop in props:
100 if prop.type_ == PropertyType.CHOICES: 109 if prop.type_ == PropertyType.CHOICES:
101 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) 110 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop)
102 c.Concat(self._GenerateEnumDeclaration(
103 enum_name,
104 prop,
105 [choice.type_.name for choice in prop.choices.values()]))
106 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) 111 c.Append('%s %s_type;' % (enum_name, prop.unix_name))
107 elif prop.type_ == PropertyType.ENUM:
108 c.Concat(self._GenerateEnumDeclaration(
109 self._cpp_type_generator.GetType(prop),
110 prop,
111 prop.enum_values))
112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): 112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props):
113 if prop.description: 113 if prop.description:
114 c.Comment(prop.description) 114 c.Comment(prop.description)
115 c.Append('%s %s;' % ( 115 c.Append('%s %s;' % (
116 self._cpp_type_generator.GetType(prop, wrap_optional=True), 116 self._cpp_type_generator.GetType(prop, wrap_optional=True),
117 prop.unix_name)) 117 prop.unix_name))
118 c.Append() 118 c.Append()
119 return c 119 return c
120 120
121 def _GenerateType(self, type_, serializable=True): 121 def _GenerateType(self, type_):
122 """Generates a struct for a type. 122 """Generates a struct for a type.
123 """ 123 """
124 classname = cpp_util.Classname(type_.name) 124 classname = cpp_util.Classname(type_.name)
125 c = code.Code() 125 c = code.Code()
126 if type_.description: 126 if type_.description:
127 c.Comment(type_.description) 127 c.Comment(type_.description)
128 (c.Sblock('struct %(classname)s {') 128 (c.Sblock('struct %(classname)s {')
129 .Append('~%(classname)s();') 129 .Append('~%(classname)s();')
130 .Append('%(classname)s();') 130 .Append('%(classname)s();')
131 .Append() 131 .Append()
132 .Concat(self._GeneratePropertyStructures(type_.properties.values()))
132 .Concat(self._GenerateFields(type_.properties.values())) 133 .Concat(self._GenerateFields(type_.properties.values()))
133 .Comment('Populates a %(classname)s object from a Value. Returns' 134 )
134 ' whether |out| was successfully populated.') 135 if type_.from_json:
136 (c.Comment('Populates a %s object from a Value. Returns'
137 ' whether |out| was successfully populated.' % classname)
135 .Append('static bool Populate(const Value& value, %(classname)s* out);') 138 .Append('static bool Populate(const Value& value, %(classname)s* out);')
136 .Append() 139 .Append()
137 ) 140 )
138 141
139 if serializable: 142 if type_.from_client:
140 (c.Comment('Returns a new DictionaryValue representing the' 143 (c.Comment('Returns a new DictionaryValue representing the'
141 ' serialized form of this %(classname)s object. Passes ' 144 ' serialized form of this %s object. Passes '
142 'ownership to caller.') 145 'ownership to caller.' % classname)
143 .Append('scoped_ptr<DictionaryValue> ToValue() const;') 146 .Append('scoped_ptr<DictionaryValue> ToValue() const;')
144 ) 147 )
145 (c.Eblock() 148 (c.Eblock()
146 .Sblock(' private:') 149 .Sblock(' private:')
147 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') 150 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
148 .Eblock('};') 151 .Eblock('};')
149 ) 152 )
150 c.Substitute({'classname': classname}) 153 c.Substitute({'classname': classname})
151 return c 154 return c
152 155
153 def _GenerateFunction(self, function): 156 def _GenerateFunction(self, function):
154 """Generates the structs for a function. 157 """Generates the structs for a function.
155 """ 158 """
156 c = code.Code() 159 c = code.Code()
157 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) 160 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name))
158 .Concat(self._GenerateFunctionParams(function)) 161 .Concat(self._GenerateFunctionParams(function))
159 .Append() 162 .Append()
160 .Concat(self._GenerateFunctionResult(function)) 163 )
164 if function.callback:
165 (c.Concat(self._GenerateFunctionResult(function))
161 .Append() 166 .Append()
162 .Eblock('};') 167 )
163 ) 168 c.Eblock('};')
169
164 return c 170 return c
165 171
166 def _GenerateFunctionParams(self, function): 172 def _GenerateFunctionParams(self, function):
167 """Generates the struct for passing parameters into a function. 173 """Generates the struct for passing parameters into a function.
168 """ 174 """
169 c = code.Code() 175 c = code.Code()
170 176
171 if function.params: 177 if function.params:
172 c.Sblock('struct Params {') 178 (c.Sblock('struct Params {')
173 for param in function.params: 179 .Concat(self._GeneratePropertyStructures(function.params))
174 if param.type_ == PropertyType.OBJECT: 180 .Concat(self._GenerateFields(function.params))
175 c.Concat(self._GenerateType(param, serializable=False)) 181 .Append('~Params();')
176 c.Append() 182 .Append()
177 (c.Concat(self._GenerateFields(function.params)) 183 .Append('static scoped_ptr<Params> Create(const ListValue& args);')
178 .Append('~Params();') 184 .Eblock()
179 .Append() 185 .Sblock(' private:')
180 .Append('static scoped_ptr<Params> Create(const ListValue& args);') 186 .Append('Params();')
181 .Eblock() 187 .Append()
182 .Sblock(' private:') 188 .Append('DISALLOW_COPY_AND_ASSIGN(Params);')
183 .Append('Params();') 189 .Eblock('};')
184 .Append()
185 .Append('DISALLOW_COPY_AND_ASSIGN(Params);')
186 .Eblock('};')
187 ) 190 )
188 191
189 return c 192 return c
190 193
194 def _GeneratePropertyStructures(self, props):
195 """Generate the structures required by a property such as OBJECT classes
196 and enums.
197 """
198 c = code.Code()
199 for prop in props:
200 if prop.type_ == PropertyType.OBJECT:
201 c.Concat(self._GenerateType(prop))
202 c.Append()
203 elif prop.type_ == PropertyType.CHOICES:
204 c.Concat(self._GenerateEnumDeclaration(
205 self._cpp_type_generator.GetChoicesEnumType(prop),
206 prop,
207 [choice.type_.name for choice in prop.choices.values()]))
208 elif prop.type_ == PropertyType.ENUM:
209 enum_name = self._cpp_type_generator.GetType(prop)
210 c.Concat(self._GenerateEnumDeclaration(
211 enum_name,
212 prop,
213 prop.enum_values))
214 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' %
215 (enum_name, prop.unix_name))
216 return c
217
191 def _GenerateFunctionResult(self, function): 218 def _GenerateFunctionResult(self, function):
192 """Generates functions for passing a function's result back. 219 """Generates functions for passing a function's result back.
193 """ 220 """
194 c = code.Code() 221 c = code.Code()
195 222
196 c.Sblock('namespace Result {') 223 c.Sblock('namespace Result {')
197 params = function.callback.params 224 params = function.callback.params
198 if not params: 225 if not params:
199 c.Append('Value* Create();') 226 c.Append('Value* Create();')
200 else: 227 else:
228 c.Concat(self._GeneratePropertyStructures(params))
229
201 # If there is a single parameter, this is straightforward. However, if 230 # If there is a single parameter, this is straightforward. However, if
202 # the callback parameter is of 'choices', this generates a Create method 231 # the callback parameter is of 'choices', this generates a Create method
203 # for each choice. This works because only 1 choice can be returned at a 232 # for each choice. This works because only 1 choice can be returned at a
204 # time. 233 # time.
205 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): 234 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params):
206 if param.description: 235 if param.description:
207 c.Comment(param.description) 236 c.Comment(param.description)
208 if param.type_ == PropertyType.OBJECT:
209 raise NotImplementedError('OBJECT return type not supported')
210 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( 237 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration(
211 param, self._cpp_type_generator.GetType(param))) 238 param, self._cpp_type_generator.GetType(param)))
212 c.Eblock('};') 239 c.Eblock('};')
213 240
214 return c 241 return c
215 242
216 def _GenerateIfndefName(self): 243 def _GenerateIfndefName(self):
217 """Formats a path and filename as a #define name. 244 """Formats a path and filename as a #define name.
218 245
219 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. 246 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__.
220 """ 247 """
221 return (('%s_%s_H__' % 248 return (('%s_%s_H__' %
222 (self._namespace.source_file_dir, self._target_namespace)) 249 (self._namespace.source_file_dir, self._target_namespace))
223 .upper().replace(os.sep, '_')) 250 .upper().replace(os.sep, '_'))
224 251
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/cpp_util.py ('k') | tools/json_schema_compiler/model.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698