command_line_interface.h
#include <google/protobuf/compiler/command_line_interface.h>
namespace google::protobuf::compiler
Implements the Protocol Compiler front-end such that it may be reused by custom compilers written to support other languages.
Classes in this file | |
---|---|
This class implements the command-line interface to the protocol compiler. |
class CommandLineInterface
#include <google/protobuf/compiler/command_line_interface.h>
namespace google::protobuf::compiler
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.
Members | |
---|---|
const char *const | kPathSeparator |
| CommandLineInterface() |
| ~CommandLineInterface() |
void | RegisterGenerator(const std::string & flag_name, CodeGenerator * generator, const std::string & help_text) Register a code generator for a language. more... |
void | RegisterGenerator(const std::string & flag_name, const std::string & option_flag_name, CodeGenerator * generator, const std::string & help_text) Register a code generator for a language. more... |
void | AllowPlugins(const std::string & exe_name_prefix) Enables "plugins". more... |
int | Run(int argc, const char *const argv) Run the Protocol Compiler with the given command-line parameters. more... |
void | SetInputsAreProtoPathRelative(bool ) DEPRECATED. more... |
void | SetVersionInfo(const std::string & text) Provides some text which will be printed when the –version flag is used. more... |
void CommandLineInterface::RegisterGenerator(
const std::string & flag_name,
CodeGenerator * generator,
const std::string & help_text)
const std::string & flag_name,
CodeGenerator * generator,
const std::string & help_text)
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 CommandLineInterface::RegisterGenerator(
const std::string & flag_name,
const std::string & option_flag_name,
CodeGenerator * generator,
const std::string & help_text)
const std::string & flag_name,
const std::string & option_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 CommandLineInterface::AllowPlugins(
const std::string & exe_name_prefix)
const std::string & exe_name_prefix)
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.
int CommandLineInterface::Run(
int argc,
const char *const argv)
int argc,
const char *const argv)
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.
void CommandLineInterface::SetInputsAreProtoPathRelative(
bool )
bool )
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 CommandLineInterface::SetVersionInfo(
const std::string & text)
const std::string & text)
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.