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

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

Issue 12041098: Initial commit of the Dart Chrome Extension APIs generators (Closed) Base URL: http://git.chromium.org/chromium/src.git@file_path_bugfix
Patch Set: Kalman fixes 2 (nocompile ignored in bundle mode) Created 7 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
« no previous file with comments | « tools/json_schema_compiler/model.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 import code
6 import cpp_util
7 from model import Platforms
8 from schema_util import CapitalizeFirstLetter
9 from schema_util import JsFunctionNameToClassName
10
11 import json
12 import os
13 import re
14
15 # TODO(miket/asargent) - parameterize this.
16 SOURCE_BASE_PATH = 'chrome/common/extensions/api'
17
18 def _RemoveDescriptions(node):
19 """Returns a copy of |schema| with "description" fields removed.
20 """
21 if isinstance(node, dict):
22 result = {}
23 for key, value in node.items():
24 # Some schemas actually have properties called "description", so only
25 # remove descriptions that have string values.
26 if key == 'description' and isinstance(value, basestring):
27 continue
28 result[key] = _RemoveDescriptions(value)
29 return result
30 if isinstance(node, list):
31 return [_RemoveDescriptions(v) for v in node]
32 return node
33
34 class SchemaBundleGenerator(object):
35 """This class contains methods to generate code based on multiple schemas.
36 """
37
38 def __init__(self, root, model, api_defs, cpp_type_generator):
39 self._root = root;
40 self._model = model
41 self._api_defs = api_defs
42 self._cpp_type_generator = cpp_type_generator
43
44 def GenerateHeader(self, file_base, body_code):
45 """Generates a code.Code object for a header file
46
47 Parameters:
48 - |file_base| - the base of the filename, e.g. 'foo' (for 'foo.h')
49 - |body_code| - the code to put in between the multiple inclusion guards"""
50 c = code.Code()
51 c.Append(cpp_util.CHROMIUM_LICENSE)
52 c.Append()
53 c.Append(cpp_util.GENERATED_BUNDLE_FILE_MESSAGE % SOURCE_BASE_PATH)
54 ifndef_name = cpp_util.GenerateIfndefName(SOURCE_BASE_PATH, file_base)
55 c.Append()
56 c.Append('#ifndef %s' % ifndef_name)
57 c.Append('#define %s' % ifndef_name)
58 c.Append()
59 c.Concat(body_code)
60 c.Append()
61 c.Append('#endif // %s' % ifndef_name)
62 c.Append()
63 return c
64
65 def _GetPlatformIfdefs(self, model_object):
66 """Generates the "defined" conditional for an #if check if |model_object|
67 has platform restrictions. Returns None if there are no restrictions.
68 """
69 if model_object.platforms is None:
70 return None
71 ifdefs = []
72 for platform in model_object.platforms:
73 if platform == Platforms.CHROMEOS:
74 ifdefs.append('defined(OS_CHROMEOS)')
75 else:
76 raise ValueError("Unsupported platform ifdef: %s" % platform.name)
77 return ' and '.join(ifdefs)
78
79 def GenerateAPIHeader(self):
80 """Generates the header for API registration / declaration"""
81 c = code.Code()
82
83 c.Append('#include <string>')
84 c.Append()
85 c.Append('#include "base/basictypes.h"')
86
87 for namespace in self._model.namespaces.values():
88 namespace_name = namespace.unix_name.replace("experimental_", "")
89 implementation_header = namespace.compiler_options.get(
90 "implemented_in",
91 "chrome/browser/extensions/api/%s/%s_api.h" % (namespace_name,
92 namespace_name))
93 if not os.path.exists(
94 os.path.join(self._root, os.path.normpath(implementation_header))):
95 if "implemented_in" in namespace.compiler_options:
96 raise ValueError('Header file for namespace "%s" specified in '
97 'compiler_options not found: %s' %
98 (namespace.unix_name, implementation_header))
99 continue
100 ifdefs = self._GetPlatformIfdefs(namespace)
101 if ifdefs is not None:
102 c.Append("#if %s" % ifdefs, indent_level=0)
103
104 c.Append('#include "%s"' % implementation_header)
105
106 if ifdefs is not None:
107 c.Append("#endif // %s" % ifdefs, indent_level=0)
108
109 c.Append()
110 c.Append("class ExtensionFunctionRegistry;")
111 c.Append()
112
113 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
114 for namespace in self._model.namespaces.values():
115 c.Append("// TODO(miket): emit code for %s" % (namespace.unix_name))
116 c.Append()
117 c.Concat(self.GenerateFunctionRegistry())
118 c.Concat(self._cpp_type_generator.GetRootNamespaceEnd())
119 c.Append()
120 return self.GenerateHeader('generated_api', c)
121
122 def _GetNamespaceFunctions(self, namespace):
123 functions = list(namespace.functions.values())
124 if namespace.compiler_options.get("generate_type_functions", False):
125 for type_ in namespace.types.values():
126 functions += list(type_.functions.values())
127 return functions
128
129 def GenerateFunctionRegistry(self):
130 c = code.Code()
131 c.Sblock("class GeneratedFunctionRegistry {")
132 c.Append(" public:")
133 c.Sblock("static void RegisterAll(ExtensionFunctionRegistry* registry) {")
134 for namespace in self._model.namespaces.values():
135 namespace_ifdefs = self._GetPlatformIfdefs(namespace)
136 if namespace_ifdefs is not None:
137 c.Append("#if %s" % namespace_ifdefs, indent_level=0)
138
139 namespace_name = CapitalizeFirstLetter(namespace.name.replace(
140 "experimental.", ""))
141 for function in self._GetNamespaceFunctions(namespace):
142 if function.nocompile:
143 continue
144 function_ifdefs = self._GetPlatformIfdefs(function)
145 if function_ifdefs is not None:
146 c.Append("#if %s" % function_ifdefs, indent_level=0)
147
148 function_name = JsFunctionNameToClassName(namespace.name, function.name)
149 c.Append("registry->RegisterFunction<%sFunction>();" % (
150 function_name))
151
152 if function_ifdefs is not None:
153 c.Append("#endif // %s" % function_ifdefs, indent_level=0)
154
155 if namespace_ifdefs is not None:
156 c.Append("#endif // %s" % namespace_ifdefs, indent_level=0)
157 c.Eblock("}")
158 c.Eblock("};")
159 c.Append()
160 return c
161
162 def GenerateSchemasHeader(self):
163 """Generates a code.Code object for the generated schemas .h file"""
164 c = code.Code()
165 c.Append('#include <map>')
166 c.Append('#include <string>')
167 c.Append();
168 c.Append('#include "base/string_piece.h"')
169 c.Append()
170 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
171 c.Append()
172 c.Sblock('class GeneratedSchemas {')
173 c.Append(' public:')
174 c.Append('// Puts all API schemas in |schemas|.')
175 c.Append('static void Get('
176 'std::map<std::string, base::StringPiece>* schemas);')
177 c.Eblock('};');
178 c.Append()
179 c.Concat(self._cpp_type_generator.GetRootNamespaceEnd())
180 c.Append()
181 return self.GenerateHeader('generated_schemas', c)
182
183 def GenerateSchemasCC(self):
184 """Generates a code.Code object for the generated schemas .cc file"""
185 c = code.Code()
186 c.Append(cpp_util.CHROMIUM_LICENSE)
187 c.Append()
188 c.Append('#include "%s"' % (os.path.join(SOURCE_BASE_PATH,
189 'generated_schemas.h')))
190 c.Append()
191 c.Concat(self._cpp_type_generator.GetRootNamespaceStart())
192 c.Append()
193 c.Append('// static')
194 c.Sblock('void GeneratedSchemas::Get('
195 'std::map<std::string, base::StringPiece>* schemas) {')
196 for api in self._api_defs:
197 namespace = self._model.namespaces[api.get('namespace')]
198 # JSON parsing code expects lists of schemas, so dump a singleton list.
199 json_content = json.dumps([_RemoveDescriptions(api)],
200 separators=(',', ':'))
201 # Escape all double-quotes and backslashes. For this to output a valid
202 # JSON C string, we need to escape \ and ".
203 json_content = json_content.replace('\\', '\\\\').replace('"', '\\"')
204 c.Append('(*schemas)["%s"] = "%s";' % (namespace.name, json_content))
205 c.Eblock('}')
206 c.Append()
207 c.Concat(self._cpp_type_generator.GetRootNamespaceEnd())
208 c.Append()
209 return c
OLDNEW
« no previous file with comments | « tools/json_schema_compiler/model.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698