Adds support for the "choices" and "any" types to json_schema_compiler, as well
[chromium-blink-merge.git] / tools / json_schema_compiler / h_generator.py
blobed85dd55d23cbfacf55825fb9eb798cf03f8a05a
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
3 # found in the LICENSE file.
5 from model import PropertyType
6 import code
7 import cpp_util
8 import os
10 class HGenerator(object):
11 """A .h generator for a namespace.
12 """
13 def __init__(self, namespace, cpp_type_generator):
14 self._cpp_type_generator = cpp_type_generator
15 self._namespace = namespace
16 self._target_namespace = (
17 self._cpp_type_generator.GetCppNamespaceName(self._namespace))
19 def Generate(self):
20 """Generates a code.Code object with the .h for a single namespace.
21 """
22 c = code.Code()
23 (c.Append(cpp_util.CHROMIUM_LICENSE)
24 .Append()
25 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file)
26 .Append()
29 ifndef_name = self._GenerateIfndefName()
30 (c.Append('#ifndef %s' % ifndef_name)
31 .Append('#define %s' % ifndef_name)
32 .Append('#pragma once')
33 .Append()
34 .Append('#include <string>')
35 .Append('#include <vector>')
36 .Append()
37 .Append('#include "base/basictypes.h"')
38 .Append('#include "base/memory/linked_ptr.h"')
39 .Append('#include "base/memory/scoped_ptr.h"')
40 .Append('#include "base/values.h"')
41 .Append()
44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
45 forward_declarations = (
46 self._cpp_type_generator.GenerateForwardDeclarations())
47 if not forward_declarations.IsEmpty():
48 (c.Append()
49 .Concat(forward_declarations)
50 .Append()
53 (c.Concat(self._cpp_type_generator.GetNamespaceStart())
54 .Append()
55 .Append('//')
56 .Append('// Types')
57 .Append('//')
58 .Append()
60 for type_ in self._namespace.types.values():
61 (c.Concat(self._GenerateType(type_))
62 .Append()
64 (c.Append('//')
65 .Append('// Functions')
66 .Append('//')
67 .Append()
69 for function in self._namespace.functions.values():
70 (c.Concat(self._GenerateFunction(function))
71 .Append()
73 (c.Append()
74 .Concat(self._cpp_type_generator.GetNamespaceEnd())
75 .Concat(self._cpp_type_generator.GetRootNamespaceEnd())
76 .Append()
77 .Append('#endif // %s' % ifndef_name)
78 .Append()
80 return c
82 def _GenerateFields(self, props):
83 """Generates the field declarations when declaring a type.
84 """
85 c = code.Code()
86 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props):
87 if prop.description:
88 c.Comment(prop.description)
89 c.Append('%s %s;' % (
90 self._cpp_type_generator.GetType(prop, wrap_optional=True),
91 prop.unix_name))
92 c.Append()
93 # Generate the enums needed for any fields with "choices"
94 for prop in props:
95 if prop.type_ == PropertyType.CHOICES:
96 c.Sblock('enum %(enum_type)s {')
97 c.Append(self._cpp_type_generator.GetChoiceEnumNoneValue(prop) + ',')
98 for choice in prop.choices.values():
99 c.Append(
100 self._cpp_type_generator.GetChoiceEnumValue( prop, choice.type_)
101 + ',')
102 (c.Eblock('};')
103 .Append()
104 .Append('%(enum_type)s %(name)s_type;')
106 c.Substitute({
107 'enum_type': self._cpp_type_generator.GetChoicesEnumType(prop),
108 'name': prop.unix_name
110 return c
112 def _GenerateType(self, type_, serializable=True):
113 """Generates a struct for a type.
115 classname = cpp_util.Classname(type_.name)
116 c = code.Code()
117 if type_.description:
118 c.Comment(type_.description)
119 (c.Sblock('struct %(classname)s {')
120 .Append('~%(classname)s();')
121 .Append('%(classname)s();')
122 .Append()
123 .Concat(self._GenerateFields(type_.properties.values()))
124 .Comment('Populates a %(classname)s object from a Value. Returns'
125 ' whether |out| was successfully populated.')
126 .Append('static bool Populate(const Value& value, %(classname)s* out);')
127 .Append()
130 if serializable:
131 (c.Comment('Returns a new DictionaryValue representing the'
132 ' serialized form of this %(classname)s object. Passes '
133 'ownership to caller.')
134 .Append('scoped_ptr<DictionaryValue> ToValue() const;')
136 (c.Eblock()
137 .Sblock(' private:')
138 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);')
139 .Eblock('};')
141 c.Substitute({'classname': classname})
142 return c
144 def _GenerateFunction(self, function):
145 """Generates the structs for a function.
147 c = code.Code()
148 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name))
149 .Concat(self._GenerateFunctionParams(function))
150 .Append()
151 .Concat(self._GenerateFunctionResult(function))
152 .Append()
153 .Eblock('};')
155 return c
157 def _GenerateFunctionParams(self, function):
158 """Generates the struct for passing parameters into a function.
160 c = code.Code()
162 if function.params:
163 c.Sblock('struct Params {')
164 for param in function.params:
165 if param.type_ == PropertyType.OBJECT:
166 c.Concat(self._GenerateType(param, serializable=False))
167 c.Append()
168 (c.Concat(self._GenerateFields(function.params))
169 .Append('~Params();')
170 .Append()
171 .Append('static scoped_ptr<Params> Create(const ListValue& args);')
172 .Eblock()
173 .Sblock(' private:')
174 .Append('Params();')
175 .Append()
176 .Append('DISALLOW_COPY_AND_ASSIGN(Params);')
177 .Eblock('};')
180 return c
182 def _GenerateFunctionResult(self, function):
183 """Generates functions for passing a function's result back.
185 c = code.Code()
187 c.Sblock('namespace Result {')
188 params = function.callback.params
189 if not params:
190 c.Append('Value* Create();')
191 else:
192 # If there is a single parameter, this is straightforward. However, if
193 # the callback parameter is of 'choices', this generates a Create method
194 # for each choice. This works because only 1 choice can be returned at a
195 # time.
196 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params):
197 if param.description:
198 c.Comment(param.description)
199 c.Append('Value* Create(%s);' %
200 cpp_util.GetConstParameterDeclaration(
201 param, self._cpp_type_generator))
202 c.Eblock('};')
204 return c
206 def _GenerateIfndefName(self):
207 """Formats a path and filename as a #define name.
209 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__.
211 return (('%s_%s_H__' %
212 (self._namespace.source_file_dir, self._target_namespace))
213 .upper().replace(os.sep, '_'))