#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.
|
#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
For a full description of the command-line syntax, invoke it with --help.
Members | |
---|---|
|
CommandLineInterface()
|
|
~CommandLineInterface()
|
void |
RegisterGenerator(const string & flag_name, CodeGenerator * generator, const string & help_text)
Register a code generator for a language.
more...
|
void |
RegisterGenerator(const string & flag_name, const string & option_flag_name, CodeGenerator * generator, const string & help_text)
Register a code generator for a language.
more...
|
void |
AllowPlugins(const 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 enable)
Call SetInputsAreCwdRelative(true) if the input files given on the command line should be interpreted relative to the proto import path specified using --proto_path or -I flags.
more...
|
void |
SetVersionInfo(const string & text)
Provides some text which will be printed when the --version flag is used.
more...
|
void CommandLineInterface::RegisterGenerator(
const string & flag_name,
CodeGenerator * generator,
const string & help_text)
Register a code generator for a language.
Parameters:
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 string & flag_name,
const string & option_flag_name,
CodeGenerator * generator,
const 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 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-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. 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.
int CommandLineInterface::Run(
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 enable)
Call SetInputsAreCwdRelative(true) if the input files given on the command line should be interpreted relative to the proto import path specified using --proto_path or -I flags.
Otherwise, input file names will be interpreted relative to the current working directory (or as absolute paths if they start with '/'), though they must still reside inside a directory given by --proto_path or the compiler will fail. The latter mode is generally more intuitive and easier to use, especially e.g. when defining implicit rules in Makefiles.
void CommandLineInterface::SetVersionInfo(
const 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.