337 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			337 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Protocol Buffers - Google's data interchange format
 | |
| // Copyright 2008 Google Inc.  All rights reserved.
 | |
| // https://developers.google.com/protocol-buffers/
 | |
| //
 | |
| // Redistribution and use in source and binary forms, with or without
 | |
| // modification, are permitted provided that the following conditions are
 | |
| // met:
 | |
| //
 | |
| //     * Redistributions of source code must retain the above copyright
 | |
| // notice, this list of conditions and the following disclaimer.
 | |
| //     * Redistributions in binary form must reproduce the above
 | |
| // copyright notice, this list of conditions and the following disclaimer
 | |
| // in the documentation and/or other materials provided with the
 | |
| // distribution.
 | |
| //     * Neither the name of Google Inc. nor the names of its
 | |
| // contributors may be used to endorse or promote products derived from
 | |
| // this software without specific prior written permission.
 | |
| //
 | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
| // Generates JavaScript code for a given .proto file.
 | |
| //
 | |
| #ifndef GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
 | |
| #define GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
 | |
| 
 | |
| #include <set>
 | |
| #include <string>
 | |
| 
 | |
| #include <google/protobuf/stubs/logging.h>
 | |
| #include <google/protobuf/stubs/common.h>
 | |
| #include <google/protobuf/compiler/scc.h>
 | |
| #include <google/protobuf/compiler/code_generator.h>
 | |
| 
 | |
| #include <google/protobuf/port_def.inc>
 | |
| 
 | |
| namespace google {
 | |
| namespace protobuf {
 | |
| 
 | |
| class Descriptor;
 | |
| class EnumDescriptor;
 | |
| class FieldDescriptor;
 | |
| class OneofDescriptor;
 | |
| class FileDescriptor;
 | |
| 
 | |
| namespace io {
 | |
| class Printer;
 | |
| }
 | |
| 
 | |
| namespace compiler {
 | |
| namespace js {
 | |
| 
 | |
| struct GeneratorOptions {
 | |
|   // Output path.
 | |
|   std::string output_dir;
 | |
|   // Namespace prefix.
 | |
|   std::string namespace_prefix;
 | |
|   // Enable binary-format support?
 | |
|   bool binary;
 | |
|   // What style of imports should be used.
 | |
|   enum ImportStyle {
 | |
|     kImportClosure,         // goog.require()
 | |
|     kImportCommonJs,        // require()
 | |
|     kImportCommonJsStrict,  // require() with no global export
 | |
|     kImportBrowser,         // no import statements
 | |
|     kImportEs6,             // import { member } from ''
 | |
|   } import_style;
 | |
| 
 | |
|   GeneratorOptions()
 | |
|       : output_dir("."),
 | |
|         namespace_prefix(""),
 | |
|         binary(false),
 | |
|         import_style(kImportClosure),
 | |
|         add_require_for_enums(false),
 | |
|         testonly(false),
 | |
|         library(""),
 | |
|         extension(".js"),
 | |
|         one_output_file_per_input_file(false),
 | |
|         annotate_code(false) {}
 | |
| 
 | |
|   bool ParseFromOptions(
 | |
|       const std::vector<std::pair<std::string, std::string> >& options,
 | |
|       std::string* error);
 | |
| 
 | |
|   // Returns the file name extension to use for generated code.
 | |
|   std::string GetFileNameExtension() const {
 | |
|     return import_style == kImportClosure ? extension : "_pb.js";
 | |
|   }
 | |
| 
 | |
|   enum OutputMode {
 | |
|     // Create an output file for each input .proto file.
 | |
|     kOneOutputFilePerInputFile,
 | |
|     // Create an output file for each type.
 | |
|     kOneOutputFilePerSCC,
 | |
|     // Put everything in a single file named by the library option.
 | |
|     kEverythingInOneFile,
 | |
|   };
 | |
| 
 | |
|   // Indicates how to output the generated code based on the provided options.
 | |
|   OutputMode output_mode() const;
 | |
| 
 | |
|   // The remaining options are only relevant when we are using kImportClosure.
 | |
| 
 | |
|   // Add a `goog.requires()` call for each enum type used. If not set, a
 | |
|   // forward declaration with `goog.forwardDeclare` is produced instead.
 | |
|   bool add_require_for_enums;
 | |
|   // Set this as a test-only module via `goog.setTestOnly();`.
 | |
|   bool testonly;
 | |
|   // Create a library with name <name>_lib.js rather than a separate .js file
 | |
|   // per type?
 | |
|   std::string library;
 | |
|   // The extension to use for output file names.
 | |
|   std::string extension;
 | |
|   // Create a separate output file for each input file?
 | |
|   bool one_output_file_per_input_file;
 | |
|   // If true, we should append annotations as comments on the last line for
 | |
|   // generated .js file. Annotations used by tools like https://kythe.io
 | |
|   // to provide cross-references between .js and .proto files. Annotations
 | |
|   // are encoded as base64 proto of GeneratedCodeInfo message (see
 | |
|   // descriptor.proto).
 | |
|   bool annotate_code;
 | |
| };
 | |
| 
 | |
| // CodeGenerator implementation which generates a JavaScript source file and
 | |
| // header.  If you create your own protocol compiler binary and you want it to
 | |
| // support JavaScript output, you can do so by registering an instance of this
 | |
| // CodeGenerator with the CommandLineInterface in your main() function.
 | |
| class PROTOC_EXPORT Generator : public CodeGenerator {
 | |
|  public:
 | |
|   Generator() {}
 | |
|   virtual ~Generator() {}
 | |
| 
 | |
|   bool Generate(const FileDescriptor* file, const std::string& parameter,
 | |
|                 GeneratorContext* context, std::string* error) const override {
 | |
|     *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   bool HasGenerateAll() const override { return true; }
 | |
| 
 | |
|   bool GenerateAll(const std::vector<const FileDescriptor*>& files,
 | |
|                    const std::string& parameter, GeneratorContext* context,
 | |
|                    std::string* error) const override;
 | |
| 
 | |
|   uint64 GetSupportedFeatures() const override {
 | |
|     return FEATURE_PROTO3_OPTIONAL;
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   void GenerateHeader(const GeneratorOptions& options,
 | |
|                       const FileDescriptor* file, io::Printer* printer) const;
 | |
| 
 | |
|   // Generate goog.provides() calls.
 | |
|   void FindProvides(const GeneratorOptions& options, io::Printer* printer,
 | |
|                     const std::vector<const FileDescriptor*>& file,
 | |
|                     std::set<std::string>* provided) const;
 | |
|   void FindProvidesForFile(const GeneratorOptions& options,
 | |
|                            io::Printer* printer, const FileDescriptor* file,
 | |
|                            std::set<std::string>* provided) const;
 | |
|   void FindProvidesForMessage(const GeneratorOptions& options,
 | |
|                               io::Printer* printer, const Descriptor* desc,
 | |
|                               std::set<std::string>* provided) const;
 | |
|   void FindProvidesForEnum(const GeneratorOptions& options,
 | |
|                            io::Printer* printer, const EnumDescriptor* enumdesc,
 | |
|                            std::set<std::string>* provided) const;
 | |
|   // For extension fields at file scope.
 | |
|   void FindProvidesForFields(const GeneratorOptions& options,
 | |
|                              io::Printer* printer,
 | |
|                              const std::vector<const FieldDescriptor*>& fields,
 | |
|                              std::set<std::string>* provided) const;
 | |
|   // Print the goog.provides() found by the methods above.
 | |
|   void GenerateProvides(const GeneratorOptions& options, io::Printer* printer,
 | |
|                         std::set<std::string>* provided) const;
 | |
| 
 | |
|   // Generate goog.setTestOnly() if indicated.
 | |
|   void GenerateTestOnly(const GeneratorOptions& options,
 | |
|                         io::Printer* printer) const;
 | |
| 
 | |
|   // Generate goog.requires() calls.
 | |
|   void GenerateRequiresForLibrary(
 | |
|       const GeneratorOptions& options, io::Printer* printer,
 | |
|       const std::vector<const FileDescriptor*>& files,
 | |
|       std::set<std::string>* provided) const;
 | |
|   void GenerateRequiresForSCC(const GeneratorOptions& options,
 | |
|                               io::Printer* printer, const SCC* scc,
 | |
|                               std::set<std::string>* provided) const;
 | |
|   // For extension fields at file scope.
 | |
|   void GenerateRequiresForExtensions(
 | |
|       const GeneratorOptions& options, io::Printer* printer,
 | |
|       const std::vector<const FieldDescriptor*>& fields,
 | |
|       std::set<std::string>* provided) const;
 | |
|   void GenerateRequiresImpl(const GeneratorOptions& options,
 | |
|                             io::Printer* printer,
 | |
|                             std::set<std::string>* required,
 | |
|                             std::set<std::string>* forwards,
 | |
|                             std::set<std::string>* provided, bool require_jspb,
 | |
|                             bool require_extension, bool require_map) const;
 | |
|   void FindRequiresForMessage(const GeneratorOptions& options,
 | |
|                               const Descriptor* desc,
 | |
|                               std::set<std::string>* required,
 | |
|                               std::set<std::string>* forwards,
 | |
|                               bool* have_message) const;
 | |
|   void FindRequiresForField(const GeneratorOptions& options,
 | |
|                             const FieldDescriptor* field,
 | |
|                             std::set<std::string>* required,
 | |
|                             std::set<std::string>* forwards) const;
 | |
|   void FindRequiresForExtension(const GeneratorOptions& options,
 | |
|                                 const FieldDescriptor* field,
 | |
|                                 std::set<std::string>* required,
 | |
|                                 std::set<std::string>* forwards) const;
 | |
|   // Generate all things in a proto file into one file.
 | |
|   // If use_short_name is true, the generated file's name will only be short
 | |
|   // name that without directory, otherwise filename equals file->name()
 | |
|   bool GenerateFile(const FileDescriptor* file, const GeneratorOptions& options,
 | |
|                     GeneratorContext* context, bool use_short_name) const;
 | |
|   void GenerateFile(const GeneratorOptions& options, io::Printer* printer,
 | |
|                     const FileDescriptor* file) const;
 | |
| 
 | |
|   // Generate definitions for all message classes and enums in all files,
 | |
|   // processing the files in dependence order.
 | |
|   void GenerateFilesInDepOrder(
 | |
|       const GeneratorOptions& options, io::Printer* printer,
 | |
|       const std::vector<const FileDescriptor*>& file) const;
 | |
|   // Helper for above.
 | |
|   void GenerateFileAndDeps(const GeneratorOptions& options,
 | |
|                            io::Printer* printer, const FileDescriptor* root,
 | |
|                            std::set<const FileDescriptor*>* all_files,
 | |
|                            std::set<const FileDescriptor*>* generated) const;
 | |
| 
 | |
|   // Generate definitions for all message classes and enums.
 | |
|   void GenerateClassesAndEnums(const GeneratorOptions& options,
 | |
|                                io::Printer* printer,
 | |
|                                const FileDescriptor* file) const;
 | |
| 
 | |
|   void GenerateFieldValueExpression(io::Printer* printer,
 | |
|                                     const char* obj_reference,
 | |
|                                     const FieldDescriptor* field,
 | |
|                                     bool use_default) const;
 | |
| 
 | |
|   // Generate definition for one class.
 | |
|   void GenerateClass(const GeneratorOptions& options, io::Printer* printer,
 | |
|                      const Descriptor* desc) const;
 | |
|   void GenerateClassConstructor(const GeneratorOptions& options,
 | |
|                                 io::Printer* printer,
 | |
|                                 const Descriptor* desc) const;
 | |
|   void GenerateClassFieldInfo(const GeneratorOptions& options,
 | |
|                               io::Printer* printer,
 | |
|                               const Descriptor* desc) const;
 | |
|   void GenerateClassConstructorAndDeclareExtensionFieldInfo(
 | |
|       const GeneratorOptions& options, io::Printer* printer,
 | |
|       const Descriptor* desc) const;
 | |
|   void GenerateClassXid(const GeneratorOptions& options, io::Printer* printer,
 | |
|                         const Descriptor* desc) const;
 | |
|   void GenerateOneofCaseDefinition(const GeneratorOptions& options,
 | |
|                                    io::Printer* printer,
 | |
|                                    const OneofDescriptor* oneof) const;
 | |
|   void GenerateObjectTypedef(const GeneratorOptions& options,
 | |
|                              io::Printer* printer,
 | |
|                              const Descriptor* desc) const;
 | |
|   void GenerateClassToObject(const GeneratorOptions& options,
 | |
|                              io::Printer* printer,
 | |
|                              const Descriptor* desc) const;
 | |
|   void GenerateClassFieldToObject(const GeneratorOptions& options,
 | |
|                                   io::Printer* printer,
 | |
|                                   const FieldDescriptor* field) const;
 | |
|   void GenerateClassFromObject(const GeneratorOptions& options,
 | |
|                                io::Printer* printer,
 | |
|                                const Descriptor* desc) const;
 | |
|   void GenerateClassFieldFromObject(const GeneratorOptions& options,
 | |
|                                     io::Printer* printer,
 | |
|                                     const FieldDescriptor* field) const;
 | |
|   void GenerateClassRegistration(const GeneratorOptions& options,
 | |
|                                  io::Printer* printer,
 | |
|                                  const Descriptor* desc) const;
 | |
|   void GenerateClassFields(const GeneratorOptions& options,
 | |
|                            io::Printer* printer, const Descriptor* desc) const;
 | |
|   void GenerateClassField(const GeneratorOptions& options, io::Printer* printer,
 | |
|                           const FieldDescriptor* desc) const;
 | |
|   void GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
 | |
|                                        io::Printer* printer,
 | |
|                                        const Descriptor* desc) const;
 | |
|   void GenerateClassDeserialize(const GeneratorOptions& options,
 | |
|                                 io::Printer* printer,
 | |
|                                 const Descriptor* desc) const;
 | |
|   void GenerateClassDeserializeBinary(const GeneratorOptions& options,
 | |
|                                       io::Printer* printer,
 | |
|                                       const Descriptor* desc) const;
 | |
|   void GenerateClassDeserializeBinaryField(const GeneratorOptions& options,
 | |
|                                            io::Printer* printer,
 | |
|                                            const FieldDescriptor* field) const;
 | |
|   void GenerateClassSerializeBinary(const GeneratorOptions& options,
 | |
|                                     io::Printer* printer,
 | |
|                                     const Descriptor* desc) const;
 | |
|   void GenerateClassSerializeBinaryField(const GeneratorOptions& options,
 | |
|                                          io::Printer* printer,
 | |
|                                          const FieldDescriptor* field) const;
 | |
| 
 | |
|   // Generate definition for one enum.
 | |
|   void GenerateEnum(const GeneratorOptions& options, io::Printer* printer,
 | |
|                     const EnumDescriptor* enumdesc) const;
 | |
| 
 | |
|   // Generate an extension definition.
 | |
|   void GenerateExtension(const GeneratorOptions& options, io::Printer* printer,
 | |
|                          const FieldDescriptor* field) const;
 | |
| 
 | |
|   // Generate addFoo() method for repeated primitive fields.
 | |
|   void GenerateRepeatedPrimitiveHelperMethods(const GeneratorOptions& options,
 | |
|                                               io::Printer* printer,
 | |
|                                               const FieldDescriptor* field,
 | |
|                                               bool untyped) const;
 | |
| 
 | |
|   // Generate addFoo() method for repeated message fields.
 | |
|   void GenerateRepeatedMessageHelperMethods(const GeneratorOptions& options,
 | |
|                                             io::Printer* printer,
 | |
|                                             const FieldDescriptor* field) const;
 | |
| 
 | |
|   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
 | |
| };
 | |
| 
 | |
| }  // namespace js
 | |
| }  // namespace compiler
 | |
| }  // namespace protobuf
 | |
| }  // namespace google
 | |
| 
 | |
| #include <google/protobuf/port_undef.inc>
 | |
| 
 | |
| #endif  // GOOGLE_PROTOBUF_COMPILER_JS_GENERATOR_H__
 |