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