add external dependencies in a pre-built way to avoid incompatibilities

This commit is contained in:
Sven Czarnian
2021-08-09 22:07:00 +02:00
parent 5f702016ad
commit 4cde0f9baf
197 changed files with 74244 additions and 0 deletions

View File

@@ -0,0 +1,205 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Defines the abstract interface implemented by each of the language-specific
// code generators.
#ifndef GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
#include <string>
#include <utility>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
class ZeroCopyOutputStream;
}
class FileDescriptor;
class GeneratedCodeInfo;
namespace compiler {
class AccessInfoMap;
class Version;
// Defined in this file.
class CodeGenerator;
class GeneratorContext;
// The abstract interface to a class which generates code implementing a
// particular proto file in a particular language. A number of these may
// be registered with CommandLineInterface to support various languages.
class PROTOC_EXPORT CodeGenerator {
public:
inline CodeGenerator() {}
virtual ~CodeGenerator();
// Generates code for the given proto file, generating one or more files in
// the given output directory.
//
// A parameter to be passed to the generator can be specified on the command
// line. This is intended to be used to pass generator specific parameters.
// It is empty if no parameter was given. ParseGeneratorParameter (below),
// can be used to accept multiple parameters within the single parameter
// command line flag.
//
// Returns true if successful. Otherwise, sets *error to a description of
// the problem (e.g. "invalid parameter") and returns false.
virtual bool Generate(const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const = 0;
// Generates code for all given proto files.
//
// WARNING: The canonical code generator design produces one or two output
// files per input .proto file, and we do not wish to encourage alternate
// designs.
//
// A parameter is given as passed on the command line, as in |Generate()|
// above.
//
// Returns true if successful. Otherwise, sets *error to a description of
// the problem (e.g. "invalid parameter") and returns false.
virtual bool GenerateAll(const std::vector<const FileDescriptor*>& files,
const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const;
// Sync with plugin.proto.
enum Feature {
FEATURE_PROTO3_OPTIONAL = 1,
};
// Implement this to indicate what features this code generator supports.
// This should be a bitwise OR of features from the Features enum in
// plugin.proto.
virtual uint64_t GetSupportedFeatures() const { return 0; }
// This is no longer used, but this class is part of the opensource protobuf
// library, so it has to remain to keep vtables the same for the current
// version of the library. When protobufs does a api breaking change, the
// method can be removed.
virtual bool HasGenerateAll() const { return true; }
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator);
};
// CodeGenerators generate one or more files in a given directory. This
// abstract interface represents the directory to which the CodeGenerator is
// to write and other information about the context in which the Generator
// runs.
class PROTOC_EXPORT GeneratorContext {
public:
inline GeneratorContext() {
}
virtual ~GeneratorContext();
// Opens the given file, truncating it if it exists, and returns a
// ZeroCopyOutputStream that writes to the file. The caller takes ownership
// of the returned object. This method never fails (a dummy stream will be
// returned instead).
//
// The filename given should be relative to the root of the source tree.
// E.g. the C++ generator, when generating code for "foo/bar.proto", will
// generate the files "foo/bar.pb.h" and "foo/bar.pb.cc"; note that
// "foo/" is included in these filenames. The filename is not allowed to
// contain "." or ".." components.
virtual io::ZeroCopyOutputStream* Open(const std::string& filename) = 0;
// Similar to Open() but the output will be appended to the file if exists
virtual io::ZeroCopyOutputStream* OpenForAppend(const std::string& filename);
// Creates a ZeroCopyOutputStream which will insert code into the given file
// at the given insertion point. See plugin.proto (plugin.pb.h) for more
// information on insertion points. The default implementation
// assert-fails -- it exists only for backwards-compatibility.
//
// WARNING: This feature is currently EXPERIMENTAL and is subject to change.
virtual io::ZeroCopyOutputStream* OpenForInsert(
const std::string& filename, const std::string& insertion_point);
// Similar to OpenForInsert, but if `info` is non-empty, will open (or create)
// filename.pb.meta and insert info at the appropriate place with the
// necessary shifts. The default implementation ignores `info`.
//
// WARNING: This feature will be REMOVED in the near future.
virtual io::ZeroCopyOutputStream* OpenForInsertWithGeneratedCodeInfo(
const std::string& filename, const std::string& insertion_point,
const google::protobuf::GeneratedCodeInfo& info);
// Returns a vector of FileDescriptors for all the files being compiled
// in this run. Useful for languages, such as Go, that treat files
// differently when compiled as a set rather than individually.
virtual void ListParsedFiles(std::vector<const FileDescriptor*>* output);
// Retrieves the version number of the protocol compiler associated with
// this GeneratorContext.
virtual void GetCompilerVersion(Version* version) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
};
// The type GeneratorContext was once called OutputDirectory. This typedef
// provides backward compatibility.
typedef GeneratorContext OutputDirectory;
// Several code generators treat the parameter argument as holding a
// list of options separated by commas. This helper function parses
// a set of comma-delimited name/value pairs: e.g.,
// "foo=bar,baz,qux=corge"
// parses to the pairs:
// ("foo", "bar"), ("baz", ""), ("qux", "corge")
PROTOC_EXPORT void ParseGeneratorParameter(
const std::string&, std::vector<std::pair<std::string, std::string> >*);
// Strips ".proto" or ".protodevel" from the end of a filename.
PROTOC_EXPORT std::string StripProto(const std::string& filename);
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__

View File

@@ -0,0 +1,462 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Implements the Protocol Compiler front-end such that it may be reused by
// custom compilers written to support other languages.
#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
#include <cstdint>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Descriptor; // descriptor.h
class DescriptorDatabase; // descriptor_database.h
class DescriptorPool; // descriptor.h
class FileDescriptor; // descriptor.h
class FileDescriptorSet; // descriptor.h
class FileDescriptorProto; // descriptor.pb.h
template <typename T>
class RepeatedPtrField; // repeated_field.h
class SimpleDescriptorDatabase; // descriptor_database.h
namespace compiler {
class CodeGenerator; // code_generator.h
class GeneratorContext; // code_generator.h
class DiskSourceTree; // importer.h
// This class implements the command-line interface to the protocol compiler.
// It is designed to make it very easy to create a custom protocol compiler
// supporting the languages of your choice. For example, if you wanted to
// create a custom protocol compiler binary which includes both the regular
// C++ support plus support for your own custom output "Foo", you would
// write a class "FooGenerator" which implements the CodeGenerator interface,
// then write a main() procedure like this:
//
// int main(int argc, char* argv[]) {
// google::protobuf::compiler::CommandLineInterface cli;
//
// // Support generation of C++ source and headers.
// google::protobuf::compiler::cpp::CppGenerator cpp_generator;
// cli.RegisterGenerator("--cpp_out", &cpp_generator,
// "Generate C++ source and header.");
//
// // Support generation of Foo code.
// FooGenerator foo_generator;
// cli.RegisterGenerator("--foo_out", &foo_generator,
// "Generate Foo file.");
//
// return cli.Run(argc, argv);
// }
//
// The compiler is invoked with syntax like:
// protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto
//
// The .proto file to compile can be specified on the command line using either
// its physical file path, or a virtual path relative to a directory specified
// in --proto_path. For example, for src/foo.proto, the following two protoc
// invocations work the same way:
// 1. protoc --proto_path=src src/foo.proto (physical file path)
// 2. protoc --proto_path=src foo.proto (virtual path relative to src)
//
// If a file path can be interpreted both as a physical file path and as a
// relative virtual path, the physical file path takes precedence.
//
// For a full description of the command-line syntax, invoke it with --help.
class PROTOC_EXPORT CommandLineInterface {
public:
static const char* const kPathSeparator;
CommandLineInterface();
~CommandLineInterface();
// Register a code generator for a language.
//
// Parameters:
// * flag_name: The command-line flag used to specify an output file of
// this type. The name must start with a '-'. If the name is longer
// than one letter, it must start with two '-'s.
// * generator: The CodeGenerator which will be called to generate files
// of this type.
// * help_text: Text describing this flag in the --help output.
//
// Some generators accept extra parameters. You can specify this parameter
// on the command-line by placing it before the output directory, separated
// by a colon:
// protoc --foo_out=enable_bar:outdir
// The text before the colon is passed to CodeGenerator::Generate() as the
// "parameter".
void RegisterGenerator(const std::string& flag_name, CodeGenerator* generator,
const std::string& help_text);
// Register a code generator for a language.
// Besides flag_name you can specify another option_flag_name that could be
// used to pass extra parameters to the registered code generator.
// Suppose you have registered a generator by calling:
// command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
// Then you could invoke the compiler with a command like:
// protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
// This will pass "enable_bar,enable_baz" as the parameter to the generator.
void RegisterGenerator(const std::string& flag_name,
const std::string& option_flag_name,
CodeGenerator* generator,
const std::string& help_text);
// Enables "plugins". In this mode, if a command-line flag ends with "_out"
// but does not match any registered generator, the compiler will attempt to
// find a "plugin" to implement the generator. Plugins are just executables.
// They should live somewhere in the PATH.
//
// The compiler determines the executable name to search for by concatenating
// exe_name_prefix with the unrecognized flag name, removing "_out". So, for
// example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out,
// the compiler will try to run the program "protoc-gen-foo".
//
// The plugin program should implement the following usage:
// plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
// --out indicates the output directory (as passed to the --foo_out
// parameter); if omitted, the current directory should be used. --parameter
// gives the generator parameter, if any was provided (see below). The
// PROTO_FILES list the .proto files which were given on the compiler
// command-line; these are the files for which the plugin is expected to
// generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet
// (as defined in descriptor.proto). This is piped to the plugin's stdin.
// The set will include descriptors for all the files listed in PROTO_FILES as
// well as all files that they import. The plugin MUST NOT attempt to read
// the PROTO_FILES directly -- it must use the FileDescriptorSet.
//
// The plugin should generate whatever files are necessary, as code generators
// normally do. It should write the names of all files it generates to
// stdout. The names should be relative to the output directory, NOT absolute
// names or relative to the current directory. If any errors occur, error
// messages should be written to stderr. If an error is fatal, the plugin
// should exit with a non-zero exit code.
//
// Plugins can have generator parameters similar to normal built-in
// generators. Extra generator parameters can be passed in via a matching
// "_opt" parameter. For example:
// protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz
// This will pass "enable_bar,enable_baz" as the parameter to the plugin.
//
void AllowPlugins(const std::string& exe_name_prefix);
// Run the Protocol Compiler with the given command-line parameters.
// Returns the error code which should be returned by main().
//
// It may not be safe to call Run() in a multi-threaded environment because
// it calls strerror(). I'm not sure why you'd want to do this anyway.
int Run(int argc, const char* const argv[]);
// DEPRECATED. Calling this method has no effect. Protocol compiler now
// always try to find the .proto file relative to the current directory
// first and if the file is not found, it will then treat the input path
// as a virtual path.
void SetInputsAreProtoPathRelative(bool /* enable */) {}
// Provides some text which will be printed when the --version flag is
// used. The version of libprotoc will also be printed on the next line
// after this text.
void SetVersionInfo(const std::string& text) { version_info_ = text; }
private:
// -----------------------------------------------------------------
class ErrorPrinter;
class GeneratorContextImpl;
class MemoryOutputStream;
typedef std::unordered_map<std::string, std::unique_ptr<GeneratorContextImpl>>
GeneratorContextMap;
// Clear state from previous Run().
void Clear();
// Remaps the proto file so that it is relative to one of the directories
// in proto_path_. Returns false if an error occurred.
bool MakeProtoProtoPathRelative(DiskSourceTree* source_tree,
std::string* proto,
DescriptorDatabase* fallback_database);
// Remaps each file in input_files_ so that it is relative to one of the
// directories in proto_path_. Returns false if an error occurred.
bool MakeInputsBeProtoPathRelative(DiskSourceTree* source_tree,
DescriptorDatabase* fallback_database);
// Fails if these files use proto3 optional and the code generator doesn't
// support it. This is a permanent check.
bool EnforceProto3OptionalSupport(
const std::string& codegen_name, uint64_t supported_features,
const std::vector<const FileDescriptor*>& parsed_files) const;
// Return status for ParseArguments() and InterpretArgument().
enum ParseArgumentStatus {
PARSE_ARGUMENT_DONE_AND_CONTINUE,
PARSE_ARGUMENT_DONE_AND_EXIT,
PARSE_ARGUMENT_FAIL
};
// Parse all command-line arguments.
ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
// Read an argument file and append the file's content to the list of
// arguments. Return false if the file cannot be read.
bool ExpandArgumentFile(const std::string& file,
std::vector<std::string>* arguments);
// Parses a command-line argument into a name/value pair. Returns
// true if the next argument in the argv should be used as the value,
// false otherwise.
//
// Examples:
// "-Isrc/protos" ->
// name = "-I", value = "src/protos"
// "--cpp_out=src/foo.pb2.cc" ->
// name = "--cpp_out", value = "src/foo.pb2.cc"
// "foo.proto" ->
// name = "", value = "foo.proto"
bool ParseArgument(const char* arg, std::string* name, std::string* value);
// Interprets arguments parsed with ParseArgument.
ParseArgumentStatus InterpretArgument(const std::string& name,
const std::string& value);
// Print the --help text to stderr.
void PrintHelpText();
// Loads proto_path_ into the provided source_tree.
bool InitializeDiskSourceTree(DiskSourceTree* source_tree,
DescriptorDatabase* fallback_database);
// Verify that all the input files exist in the given database.
bool VerifyInputFilesInDescriptors(DescriptorDatabase* fallback_database);
// Parses input_files_ into parsed_files
bool ParseInputFiles(DescriptorPool* descriptor_pool,
DiskSourceTree* source_tree,
std::vector<const FileDescriptor*>* parsed_files);
// Generate the given output file from the given input.
struct OutputDirective; // see below
bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files,
const OutputDirective& output_directive,
GeneratorContext* generator_context);
bool GeneratePluginOutput(
const std::vector<const FileDescriptor*>& parsed_files,
const std::string& plugin_name, const std::string& parameter,
GeneratorContext* generator_context, std::string* error);
// Implements --encode and --decode.
bool EncodeOrDecode(const DescriptorPool* pool);
// Implements the --descriptor_set_out option.
bool WriteDescriptorSet(
const std::vector<const FileDescriptor*>& parsed_files);
// Implements the --dependency_out option
bool GenerateDependencyManifestFile(
const std::vector<const FileDescriptor*>& parsed_files,
const GeneratorContextMap& output_directories,
DiskSourceTree* source_tree);
// Get all transitive dependencies of the given file (including the file
// itself), adding them to the given list of FileDescriptorProtos. The
// protos will be ordered such that every file is listed before any file that
// depends on it, so that you can call DescriptorPool::BuildFile() on them
// in order. Any files in *already_seen will not be added, and each file
// added will be inserted into *already_seen. If include_source_code_info is
// true then include the source code information in the FileDescriptorProtos.
// If include_json_name is true, populate the json_name field of
// FieldDescriptorProto for all fields.
static void GetTransitiveDependencies(
const FileDescriptor* file, bool include_json_name,
bool include_source_code_info,
std::set<const FileDescriptor*>* already_seen,
RepeatedPtrField<FileDescriptorProto>* output);
// Implements the --print_free_field_numbers. This function prints free field
// numbers into stdout for the message and it's nested message types in
// post-order, i.e. nested types first. Printed range are left-right
// inclusive, i.e. [a, b].
//
// Groups:
// For historical reasons, groups are considered to share the same
// field number space with the parent message, thus it will not print free
// field numbers for groups. The field numbers used in the groups are
// excluded in the free field numbers of the parent message.
//
// Extension Ranges:
// Extension ranges are considered ocuppied field numbers and they will not be
// listed as free numbers in the output.
void PrintFreeFieldNumbers(const Descriptor* descriptor);
// -----------------------------------------------------------------
// The name of the executable as invoked (i.e. argv[0]).
std::string executable_name_;
// Version info set with SetVersionInfo().
std::string version_info_;
// Registered generators.
struct GeneratorInfo {
std::string flag_name;
std::string option_flag_name;
CodeGenerator* generator;
std::string help_text;
};
typedef std::map<std::string, GeneratorInfo> GeneratorMap;
GeneratorMap generators_by_flag_name_;
GeneratorMap generators_by_option_name_;
// A map from generator names to the parameters specified using the option
// flag. For example, if the user invokes the compiler with:
// protoc --foo_out=outputdir --foo_opt=enable_bar ...
// Then there will be an entry ("--foo_out", "enable_bar") in this map.
std::map<std::string, std::string> generator_parameters_;
// Similar to generator_parameters_, but stores the parameters for plugins.
std::map<std::string, std::string> plugin_parameters_;
// See AllowPlugins(). If this is empty, plugins aren't allowed.
std::string plugin_prefix_;
// Maps specific plugin names to files. When executing a plugin, this map
// is searched first to find the plugin executable. If not found here, the
// PATH (or other OS-specific search strategy) is searched.
std::map<std::string, std::string> plugins_;
// Stuff parsed from command line.
enum Mode {
MODE_COMPILE, // Normal mode: parse .proto files and compile them.
MODE_ENCODE, // --encode: read text from stdin, write binary to stdout.
MODE_DECODE, // --decode: read binary from stdin, write text to stdout.
MODE_PRINT, // Print mode: print info of the given .proto files and exit.
};
Mode mode_ = MODE_COMPILE;
enum PrintMode {
PRINT_NONE, // Not in MODE_PRINT
PRINT_FREE_FIELDS, // --print_free_fields
};
PrintMode print_mode_ = PRINT_NONE;
enum ErrorFormat {
ERROR_FORMAT_GCC, // GCC error output format (default).
ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
};
ErrorFormat error_format_ = ERROR_FORMAT_GCC;
// True if we should treat warnings as errors that fail the compilation.
bool fatal_warnings_ = false;
std::vector<std::pair<std::string, std::string> >
proto_path_; // Search path for proto files.
std::vector<std::string> input_files_; // Names of the input proto files.
// Names of proto files which are allowed to be imported. Used by build
// systems to enforce depend-on-what-you-import.
std::set<std::string> direct_dependencies_;
bool direct_dependencies_explicitly_set_ = false;
// If there's a violation of depend-on-what-you-import, this string will be
// presented to the user. "%s" will be replaced with the violating import.
std::string direct_dependencies_violation_msg_;
// output_directives_ lists all the files we are supposed to output and what
// generator to use for each.
struct OutputDirective {
std::string name; // E.g. "--foo_out"
CodeGenerator* generator; // NULL for plugins
std::string parameter;
std::string output_location;
};
std::vector<OutputDirective> output_directives_;
// When using --encode or --decode, this names the type we are encoding or
// decoding. (Empty string indicates --decode_raw.)
std::string codec_type_;
// If --descriptor_set_in was given, these are filenames containing
// parsed FileDescriptorSets to be used for loading protos. Otherwise, empty.
std::vector<std::string> descriptor_set_in_names_;
// If --descriptor_set_out was given, this is the filename to which the
// FileDescriptorSet should be written. Otherwise, empty.
std::string descriptor_set_out_name_;
// If --dependency_out was given, this is the path to the file where the
// dependency file will be written. Otherwise, empty.
std::string dependency_out_name_;
// True if --include_imports was given, meaning that we should
// write all transitive dependencies to the DescriptorSet. Otherwise, only
// the .proto files listed on the command-line are added.
bool imports_in_descriptor_set_;
// True if --include_source_info was given, meaning that we should not strip
// SourceCodeInfo from the DescriptorSet.
bool source_info_in_descriptor_set_ = false;
// Was the --disallow_services flag used?
bool disallow_services_ = false;
// When using --encode, this will be passed to SetSerializationDeterministic.
bool deterministic_output_ = false;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
};
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__

View File

@@ -0,0 +1,106 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Generates C++ code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace cpp {
// CodeGenerator implementation which generates a C++ source file and
// header. If you create your own protocol compiler binary and you want
// it to support C++ output, you can do so by registering an instance of this
// CodeGenerator with the CommandLineInterface in your main() function.
class PROTOC_EXPORT CppGenerator : public CodeGenerator {
public:
CppGenerator();
~CppGenerator();
enum class Runtime {
kGoogle3, // Use the internal google3 runtime.
kOpensource, // Use the open-source runtime.
// Use the open-source runtime with google3 #include paths. We make these
// absolute to avoid ambiguity, so the runtime will be #included like:
// #include "third_party/protobuf/.../google/protobuf/message.h"
kOpensourceGoogle3
};
void set_opensource_runtime(bool opensource) {
opensource_runtime_ = opensource;
}
// If set to a non-empty string, generated code will do:
// #include "<BASE>/google/protobuf/message.h"
// instead of:
// #include <google/protobuf/message.h>
// This has no effect if opensource_runtime = false.
void set_runtime_include_base(const std::string& base) {
runtime_include_base_ = base;
}
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override {
// We don't fully support this yet, but this is needed to unblock the tests,
// and we will have full support before the experimental flag is removed.
return FEATURE_PROTO3_OPTIONAL;
}
private:
bool opensource_runtime_ = true;
std::string runtime_include_base_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
};
} // namespace cpp
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__

View File

@@ -0,0 +1,70 @@
// 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 C# code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
// CodeGenerator implementation which generates a C# source file and
// header. If you create your own protocol compiler binary and you want
// it to support C# 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();
~Generator();
bool Generate(
const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override;
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__

View File

@@ -0,0 +1,109 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Provides a mechanism for mapping a descriptor to the
// fully-qualified name of the corresponding C# class.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__
#include <string>
#include <google/protobuf/port.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Descriptor;
class EnumDescriptor;
class FileDescriptor;
class ServiceDescriptor;
namespace compiler {
namespace csharp {
// Requires:
// descriptor != NULL
//
// Returns:
// The namespace to use for given file descriptor.
std::string PROTOC_EXPORT GetFileNamespace(const FileDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified C# class name.
std::string PROTOC_EXPORT GetClassName(const Descriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified name of the C# class that provides
// access to the file descriptor. Proto compiler generates
// such class for each .proto file processed.
std::string PROTOC_EXPORT
GetReflectionClassName(const FileDescriptor* descriptor);
// Generates output file name for given file descriptor. If generate_directories
// is true, the output file will be put under directory corresponding to file's
// namespace. base_namespace can be used to strip some of the top level
// directories. E.g. for file with namespace "Bar.Foo" and base_namespace="Bar",
// the resulting file will be put under directory "Foo" (and not "Bar/Foo").
//
// Requires:
// descriptor != NULL
// error != NULL
//
// Returns:
// The file name to use as output file for given file descriptor. In case
// of failure, this function will return empty string and error parameter
// will contain the error message.
std::string PROTOC_EXPORT GetOutputFile(const FileDescriptor* descriptor,
const std::string file_extension,
const bool generate_directories,
const std::string base_namespace,
std::string* error);
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_NAMES_H__

View File

@@ -0,0 +1,336 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// This file is the public interface to the .proto file parser.
#ifndef GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
#define GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <google/protobuf/compiler/parser.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor_database.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace io {
class ZeroCopyInputStream;
}
namespace compiler {
// Defined in this file.
class Importer;
class MultiFileErrorCollector;
class SourceTree;
class DiskSourceTree;
// TODO(kenton): Move all SourceTree stuff to a separate file?
// An implementation of DescriptorDatabase which loads files from a SourceTree
// and parses them.
//
// Note: This class is not thread-safe since it maintains a table of source
// code locations for error reporting. However, when a DescriptorPool wraps
// a DescriptorDatabase, it uses mutex locking to make sure only one method
// of the database is called at a time, even if the DescriptorPool is used
// from multiple threads. Therefore, there is only a problem if you create
// multiple DescriptorPools wrapping the same SourceTreeDescriptorDatabase
// and use them from multiple threads.
//
// Note: This class does not implement FindFileContainingSymbol() or
// FindFileContainingExtension(); these will always return false.
class PROTOBUF_EXPORT SourceTreeDescriptorDatabase : public DescriptorDatabase {
public:
SourceTreeDescriptorDatabase(SourceTree* source_tree);
// If non-NULL, fallback_database will be checked if a file doesn't exist in
// the specified source_tree.
SourceTreeDescriptorDatabase(SourceTree* source_tree,
DescriptorDatabase* fallback_database);
~SourceTreeDescriptorDatabase();
// Instructs the SourceTreeDescriptorDatabase to report any parse errors
// to the given MultiFileErrorCollector. This should be called before
// parsing. error_collector must remain valid until either this method
// is called again or the SourceTreeDescriptorDatabase is destroyed.
void RecordErrorsTo(MultiFileErrorCollector* error_collector) {
error_collector_ = error_collector;
}
// Gets a DescriptorPool::ErrorCollector which records errors to the
// MultiFileErrorCollector specified with RecordErrorsTo(). This collector
// has the ability to determine exact line and column numbers of errors
// from the information given to it by the DescriptorPool.
DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
using_validation_error_collector_ = true;
return &validation_error_collector_;
}
// implements DescriptorDatabase -----------------------------------
bool FindFileByName(const std::string& filename,
FileDescriptorProto* output) override;
bool FindFileContainingSymbol(const std::string& symbol_name,
FileDescriptorProto* output) override;
bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
FileDescriptorProto* output) override;
private:
class SingleFileErrorCollector;
SourceTree* source_tree_;
DescriptorDatabase* fallback_database_;
MultiFileErrorCollector* error_collector_;
class PROTOBUF_EXPORT ValidationErrorCollector
: public DescriptorPool::ErrorCollector {
public:
ValidationErrorCollector(SourceTreeDescriptorDatabase* owner);
~ValidationErrorCollector();
// implements ErrorCollector ---------------------------------------
void AddError(const std::string& filename, const std::string& element_name,
const Message* descriptor, ErrorLocation location,
const std::string& message) override;
void AddWarning(const std::string& filename,
const std::string& element_name, const Message* descriptor,
ErrorLocation location,
const std::string& message) override;
private:
SourceTreeDescriptorDatabase* owner_;
};
friend class ValidationErrorCollector;
bool using_validation_error_collector_;
SourceLocationTable source_locations_;
ValidationErrorCollector validation_error_collector_;
};
// Simple interface for parsing .proto files. This wraps the process
// of opening the file, parsing it with a Parser, recursively parsing all its
// imports, and then cross-linking the results to produce a FileDescriptor.
//
// This is really just a thin wrapper around SourceTreeDescriptorDatabase.
// You may find that SourceTreeDescriptorDatabase is more flexible.
//
// TODO(kenton): I feel like this class is not well-named.
class PROTOBUF_EXPORT Importer {
public:
Importer(SourceTree* source_tree, MultiFileErrorCollector* error_collector);
~Importer();
// Import the given file and build a FileDescriptor representing it. If
// the file is already in the DescriptorPool, the existing FileDescriptor
// will be returned. The FileDescriptor is property of the DescriptorPool,
// and will remain valid until it is destroyed. If any errors occur, they
// will be reported using the error collector and Import() will return NULL.
//
// A particular Importer object will only report errors for a particular
// file once. All future attempts to import the same file will return NULL
// without reporting any errors. The idea is that you might want to import
// a lot of files without seeing the same errors over and over again. If
// you want to see errors for the same files repeatedly, you can use a
// separate Importer object to import each one (but use the same
// DescriptorPool so that they can be cross-linked).
const FileDescriptor* Import(const std::string& filename);
// The DescriptorPool in which all imported FileDescriptors and their
// contents are stored.
inline const DescriptorPool* pool() const { return &pool_; }
void AddUnusedImportTrackFile(const std::string& file_name,
bool is_error = false);
void ClearUnusedImportTrackFiles();
private:
SourceTreeDescriptorDatabase database_;
DescriptorPool pool_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Importer);
};
// If the importer encounters problems while trying to import the proto files,
// it reports them to a MultiFileErrorCollector.
class PROTOBUF_EXPORT MultiFileErrorCollector {
public:
inline MultiFileErrorCollector() {}
virtual ~MultiFileErrorCollector();
// Line and column numbers are zero-based. A line number of -1 indicates
// an error with the entire file (e.g. "not found").
virtual void AddError(const std::string& filename, int line, int column,
const std::string& message) = 0;
virtual void AddWarning(const std::string& /* filename */, int /* line */,
int /* column */, const std::string& /* message */) {}
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MultiFileErrorCollector);
};
// Abstract interface which represents a directory tree containing proto files.
// Used by the default implementation of Importer to resolve import statements
// Most users will probably want to use the DiskSourceTree implementation,
// below.
class PROTOBUF_EXPORT SourceTree {
public:
inline SourceTree() {}
virtual ~SourceTree();
// Open the given file and return a stream that reads it, or NULL if not
// found. The caller takes ownership of the returned object. The filename
// must be a path relative to the root of the source tree and must not
// contain "." or ".." components.
virtual io::ZeroCopyInputStream* Open(const std::string& filename) = 0;
// If Open() returns NULL, calling this method immediately will return an
// description of the error.
// Subclasses should implement this method and return a meaningful value for
// better error reporting.
// TODO(xiaofeng): change this to a pure virtual function.
virtual std::string GetLastErrorMessage();
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceTree);
};
// An implementation of SourceTree which loads files from locations on disk.
// Multiple mappings can be set up to map locations in the DiskSourceTree to
// locations in the physical filesystem.
class PROTOBUF_EXPORT DiskSourceTree : public SourceTree {
public:
DiskSourceTree();
~DiskSourceTree();
// Map a path on disk to a location in the SourceTree. The path may be
// either a file or a directory. If it is a directory, the entire tree
// under it will be mapped to the given virtual location. To map a directory
// to the root of the source tree, pass an empty string for virtual_path.
//
// If multiple mapped paths apply when opening a file, they will be searched
// in order. For example, if you do:
// MapPath("bar", "foo/bar");
// MapPath("", "baz");
// and then you do:
// Open("bar/qux");
// the DiskSourceTree will first try to open foo/bar/qux, then baz/bar/qux,
// returning the first one that opens successfully.
//
// disk_path may be an absolute path or relative to the current directory,
// just like a path you'd pass to open().
void MapPath(const std::string& virtual_path, const std::string& disk_path);
// Return type for DiskFileToVirtualFile().
enum DiskFileToVirtualFileResult {
SUCCESS,
SHADOWED,
CANNOT_OPEN,
NO_MAPPING
};
// Given a path to a file on disk, find a virtual path mapping to that
// file. The first mapping created with MapPath() whose disk_path contains
// the filename is used. However, that virtual path may not actually be
// usable to open the given file. Possible return values are:
// * SUCCESS: The mapping was found. *virtual_file is filled in so that
// calling Open(*virtual_file) will open the file named by disk_file.
// * SHADOWED: A mapping was found, but using Open() to open this virtual
// path will end up returning some different file. This is because some
// other mapping with a higher precedence also matches this virtual path
// and maps it to a different file that exists on disk. *virtual_file
// is filled in as it would be in the SUCCESS case. *shadowing_disk_file
// is filled in with the disk path of the file which would be opened if
// you were to call Open(*virtual_file).
// * CANNOT_OPEN: The mapping was found and was not shadowed, but the
// file specified cannot be opened. When this value is returned,
// errno will indicate the reason the file cannot be opened. *virtual_file
// will be set to the virtual path as in the SUCCESS case, even though
// it is not useful.
// * NO_MAPPING: Indicates that no mapping was found which contains this
// file.
DiskFileToVirtualFileResult DiskFileToVirtualFile(
const std::string& disk_file, std::string* virtual_file,
std::string* shadowing_disk_file);
// Given a virtual path, find the path to the file on disk.
// Return true and update disk_file with the on-disk path if the file exists.
// Return false and leave disk_file untouched if the file doesn't exist.
bool VirtualFileToDiskFile(const std::string& virtual_file,
std::string* disk_file);
// implements SourceTree -------------------------------------------
io::ZeroCopyInputStream* Open(const std::string& filename) override;
std::string GetLastErrorMessage() override;
private:
struct Mapping {
std::string virtual_path;
std::string disk_path;
inline Mapping(const std::string& virtual_path_param,
const std::string& disk_path_param)
: virtual_path(virtual_path_param), disk_path(disk_path_param) {}
};
std::vector<Mapping> mappings_;
std::string last_error_message_;
// Like Open(), but returns the on-disk path in disk_file if disk_file is
// non-NULL and the file could be successfully opened.
io::ZeroCopyInputStream* OpenVirtualFile(const std::string& virtual_file,
std::string* disk_file);
// Like Open() but given the actual on-disk path.
io::ZeroCopyInputStream* OpenDiskFile(const std::string& filename);
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DiskSourceTree);
};
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_IMPORTER_H__

View File

@@ -0,0 +1,76 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Generates Java code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
// CodeGenerator implementation which generates Java code. If you create your
// own protocol compiler binary and you want it to support Java output, you
// can do so by registering an instance of this CodeGenerator with the
// CommandLineInterface in your main() function.
class PROTOC_EXPORT JavaGenerator : public CodeGenerator {
public:
JavaGenerator();
~JavaGenerator();
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* context, std::string* error) const override;
uint64_t GetSupportedFeatures() const override;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator);
};
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__

View File

@@ -0,0 +1,72 @@
// 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 Kotlin code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace java {
// CodeGenerator implementation which generates Kotlin code. If you create your
// own protocol compiler binary and you want it to support Kotlin output, you
// can do so by registering an instance of this CodeGenerator with the
// CommandLineInterface in your main() function.
class PROTOC_EXPORT KotlinGenerator : public CodeGenerator {
public:
KotlinGenerator();
~KotlinGenerator() override;
// implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* context, std::string* error) const override;
uint64_t GetSupportedFeatures() const override;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(KotlinGenerator);
};
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__

View File

@@ -0,0 +1,100 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Provides a mechanism for mapping a descriptor to the
// fully-qualified name of the corresponding Java class.
#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__
#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__
#include <string>
namespace google {
namespace protobuf {
class Descriptor;
class EnumDescriptor;
class FileDescriptor;
class FieldDescriptor;
class ServiceDescriptor;
namespace compiler {
namespace java {
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified Java class name.
std::string ClassName(const Descriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified Java class name.
std::string ClassName(const EnumDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified Java class name.
std::string ClassName(const FileDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// The fully-qualified Java class name.
std::string ClassName(const ServiceDescriptor* descriptor);
// Requires:
// descriptor != NULL
//
// Returns:
// Java package name.
std::string FileJavaPackage(const FileDescriptor* descriptor);
// Requires:
// descriptor != NULL
// Returns:
// Capitalized camel case name field name.
std::string CapitalizedFieldName(const FieldDescriptor* descriptor);
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__

View File

@@ -0,0 +1,339 @@
// 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(""),
error_on_name_conflict(false),
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;
// Error if there are two types that would generate the same output file?
bool error_on_name_conflict;
// 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__

View File

@@ -0,0 +1,43 @@
// 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.
#ifndef GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__
#define GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__
#include <stddef.h>
struct FileToc {
const char* name;
const char* data;
};
extern struct FileToc well_known_types_js[];
#endif // GOOGLE_PROTOBUF_COMPILER_JS_WELL_KNOWN_TYPES_EMBED_H__

View File

@@ -0,0 +1,79 @@
// 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 ObjectiveC code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace objectivec {
// CodeGenerator implementation which generates a ObjectiveC source file and
// header. If you create your own protocol compiler binary and you want it to
// support ObjectiveC output, you can do so by registering an instance of this
// CodeGenerator with the CommandLineInterface in your main() function.
class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
public:
ObjectiveCGenerator();
~ObjectiveCGenerator();
ObjectiveCGenerator(const ObjectiveCGenerator&) = delete;
ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete;
// implements CodeGenerator ----------------------------------------
bool HasGenerateAll() const override;
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* context, std::string* error) const override;
bool GenerateAll(const std::vector<const FileDescriptor*>& files,
const std::string& parameter, GeneratorContext* context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override {
return FEATURE_PROTO3_OPTIONAL;
}
};
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__

View File

@@ -0,0 +1,326 @@
// 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.
// Helper functions for generating ObjectiveC code.
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
#include <string>
#include <vector>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace objectivec {
// Generator options (see objectivec_generator.cc for a description of each):
struct Options {
Options();
std::string expected_prefixes_path;
std::vector<std::string> expected_prefixes_suppressions;
std::string generate_for_named_framework;
std::string named_framework_to_proto_path_mappings_path;
std::string runtime_import_prefix;
};
// Escape C++ trigraphs by escaping question marks to "\?".
std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape);
// Remove white space from either end of a StringPiece.
void PROTOC_EXPORT TrimWhitespace(StringPiece* input);
// Returns true if the name requires a ns_returns_not_retained attribute applied
// to it.
bool PROTOC_EXPORT IsRetainedName(const std::string& name);
// Returns true if the name starts with "init" and will need to have special
// handling under ARC.
bool PROTOC_EXPORT IsInitName(const std::string& name);
// Gets the objc_class_prefix.
std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
// Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package
// declared in the proto package.
std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
// Just like FilePath(), but without the directory part.
std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
// Gets the name of the root class we'll generate in the file. This class
// is not meant for external consumption, but instead contains helpers that
// the rest of the classes need
std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
std::string* out_suffix_added);
std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
// Returns the fully-qualified name of the enum value corresponding to the
// the descriptor.
std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
// Returns the name of the enum value corresponding to the descriptor.
std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
// Reverse what an enum does.
std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
// Returns the name to use for the extension (used as the method off the file's
// Root class).
std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
// Returns the transformed field name.
std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
// Returns the transformed oneof name.
std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
// Returns a symbol that can be used in C code to refer to an Objective C
// class without initializing the class.
std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
// Declares an Objective C class without initializing the class so that it can
// be refrerred to by ObjCClass.
std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name);
inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
}
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
return descriptor->options().map_entry();
}
// Reverse of the above.
std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
const FieldDescriptor* field);
enum ObjectiveCType {
OBJECTIVECTYPE_INT32,
OBJECTIVECTYPE_UINT32,
OBJECTIVECTYPE_INT64,
OBJECTIVECTYPE_UINT64,
OBJECTIVECTYPE_FLOAT,
OBJECTIVECTYPE_DOUBLE,
OBJECTIVECTYPE_BOOLEAN,
OBJECTIVECTYPE_STRING,
OBJECTIVECTYPE_DATA,
OBJECTIVECTYPE_ENUM,
OBJECTIVECTYPE_MESSAGE
};
enum FlagType {
FLAGTYPE_DESCRIPTOR_INITIALIZATION,
FLAGTYPE_EXTENSION,
FLAGTYPE_FIELD
};
template <class TDescriptor>
std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
const FileDescriptor* file = NULL,
bool preSpace = true,
bool postNewline = false) {
bool isDeprecated = descriptor->options().deprecated();
// The file is only passed when checking Messages & Enums, so those types
// get tagged. At the moment, it doesn't seem to make sense to tag every
// field or enum value with when the file is deprecated.
bool isFileLevelDeprecation = false;
if (!isDeprecated && file) {
isFileLevelDeprecation = file->options().deprecated();
isDeprecated = isFileLevelDeprecation;
}
if (isDeprecated) {
std::string message;
const FileDescriptor* sourceFile = descriptor->file();
if (isFileLevelDeprecation) {
message = sourceFile->name() + " is deprecated.";
} else {
message = descriptor->full_name() + " is deprecated (see " +
sourceFile->name() + ").";
}
std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
if (preSpace) {
result.insert(0, " ");
}
if (postNewline) {
result.append("\n");
}
return result;
} else {
return "";
}
}
std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
ObjectiveCType PROTOC_EXPORT
GetObjectiveCType(FieldDescriptor::Type field_type);
inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
return GetObjectiveCType(field->type());
}
bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field);
bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field);
std::string PROTOC_EXPORT
GPBGenericValueFieldName(const FieldDescriptor* field);
std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
std::string PROTOC_EXPORT
BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
// file.
std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
bool prefer_single_line);
// The name the commonly used by the library when built as a framework.
// This lines up to the name used in the CocoaPod.
extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
// Returns the CPP symbol name to use as the gate for framework style imports
// for the given framework name to use.
std::string PROTOC_EXPORT
ProtobufFrameworkImportSymbol(const std::string& framework_name);
// Checks if the file is one of the proto's bundled with the library.
bool PROTOC_EXPORT
IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
// Checks the prefix for the given files and outputs any warnings as needed. If
// there are flat out errors, then out_error is filled in with the first error
// and the result is false.
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
const std::vector<const FileDescriptor*>& files,
const Options& generation_options, std::string* out_error);
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
// the input into the expected output.
class PROTOC_EXPORT TextFormatDecodeData {
public:
TextFormatDecodeData();
~TextFormatDecodeData();
TextFormatDecodeData(const TextFormatDecodeData&) = delete;
TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
void AddString(int32 key, const std::string& input_for_decode,
const std::string& desired_output);
size_t num_entries() const { return entries_.size(); }
std::string Data() const;
static std::string DecodeDataForString(const std::string& input_for_decode,
const std::string& desired_output);
private:
typedef std::pair<int32, std::string> DataEntry;
std::vector<DataEntry> entries_;
};
// Helper for parsing simple files.
class PROTOC_EXPORT LineConsumer {
public:
LineConsumer();
virtual ~LineConsumer();
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0;
};
bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
LineConsumer* line_consumer,
std::string* out_error);
// Helper class for parsing framework import mappings and generating
// import statements.
class PROTOC_EXPORT ImportWriter {
public:
ImportWriter(const std::string& generate_for_named_framework,
const std::string& named_framework_to_proto_path_mappings_path,
const std::string& runtime_import_prefix,
bool include_wkt_imports);
~ImportWriter();
void AddFile(const FileDescriptor* file, const std::string& header_extension);
void Print(io::Printer* printer) const;
static void PrintRuntimeImports(io::Printer* printer,
const std::vector<std::string>& header_to_import,
const std::string& runtime_import_prefix,
bool default_cpp_symbol = false);
private:
class ProtoFrameworkCollector : public LineConsumer {
public:
ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
: map_(inout_proto_file_to_framework_name) {}
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error);
private:
std::map<std::string, std::string>* map_;
};
void ParseFrameworkMappings();
const std::string generate_for_named_framework_;
const std::string named_framework_to_proto_path_mappings_path_;
const std::string runtime_import_prefix_;
const bool include_wkt_imports_;
std::map<std::string, std::string> proto_file_to_framework_name_;
bool need_to_parse_mapping_file_;
std::vector<std::string> protobuf_imports_;
std::vector<std::string> other_framework_imports_;
std::vector<std::string> other_imports_;
};
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__

View File

@@ -0,0 +1,603 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
// Implements parsing of .proto files to FileDescriptorProtos.
#ifndef GOOGLE_PROTOBUF_COMPILER_PARSER_H__
#define GOOGLE_PROTOBUF_COMPILER_PARSER_H__
#include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/repeated_field.h>
// Must be included last.
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Message;
namespace compiler {
// Defined in this file.
class Parser;
class SourceLocationTable;
// Implements parsing of protocol definitions (such as .proto files).
//
// Note that most users will be more interested in the Importer class.
// Parser is a lower-level class which simply converts a single .proto file
// to a FileDescriptorProto. It does not resolve import directives or perform
// many other kinds of validation needed to construct a complete
// FileDescriptor.
class PROTOBUF_EXPORT Parser {
public:
Parser();
~Parser();
// Parse the entire input and construct a FileDescriptorProto representing
// it. Returns true if no errors occurred, false otherwise.
bool Parse(io::Tokenizer* input, FileDescriptorProto* file);
// Optional features:
// DEPRECATED: New code should use the SourceCodeInfo embedded in the
// FileDescriptorProto.
//
// Requests that locations of certain definitions be recorded to the given
// SourceLocationTable while parsing. This can be used to look up exact line
// and column numbers for errors reported by DescriptorPool during validation.
// Set to NULL (the default) to discard source location information.
void RecordSourceLocationsTo(SourceLocationTable* location_table) {
source_location_table_ = location_table;
}
// Requests that errors be recorded to the given ErrorCollector while
// parsing. Set to NULL (the default) to discard error messages.
void RecordErrorsTo(io::ErrorCollector* error_collector) {
error_collector_ = error_collector;
}
// Returns the identifier used in the "syntax = " declaration, if one was
// seen during the last call to Parse(), or the empty string otherwise.
const std::string& GetSyntaxIdentifier() { return syntax_identifier_; }
// If set true, input files will be required to begin with a syntax
// identifier. Otherwise, files may omit this. If a syntax identifier
// is provided, it must be 'syntax = "proto2";' and must appear at the
// top of this file regardless of whether or not it was required.
void SetRequireSyntaxIdentifier(bool value) {
require_syntax_identifier_ = value;
}
// Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
// parsing as soon as it has seen the syntax identifier, or lack thereof.
// This is useful for quickly identifying the syntax of the file without
// parsing the whole thing. If this is enabled, no error will be recorded
// if the syntax identifier is something other than "proto2" (since
// presumably the caller intends to deal with that), but other kinds of
// errors (e.g. parse errors) will still be reported. When this is enabled,
// you may pass a NULL FileDescriptorProto to Parse().
void SetStopAfterSyntaxIdentifier(bool value) {
stop_after_syntax_identifier_ = value;
}
private:
class LocationRecorder;
// =================================================================
// Error recovery helpers
// Consume the rest of the current statement. This consumes tokens
// until it sees one of:
// ';' Consumes the token and returns.
// '{' Consumes the brace then calls SkipRestOfBlock().
// '}' Returns without consuming.
// EOF Returns (can't consume).
// The Parser often calls SkipStatement() after encountering a syntax
// error. This allows it to go on parsing the following lines, allowing
// it to report more than just one error in the file.
void SkipStatement();
// Consume the rest of the current block, including nested blocks,
// ending after the closing '}' is encountered and consumed, or at EOF.
void SkipRestOfBlock();
// -----------------------------------------------------------------
// Single-token consuming helpers
//
// These make parsing code more readable.
// True if the current token is TYPE_END.
inline bool AtEnd();
// True if the next token matches the given text.
inline bool LookingAt(const char* text);
// True if the next token is of the given type.
inline bool LookingAtType(io::Tokenizer::TokenType token_type);
// If the next token exactly matches the text given, consume it and return
// true. Otherwise, return false without logging an error.
bool TryConsume(const char* text);
// These attempt to read some kind of token from the input. If successful,
// they return true. Otherwise they return false and add the given error
// to the error list.
// Consume a token with the exact text given.
bool Consume(const char* text, const char* error);
// Same as above, but automatically generates the error "Expected \"text\".",
// where "text" is the expected token text.
bool Consume(const char* text);
// Consume a token of type IDENTIFIER and store its text in "output".
bool ConsumeIdentifier(std::string* output, const char* error);
// Consume an integer and store its value in "output".
bool ConsumeInteger(int* output, const char* error);
// Consume a signed integer and store its value in "output".
bool ConsumeSignedInteger(int* output, const char* error);
// Consume a 64-bit integer and store its value in "output". If the value
// is greater than max_value, an error will be reported.
bool ConsumeInteger64(uint64_t max_value, uint64_t* output,
const char* error);
// Consume a number and store its value in "output". This will accept
// tokens of either INTEGER or FLOAT type.
bool ConsumeNumber(double* output, const char* error);
// Consume a string literal and store its (unescaped) value in "output".
bool ConsumeString(std::string* output, const char* error);
// Consume a token representing the end of the statement. Comments between
// this token and the next will be harvested for documentation. The given
// LocationRecorder should refer to the declaration that was just parsed;
// it will be populated with these comments.
//
// TODO(kenton): The LocationRecorder is const because historically locations
// have been passed around by const reference, for no particularly good
// reason. We should probably go through and change them all to mutable
// pointer to make this more intuitive.
bool TryConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location);
bool TryConsumeEndOfDeclarationFinishScope(const char* text,
const LocationRecorder* location);
bool ConsumeEndOfDeclaration(const char* text,
const LocationRecorder* location);
// -----------------------------------------------------------------
// Error logging helpers
// Invokes error_collector_->AddError(), if error_collector_ is not NULL.
void AddError(int line, int column, const std::string& error);
// Invokes error_collector_->AddError() with the line and column number
// of the current token.
void AddError(const std::string& error);
// Invokes error_collector_->AddWarning() with the line and column number
// of the current token.
void AddWarning(const std::string& warning);
// Records a location in the SourceCodeInfo.location table (see
// descriptor.proto). We use RAII to ensure that the start and end locations
// are recorded -- the constructor records the start location and the
// destructor records the end location. Since the parser is
// recursive-descent, this works out beautifully.
class PROTOBUF_EXPORT LocationRecorder {
public:
// Construct the file's "root" location.
LocationRecorder(Parser* parser);
// Construct a location that represents a declaration nested within the
// given parent. E.g. a field's location is nested within the location
// for a message type. The parent's path will be copied, so you should
// call AddPath() only to add the path components leading from the parent
// to the child (as opposed to leading from the root to the child).
LocationRecorder(const LocationRecorder& parent);
// Convenience constructors that call AddPath() one or two times.
LocationRecorder(const LocationRecorder& parent, int path1);
LocationRecorder(const LocationRecorder& parent, int path1, int path2);
// Creates a recorder that generates locations into given source code info.
LocationRecorder(const LocationRecorder& parent, int path1,
SourceCodeInfo* source_code_info);
~LocationRecorder();
// Add a path component. See SourceCodeInfo.Location.path in
// descriptor.proto.
void AddPath(int path_component);
// By default the location is considered to start at the current token at
// the time the LocationRecorder is created. StartAt() sets the start
// location to the given token instead.
void StartAt(const io::Tokenizer::Token& token);
// Start at the same location as some other LocationRecorder.
void StartAt(const LocationRecorder& other);
// By default the location is considered to end at the previous token at
// the time the LocationRecorder is destroyed. EndAt() sets the end
// location to the given token instead.
void EndAt(const io::Tokenizer::Token& token);
// Records the start point of this location to the SourceLocationTable that
// was passed to RecordSourceLocationsTo(), if any. SourceLocationTable
// is an older way of keeping track of source locations which is still
// used in some places.
void RecordLegacyLocation(
const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location);
void RecordLegacyImportLocation(const Message* descriptor,
const std::string& name);
// Returns the number of path components in the recorder's current location.
int CurrentPathSize() const;
// Attaches leading and trailing comments to the location. The two strings
// will be swapped into place, so after this is called *leading and
// *trailing will be empty.
//
// TODO(kenton): See comment on TryConsumeEndOfDeclaration(), above, for
// why this is const.
void AttachComments(std::string* leading, std::string* trailing,
std::vector<std::string>* detached_comments) const;
private:
// Indexes of parent and current location in the parent
// SourceCodeInfo.location repeated field. For top-level elements,
// parent_index_ is -1.
Parser* parser_;
SourceCodeInfo* source_code_info_;
SourceCodeInfo::Location* location_;
void Init(const LocationRecorder& parent, SourceCodeInfo* source_code_info);
};
// =================================================================
// Parsers for various language constructs
// Parses the "syntax = \"proto2\";" line at the top of the file. Returns
// false if it failed to parse or if the syntax identifier was not
// recognized.
bool ParseSyntaxIdentifier(const LocationRecorder& parent);
// These methods parse various individual bits of code. They return
// false if they completely fail to parse the construct. In this case,
// it is probably necessary to skip the rest of the statement to recover.
// However, if these methods return true, it does NOT mean that there
// were no errors; only that there were no *syntax* errors. For instance,
// if a service method is defined using proper syntax but uses a primitive
// type as its input or output, ParseMethodField() still returns true
// and only reports the error by calling AddError(). In practice, this
// makes logic much simpler for the caller.
// Parse a top-level message, enum, service, etc.
bool ParseTopLevelStatement(FileDescriptorProto* file,
const LocationRecorder& root_location);
// Parse various language high-level language construrcts.
bool ParseMessageDefinition(DescriptorProto* message,
const LocationRecorder& message_location,
const FileDescriptorProto* containing_file);
bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
const LocationRecorder& enum_location,
const FileDescriptorProto* containing_file);
bool ParseServiceDefinition(ServiceDescriptorProto* service,
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
bool ParsePackage(FileDescriptorProto* file,
const LocationRecorder& root_location,
const FileDescriptorProto* containing_file);
bool ParseImport(RepeatedPtrField<std::string>* dependency,
RepeatedField<int32_t>* public_dependency,
RepeatedField<int32_t>* weak_dependency,
const LocationRecorder& root_location,
const FileDescriptorProto* containing_file);
// These methods parse the contents of a message, enum, or service type and
// add them to the given object. They consume the entire block including
// the beginning and ending brace.
bool ParseMessageBlock(DescriptorProto* message,
const LocationRecorder& message_location,
const FileDescriptorProto* containing_file);
bool ParseEnumBlock(EnumDescriptorProto* enum_type,
const LocationRecorder& enum_location,
const FileDescriptorProto* containing_file);
bool ParseServiceBlock(ServiceDescriptorProto* service,
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
// Parse one statement within a message, enum, or service block, including
// final semicolon.
bool ParseMessageStatement(DescriptorProto* message,
const LocationRecorder& message_location,
const FileDescriptorProto* containing_file);
bool ParseEnumStatement(EnumDescriptorProto* message,
const LocationRecorder& enum_location,
const FileDescriptorProto* containing_file);
bool ParseServiceStatement(ServiceDescriptorProto* message,
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
// Parse a field of a message. If the field is a group, its type will be
// added to "messages".
//
// parent_location and location_field_number_for_nested_type are needed when
// parsing groups -- we need to generate a nested message type within the
// parent and record its location accordingly. Since the parent could be
// either a FileDescriptorProto or a DescriptorProto, we must pass in the
// correct field number to use.
bool ParseMessageField(FieldDescriptorProto* field,
RepeatedPtrField<DescriptorProto>* messages,
const LocationRecorder& parent_location,
int location_field_number_for_nested_type,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
// Like ParseMessageField() but expects the label has already been filled in
// by the caller.
bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
RepeatedPtrField<DescriptorProto>* messages,
const LocationRecorder& parent_location,
int location_field_number_for_nested_type,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
// Parse an "extensions" declaration.
bool ParseExtensions(DescriptorProto* message,
const LocationRecorder& extensions_location,
const FileDescriptorProto* containing_file);
// Parse a "reserved" declaration.
bool ParseReserved(DescriptorProto* message,
const LocationRecorder& message_location);
bool ParseReservedNames(DescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseReservedNumbers(DescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseReserved(EnumDescriptorProto* message,
const LocationRecorder& message_location);
bool ParseReservedNames(EnumDescriptorProto* message,
const LocationRecorder& parent_location);
bool ParseReservedNumbers(EnumDescriptorProto* message,
const LocationRecorder& parent_location);
// Parse an "extend" declaration. (See also comments for
// ParseMessageField().)
bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
RepeatedPtrField<DescriptorProto>* messages,
const LocationRecorder& parent_location,
int location_field_number_for_nested_type,
const LocationRecorder& extend_location,
const FileDescriptorProto* containing_file);
// Parse a "oneof" declaration. The caller is responsible for setting
// oneof_decl->label() since it will have had to parse the label before it
// knew it was parsing a oneof.
bool ParseOneof(OneofDescriptorProto* oneof_decl,
DescriptorProto* containing_type, int oneof_index,
const LocationRecorder& oneof_location,
const LocationRecorder& containing_type_location,
const FileDescriptorProto* containing_file);
// Parse a single enum value within an enum block.
bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
const LocationRecorder& enum_value_location,
const FileDescriptorProto* containing_file);
// Parse enum constant options, i.e. the list in square brackets at the end
// of the enum constant value definition.
bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
const LocationRecorder& enum_value_location,
const FileDescriptorProto* containing_file);
// Parse a single method within a service definition.
bool ParseServiceMethod(MethodDescriptorProto* method,
const LocationRecorder& method_location,
const FileDescriptorProto* containing_file);
// Parse options of a single method or stream.
bool ParseMethodOptions(const LocationRecorder& parent_location,
const FileDescriptorProto* containing_file,
const int optionsFieldNumber,
Message* mutable_options);
// Parse "required", "optional", or "repeated" and fill in "label"
// with the value. Returns true if such a label is consumed.
bool ParseLabel(FieldDescriptorProto::Label* label,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
// Parse a type name and fill in "type" (if it is a primitive) or
// "type_name" (if it is not) with the type parsed.
bool ParseType(FieldDescriptorProto::Type* type, std::string* type_name);
// Parse a user-defined type and fill in "type_name" with the name.
// If a primitive type is named, it is treated as an error.
bool ParseUserDefinedType(std::string* type_name);
// Parses field options, i.e. the stuff in square brackets at the end
// of a field definition. Also parses default value.
bool ParseFieldOptions(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
// Parse the "default" option. This needs special handling because its
// type is the field's type.
bool ParseDefaultAssignment(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
bool ParseJsonName(FieldDescriptorProto* field,
const LocationRecorder& field_location,
const FileDescriptorProto* containing_file);
enum OptionStyle {
OPTION_ASSIGNMENT, // just "name = value"
OPTION_STATEMENT // "option name = value;"
};
// Parse a single option name/value pair, e.g. "ctype = CORD". The name
// identifies a field of the given Message, and the value of that field
// is set to the parsed value.
bool ParseOption(Message* options, const LocationRecorder& options_location,
const FileDescriptorProto* containing_file,
OptionStyle style);
// Parses a single part of a multipart option name. A multipart name consists
// of names separated by dots. Each name is either an identifier or a series
// of identifiers separated by dots and enclosed in parentheses. E.g.,
// "foo.(bar.baz).qux".
bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
const LocationRecorder& part_location,
const FileDescriptorProto* containing_file);
// Parses a string surrounded by balanced braces. Strips off the outer
// braces and stores the enclosed string in *value.
// E.g.,
// { foo } *value gets 'foo'
// { foo { bar: box } } *value gets 'foo { bar: box }'
// {} *value gets ''
//
// REQUIRES: LookingAt("{")
// When finished successfully, we are looking at the first token past
// the ending brace.
bool ParseUninterpretedBlock(std::string* value);
struct MapField {
// Whether the field is a map field.
bool is_map_field;
// The types of the key and value if they are primitive types.
FieldDescriptorProto::Type key_type;
FieldDescriptorProto::Type value_type;
// Or the type names string if the types are customized types.
std::string key_type_name;
std::string value_type_name;
MapField() : is_map_field(false) {}
};
// Desugar the map syntax to generate a nested map entry message.
void GenerateMapEntry(const MapField& map_field, FieldDescriptorProto* field,
RepeatedPtrField<DescriptorProto>* messages);
// Whether fields without label default to optional fields.
bool DefaultToOptionalFields() const {
return syntax_identifier_ == "proto3";
}
bool ValidateEnum(const EnumDescriptorProto* proto);
// =================================================================
io::Tokenizer* input_;
io::ErrorCollector* error_collector_;
SourceCodeInfo* source_code_info_;
SourceLocationTable* source_location_table_; // legacy
bool had_errors_;
bool require_syntax_identifier_;
bool stop_after_syntax_identifier_;
std::string syntax_identifier_;
// Leading doc comments for the next declaration. These are not complete
// yet; use ConsumeEndOfDeclaration() to get the complete comments.
std::string upcoming_doc_comments_;
// Detached comments are not connected to any syntax entities. Elements in
// this vector are paragraphs of comments separated by empty lines. The
// detached comments will be put into the leading_detached_comments field for
// the next element (See SourceCodeInfo.Location in descriptor.proto), when
// ConsumeEndOfDeclaration() is called.
std::vector<std::string> upcoming_detached_comments_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Parser);
};
// A table mapping (descriptor, ErrorLocation) pairs -- as reported by
// DescriptorPool when validating descriptors -- to line and column numbers
// within the original source code.
//
// This is semi-obsolete: FileDescriptorProto.source_code_info now contains
// far more complete information about source locations. However, as of this
// writing you still need to use SourceLocationTable when integrating with
// DescriptorPool.
class PROTOBUF_EXPORT SourceLocationTable {
public:
SourceLocationTable();
~SourceLocationTable();
// Finds the precise location of the given error and fills in *line and
// *column with the line and column numbers. If not found, sets *line to
// -1 and *column to 0 (since line = -1 is used to mean "error has no exact
// location" in the ErrorCollector interface). Returns true if found, false
// otherwise.
bool Find(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location, int* line,
int* column) const;
bool FindImport(const Message* descriptor, const std::string& name, int* line,
int* column) const;
// Adds a location to the table.
void Add(const Message* descriptor,
DescriptorPool::ErrorCollector::ErrorLocation location, int line,
int column);
void AddImport(const Message* descriptor, const std::string& name, int line,
int column);
// Clears the contents of the table.
void Clear();
private:
typedef std::map<
std::pair<const Message*, DescriptorPool::ErrorCollector::ErrorLocation>,
std::pair<int, int> >
LocationMap;
LocationMap location_map_;
std::map<std::pair<const Message*, std::string>, std::pair<int, int> >
import_location_map_;
};
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_PARSER_H__

View File

@@ -0,0 +1,92 @@
// 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.
#ifndef GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/descriptor.h>
#include <string>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace php {
struct Options;
class PROTOC_EXPORT Generator : public CodeGenerator {
public:
virtual bool Generate(
const FileDescriptor* file,
const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const override;
bool GenerateAll(const std::vector<const FileDescriptor*>& files,
const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override {
return FEATURE_PROTO3_OPTIONAL;
}
private:
bool Generate(
const FileDescriptor* file,
const Options& options,
GeneratorContext* generator_context,
std::string* error) const;
};
// To skip reserved keywords in php, some generated classname are prefixed.
// Other code generators may need following API to figure out the actual
// classname.
PROTOC_EXPORT std::string GeneratedClassName(const Descriptor* desc);
PROTOC_EXPORT std::string GeneratedClassName(const EnumDescriptor* desc);
PROTOC_EXPORT std::string GeneratedClassName(const ServiceDescriptor* desc);
inline bool IsWrapperType(const FieldDescriptor* descriptor) {
return descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";
}
} // namespace php
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_PHP_GENERATOR_H__

View File

@@ -0,0 +1,94 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
//
// Front-end for protoc code generator plugins written in C++.
//
// To implement a protoc plugin in C++, simply write an implementation of
// CodeGenerator, then create a main() function like:
// int main(int argc, char* argv[]) {
// MyCodeGenerator generator;
// return google::protobuf::compiler::PluginMain(argc, argv, &generator);
// }
// You must link your plugin against libprotobuf and libprotoc.
//
// The core part of PluginMain is to invoke the given CodeGenerator on a
// CodeGeneratorRequest to generate a CodeGeneratorResponse. This part is
// abstracted out and made into function GenerateCode so that it can be reused,
// for example, to implement a variant of PluginMain that does some
// preprocessing on the input CodeGeneratorRequest before feeding the request
// to the given code generator.
//
// To get protoc to use the plugin, do one of the following:
// * Place the plugin binary somewhere in the PATH and give it the name
// "protoc-gen-NAME" (replacing "NAME" with the name of your plugin). If you
// then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace
// "NAME" with your plugin's name), protoc will invoke your plugin to generate
// the output, which will be placed in OUT_DIR.
// * Place the plugin binary anywhere, with any name, and pass the --plugin
// parameter to protoc to direct it to your plugin like so:
// protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR
// On Windows, make sure to include the .exe suffix:
// protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR
#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#include <string>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
class CodeGenerator; // code_generator.h
class CodeGeneratorRequest;
class CodeGeneratorResponse;
// Implements main() for a protoc plugin exposing the given code generator.
PROTOC_EXPORT int PluginMain(int argc, char* argv[],
const CodeGenerator* generator);
// Generates code using the given code generator. Returns true if the code
// generation is successful. If the code generation fails, error_msg may be
// populated to describe the failure cause.
bool GenerateCode(const CodeGeneratorRequest& request,
const CodeGenerator& generator,
CodeGeneratorResponse* response, std::string* error_msg);
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
// 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.
// Author: kenton@google.com (Kenton Varda)
//
// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to
// change.
//
// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
// just a program that reads a CodeGeneratorRequest from stdin and writes a
// CodeGeneratorResponse to stdout.
//
// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
// of dealing with the raw protocol defined here.
//
// A plugin executable needs only to be placed somewhere in the path. The
// plugin should be named "protoc-gen-$NAME", and will then be used when the
// flag "--${NAME}_out" is passed to protoc.
syntax = "proto2";
package google.protobuf.compiler;
option java_package = "com.google.protobuf.compiler";
option java_outer_classname = "PluginProtos";
option go_package = "google.golang.org/protobuf/types/pluginpb";
import "google/protobuf/descriptor.proto";
// The version number of protocol compiler.
message Version {
optional int32 major = 1;
optional int32 minor = 2;
optional int32 patch = 3;
// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
// be empty for mainline stable releases.
optional string suffix = 4;
}
// An encoded CodeGeneratorRequest is written to the plugin's stdin.
message CodeGeneratorRequest {
// The .proto files that were explicitly listed on the command-line. The
// code generator should generate code only for these files. Each file's
// descriptor will be included in proto_file, below.
repeated string file_to_generate = 1;
// The generator parameter passed on the command-line.
optional string parameter = 2;
// FileDescriptorProtos for all files in files_to_generate and everything
// they import. The files will appear in topological order, so each file
// appears before any file that imports it.
//
// protoc guarantees that all proto_files will be written after
// the fields above, even though this is not technically guaranteed by the
// protobuf wire format. This theoretically could allow a plugin to stream
// in the FileDescriptorProtos and handle them one by one rather than read
// the entire set into memory at once. However, as of this writing, this
// is not similarly optimized on protoc's end -- it will store all fields in
// memory at once before sending them to the plugin.
//
// Type names of fields and extensions in the FileDescriptorProto are always
// fully qualified.
repeated FileDescriptorProto proto_file = 15;
// The version number of protocol compiler.
optional Version compiler_version = 3;
}
// The plugin writes an encoded CodeGeneratorResponse to stdout.
message CodeGeneratorResponse {
// Error message. If non-empty, code generation failed. The plugin process
// should exit with status code zero even if it reports an error in this way.
//
// This should be used to indicate errors in .proto files which prevent the
// code generator from generating correct code. Errors which indicate a
// problem in protoc itself -- such as the input CodeGeneratorRequest being
// unparseable -- should be reported by writing a message to stderr and
// exiting with a non-zero status code.
optional string error = 1;
// A bitmask of supported features that the code generator supports.
// This is a bitwise "or" of values from the Feature enum.
optional uint64 supported_features = 2;
// Sync with code_generator.h.
enum Feature {
FEATURE_NONE = 0;
FEATURE_PROTO3_OPTIONAL = 1;
}
// Represents a single generated file.
message File {
// The file name, relative to the output directory. The name must not
// contain "." or ".." components and must be relative, not be absolute (so,
// the file cannot lie outside the output directory). "/" must be used as
// the path separator, not "\".
//
// If the name is omitted, the content will be appended to the previous
// file. This allows the generator to break large files into small chunks,
// and allows the generated text to be streamed back to protoc so that large
// files need not reside completely in memory at one time. Note that as of
// this writing protoc does not optimize for this -- it will read the entire
// CodeGeneratorResponse before writing files to disk.
optional string name = 1;
// If non-empty, indicates that the named file should already exist, and the
// content here is to be inserted into that file at a defined insertion
// point. This feature allows a code generator to extend the output
// produced by another code generator. The original generator may provide
// insertion points by placing special annotations in the file that look
// like:
// @@protoc_insertion_point(NAME)
// The annotation can have arbitrary text before and after it on the line,
// which allows it to be placed in a comment. NAME should be replaced with
// an identifier naming the point -- this is what other generators will use
// as the insertion_point. Code inserted at this point will be placed
// immediately above the line containing the insertion point (thus multiple
// insertions to the same point will come out in the order they were added).
// The double-@ is intended to make it unlikely that the generated code
// could contain things that look like insertion points by accident.
//
// For example, the C++ code generator places the following line in the
// .pb.h files that it generates:
// // @@protoc_insertion_point(namespace_scope)
// This line appears within the scope of the file's package namespace, but
// outside of any particular class. Another plugin can then specify the
// insertion_point "namespace_scope" to generate additional classes or
// other declarations that should be placed in this scope.
//
// Note that if the line containing the insertion point begins with
// whitespace, the same whitespace will be added to every line of the
// inserted text. This is useful for languages like Python, where
// indentation matters. In these languages, the insertion point comment
// should be indented the same amount as any inserted code will need to be
// in order to work correctly in that context.
//
// The code generator that generates the initial file and the one which
// inserts into it must both run as part of a single invocation of protoc.
// Code generators are executed in the order in which they appear on the
// command line.
//
// If |insertion_point| is present, |name| must also be present.
optional string insertion_point = 2;
// The file contents.
optional string content = 15;
// Information describing the file content being inserted. If an insertion
// point is used, this information will be appropriately offset and inserted
// into the code generation metadata for the generated files.
optional GeneratedCodeInfo generated_code_info = 16;
}
repeated File file = 15;
}

View File

@@ -0,0 +1,182 @@
// 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.
// Author: robinson@google.com (Will Robinson)
//
// Generates Python code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
class Descriptor;
class EnumDescriptor;
class EnumValueDescriptor;
class FieldDescriptor;
class OneofDescriptor;
class ServiceDescriptor;
namespace io {
class Printer;
}
namespace compiler {
namespace python {
// CodeGenerator implementation for generated Python protocol buffer classes.
// If you create your own protocol compiler binary and you want it to support
// Python 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();
// CodeGenerator methods.
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override;
private:
void PrintImports() const;
void PrintFileDescriptor() const;
void PrintTopLevelEnums() const;
void PrintAllNestedEnumsInFile() const;
void PrintNestedEnums(const Descriptor& descriptor) const;
void PrintEnum(const EnumDescriptor& enum_descriptor) const;
void PrintTopLevelExtensions() const;
void PrintFieldDescriptor(const FieldDescriptor& field,
bool is_extension) const;
void PrintFieldDescriptorsInDescriptor(
const Descriptor& message_descriptor, bool is_extension,
const std::string& list_variable_name, int (Descriptor::*CountFn)() const,
const FieldDescriptor* (Descriptor::*GetterFn)(int)const) const;
void PrintFieldsInDescriptor(const Descriptor& message_descriptor) const;
void PrintExtensionsInDescriptor(const Descriptor& message_descriptor) const;
void PrintMessageDescriptors() const;
void PrintDescriptor(const Descriptor& message_descriptor) const;
void PrintNestedDescriptors(const Descriptor& containing_descriptor) const;
void PrintMessages() const;
void PrintMessage(const Descriptor& message_descriptor,
const std::string& prefix,
std::vector<std::string>* to_register,
bool is_nested) const;
void PrintNestedMessages(const Descriptor& containing_descriptor,
const std::string& prefix,
std::vector<std::string>* to_register) const;
void FixForeignFieldsInDescriptors() const;
void FixForeignFieldsInDescriptor(
const Descriptor& descriptor,
const Descriptor* containing_descriptor) const;
void FixForeignFieldsInField(const Descriptor* containing_type,
const FieldDescriptor& field,
const std::string& python_dict_name) const;
void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const;
std::string FieldReferencingExpression(
const Descriptor* containing_type, const FieldDescriptor& field,
const std::string& python_dict_name) const;
template <typename DescriptorT>
void FixContainingTypeInDescriptor(
const DescriptorT& descriptor,
const Descriptor* containing_descriptor) const;
void FixForeignFieldsInExtensions() const;
void FixForeignFieldsInExtension(
const FieldDescriptor& extension_field) const;
void FixForeignFieldsInNestedExtensions(const Descriptor& descriptor) const;
void PrintServices() const;
void PrintServiceDescriptors() const;
void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
void PrintServiceClass(const ServiceDescriptor& descriptor) const;
void PrintServiceStub(const ServiceDescriptor& descriptor) const;
void PrintDescriptorKeyAndModuleName(
const ServiceDescriptor& descriptor) const;
void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor) const;
std::string OptionsValue(const std::string& serialized_options) const;
bool GeneratingDescriptorProto() const;
template <typename DescriptorT>
std::string ModuleLevelDescriptorName(const DescriptorT& descriptor) const;
std::string ModuleLevelMessageName(const Descriptor& descriptor) const;
std::string ModuleLevelServiceDescriptorName(
const ServiceDescriptor& descriptor) const;
template <typename DescriptorT, typename DescriptorProtoT>
void PrintSerializedPbInterval(const DescriptorT& descriptor,
DescriptorProtoT& proto) const;
void FixAllDescriptorOptions() const;
void FixOptionsForField(const FieldDescriptor& field) const;
void FixOptionsForOneof(const OneofDescriptor& oneof) const;
void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
void FixOptionsForMessage(const Descriptor& descriptor) const;
void CopyPublicDependenciesAliases(const std::string& copy_from,
const FileDescriptor* file) const;
// Very coarse-grained lock to ensure that Generate() is reentrant.
// Guards file_, printer_ and file_descriptor_serialized_.
mutable Mutex mutex_;
mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_.
mutable std::string file_descriptor_serialized_;
mutable io::Printer* printer_; // Set in Generate(). Under mutex_.
mutable bool pure_python_workable_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator);
};
} // namespace python
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__

View File

@@ -0,0 +1,67 @@
// 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 Ruby code for a given .proto file.
#ifndef GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/port_def.inc>
namespace google {
namespace protobuf {
namespace compiler {
namespace ruby {
// CodeGenerator implementation for generated Ruby protocol buffer classes.
// If you create your own protocol compiler binary and you want it to support
// Ruby 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 {
bool Generate(const FileDescriptor* file, const std::string& parameter,
GeneratorContext* generator_context,
std::string* error) const override;
uint64_t GetSupportedFeatures() const override {
return FEATURE_PROTO3_OPTIONAL;
}
};
} // namespace ruby
} // namespace compiler
} // namespace protobuf
} // namespace google
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__