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

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

Issue 9309044: Supporting more APIs with json_schema_compiler (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: support for choices Created 8 years, 10 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 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
9 8
10 class HGenerator(object): 9 class HGenerator(object):
11 """A .h generator for a namespace. 10 """A .h generator for a namespace.
12 """ 11 """
13 def __init__(self, namespace, cpp_type_generator): 12 def __init__(self, namespace, cpp_type_generator):
14 self._cpp_type_generator = cpp_type_generator 13 self._cpp_type_generator = cpp_type_generator
15 self._namespace = namespace 14 self._namespace = namespace
16 self._target_namespace = ( 15 self._target_namespace = (
17 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) 16 self._cpp_type_generator.GetCppNamespaceName(self._namespace))
18 17
19 def Generate(self): 18 def Generate(self):
20 """Generates a code.Code object with the .h for a single namespace. 19 """Generates a code.Code object with the .h for a single namespace.
21 """ 20 """
22 c = code.Code() 21 c = code.Code()
23 (c.Append(cpp_util.CHROMIUM_LICENSE) 22 (c.Append(cpp_util.CHROMIUM_LICENSE)
24 .Append() 23 .Append()
25 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) 24 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file)
26 .Append() 25 .Append()
27 ) 26 )
28 27
29 ifndef_name = self._GenerateIfndefName() 28 ifndef_name = self._GenerateIfndefName()
30 (c.Append('#ifndef %s' % ifndef_name) 29 (c.Append('#ifndef %s' % ifndef_name)
31 .Append('#define %s' % ifndef_name) 30 .Append('#define %s' % ifndef_name)
32 .Append('#pragma once') 31 .Append('#pragma once')
33 .Append() 32 .Append()
34 .Append('#include <string>') 33 .Append('#include <string>')
35 .Append('#include <vector>') 34 .Append('#include <vector>')
36 .Append() 35 .Append()
37 .Append('#include "base/basictypes.h"') 36 .Append('#include "base/basictypes.h"')
37 .Append('#include "base/memory/linked_ptr.h"')
38 .Append('#include "base/memory/scoped_ptr.h"') 38 .Append('#include "base/memory/scoped_ptr.h"')
39 .Append('#include "base/values.h"') 39 .Append('#include "base/values.h"')
40 .Append() 40 .Append()
41 .Append('using base::Value;') 41 .Append('using base::Value;')
42 .Append('using base::DictionaryValue;') 42 .Append('using base::DictionaryValue;')
43 .Append('using base::ListValue;') 43 .Append('using base::ListValue;')
44 .Append() 44 .Append()
45 ) 45 )
46 46
47 includes = self._cpp_type_generator.GenerateCppIncludes() 47 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
48 if not includes.IsEmpty(): 48 forward_declarations = (
49 (c.Concat(includes) 49 self._cpp_type_generator.GenerateForwardDeclarations())
50 if not forward_declarations.IsEmpty():
51 (c.Append()
52 .Concat(forward_declarations)
50 .Append() 53 .Append()
51 ) 54 )
52 55
53 (c.Concat(self._cpp_type_generator.GetCppNamespaceStart()) 56 (c.Concat(self._cpp_type_generator.GetNamespaceStart())
54 .Append() 57 .Append()
55 .Append('//') 58 .Append('//')
56 .Append('// Types') 59 .Append('// Types')
57 .Append('//') 60 .Append('//')
58 .Append() 61 .Append()
59 ) 62 )
60 for type_ in self._namespace.types.values(): 63 for type_ in self._namespace.types.values():
61 (c.Concat(self._GenerateType(type_)) 64 (c.Concat(self._GenerateType(type_))
62 .Append() 65 .Append()
63 ) 66 )
64 (c.Append('//') 67 (c.Append('//')
65 .Append('// Functions') 68 .Append('// Functions')
66 .Append('//') 69 .Append('//')
67 .Append() 70 .Append()
68 ) 71 )
69 for function in self._namespace.functions.values(): 72 for function in self._namespace.functions.values():
70 (c.Concat(self._GenerateFunction(function)) 73 (c.Concat(self._GenerateFunction(function))
71 .Append() 74 .Append()
72 ) 75 )
73 (c.Append() 76 (c.Append()
74 .Append() 77 .Concat(self._cpp_type_generator.GetNamespaceEnd())
75 .Concat(self._cpp_type_generator.GetCppNamespaceEnd()) 78 .Concat(self._cpp_type_generator.GetRootNamespaceEnd())
76 .Append() 79 .Append()
77 .Append('#endif // %s' % ifndef_name) 80 .Append('#endif // %s' % ifndef_name)
78 .Append() 81 .Append()
79 ) 82 )
80 return c 83 return c
81 84
85 def _GenerateFields(self, props):
86 """Generates the field declarations when declaring a type.
87 """
88 c = code.Code()
89 for prop in self._cpp_type_generator.ExpandedChoicesInParams(props):
90 if prop.description:
91 c.Comment(prop.description)
92 c.Append('%s %s;' % (
93 self._cpp_type_generator.GetType(prop, wrap_optional=True),
94 prop.unix_name))
95 c.Append()
96 for prop in [x for x in props if x.type_ == PropertyType.CHOICES]:
not at google - send to devlin 2012/02/08 05:02:08 I think this needs a comment, like # Generate the
calamity 2012/02/08 07:01:18 Done.
97 enum_name = self._cpp_type_generator.GetChoicesEnumName(prop)
98 c.Sblock('enum %s {' % enum_name)
99 enums = []
100 enums.append(self._cpp_type_generator.GetChoiceEnum(prop, None))
101 for choice in prop.choices.values():
102 enums.append(
103 self._cpp_type_generator.GetChoiceEnum(prop, choice.type_))
104 for enum in ', '.join(enums).split():
105 c.Append(enum)
not at google - send to devlin 2012/02/08 05:02:08 I don't understand why you've done it this way rat
calamity 2012/02/08 07:01:18 Hah. Didn't know that. My default assumption is th
106 (c.Eblock('};')
107 .Append()
108 .Append('%s %s_type;' % (enum_name, prop.unix_name))
109 )
110 return c
111
82 def _GenerateType(self, type_, serializable=True): 112 def _GenerateType(self, type_, serializable=True):
83 """Generates a struct for a type. 113 """Generates a struct for a type.
84 """ 114 """
85 classname = cpp_util.CppName(type_.name) 115 classname = cpp_util.Classname(type_.name)
86 c = code.Code() 116 c = code.Code()
87 if type_.description: 117 if type_.description:
88 c.Comment(type_.description) 118 c.Comment(type_.description)
89 (c.Sblock('struct %(classname)s {') 119 (c.Sblock('struct %(classname)s {')
90 .Append('~%(classname)s();') 120 .Append('~%(classname)s();')
91 .Append('%(classname)s();') 121 .Append('%(classname)s();')
92 .Append() 122 .Append()
93 ) 123 .Concat(self._GenerateFields(type_.properties.values()))
94 124 .Comment('Populates a %(classname)s object from a Value. Returns'
95 for prop in type_.properties.values(): 125 ' whether |out| was successfully populated.')
96 if prop.description: 126 .Append('static bool Populate(const Value& value, %(classname)s* out);')
97 c.Comment(prop.description) 127 .Append()
98 if prop.optional:
99 c.Append('scoped_ptr<%s> %s;' %
100 (self._cpp_type_generator.GetType(prop, pad_for_generics=True),
101 prop.name))
102 else:
103 c.Append('%s %s;' %
104 (self._cpp_type_generator.GetType(prop), prop.name))
105 c.Append()
106
107 (c.Comment('Populates a %(classname)s object from a Value. Returns'
108 ' whether |out| was successfully populated.')
109 .Append('static bool Populate(const Value& value, %(classname)s* out);')
110 .Append()
111 ) 128 )
112 129
113 if serializable: 130 if serializable:
114 (c.Comment('Returns a new DictionaryValue representing the' 131 (c.Comment('Returns a new DictionaryValue representing the'
115 ' serialized form of this %(classname)s object. Passes' 132 ' serialized form of this %(classname)s object. Passes'
116 'ownership to caller.') 133 'ownership to caller.')
117 .Append('DictionaryValue* ToValue() const;') 134 .Append('DictionaryValue* ToValue() const;')
118 ) 135 )
119 (c.Eblock() 136 (c.Eblock()
120 .Sblock(' private:') 137 .Sblock(' private:')
121 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') 138 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
122 .Eblock('};') 139 .Eblock('};')
123 ) 140 )
124 c.Substitute({'classname': classname}) 141 c.Substitute({'classname': classname})
125 return c 142 return c
126 143
127 def _GenerateFunction(self, function): 144 def _GenerateFunction(self, function):
128 """Generates the structs for a function. 145 """Generates the structs for a function.
129 """ 146 """
130 c = code.Code() 147 c = code.Code()
131 (c.Sblock('namespace %s {' % cpp_util.CppName(function.name)) 148 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name))
132 .Concat(self._GenerateFunctionParams(function)) 149 .Concat(self._GenerateFunctionParams(function))
133 .Append() 150 .Append()
134 .Concat(self._GenerateFunctionResult(function)) 151 .Concat(self._GenerateFunctionResult(function))
135 .Append() 152 .Append()
136 .Eblock('};') 153 .Eblock('};')
137 ) 154 )
138 return c 155 return c
139 156
140 def _GenerateFunctionParams(self, function): 157 def _GenerateFunctionParams(self, function):
141 """Generates the struct for passing parameters into a function. 158 """Generates the struct for passing parameters into a function.
142 """ 159 """
143 c = code.Code() 160 c = code.Code()
144 161
145 if function.params: 162 if function.params:
146 c.Sblock('struct Params {') 163 c.Sblock('struct Params {')
147 for param in function.params: 164 for param in function.params:
148 if param.description: 165 if param.description:
149 c.Comment(param.description) 166 c.Comment(param.description)
150 if param.type_ == PropertyType.OBJECT: 167 if param.type_ == PropertyType.OBJECT:
151 c.Concat(self._GenerateType(param, serializable=False)) 168 c.Concat(self._GenerateType(param, serializable=False))
152 c.Append() 169 c.Append()
153 for param in function.params: 170 (c.Concat(self._GenerateFields(function.params))
154 c.Append('%s %s;' % 171 .Append()
155 (self._cpp_type_generator.GetType(param), param.name))
156
157 (c.Append()
158 .Append('~Params();') 172 .Append('~Params();')
159 .Append() 173 .Append()
160 .Append('static scoped_ptr<Params> Create(const ListValue& args);') 174 .Append('static scoped_ptr<Params> Create(const ListValue& args);')
161 .Eblock() 175 .Eblock()
162 .Sblock(' private:') 176 .Sblock(' private:')
163 .Append('Params();') 177 .Append('Params();')
164 .Append() 178 .Append()
165 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') 179 .Append('DISALLOW_COPY_AND_ASSIGN(Params);')
180 .Eblock('};')
166 ) 181 )
167 182
168 c.Eblock('};')
169
170 return c 183 return c
171 184
172 def _GenerateFunctionResult(self, function): 185 def _GenerateFunctionResult(self, function):
173 """Generates the struct for passing a function's result back. 186 """Generates the struct for passing a function's result back.
174 """ 187 """
175 # TODO(calamity): Handle returning an object
176 c = code.Code() 188 c = code.Code()
177 189
178 param = function.callback.param
179 # TODO(calamity): Put this description comment in less stupid place
180 if param.description:
181 c.Comment(param.description)
182 (c.Append('class Result {') 190 (c.Append('class Result {')
183 .Sblock(' public:') 191 .Sblock(' public:')
184 ) 192 )
185 arg = '' 193 params = function.callback.params
186 # TODO(calamity): handle object 194 if not params:
187 if param: 195 c.Append('static Value* Create();')
188 if param.type_ == PropertyType.REF: 196 else:
189 arg = 'const %(type)s& %(name)s' 197 # If there is a single parameter, this is straightforward. However, if
190 else: 198 # the callback parameter is of 'choices', this generates a Create method
199 # for each choice. This works because only 1 choice can be returned at a
200 # time.
201 for param in self._cpp_type_generator.ExpandedChoicesInParams(params):
191 arg = 'const %(type)s %(name)s' 202 arg = 'const %(type)s %(name)s'
192 arg = arg % { 203 if param.type_ == PropertyType.REF:
193 'type': self._cpp_type_generator.GetType(param), 204 arg = 'const %(type)s& %(name)s'
194 'name': param.name 205 arg %= {
195 } 206 'type': self._cpp_type_generator.GetType(param, wrap_optional=True),
196 (c.Append('static Value* Create(%s);' % arg) 207 'name': param.unix_name,
197 .Eblock() 208 }
198 .Sblock(' private:') 209 if param.description:
199 .Append('Result() {};') 210 c.Comment(param.description)
200 .Append('DISALLOW_COPY_AND_ASSIGN(Result);') 211 c.Append('static Value* Create(%s);' % arg)
201 .Eblock('};') 212 (c.Eblock()
213 .Sblock(' private:')
214 .Append('Result() {};')
215 .Append('DISALLOW_COPY_AND_ASSIGN(Result);')
216 .Eblock('};')
202 ) 217 )
203 218
204 return c 219 return c
205 220
206 def _GenerateIfndefName(self): 221 def _GenerateIfndefName(self):
207 """Formats a path and filename as a #define name. 222 """Formats a path and filename as a #define name.
208 223
209 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. 224 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__.
210 """ 225 """
211 return (('%s_%s_H__' % 226 return (('%s/%s_H__' %
212 (self._namespace.source_file_dir, self._target_namespace)) 227 (self._namespace.source_file_dir, self._target_namespace))
213 .upper().replace(os.sep, '_')) 228 .upper().replace('/', '_'))
214 229
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698