// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.
//
// Implements the Protocol Compiler front-end such that it may be reused by
// custom compilers written to support other languages.

#ifndef GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
#define GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__

#include <map>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include <google/protobuf/stubs/common.h>

#include <google/protobuf/port_def.inc>

namespace google {
namespace protobuf {

class Descriptor;           // descriptor.h
class DescriptorDatabase;   // descriptor_database.h
class DescriptorPool;       // descriptor.h
class FileDescriptor;       // descriptor.h
class FileDescriptorSet;    // descriptor.h
class FileDescriptorProto;  // descriptor.pb.h
template <typename T>
class RepeatedPtrField;          // repeated_field.h
class SimpleDescriptorDatabase;  // descriptor_database.h

namespace compiler {

class CodeGenerator;     // code_generator.h
class GeneratorContext;  // code_generator.h
class DiskSourceTree;    // importer.h

// 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 diretory 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 precendence.
//
// For a full description of the command-line syntax, invoke it with --help.
class PROTOC_EXPORT CommandLineInterface {
 public:
  static const char* const kPathSeparator;

  CommandLineInterface();
  ~CommandLineInterface();

  // 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 RegisterGenerator(const std::string& 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 RegisterGenerator(const std::string& flag_name,
                         const std::string& option_flag_name,
                         CodeGenerator* generator,
                         const std::string& help_text);

  // 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 (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.
  //
  void AllowPlugins(const std::string& exe_name_prefix);

  // 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.
  int Run(int argc, const char* const argv[]);

  // 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 virutal path.
  void SetInputsAreProtoPathRelative(bool /* enable */) {}

  // 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.
  void SetVersionInfo(const std::string& text) { version_info_ = text; }


 private:
  // -----------------------------------------------------------------

  class ErrorPrinter;
  class GeneratorContextImpl;
  class MemoryOutputStream;
  typedef std::unordered_map<std::string, GeneratorContextImpl*>
      GeneratorContextMap;

  // Clear state from previous Run().
  void Clear();

  // Remaps the proto file so that it is relative to one of the directories
  // in proto_path_.  Returns false if an error occurred.
  bool MakeProtoProtoPathRelative(DiskSourceTree* source_tree,
                                  std::string* proto,
                                  DescriptorDatabase* fallback_database);

  // Remaps each file in input_files_ so that it is relative to one of the
  // directories in proto_path_.  Returns false if an error occurred.
  bool MakeInputsBeProtoPathRelative(DiskSourceTree* source_tree,
                                     DescriptorDatabase* fallback_database);


  // Return status for ParseArguments() and InterpretArgument().
  enum ParseArgumentStatus {
    PARSE_ARGUMENT_DONE_AND_CONTINUE,
    PARSE_ARGUMENT_DONE_AND_EXIT,
    PARSE_ARGUMENT_FAIL
  };

  // Parse all command-line arguments.
  ParseArgumentStatus ParseArguments(int argc, const char* const argv[]);

  // Read an argument file and append the file's content to the list of
  // arguments. Return false if the file cannot be read.
  bool ExpandArgumentFile(const std::string& file,
                          std::vector<std::string>* arguments);

  // Parses a command-line argument into a name/value pair.  Returns
  // true if the next argument in the argv should be used as the value,
  // false otherwise.
  //
  // Examples:
  //   "-Isrc/protos" ->
  //     name = "-I", value = "src/protos"
  //   "--cpp_out=src/foo.pb2.cc" ->
  //     name = "--cpp_out", value = "src/foo.pb2.cc"
  //   "foo.proto" ->
  //     name = "", value = "foo.proto"
  bool ParseArgument(const char* arg, std::string* name, std::string* value);

  // Interprets arguments parsed with ParseArgument.
  ParseArgumentStatus InterpretArgument(const std::string& name,
                                        const std::string& value);

  // Print the --help text to stderr.
  void PrintHelpText();

  // Loads proto_path_ into the provided source_tree.
  bool InitializeDiskSourceTree(DiskSourceTree* source_tree,
                                DescriptorDatabase* fallback_database);

  // Verify that all the input files exist in the given database.
  bool VerifyInputFilesInDescriptors(DescriptorDatabase* fallback_database);

  // Loads descriptor_set_in into the provided database
  bool PopulateSimpleDescriptorDatabase(SimpleDescriptorDatabase* database);

  // Parses input_files_ into parsed_files
  bool ParseInputFiles(DescriptorPool* descriptor_pool,
                       std::vector<const FileDescriptor*>* parsed_files);

  // Generate the given output file from the given input.
  struct OutputDirective;  // see below
  bool GenerateOutput(const std::vector<const FileDescriptor*>& parsed_files,
                      const OutputDirective& output_directive,
                      GeneratorContext* generator_context);
  bool GeneratePluginOutput(
      const std::vector<const FileDescriptor*>& parsed_files,
      const std::string& plugin_name, const std::string& parameter,
      GeneratorContext* generator_context, std::string* error);

  // Implements --encode and --decode.
  bool EncodeOrDecode(const DescriptorPool* pool);

  // Implements the --descriptor_set_out option.
  bool WriteDescriptorSet(
      const std::vector<const FileDescriptor*>& parsed_files);

  // Implements the --dependency_out option
  bool GenerateDependencyManifestFile(
      const std::vector<const FileDescriptor*>& parsed_files,
      const GeneratorContextMap& output_directories,
      DiskSourceTree* source_tree);

  // Get all transitive dependencies of the given file (including the file
  // itself), adding them to the given list of FileDescriptorProtos.  The
  // protos will be ordered such that every file is listed before any file that
  // depends on it, so that you can call DescriptorPool::BuildFile() on them
  // in order.  Any files in *already_seen will not be added, and each file
  // added will be inserted into *already_seen.  If include_source_code_info is
  // true then include the source code information in the FileDescriptorProtos.
  // If include_json_name is true, populate the json_name field of
  // FieldDescriptorProto for all fields.
  static void GetTransitiveDependencies(
      const FileDescriptor* file, bool include_json_name,
      bool include_source_code_info,
      std::set<const FileDescriptor*>* already_seen,
      RepeatedPtrField<FileDescriptorProto>* output);

  // Implements the --print_free_field_numbers. This function prints free field
  // numbers into stdout for the message and it's nested message types in
  // post-order, i.e. nested types first. Printed range are left-right
  // inclusive, i.e. [a, b].
  //
  // Groups:
  // For historical reasons, groups are considered to share the same
  // field number space with the parent message, thus it will not print free
  // field numbers for groups. The field numbers used in the groups are
  // excluded in the free field numbers of the parent message.
  //
  // Extension Ranges:
  // Extension ranges are considered ocuppied field numbers and they will not be
  // listed as free numbers in the output.
  void PrintFreeFieldNumbers(const Descriptor* descriptor);

  // -----------------------------------------------------------------

  // The name of the executable as invoked (i.e. argv[0]).
  std::string executable_name_;

  // Version info set with SetVersionInfo().
  std::string version_info_;

  // Registered generators.
  struct GeneratorInfo {
    std::string flag_name;
    std::string option_flag_name;
    CodeGenerator* generator;
    std::string help_text;
  };
  typedef std::map<std::string, GeneratorInfo> GeneratorMap;
  GeneratorMap generators_by_flag_name_;
  GeneratorMap generators_by_option_name_;
  // A map from generator names to the parameters specified using the option
  // flag. For example, if the user invokes the compiler with:
  //   protoc --foo_out=outputdir --foo_opt=enable_bar ...
  // Then there will be an entry ("--foo_out", "enable_bar") in this map.
  std::map<std::string, std::string> generator_parameters_;
  // Similar to generator_parameters_, but stores the parameters for plugins.
  std::map<std::string, std::string> plugin_parameters_;

  // See AllowPlugins().  If this is empty, plugins aren't allowed.
  std::string plugin_prefix_;

  // Maps specific plugin names to files.  When executing a plugin, this map
  // is searched first to find the plugin executable.  If not found here, the
  // PATH (or other OS-specific search strategy) is searched.
  std::map<std::string, std::string> plugins_;

  // Stuff parsed from command line.
  enum Mode {
    MODE_COMPILE,  // Normal mode:  parse .proto files and compile them.
    MODE_ENCODE,   // --encode:  read text from stdin, write binary to stdout.
    MODE_DECODE,   // --decode:  read binary from stdin, write text to stdout.
    MODE_PRINT,    // Print mode: print info of the given .proto files and exit.
  };

  Mode mode_;

  enum PrintMode {
    PRINT_NONE,         // Not in MODE_PRINT
    PRINT_FREE_FIELDS,  // --print_free_fields
  };

  PrintMode print_mode_;

  enum ErrorFormat {
    ERROR_FORMAT_GCC,  // GCC error output format (default).
    ERROR_FORMAT_MSVS  // Visual Studio output (--error_format=msvs).
  };

  ErrorFormat error_format_;

  std::vector<std::pair<std::string, std::string> >
      proto_path_;                        // Search path for proto files.
  std::vector<std::string> input_files_;  // Names of the input proto files.

  // Names of proto files which are allowed to be imported. Used by build
  // systems to enforce depend-on-what-you-import.
  std::set<std::string> direct_dependencies_;
  bool direct_dependencies_explicitly_set_;

  // If there's a violation of depend-on-what-you-import, this string will be
  // presented to the user. "%s" will be replaced with the violating import.
  std::string direct_dependencies_violation_msg_;

  // output_directives_ lists all the files we are supposed to output and what
  // generator to use for each.
  struct OutputDirective {
    std::string name;          // E.g. "--foo_out"
    CodeGenerator* generator;  // NULL for plugins
    std::string parameter;
    std::string output_location;
  };
  std::vector<OutputDirective> output_directives_;

  // When using --encode or --decode, this names the type we are encoding or
  // decoding.  (Empty string indicates --decode_raw.)
  std::string codec_type_;

  // If --descriptor_set_in was given, these are filenames containing
  // parsed FileDescriptorSets to be used for loading protos.  Otherwise, empty.
  std::vector<std::string> descriptor_set_in_names_;

  // If --descriptor_set_out was given, this is the filename to which the
  // FileDescriptorSet should be written.  Otherwise, empty.
  std::string descriptor_set_out_name_;

  // If --dependency_out was given, this is the path to the file where the
  // dependency file will be written. Otherwise, empty.
  std::string dependency_out_name_;

  // True if --include_imports was given, meaning that we should
  // write all transitive dependencies to the DescriptorSet.  Otherwise, only
  // the .proto files listed on the command-line are added.
  bool imports_in_descriptor_set_;

  // True if --include_source_info was given, meaning that we should not strip
  // SourceCodeInfo from the DescriptorSet.
  bool source_info_in_descriptor_set_;

  // Was the --disallow_services flag used?
  bool disallow_services_;

  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface);
};

}  // namespace compiler
}  // namespace protobuf
}  // namespace google

#include <google/protobuf/port_undef.inc>

#endif  // GOOGLE_PROTOBUF_COMPILER_COMMAND_LINE_INTERFACE_H__
