command_line_interface.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. //
  34. // Implements the Protocol Compiler front-end such that it may be reused by
  35. // custom compilers written to support other languages.
  36. #ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
  37. #define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
  38. #include <google/protobuf/stubs/common.h>
  39. #include <google/protobuf/stubs/hash.h>
  40. #include <string>
  41. #include <vector>
  42. #include <map>
  43. #include <set>
  44. #include <utility>
  45. namespace google {
  46. namespace protobuf {
  47. class Descriptor; // descriptor.h
  48. class DescriptorPool; // descriptor.h
  49. class FileDescriptor; // descriptor.h
  50. class FileDescriptorSet; // descriptor.h
  51. class FileDescriptorProto; // descriptor.pb.h
  52. template<typename T> class RepeatedPtrField; // repeated_field.h
  53. class SimpleDescriptorDatabase; // descriptor_database.h
  54. namespace compiler {
  55. class CodeGenerator; // code_generator.h
  56. class GeneratorContext; // code_generator.h
  57. class DiskSourceTree; // importer.h
  58. // This class implements the command-line interface to the protocol compiler.
  59. // It is designed to make it very easy to create a custom protocol compiler
  60. // supporting the languages of your choice. For example, if you wanted to
  61. // create a custom protocol compiler binary which includes both the regular
  62. // C++ support plus support for your own custom output "Foo", you would
  63. // write a class "FooGenerator" which implements the CodeGenerator interface,
  64. // then write a main() procedure like this:
  65. //
  66. // int main(int argc, char* argv[]) {
  67. // google::protobuf::compiler::CommandLineInterface cli;
  68. //
  69. // // Support generation of C++ source and headers.
  70. // google::protobuf::compiler::cpp::CppGenerator cpp_generator;
  71. // cli.RegisterGenerator("--cpp_out", &cpp_generator,
  72. // "Generate C++ source and header.");
  73. //
  74. // // Support generation of Foo code.
  75. // FooGenerator foo_generator;
  76. // cli.RegisterGenerator("--foo_out", &foo_generator,
  77. // "Generate Foo file.");
  78. //
  79. // return cli.Run(argc, argv);
  80. // }
  81. //
  82. // The compiler is invoked with syntax like:
  83. // protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto
  84. //
  85. // The .proto file to compile can be specified on the command line using either
  86. // its physical file path, or a virtual path relative to a diretory specified
  87. // in --proto_path. For example, for src/foo.proto, the following two protoc
  88. // invocations work the same way:
  89. // 1. protoc --proto_path=src src/foo.proto (physical file path)
  90. // 2. protoc --proto_path=src foo.proto (virtual path relative to src)
  91. //
  92. // If a file path can be interpreted both as a physical file path and as a
  93. // relative virtual path, the physical file path takes precendence.
  94. //
  95. // For a full description of the command-line syntax, invoke it with --help.
  96. class LIBPROTOC_EXPORT CommandLineInterface {
  97. public:
  98. static const char* const kPathSeparator;
  99. CommandLineInterface();
  100. ~CommandLineInterface();
  101. // Register a code generator for a language.
  102. //
  103. // Parameters:
  104. // * flag_name: The command-line flag used to specify an output file of
  105. // this type. The name must start with a '-'. If the name is longer
  106. // than one letter, it must start with two '-'s.
  107. // * generator: The CodeGenerator which will be called to generate files
  108. // of this type.
  109. // * help_text: Text describing this flag in the --help output.
  110. //
  111. // Some generators accept extra parameters. You can specify this parameter
  112. // on the command-line by placing it before the output directory, separated
  113. // by a colon:
  114. // protoc --foo_out=enable_bar:outdir
  115. // The text before the colon is passed to CodeGenerator::Generate() as the
  116. // "parameter".
  117. void RegisterGenerator(const string& flag_name,
  118. CodeGenerator* generator,
  119. const string& help_text);
  120. // Register a code generator for a language.
  121. // Besides flag_name you can specify another option_flag_name that could be
  122. // used to pass extra parameters to the registered code generator.
  123. // Suppose you have registered a generator by calling:
  124. // command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
  125. // Then you could invoke the compiler with a command like:
  126. // protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
  127. // This will pass "enable_bar,enable_baz" as the parameter to the generator.
  128. void RegisterGenerator(const string& flag_name,
  129. const string& option_flag_name,
  130. CodeGenerator* generator,
  131. const string& help_text);
  132. // Enables "plugins". In this mode, if a command-line flag ends with "_out"
  133. // but does not match any registered generator, the compiler will attempt to
  134. // find a "plugin" to implement the generator. Plugins are just executables.
  135. // They should live somewhere in the PATH.
  136. //
  137. // The compiler determines the executable name to search for by concatenating
  138. // exe_name_prefix with the unrecognized flag name, removing "_out". So, for
  139. // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out,
  140. // the compiler will try to run the program "protoc-foo".
  141. //
  142. // The plugin program should implement the following usage:
  143. // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
  144. // --out indicates the output directory (as passed to the --foo_out
  145. // parameter); if omitted, the current directory should be used. --parameter
  146. // gives the generator parameter, if any was provided (see below). The
  147. // PROTO_FILES list the .proto files which were given on the compiler
  148. // command-line; these are the files for which the plugin is expected to
  149. // generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet
  150. // (as defined in descriptor.proto). This is piped to the plugin's stdin.
  151. // The set will include descriptors for all the files listed in PROTO_FILES as
  152. // well as all files that they import. The plugin MUST NOT attempt to read
  153. // the PROTO_FILES directly -- it must use the FileDescriptorSet.
  154. //
  155. // The plugin should generate whatever files are necessary, as code generators
  156. // normally do. It should write the names of all files it generates to
  157. // stdout. The names should be relative to the output directory, NOT absolute
  158. // names or relative to the current directory. If any errors occur, error
  159. // messages should be written to stderr. If an error is fatal, the plugin
  160. // should exit with a non-zero exit code.
  161. //
  162. // Plugins can have generator parameters similar to normal built-in
  163. // generators. Extra generator parameters can be passed in via a matching
  164. // "_opt" parameter. For example:
  165. // protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz
  166. // This will pass "enable_bar,enable_baz" as the parameter to the plugin.
  167. //
  168. void AllowPlugins(const string& exe_name_prefix);
  169. // Run the Protocol Compiler with the given command-line parameters.
  170. // Returns the error code which should be returned by main().
  171. //
  172. // It may not be safe to call Run() in a multi-threaded environment because
  173. // it calls strerror(). I'm not sure why you'd want to do this anyway.
  174. int Run(int argc, const char* const argv[]);
  175. // DEPRECATED. Calling this method has no effect. Protocol compiler now
  176. // always try to find the .proto file relative to the current directory
  177. // first and if the file is not found, it will then treat the input path
  178. // as a virutal path.
  179. void SetInputsAreProtoPathRelative(bool /* enable */) {}
  180. // Provides some text which will be printed when the --version flag is
  181. // used. The version of libprotoc will also be printed on the next line
  182. // after this text.
  183. void SetVersionInfo(const string& text) {
  184. version_info_ = text;
  185. }
  186. private:
  187. // -----------------------------------------------------------------
  188. class ErrorPrinter;
  189. class GeneratorContextImpl;
  190. class MemoryOutputStream;
  191. typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
  192. // Clear state from previous Run().
  193. void Clear();
  194. // Remaps each file in input_files_ so that it is relative to one of the
  195. // directories in proto_path_. Returns false if an error occurred. This
  196. // is only used if inputs_are_proto_path_relative_ is false.
  197. bool MakeInputsBeProtoPathRelative(
  198. DiskSourceTree* source_tree);
  199. // Return status for ParseArguments() and InterpretArgument().
  200. enum ParseArgumentStatus {
  201. PARSE_ARGUMENT_DONE_AND_CONTINUE,
  202. PARSE_ARGUMENT_DONE_AND_EXIT,
  203. PARSE_ARGUMENT_FAIL
  204. };
  205. // Parse all command-line arguments.
  206. ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);
  207. // Read an argument file and append the file's content to the list of
  208. // arguments. Return false if the file cannot be read.
  209. bool ExpandArgumentFile(const string& file, std::vector<string>* arguments);
  210. // Parses a command-line argument into a name/value pair. Returns
  211. // true if the next argument in the argv should be used as the value,
  212. // false otherwise.
  213. //
  214. // Examples:
  215. // "-Isrc/protos" ->
  216. // name = "-I", value = "src/protos"
  217. // "--cpp_out=src/foo.pb2.cc" ->
  218. // name = "--cpp_out", value = "src/foo.pb2.cc"
  219. // "foo.proto" ->
  220. // name = "", value = "foo.proto"
  221. bool ParseArgument(const char* arg, string* name, string* value);
  222. // Interprets arguments parsed with ParseArgument.
  223. ParseArgumentStatus InterpretArgument(const string& name,
  224. const string& value);
  225. // Print the --help text to stderr.
  226. void PrintHelpText();
  227. // Loads proto_path_ into the provided source_tree.
  228. bool InitializeDiskSourceTree(DiskSourceTree* source_tree);
  229. // Loads descriptor_set_in into the provided database
  230. bool PopulateSimpleDescriptorDatabase(SimpleDescriptorDatabase* database);
  231. // Parses input_files_ into parsed_files
  232. bool ParseInputFiles(DescriptorPool* descriptor_pool,
  233. std::vector<const FileDescriptor*>* parsed_files);
  234. // Generate the given output file from the given input.
  235. struct OutputDirective; // see below
  236. bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files,
  237. const OutputDirective& output_directive,
  238. GeneratorContext* generator_context);
  239. bool GeneratePluginOutput(
  240. const std::vector<const FileDescriptor*>& parsed_files,
  241. const string& plugin_name, const string& parameter,
  242. GeneratorContext* generator_context, string* error);
  243. // Implements --encode and --decode.
  244. bool EncodeOrDecode(const DescriptorPool* pool);
  245. // Implements the --descriptor_set_out option.
  246. bool WriteDescriptorSet(
  247. const std::vector<const FileDescriptor*>& parsed_files);
  248. // Implements the --dependency_out option
  249. bool GenerateDependencyManifestFile(
  250. const std::vector<const FileDescriptor*>& parsed_files,
  251. const GeneratorContextMap& output_directories,
  252. DiskSourceTree* source_tree);
  253. // Get all transitive dependencies of the given file (including the file
  254. // itself), adding them to the given list of FileDescriptorProtos. The
  255. // protos will be ordered such that every file is listed before any file that
  256. // depends on it, so that you can call DescriptorPool::BuildFile() on them
  257. // in order. Any files in *already_seen will not be added, and each file
  258. // added will be inserted into *already_seen. If include_source_code_info is
  259. // true then include the source code information in the FileDescriptorProtos.
  260. // If include_json_name is true, populate the json_name field of
  261. // FieldDescriptorProto for all fields.
  262. static void GetTransitiveDependencies(
  263. const FileDescriptor* file,
  264. bool include_json_name,
  265. bool include_source_code_info,
  266. std::set<const FileDescriptor*>* already_seen,
  267. RepeatedPtrField<FileDescriptorProto>* output);
  268. // Implements the --print_free_field_numbers. This function prints free field
  269. // numbers into stdout for the message and it's nested message types in
  270. // post-order, i.e. nested types first. Printed range are left-right
  271. // inclusive, i.e. [a, b].
  272. //
  273. // Groups:
  274. // For historical reasons, groups are considered to share the same
  275. // field number space with the parent message, thus it will not print free
  276. // field numbers for groups. The field numbers used in the groups are
  277. // excluded in the free field numbers of the parent message.
  278. //
  279. // Extension Ranges:
  280. // Extension ranges are considered ocuppied field numbers and they will not be
  281. // listed as free numbers in the output.
  282. void PrintFreeFieldNumbers(const Descriptor* descriptor);
  283. // -----------------------------------------------------------------
  284. // The name of the executable as invoked (i.e. argv[0]).
  285. string executable_name_;
  286. // Version info set with SetVersionInfo().
  287. string version_info_;
  288. // Registered generators.
  289. struct GeneratorInfo {
  290. string flag_name;
  291. string option_flag_name;
  292. CodeGenerator* generator;
  293. string help_text;
  294. };
  295. typedef std::map<string, GeneratorInfo> GeneratorMap;
  296. GeneratorMap generators_by_flag_name_;
  297. GeneratorMap generators_by_option_name_;
  298. // A map from generator names to the parameters specified using the option
  299. // flag. For example, if the user invokes the compiler with:
  300. // protoc --foo_out=outputdir --foo_opt=enable_bar ...
  301. // Then there will be an entry ("--foo_out", "enable_bar") in this map.
  302. std::map<string, string> generator_parameters_;
  303. // Similar to generator_parameters_, but stores the parameters for plugins.
  304. std::map<string, string> plugin_parameters_;
  305. // See AllowPlugins(). If this is empty, plugins aren't allowed.
  306. string plugin_prefix_;
  307. // Maps specific plugin names to files. When executing a plugin, this map
  308. // is searched first to find the plugin executable. If not found here, the
  309. // PATH (or other OS-specific search strategy) is searched.
  310. std::map<string, string> plugins_;
  311. // Stuff parsed from command line.
  312. enum Mode {
  313. MODE_COMPILE, // Normal mode: parse .proto files and compile them.
  314. MODE_ENCODE, // --encode: read text from stdin, write binary to stdout.
  315. MODE_DECODE, // --decode: read binary from stdin, write text to stdout.
  316. MODE_PRINT, // Print mode: print info of the given .proto files and exit.
  317. };
  318. Mode mode_;
  319. enum PrintMode {
  320. PRINT_NONE, // Not in MODE_PRINT
  321. PRINT_FREE_FIELDS, // --print_free_fields
  322. };
  323. PrintMode print_mode_;
  324. enum ErrorFormat {
  325. ERROR_FORMAT_GCC, // GCC error output format (default).
  326. ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
  327. };
  328. ErrorFormat error_format_;
  329. std::vector<std::pair<string, string> >
  330. proto_path_; // Search path for proto files.
  331. std::vector<string> input_files_; // Names of the input proto files.
  332. // Names of proto files which are allowed to be imported. Used by build
  333. // systems to enforce depend-on-what-you-import.
  334. std::set<string> direct_dependencies_;
  335. bool direct_dependencies_explicitly_set_;
  336. // If there's a violation of depend-on-what-you-import, this string will be
  337. // presented to the user. "%s" will be replaced with the violating import.
  338. string direct_dependencies_violation_msg_;
  339. // output_directives_ lists all the files we are supposed to output and what
  340. // generator to use for each.
  341. struct OutputDirective {
  342. string name; // E.g. "--foo_out"
  343. CodeGenerator* generator; // NULL for plugins
  344. string parameter;
  345. string output_location;
  346. };
  347. std::vector<OutputDirective> output_directives_;
  348. // When using --encode or --decode, this names the type we are encoding or
  349. // decoding. (Empty string indicates --decode_raw.)
  350. string codec_type_;
  351. // If --descriptor_set_in was given, these are filenames containing
  352. // parsed FileDescriptorSets to be used for loading protos. Otherwise, empty.
  353. std::vector<string> descriptor_set_in_names_;
  354. // If --descriptor_set_out was given, this is the filename to which the
  355. // FileDescriptorSet should be written. Otherwise, empty.
  356. string descriptor_set_out_name_;
  357. // If --dependency_out was given, this is the path to the file where the
  358. // dependency file will be written. Otherwise, empty.
  359. string dependency_out_name_;
  360. // True if --include_imports was given, meaning that we should
  361. // write all transitive dependencies to the DescriptorSet. Otherwise, only
  362. // the .proto files listed on the command-line are added.
  363. bool imports_in_descriptor_set_;
  364. // True if --include_source_info was given, meaning that we should not strip
  365. // SourceCodeInfo from the DescriptorSet.
  366. bool source_info_in_descriptor_set_;
  367. // Was the --disallow_services flag used?
  368. bool disallow_services_;
  369. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
  370. };
  371. } // namespace compiler
  372. } // namespace protobuf
  373. } // namespace google
  374. #endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__