BWAPI
|
00001 // Protocol Buffers - Google's data interchange format 00002 // Copyright 2008 Google Inc. All rights reserved. 00003 // http://code.google.com/p/protobuf/ 00004 // 00005 // Redistribution and use in source and binary forms, with or without 00006 // modification, are permitted provided that the following conditions are 00007 // met: 00008 // 00009 // * Redistributions of source code must retain the above copyright 00010 // notice, this list of conditions and the following disclaimer. 00011 // * Redistributions in binary form must reproduce the above 00012 // copyright notice, this list of conditions and the following disclaimer 00013 // in the documentation and/or other materials provided with the 00014 // distribution. 00015 // * Neither the name of Google Inc. nor the names of its 00016 // contributors may be used to endorse or promote products derived from 00017 // this software without specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00031 // Author: kenton@google.com (Kenton Varda) 00032 // Based on original Protocol Buffers design by 00033 // Sanjay Ghemawat, Jeff Dean, and others. 00034 // 00035 // Implements the Protocol Compiler front-end such that it may be reused by 00036 // custom compilers written to support other languages. 00037 00038 #ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ 00039 #define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__ 00040 00041 #include <google/protobuf/stubs/common.h> 00042 #include <string> 00043 #include <vector> 00044 #include <map> 00045 #include <set> 00046 #include <utility> 00047 00048 namespace google { 00049 namespace protobuf { 00050 00051 class FileDescriptor; // descriptor.h 00052 class DescriptorPool; // descriptor.h 00053 class FileDescriptorProto; // descriptor.pb.h 00054 template<typename T> class RepeatedPtrField; // repeated_field.h 00055 00056 namespace compiler { 00057 00058 class CodeGenerator; // code_generator.h 00059 class OutputDirectory; // code_generator.h 00060 class DiskSourceTree; // importer.h 00061 00062 // This class implements the command-line interface to the protocol compiler. 00063 // It is designed to make it very easy to create a custom protocol compiler 00064 // supporting the languages of your choice. For example, if you wanted to 00065 // create a custom protocol compiler binary which includes both the regular 00066 // C++ support plus support for your own custom output "Foo", you would 00067 // write a class "FooGenerator" which implements the CodeGenerator interface, 00068 // then write a main() procedure like this: 00069 // 00070 // int main(int argc, char* argv[]) { 00071 // google::protobuf::compiler::CommandLineInterface cli; 00072 // 00073 // // Support generation of C++ source and headers. 00074 // google::protobuf::compiler::cpp::CppGenerator cpp_generator; 00075 // cli.RegisterGenerator("--cpp_out", &cpp_generator, 00076 // "Generate C++ source and header."); 00077 // 00078 // // Support generation of Foo code. 00079 // FooGenerator foo_generator; 00080 // cli.RegisterGenerator("--foo_out", &foo_generator, 00081 // "Generate Foo file."); 00082 // 00083 // return cli.Run(argc, argv); 00084 // } 00085 // 00086 // The compiler is invoked with syntax like: 00087 // protoc --cpp_out=outdir --foo_out=outdir --proto_path=src src/foo.proto 00088 // 00089 // For a full description of the command-line syntax, invoke it with --help. 00090 class LIBPROTOC_EXPORT CommandLineInterface { 00091 public: 00092 CommandLineInterface(); 00093 ~CommandLineInterface(); 00094 00095 // Register a code generator for a language. 00096 // 00097 // Parameters: 00098 // * flag_name: The command-line flag used to specify an output file of 00099 // this type. The name must start with a '-'. If the name is longer 00100 // than one letter, it must start with two '-'s. 00101 // * generator: The CodeGenerator which will be called to generate files 00102 // of this type. 00103 // * help_text: Text describing this flag in the --help output. 00104 // 00105 // Some generators accept extra parameters. You can specify this parameter 00106 // on the command-line by placing it before the output directory, separated 00107 // by a colon: 00108 // protoc --foo_out=enable_bar:outdir 00109 // The text before the colon is passed to CodeGenerator::Generate() as the 00110 // "parameter". 00111 void RegisterGenerator(const string& flag_name, 00112 CodeGenerator* generator, 00113 const string& help_text); 00114 00115 // Enables "plugins". In this mode, if a command-line flag ends with "_out" 00116 // but does not match any registered generator, the compiler will attempt to 00117 // find a "plugin" to implement the generator. Plugins are just executables. 00118 // They should live somewhere in the PATH. 00119 // 00120 // The compiler determines the executable name to search for by concatenating 00121 // exe_name_prefix with the unrecognized flag name, removing "_out". So, for 00122 // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out, 00123 // the compiler will try to run the program "protoc-foo". 00124 // 00125 // The plugin program should implement the following usage: 00126 // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS 00127 // --out indicates the output directory (as passed to the --foo_out 00128 // parameter); if omitted, the current directory should be used. --parameter 00129 // gives the generator parameter, if any was provided. The PROTO_FILES list 00130 // the .proto files which were given on the compiler command-line; these are 00131 // the files for which the plugin is expected to generate output code. 00132 // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in 00133 // descriptor.proto). This is piped to the plugin's stdin. The set will 00134 // include descriptors for all the files listed in PROTO_FILES as well as 00135 // all files that they import. The plugin MUST NOT attempt to read the 00136 // PROTO_FILES directly -- it must use the FileDescriptorSet. 00137 // 00138 // The plugin should generate whatever files are necessary, as code generators 00139 // normally do. It should write the names of all files it generates to 00140 // stdout. The names should be relative to the output directory, NOT absolute 00141 // names or relative to the current directory. If any errors occur, error 00142 // messages should be written to stderr. If an error is fatal, the plugin 00143 // should exit with a non-zero exit code. 00144 void AllowPlugins(const string& exe_name_prefix); 00145 00146 // Run the Protocol Compiler with the given command-line parameters. 00147 // Returns the error code which should be returned by main(). 00148 // 00149 // It may not be safe to call Run() in a multi-threaded environment because 00150 // it calls strerror(). I'm not sure why you'd want to do this anyway. 00151 int Run(int argc, const char* const argv[]); 00152 00153 // Call SetInputsAreCwdRelative(true) if the input files given on the command 00154 // line should be interpreted relative to the proto import path specified 00155 // using --proto_path or -I flags. Otherwise, input file names will be 00156 // interpreted relative to the current working directory (or as absolute 00157 // paths if they start with '/'), though they must still reside inside 00158 // a directory given by --proto_path or the compiler will fail. The latter 00159 // mode is generally more intuitive and easier to use, especially e.g. when 00160 // defining implicit rules in Makefiles. 00161 void SetInputsAreProtoPathRelative(bool enable) { 00162 inputs_are_proto_path_relative_ = enable; 00163 } 00164 00165 // Provides some text which will be printed when the --version flag is 00166 // used. The version of libprotoc will also be printed on the next line 00167 // after this text. 00168 void SetVersionInfo(const string& text) { 00169 version_info_ = text; 00170 } 00171 00172 00173 private: 00174 // ----------------------------------------------------------------- 00175 00176 class ErrorPrinter; 00177 class MemoryOutputDirectory; 00178 class MemoryOutputStream; 00179 00180 // Clear state from previous Run(). 00181 void Clear(); 00182 00183 // Remaps each file in input_files_ so that it is relative to one of the 00184 // directories in proto_path_. Returns false if an error occurred. This 00185 // is only used if inputs_are_proto_path_relative_ is false. 00186 bool MakeInputsBeProtoPathRelative( 00187 DiskSourceTree* source_tree); 00188 00189 // Parse all command-line arguments. 00190 bool ParseArguments(int argc, const char* const argv[]); 00191 00192 // Parses a command-line argument into a name/value pair. Returns 00193 // true if the next argument in the argv should be used as the value, 00194 // false otherwise. 00195 // 00196 // Exmaples: 00197 // "-Isrc/protos" -> 00198 // name = "-I", value = "src/protos" 00199 // "--cpp_out=src/foo.pb2.cc" -> 00200 // name = "--cpp_out", value = "src/foo.pb2.cc" 00201 // "foo.proto" -> 00202 // name = "", value = "foo.proto" 00203 bool ParseArgument(const char* arg, string* name, string* value); 00204 00205 // Interprets arguments parsed with ParseArgument. 00206 bool InterpretArgument(const string& name, const string& value); 00207 00208 // Print the --help text to stderr. 00209 void PrintHelpText(); 00210 00211 // Generate the given output file from the given input. 00212 struct OutputDirective; // see below 00213 bool GenerateOutput(const vector<const FileDescriptor*>& parsed_files, 00214 const OutputDirective& output_directive, 00215 OutputDirectory* output_directory); 00216 bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files, 00217 const string& plugin_name, 00218 const string& parameter, 00219 OutputDirectory* output_directory, 00220 string* error); 00221 00222 // Implements --encode and --decode. 00223 bool EncodeOrDecode(const DescriptorPool* pool); 00224 00225 // Implements the --descriptor_set_out option. 00226 bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files); 00227 00228 // Get all transitive dependencies of the given file (including the file 00229 // itself), adding them to the given list of FileDescriptorProtos. The 00230 // protos will be ordered such that every file is listed before any file that 00231 // depends on it, so that you can call DescriptorPool::BuildFile() on them 00232 // in order. Any files in *already_seen will not be added, and each file 00233 // added will be inserted into *already_seen. 00234 static void GetTransitiveDependencies( 00235 const FileDescriptor* file, 00236 set<const FileDescriptor*>* already_seen, 00237 RepeatedPtrField<FileDescriptorProto>* output); 00238 00239 // ----------------------------------------------------------------- 00240 00241 // The name of the executable as invoked (i.e. argv[0]). 00242 string executable_name_; 00243 00244 // Version info set with SetVersionInfo(). 00245 string version_info_; 00246 00247 // Map from flag names to registered generators. 00248 struct GeneratorInfo { 00249 CodeGenerator* generator; 00250 string help_text; 00251 }; 00252 typedef map<string, GeneratorInfo> GeneratorMap; 00253 GeneratorMap generators_; 00254 00255 // See AllowPlugins(). If this is empty, plugins aren't allowed. 00256 string plugin_prefix_; 00257 00258 // Maps specific plugin names to files. When executing a plugin, this map 00259 // is searched first to find the plugin executable. If not found here, the 00260 // PATH (or other OS-specific search strategy) is searched. 00261 map<string, string> plugins_; 00262 00263 // Stuff parsed from command line. 00264 enum Mode { 00265 MODE_COMPILE, // Normal mode: parse .proto files and compile them. 00266 MODE_ENCODE, // --encode: read text from stdin, write binary to stdout. 00267 MODE_DECODE // --decode: read binary from stdin, write text to stdout. 00268 }; 00269 00270 Mode mode_; 00271 00272 enum ErrorFormat { 00273 ERROR_FORMAT_GCC, // GCC error output format (default). 00274 ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs). 00275 }; 00276 00277 ErrorFormat error_format_; 00278 00279 vector<pair<string, string> > proto_path_; // Search path for proto files. 00280 vector<string> input_files_; // Names of the input proto files. 00281 00282 // output_directives_ lists all the files we are supposed to output and what 00283 // generator to use for each. 00284 struct OutputDirective { 00285 string name; // E.g. "--foo_out" 00286 CodeGenerator* generator; // NULL for plugins 00287 string parameter; 00288 string output_location; 00289 }; 00290 vector<OutputDirective> output_directives_; 00291 00292 // When using --encode or --decode, this names the type we are encoding or 00293 // decoding. (Empty string indicates --decode_raw.) 00294 string codec_type_; 00295 00296 // If --descriptor_set_out was given, this is the filename to which the 00297 // FileDescriptorSet should be written. Otherwise, empty. 00298 string descriptor_set_name_; 00299 00300 // True if --include_imports was given, meaning that we should 00301 // write all transitive dependencies to the DescriptorSet. Otherwise, only 00302 // the .proto files listed on the command-line are added. 00303 bool imports_in_descriptor_set_; 00304 00305 // Was the --disallow_services flag used? 00306 bool disallow_services_; 00307 00308 // See SetInputsAreProtoPathRelative(). 00309 bool inputs_are_proto_path_relative_; 00310 00311 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); 00312 }; 00313 00314 } // namespace compiler 00315 } // namespace protobuf 00316 00317 } // namespace google 00318 #endif // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__