• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
32 #define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
33 
34 #include <string>
35 #include <set>
36 
37 #include <google/protobuf/compiler/code_generator.h>
38 
39 namespace google {
40 namespace protobuf {
41 
42 class Descriptor;
43 class EnumDescriptor;
44 class FieldDescriptor;
45 class OneofDescriptor;
46 class FileDescriptor;
47 
48 namespace io { class Printer; }
49 
50 namespace compiler {
51 namespace js {
52 
53 struct GeneratorOptions {
54   // Add a `goog.requires()` call for each enum type used. If not set, a forward
55   // declaration with `goog.forwardDeclare` is produced instead.
56   bool add_require_for_enums;
57   // Set this as a test-only module via `goog.setTestOnly();`.
58   bool testonly;
59   // Output path.
60   string output_dir;
61   // Namespace prefix.
62   string namespace_prefix;
63   // Create a library with name <name>_lib.js rather than a separate .js file
64   // per type?
65   string library;
66   // Error if there are two types that would generate the same output file?
67   bool error_on_name_conflict;
68   // Enable binary-format support?
69   bool binary;
70   // What style of imports should be used.
71   enum ImportStyle {
72     IMPORT_CLOSURE,    // goog.require()
73     IMPORT_COMMONJS,   // require()
74     IMPORT_BROWSER,    // no import statements
75     IMPORT_ES6,        // import { member } from ''
76   } import_style;
77 
GeneratorOptionsGeneratorOptions78   GeneratorOptions()
79       : add_require_for_enums(false),
80         testonly(false),
81         output_dir("."),
82         namespace_prefix(""),
83         library(""),
84         error_on_name_conflict(false),
85         binary(false),
86         import_style(IMPORT_CLOSURE) {}
87 
88   bool ParseFromOptions(
89       const vector< pair< string, string > >& options,
90       string* error);
91 };
92 
93 class LIBPROTOC_EXPORT Generator : public CodeGenerator {
94  public:
Generator()95   Generator() {}
~Generator()96   virtual ~Generator() {}
97 
Generate(const FileDescriptor * file,const string & parameter,GeneratorContext * context,string * error)98   virtual bool Generate(const FileDescriptor* file,
99                         const string& parameter,
100                         GeneratorContext* context,
101                         string* error) const {
102     *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
103     return false;
104   }
105 
HasGenerateAll()106   virtual bool HasGenerateAll() const { return true; }
107 
108   virtual bool GenerateAll(const vector<const FileDescriptor*>& files,
109                            const string& parameter,
110                            GeneratorContext* context,
111                            string* error) const;
112 
113  private:
114   void GenerateHeader(const GeneratorOptions& options,
115                       io::Printer* printer) const;
116 
117   // Generate goog.provides() calls.
118   void FindProvides(const GeneratorOptions& options,
119                     io::Printer* printer,
120                     const vector<const FileDescriptor*>& file,
121                     std::set<string>* provided) const;
122   void FindProvidesForFile(const GeneratorOptions& options,
123                            io::Printer* printer,
124                            const FileDescriptor* file,
125                            std::set<string>* provided) const;
126   void FindProvidesForMessage(const GeneratorOptions& options,
127                               io::Printer* printer,
128                               const Descriptor* desc,
129                               std::set<string>* provided) const;
130   void FindProvidesForEnum(const GeneratorOptions& options,
131                            io::Printer* printer,
132                            const EnumDescriptor* enumdesc,
133                            std::set<string>* provided) const;
134   // For extension fields at file scope.
135   void FindProvidesForFields(const GeneratorOptions& options,
136                              io::Printer* printer,
137                              const vector<const FieldDescriptor*>& fields,
138                              std::set<string>* provided) const;
139   // Print the goog.provides() found by the methods above.
140   void GenerateProvides(const GeneratorOptions& options,
141                         io::Printer* printer,
142                         std::set<string>* provided) const;
143 
144   // Generate goog.setTestOnly() if indicated.
145   void GenerateTestOnly(const GeneratorOptions& options,
146                         io::Printer* printer) const;
147 
148   // Generate goog.requires() calls.
149   void GenerateRequiresForLibrary(const GeneratorOptions& options,
150                                   io::Printer* printer,
151                                   const vector<const FileDescriptor*>& files,
152                                   std::set<string>* provided) const;
153   void GenerateRequiresForMessage(const GeneratorOptions& options,
154                         io::Printer* printer,
155                         const Descriptor* desc,
156                         std::set<string>* provided) const;
157   // For extension fields at file scope.
158   void GenerateRequiresForExtensions(
159       const GeneratorOptions& options, io::Printer* printer,
160       const vector<const FieldDescriptor*>& fields,
161       std::set<string>* provided) const;
162   void GenerateRequiresImpl(const GeneratorOptions& options,
163                             io::Printer* printer,
164                             std::set<string>* required,
165                             std::set<string>* forwards,
166                             std::set<string>* provided,
167                             bool require_jspb,
168                             bool require_extension) const;
169   void FindRequiresForMessage(const GeneratorOptions& options,
170                               const Descriptor* desc,
171                               std::set<string>* required,
172                               std::set<string>* forwards,
173                               bool* have_message) const;
174   void FindRequiresForField(const GeneratorOptions& options,
175                             const FieldDescriptor* field,
176                             std::set<string>* required,
177                             std::set<string>* forwards) const;
178   void FindRequiresForExtension(const GeneratorOptions& options,
179                                 const FieldDescriptor* field,
180                                 std::set<string>* required,
181                                 std::set<string>* forwards) const;
182 
183   void GenerateFile(const GeneratorOptions& options,
184                     io::Printer* printer,
185                     const FileDescriptor* file) const;
186 
187   // Generate definitions for all message classes and enums in all files,
188   // processing the files in dependence order.
189   void GenerateFilesInDepOrder(const GeneratorOptions& options,
190                                io::Printer* printer,
191                                const vector<const FileDescriptor*>& file) const;
192   // Helper for above.
193   void GenerateFileAndDeps(const GeneratorOptions& options,
194                            io::Printer* printer,
195                            const FileDescriptor* root,
196                            std::set<const FileDescriptor*>* all_files,
197                            std::set<const FileDescriptor*>* generated) const;
198 
199   // Generate definitions for all message classes and enums.
200   void GenerateClassesAndEnums(const GeneratorOptions& options,
201                                io::Printer* printer,
202                                const FileDescriptor* file) const;
203 
204   // Generate definition for one class.
205   void GenerateClass(const GeneratorOptions& options,
206                      io::Printer* printer,
207                      const Descriptor* desc) const;
208   void GenerateClassConstructor(const GeneratorOptions& options,
209                                 io::Printer* printer,
210                                 const Descriptor* desc) const;
211   void GenerateClassFieldInfo(const GeneratorOptions& options,
212                               io::Printer* printer,
213                               const Descriptor* desc) const;
214   void GenerateClassXid(const GeneratorOptions& options,
215                         io::Printer* printer,
216                         const Descriptor* desc) const;
217   void GenerateOneofCaseDefinition(const GeneratorOptions& options,
218                                    io::Printer* printer,
219                                    const OneofDescriptor* oneof) const;
220   void GenerateClassToObject(const GeneratorOptions& options,
221                              io::Printer* printer,
222                              const Descriptor* desc) const;
223   void GenerateClassFieldToObject(const GeneratorOptions& options,
224                                   io::Printer* printer,
225                                   const FieldDescriptor* field) const;
226   void GenerateClassFromObject(const GeneratorOptions& options,
227                                io::Printer* printer,
228                                const Descriptor* desc) const;
229   void GenerateClassFieldFromObject(const GeneratorOptions& options,
230                                     io::Printer* printer,
231                                     const FieldDescriptor* field) const;
232   void GenerateClassClone(const GeneratorOptions& options,
233                           io::Printer* printer,
234                           const Descriptor* desc) const;
235   void GenerateClassRegistration(const GeneratorOptions& options,
236                                  io::Printer* printer,
237                                  const Descriptor* desc) const;
238   void GenerateClassFields(const GeneratorOptions& options,
239                            io::Printer* printer,
240                            const Descriptor* desc) const;
241   void GenerateClassField(const GeneratorOptions& options,
242                           io::Printer* printer,
243                           const FieldDescriptor* desc) const;
244   void GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
245                                        io::Printer* printer,
246                                        const Descriptor* desc) const;
247   void GenerateClassDeserialize(const GeneratorOptions& options,
248                                 io::Printer* printer,
249                                 const Descriptor* desc) const;
250   void GenerateClassDeserializeBinary(const GeneratorOptions& options,
251                                       io::Printer* printer,
252                                       const Descriptor* desc) const;
253   void GenerateClassDeserializeBinaryField(const GeneratorOptions& options,
254                                            io::Printer* printer,
255                                            const FieldDescriptor* field) const;
256   void GenerateClassSerializeBinary(const GeneratorOptions& options,
257                                     io::Printer* printer,
258                                     const Descriptor* desc) const;
259   void GenerateClassSerializeBinaryField(const GeneratorOptions& options,
260                                          io::Printer* printer,
261                                          const FieldDescriptor* field) const;
262 
263   // Generate definition for one enum.
264   void GenerateEnum(const GeneratorOptions& options,
265                     io::Printer* printer,
266                     const EnumDescriptor* enumdesc) const;
267 
268   // Generate an extension definition.
269   void GenerateExtension(const GeneratorOptions& options,
270                          io::Printer* printer,
271                          const FieldDescriptor* field) const;
272 
273   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
274 };
275 
276 }  // namespace js
277 }  // namespace compiler
278 }  // namespace protobuf
279 
280 }  // namespace google
281 #endif  // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
282