Forráskód Böngészése

Add version number to plugin protocol.

Feng Xiao 9 éve
szülő
commit
ced8f73ffc

+ 8 - 0
src/google/protobuf/compiler/code_generator.cc

@@ -34,6 +34,7 @@
 
 #include <google/protobuf/compiler/code_generator.h>
 
+#include <google/protobuf/compiler/plugin.pb.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/descriptor.h>
@@ -89,6 +90,13 @@ void GeneratorContext::ListParsedFiles(
   GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
 }
 
+void GeneratorContext::GetCompilerVersion(Version* version) const {
+  version->set_major(GOOGLE_PROTOBUF_VERSION / 1000000);
+  version->set_minor(GOOGLE_PROTOBUF_VERSION / 1000 % 1000);
+  version->set_patch(GOOGLE_PROTOBUF_VERSION % 1000);
+  version->set_suffix(GOOGLE_PROTOBUF_VERSION_SUFFIX);
+}
+
 // Parses a set of comma-delimited name/value pairs.
 void ParseGeneratorParameter(const string& text,
                              std::vector<std::pair<string, string> >* output) {

+ 5 - 0
src/google/protobuf/compiler/code_generator.h

@@ -50,6 +50,7 @@ namespace io { class ZeroCopyOutputStream; }
 class FileDescriptor;
 
 namespace compiler {
+class Version;
 
 // Defined in this file.
 class CodeGenerator;
@@ -143,6 +144,10 @@ class LIBPROTOC_EXPORT GeneratorContext {
   // differently when compiled as a set rather than individually.
   virtual void ListParsedFiles(std::vector<const FileDescriptor*>* output);
 
+  // Retrieves the version number of the protocol compiler associated with
+  // this GeneratorContext.
+  virtual void GetCompilerVersion(Version* version) const;
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
 };

+ 7 - 0
src/google/protobuf/compiler/command_line_interface.cc

@@ -1619,6 +1619,13 @@ bool CommandLineInterface::GeneratePluginOutput(
                               &already_seen, request.mutable_proto_file());
   }
 
+  google::protobuf::compiler::Version* version =
+      request.mutable_compiler_version();
+  version->set_major(GOOGLE_PROTOBUF_VERSION / 1000000);
+  version->set_minor(GOOGLE_PROTOBUF_VERSION / 1000 % 1000);
+  version->set_patch(GOOGLE_PROTOBUF_VERSION % 1000);
+  version->set_suffix(GOOGLE_PROTOBUF_VERSION_SUFFIX);
+
   // Invoke the plugin.
   Subprocess subprocess;
 

+ 16 - 0
src/google/protobuf/compiler/command_line_interface_unittest.cc

@@ -57,6 +57,7 @@
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 
@@ -1582,6 +1583,21 @@ TEST_F(CommandLineInterfaceTest, PluginReceivesJsonName) {
   ExpectErrorSubstring("Saw json_name: 1");
 }
 
+TEST_F(CommandLineInterfaceTest, PluginReceivesCompilerVersion) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message MockCodeGenerator_ShowVersionNumber {\n"
+    "  optional int32 value = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring(
+      StringPrintf("Saw compiler_version: %d %s",
+                   GOOGLE_PROTOBUF_VERSION,
+                   GOOGLE_PROTOBUF_VERSION_SUFFIX));
+}
+
 TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
   // Test what happens if the plugin isn't found.
 

+ 10 - 0
src/google/protobuf/compiler/mock_code_generator.cc

@@ -40,6 +40,7 @@
 #endif
 #include <vector>
 
+#include <google/protobuf/compiler/plugin.pb.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/testing/file.h>
@@ -160,6 +161,15 @@ bool MockCodeGenerator::Generate(
         std::cerr << "Saw json_name: "
                   << field_descriptor_proto.has_json_name() << std::endl;
         abort();
+      } else if (command == "ShowVersionNumber") {
+        Version compiler_version;
+        context->GetCompilerVersion(&compiler_version);
+        std::cerr << "Saw compiler_version: "
+                  << compiler_version.major() * 1000000 +
+                     compiler_version.minor() * 1000 +
+                     compiler_version.patch()
+                  << " " << compiler_version.suffix() << std::endl;
+        abort();
       } else {
         GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
       }

+ 11 - 2
src/google/protobuf/compiler/plugin.cc

@@ -63,9 +63,12 @@ namespace compiler {
 class GeneratorResponseContext : public GeneratorContext {
  public:
   GeneratorResponseContext(
+      const Version& compiler_version,
       CodeGeneratorResponse* response,
       const std::vector<const FileDescriptor*>& parsed_files)
-      : response_(response), parsed_files_(parsed_files) {}
+      : compiler_version_(compiler_version),
+        response_(response),
+        parsed_files_(parsed_files) {}
   virtual ~GeneratorResponseContext() {}
 
   // implements GeneratorContext --------------------------------------
@@ -88,7 +91,12 @@ class GeneratorResponseContext : public GeneratorContext {
     *output = parsed_files_;
   }
 
+  void GetCompilerVersion(Version* version) const {
+    *version = compiler_version_;
+  }
+
  private:
+  Version compiler_version_;
   CodeGeneratorResponse* response_;
   const std::vector<const FileDescriptor*>& parsed_files_;
 };
@@ -116,7 +124,8 @@ bool GenerateCode(const CodeGeneratorRequest& request,
     }
   }
 
-  GeneratorResponseContext context(response, parsed_files);
+  GeneratorResponseContext context(
+      request.compiler_version(), response, parsed_files);
 
   string error;
   bool succeeded = generator.GenerateAll(

+ 660 - 39
src/google/protobuf/compiler/plugin.pb.cc

@@ -20,6 +20,8 @@
 namespace google {
 namespace protobuf {
 namespace compiler {
+class VersionDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<Version> {};
+VersionDefaultTypeInternal _Version_default_instance_;
 class CodeGeneratorRequestDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorRequest> {};
 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_;
 class CodeGeneratorResponse_FileDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed<CodeGeneratorResponse_File> {};
@@ -29,7 +31,7 @@ CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance
 
 namespace {
 
-::google::protobuf::Metadata file_level_metadata[3];
+::google::protobuf::Metadata file_level_metadata[4];
 
 }  // namespace
 
@@ -37,6 +39,18 @@ namespace {
 const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
 const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
   static const ::google::protobuf::uint32 offsets[] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _has_bits_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _internal_metadata_),
+    ~0u,  // no _extensions_
+    ~0u,  // no _oneof_case_
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, major_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, minor_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, patch_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, suffix_),
+    1,
+    2,
+    3,
+    0,
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_),
     ~0u,  // no _extensions_
@@ -44,9 +58,11 @@ const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fcompiler_
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_),
-    1,
-    0,
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, compiler_version_),
     2,
+    0,
+    3,
+    1,
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_),
     ~0u,  // no _extensions_
@@ -70,12 +86,14 @@ const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fcompiler_
 }
 
 static const ::google::protobuf::internal::MigrationSchema schemas[] = {
-  { 0, 7, sizeof(CodeGeneratorRequest)},
-  { 10, 17, sizeof(CodeGeneratorResponse_File)},
-  { 20, 26, sizeof(CodeGeneratorResponse)},
+  { 0, 8, sizeof(Version)},
+  { 12, 20, sizeof(CodeGeneratorRequest)},
+  { 24, 31, sizeof(CodeGeneratorResponse_File)},
+  { 34, 40, sizeof(CodeGeneratorResponse)},
 };
 
 static const ::google::protobuf::internal::DefaultInstanceData file_default_instances[] = {
+  {reinterpret_cast<const ::google::protobuf::Message*>(&_Version_default_instance_), NULL},
   {reinterpret_cast<const ::google::protobuf::Message*>(&_CodeGeneratorRequest_default_instance_), NULL},
   {reinterpret_cast<const ::google::protobuf::Message*>(&_CodeGeneratorResponse_File_default_instance_), NULL},
   {reinterpret_cast<const ::google::protobuf::Message*>(&_CodeGeneratorResponse_default_instance_), NULL},
@@ -99,18 +117,20 @@ void protobuf_AssignDescriptorsOnce() {
 void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
 void protobuf_RegisterTypes(const ::std::string&) {
   protobuf_AssignDescriptorsOnce();
-  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3);
+  ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4);
 }
 
 }  // namespace
 
 void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
-  _CodeGeneratorRequest_default_instance_.Shutdown();
+  _Version_default_instance_.Shutdown();
   delete file_level_metadata[0].reflection;
-  _CodeGeneratorResponse_File_default_instance_.Shutdown();
+  _CodeGeneratorRequest_default_instance_.Shutdown();
   delete file_level_metadata[1].reflection;
-  _CodeGeneratorResponse_default_instance_.Shutdown();
+  _CodeGeneratorResponse_File_default_instance_.Shutdown();
   delete file_level_metadata[2].reflection;
+  _CodeGeneratorResponse_default_instance_.Shutdown();
+  delete file_level_metadata[3].reflection;
 }
 
 void protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl() {
@@ -118,9 +138,12 @@ void protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl()
 
   ::google::protobuf::protobuf_InitDefaults_google_2fprotobuf_2fdescriptor_2eproto();
   ::google::protobuf::internal::InitProtobufDefaults();
+  _Version_default_instance_.DefaultConstruct();
   _CodeGeneratorRequest_default_instance_.DefaultConstruct();
   _CodeGeneratorResponse_File_default_instance_.DefaultConstruct();
   _CodeGeneratorResponse_default_instance_.DefaultConstruct();
+  _CodeGeneratorRequest_default_instance_.get_mutable()->compiler_version_ = const_cast< ::google::protobuf::compiler::Version*>(
+      ::google::protobuf::compiler::Version::internal_default_instance());
 }
 
 void protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
@@ -132,19 +155,22 @@ void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl() {
   static const char descriptor[] = {
       "\n%google/protobuf/compiler/plugin.proto\022"
       "\030google.protobuf.compiler\032 google/protob"
-      "uf/descriptor.proto\"}\n\024CodeGeneratorRequ"
-      "est\022\030\n\020file_to_generate\030\001 \003(\t\022\021\n\tparamet"
-      "er\030\002 \001(\t\0228\n\nproto_file\030\017 \003(\0132$.google.pr"
-      "otobuf.FileDescriptorProto\"\252\001\n\025CodeGener"
-      "atorResponse\022\r\n\005error\030\001 \001(\t\022B\n\004file\030\017 \003("
-      "\01324.google.protobuf.compiler.CodeGenerat"
-      "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n"
-      "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB"
-      "7\n\034com.google.protobuf.compilerB\014PluginP"
-      "rotosZ\tplugin_go"
+      "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"
+      "\001 \001(\005\022\r\n\005minor\030\002 \001(\005\022\r\n\005patch\030\003 \001(\005\022\016\n\006s"
+      "uffix\030\004 \001(\t\"\272\001\n\024CodeGeneratorRequest\022\030\n\020"
+      "file_to_generate\030\001 \003(\t\022\021\n\tparameter\030\002 \001("
+      "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf."
+      "FileDescriptorProto\022;\n\020compiler_version\030"
+      "\003 \001(\0132!.google.protobuf.compiler.Version"
+      "\"\252\001\n\025CodeGeneratorResponse\022\r\n\005error\030\001 \001("
+      "\t\022B\n\004file\030\017 \003(\01324.google.protobuf.compil"
+      "er.CodeGeneratorResponse.File\032>\n\004File\022\014\n"
+      "\004name\030\001 \001(\t\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007"
+      "content\030\017 \001(\tB7\n\034com.google.protobuf.com"
+      "pilerB\014PluginProtosZ\tplugin_go"
   };
   ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
-      descriptor, 456);
+      descriptor, 590);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
   ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
@@ -165,10 +191,506 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
 
 // ===================================================================
 
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int Version::kMajorFieldNumber;
+const int Version::kMinorFieldNumber;
+const int Version::kPatchFieldNumber;
+const int Version::kSuffixFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+Version::Version()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) {
+    protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  }
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.Version)
+}
+Version::Version(const Version& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(NULL),
+      _has_bits_(from._has_bits_),
+      _cached_size_(0) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.has_suffix()) {
+    suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_);
+  }
+  ::memcpy(&major_, &from.major_,
+    reinterpret_cast<char*>(&patch_) -
+    reinterpret_cast<char*>(&major_) + sizeof(patch_));
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version)
+}
+
+void Version::SharedCtor() {
+  _cached_size_ = 0;
+  suffix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&major_, 0, reinterpret_cast<char*>(&patch_) -
+    reinterpret_cast<char*>(&major_) + sizeof(patch_));
+}
+
+Version::~Version() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version)
+  SharedDtor();
+}
+
+void Version::SharedDtor() {
+  suffix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void Version::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* Version::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return file_level_metadata[0].descriptor;
+}
+
+const Version& Version::default_instance() {
+  protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  return *internal_default_instance();
+}
+
+Version* Version::New(::google::protobuf::Arena* arena) const {
+  Version* n = new Version;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void Version::Clear() {
+// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version)
+  if (has_suffix()) {
+    GOOGLE_DCHECK(!suffix_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+    (*suffix_.UnsafeRawStringPointer())->clear();
+  }
+  if (_has_bits_[0 / 32] & 14u) {
+    ::memset(&major_, 0, reinterpret_cast<char*>(&patch_) -
+      reinterpret_cast<char*>(&major_) + sizeof(patch_));
+  }
+  _has_bits_.Clear();
+  _internal_metadata_.Clear();
+}
+
+bool Version::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.Version)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional int32 major = 1;
+      case 1: {
+        if (tag == 8u) {
+          set_has_major();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &major_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional int32 minor = 2;
+      case 2: {
+        if (tag == 16u) {
+          set_has_minor();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &minor_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional int32 patch = 3;
+      case 3: {
+        if (tag == 24u) {
+          set_has_patch();
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &patch_)));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // optional string suffix = 4;
+      case 4: {
+        if (tag == 34u) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_suffix()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->suffix().data(), this->suffix().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.compiler.Version.suffix");
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.Version)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.Version)
+  return false;
+#undef DO_
+}
+
+void Version::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.Version)
+  // optional int32 major = 1;
+  if (has_major()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->major(), output);
+  }
+
+  // optional int32 minor = 2;
+  if (has_minor()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->minor(), output);
+  }
+
+  // optional int32 patch = 3;
+  if (has_patch()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->patch(), output);
+  }
+
+  // optional string suffix = 4;
+  if (has_suffix()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->suffix().data(), this->suffix().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.compiler.Version.suffix");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->suffix(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.Version)
+}
+
+::google::protobuf::uint8* Version::InternalSerializeWithCachedSizesToArray(
+    bool deterministic, ::google::protobuf::uint8* target) const {
+  (void)deterministic; // Unused
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version)
+  // optional int32 major = 1;
+  if (has_major()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->major(), target);
+  }
+
+  // optional int32 minor = 2;
+  if (has_minor()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->minor(), target);
+  }
+
+  // optional int32 patch = 3;
+  if (has_patch()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->patch(), target);
+  }
+
+  // optional string suffix = 4;
+  if (has_suffix()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->suffix().data(), this->suffix().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.compiler.Version.suffix");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->suffix(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version)
+  return target;
+}
+
+size_t Version::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.Version)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  if (_has_bits_[0 / 32] & 15u) {
+    // optional string suffix = 4;
+    if (has_suffix()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->suffix());
+    }
+
+    // optional int32 major = 1;
+    if (has_major()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->major());
+    }
+
+    // optional int32 minor = 2;
+    if (has_minor()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->minor());
+    }
+
+    // optional int32 patch = 3;
+    if (has_patch()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->patch());
+    }
+
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = cached_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void Version::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.Version)
+  GOOGLE_DCHECK_NE(&from, this);
+  const Version* source =
+      ::google::protobuf::internal::DynamicCastToGenerated<const Version>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.Version)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.Version)
+    MergeFrom(*source);
+  }
+}
+
+void Version::MergeFrom(const Version& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  if (from._has_bits_[0 / 32] & 15u) {
+    if (from.has_suffix()) {
+      set_has_suffix();
+      suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_);
+    }
+    if (from.has_major()) {
+      set_major(from.major());
+    }
+    if (from.has_minor()) {
+      set_minor(from.minor());
+    }
+    if (from.has_patch()) {
+      set_patch(from.patch());
+    }
+  }
+}
+
+void Version::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.Version)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void Version::CopyFrom(const Version& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.Version)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool Version::IsInitialized() const {
+  return true;
+}
+
+void Version::Swap(Version* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void Version::InternalSwap(Version* other) {
+  suffix_.Swap(&other->suffix_);
+  std::swap(major_, other->major_);
+  std::swap(minor_, other->minor_);
+  std::swap(patch_, other->patch_);
+  std::swap(_has_bits_[0], other->_has_bits_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata Version::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  return file_level_metadata[0];
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Version
+
+// optional int32 major = 1;
+bool Version::has_major() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void Version::set_has_major() {
+  _has_bits_[0] |= 0x00000002u;
+}
+void Version::clear_has_major() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+void Version::clear_major() {
+  major_ = 0;
+  clear_has_major();
+}
+::google::protobuf::int32 Version::major() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major)
+  return major_;
+}
+void Version::set_major(::google::protobuf::int32 value) {
+  set_has_major();
+  major_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major)
+}
+
+// optional int32 minor = 2;
+bool Version::has_minor() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+void Version::set_has_minor() {
+  _has_bits_[0] |= 0x00000004u;
+}
+void Version::clear_has_minor() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+void Version::clear_minor() {
+  minor_ = 0;
+  clear_has_minor();
+}
+::google::protobuf::int32 Version::minor() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor)
+  return minor_;
+}
+void Version::set_minor(::google::protobuf::int32 value) {
+  set_has_minor();
+  minor_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor)
+}
+
+// optional int32 patch = 3;
+bool Version::has_patch() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+void Version::set_has_patch() {
+  _has_bits_[0] |= 0x00000008u;
+}
+void Version::clear_has_patch() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+void Version::clear_patch() {
+  patch_ = 0;
+  clear_has_patch();
+}
+::google::protobuf::int32 Version::patch() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch)
+  return patch_;
+}
+void Version::set_patch(::google::protobuf::int32 value) {
+  set_has_patch();
+  patch_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch)
+}
+
+// optional string suffix = 4;
+bool Version::has_suffix() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+void Version::set_has_suffix() {
+  _has_bits_[0] |= 0x00000001u;
+}
+void Version::clear_has_suffix() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+void Version::clear_suffix() {
+  suffix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_suffix();
+}
+const ::std::string& Version::suffix() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix)
+  return suffix_.GetNoArena();
+}
+void Version::set_suffix(const ::std::string& value) {
+  set_has_suffix();
+  suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
+}
+void Version::set_suffix(const char* value) {
+  set_has_suffix();
+  suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix)
+}
+void Version::set_suffix(const char* value, size_t size) {
+  set_has_suffix();
+  suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.Version.suffix)
+}
+::std::string* Version::mutable_suffix() {
+  set_has_suffix();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix)
+  return suffix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+::std::string* Version::release_suffix() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix)
+  clear_has_suffix();
+  return suffix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+void Version::set_allocated_suffix(::std::string* suffix) {
+  if (suffix != NULL) {
+    set_has_suffix();
+  } else {
+    clear_has_suffix();
+  }
+  suffix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), suffix);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
 #if !defined(_MSC_VER) || _MSC_VER >= 1900
 const int CodeGeneratorRequest::kFileToGenerateFieldNumber;
 const int CodeGeneratorRequest::kParameterFieldNumber;
 const int CodeGeneratorRequest::kProtoFileFieldNumber;
+const int CodeGeneratorRequest::kCompilerVersionFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 CodeGeneratorRequest::CodeGeneratorRequest()
@@ -191,12 +713,18 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
   if (from.has_parameter()) {
     parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_);
   }
+  if (from.has_compiler_version()) {
+    compiler_version_ = new ::google::protobuf::compiler::Version(*from.compiler_version_);
+  } else {
+    compiler_version_ = NULL;
+  }
   // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
 }
 
 void CodeGeneratorRequest::SharedCtor() {
   _cached_size_ = 0;
   parameter_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  compiler_version_ = NULL;
 }
 
 CodeGeneratorRequest::~CodeGeneratorRequest() {
@@ -206,6 +734,9 @@ CodeGeneratorRequest::~CodeGeneratorRequest() {
 
 void CodeGeneratorRequest::SharedDtor() {
   parameter_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) {
+    delete compiler_version_;
+  }
 }
 
 void CodeGeneratorRequest::SetCachedSize(int size) const {
@@ -215,7 +746,7 @@ void CodeGeneratorRequest::SetCachedSize(int size) const {
 }
 const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
   protobuf_AssignDescriptorsOnce();
-  return file_level_metadata[0].descriptor;
+  return file_level_metadata[1].descriptor;
 }
 
 const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
@@ -235,9 +766,15 @@ void CodeGeneratorRequest::Clear() {
 // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest)
   file_to_generate_.Clear();
   proto_file_.Clear();
-  if (has_parameter()) {
-    GOOGLE_DCHECK(!parameter_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
-    (*parameter_.UnsafeRawStringPointer())->clear();
+  if (_has_bits_[0 / 32] & 3u) {
+    if (has_parameter()) {
+      GOOGLE_DCHECK(!parameter_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
+      (*parameter_.UnsafeRawStringPointer())->clear();
+    }
+    if (has_compiler_version()) {
+      GOOGLE_DCHECK(compiler_version_ != NULL);
+      compiler_version_->::google::protobuf::compiler::Version::Clear();
+    }
   }
   _has_bits_.Clear();
   _internal_metadata_.Clear();
@@ -284,6 +821,17 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream(
         break;
       }
 
+      // optional .google.protobuf.compiler.Version compiler_version = 3;
+      case 3: {
+        if (tag == 26u) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_compiler_version()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
       // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
       case 15: {
         if (tag == 122u) {
@@ -342,6 +890,12 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
       2, this->parameter(), output);
   }
 
+  // optional .google.protobuf.compiler.Version compiler_version = 3;
+  if (has_compiler_version()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, *this->compiler_version_, output);
+  }
+
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
   for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -380,6 +934,13 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
         2, this->parameter(), target);
   }
 
+  // optional .google.protobuf.compiler.Version compiler_version = 3;
+  if (has_compiler_version()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageNoVirtualToArray(
+        3, *this->compiler_version_, false, target);
+  }
+
   // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
   for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
@@ -423,13 +984,22 @@ size_t CodeGeneratorRequest::ByteSizeLong() const {
     }
   }
 
-  // optional string parameter = 2;
-  if (has_parameter()) {
-    total_size += 1 +
-      ::google::protobuf::internal::WireFormatLite::StringSize(
-        this->parameter());
-  }
+  if (_has_bits_[0 / 32] & 3u) {
+    // optional string parameter = 2;
+    if (has_parameter()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->parameter());
+    }
 
+    // optional .google.protobuf.compiler.Version compiler_version = 3;
+    if (has_compiler_version()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *this->compiler_version_);
+    }
+
+  }
   int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
   GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
   _cached_size_ = cached_size;
@@ -458,9 +1028,14 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
   _internal_metadata_.MergeFrom(from._internal_metadata_);
   file_to_generate_.MergeFrom(from.file_to_generate_);
   proto_file_.MergeFrom(from.proto_file_);
-  if (from.has_parameter()) {
-    set_has_parameter();
-    parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_);
+  if (from._has_bits_[0 / 32] & 3u) {
+    if (from.has_parameter()) {
+      set_has_parameter();
+      parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_);
+    }
+    if (from.has_compiler_version()) {
+      mutable_compiler_version()->::google::protobuf::compiler::Version::MergeFrom(from.compiler_version());
+    }
   }
 }
 
@@ -491,6 +1066,7 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
   file_to_generate_.UnsafeArenaSwap(&other->file_to_generate_);
   proto_file_.UnsafeArenaSwap(&other->proto_file_);
   parameter_.Swap(&other->parameter_);
+  std::swap(compiler_version_, other->compiler_version_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   std::swap(_cached_size_, other->_cached_size_);
@@ -498,7 +1074,7 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) {
 
 ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
   protobuf_AssignDescriptorsOnce();
-  return file_level_metadata[0];
+  return file_level_metadata[1];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -643,6 +1219,51 @@ CodeGeneratorRequest::proto_file() const {
   return proto_file_;
 }
 
+// optional .google.protobuf.compiler.Version compiler_version = 3;
+bool CodeGeneratorRequest::has_compiler_version() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+void CodeGeneratorRequest::set_has_compiler_version() {
+  _has_bits_[0] |= 0x00000002u;
+}
+void CodeGeneratorRequest::clear_has_compiler_version() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+void CodeGeneratorRequest::clear_compiler_version() {
+  if (compiler_version_ != NULL) compiler_version_->::google::protobuf::compiler::Version::Clear();
+  clear_has_compiler_version();
+}
+const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+  return compiler_version_ != NULL ? *compiler_version_
+                         : *::google::protobuf::compiler::Version::internal_default_instance();
+}
+::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() {
+  set_has_compiler_version();
+  if (compiler_version_ == NULL) {
+    compiler_version_ = new ::google::protobuf::compiler::Version;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+  return compiler_version_;
+}
+::google::protobuf::compiler::Version* CodeGeneratorRequest::release_compiler_version() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+  clear_has_compiler_version();
+  ::google::protobuf::compiler::Version* temp = compiler_version_;
+  compiler_version_ = NULL;
+  return temp;
+}
+void CodeGeneratorRequest::set_allocated_compiler_version(::google::protobuf::compiler::Version* compiler_version) {
+  delete compiler_version_;
+  compiler_version_ = compiler_version;
+  if (compiler_version) {
+    set_has_compiler_version();
+  } else {
+    clear_has_compiler_version();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+}
+
 #endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
 
 // ===================================================================
@@ -707,7 +1328,7 @@ void CodeGeneratorResponse_File::SetCachedSize(int size) const {
 }
 const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
   protobuf_AssignDescriptorsOnce();
-  return file_level_metadata[1].descriptor;
+  return file_level_metadata[2].descriptor;
 }
 
 const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
@@ -1012,7 +1633,7 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other)
 
 ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
   protobuf_AssignDescriptorsOnce();
-  return file_level_metadata[1];
+  return file_level_metadata[2];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1232,7 +1853,7 @@ void CodeGeneratorResponse::SetCachedSize(int size) const {
 }
 const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
   protobuf_AssignDescriptorsOnce();
-  return file_level_metadata[2].descriptor;
+  return file_level_metadata[3].descriptor;
 }
 
 const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
@@ -1467,7 +2088,7 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) {
 
 ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
   protobuf_AssignDescriptorsOnce();
-  return file_level_metadata[2];
+  return file_level_metadata[3];
 }
 
 #if PROTOBUF_INLINE_NOT_IN_HEADERS

+ 325 - 0
src/google/protobuf/compiler/plugin.pb.h

@@ -116,6 +116,9 @@ extern CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_i
 class CodeGeneratorResponse_File;
 class CodeGeneratorResponse_FileDefaultTypeInternal;
 extern CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_;
+class Version;
+class VersionDefaultTypeInternal;
+extern VersionDefaultTypeInternal _Version_default_instance_;
 }  // namespace compiler
 }  // namespace protobuf
 }  // namespace google
@@ -130,6 +133,139 @@ void LIBPROTOC_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugi
 
 // ===================================================================
 
+class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ {
+ public:
+  Version();
+  virtual ~Version();
+
+  Version(const Version& from);
+
+  inline Version& operator=(const Version& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _internal_metadata_.unknown_fields();
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return _internal_metadata_.mutable_unknown_fields();
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const Version& default_instance();
+
+  static inline const Version* internal_default_instance() {
+    return reinterpret_cast<const Version*>(
+               &_Version_default_instance_);
+  }
+
+  void Swap(Version* other);
+
+  // implements Message ----------------------------------------------
+
+  inline Version* New() const PROTOBUF_FINAL { return New(NULL); }
+
+  Version* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
+  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
+  void CopyFrom(const Version& from);
+  void MergeFrom(const Version& from);
+  void Clear() PROTOBUF_FINAL;
+  bool IsInitialized() const PROTOBUF_FINAL;
+
+  size_t ByteSizeLong() const PROTOBUF_FINAL;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)
+      const PROTOBUF_FINAL {
+    return InternalSerializeWithCachedSizesToArray(false, output);
+  }
+  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const PROTOBUF_FINAL;
+  void InternalSwap(Version* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return NULL;
+  }
+  inline void* MaybeArenaPtr() const {
+    return NULL;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional int32 major = 1;
+  bool has_major() const;
+  void clear_major();
+  static const int kMajorFieldNumber = 1;
+  ::google::protobuf::int32 major() const;
+  void set_major(::google::protobuf::int32 value);
+
+  // optional int32 minor = 2;
+  bool has_minor() const;
+  void clear_minor();
+  static const int kMinorFieldNumber = 2;
+  ::google::protobuf::int32 minor() const;
+  void set_minor(::google::protobuf::int32 value);
+
+  // optional int32 patch = 3;
+  bool has_patch() const;
+  void clear_patch();
+  static const int kPatchFieldNumber = 3;
+  ::google::protobuf::int32 patch() const;
+  void set_patch(::google::protobuf::int32 value);
+
+  // optional string suffix = 4;
+  bool has_suffix() const;
+  void clear_suffix();
+  static const int kSuffixFieldNumber = 4;
+  const ::std::string& suffix() const;
+  void set_suffix(const ::std::string& value);
+  void set_suffix(const char* value);
+  void set_suffix(const char* value, size_t size);
+  ::std::string* mutable_suffix();
+  ::std::string* release_suffix();
+  void set_allocated_suffix(::std::string* suffix);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.Version)
+ private:
+  void set_has_major();
+  void clear_has_major();
+  void set_has_minor();
+  void clear_has_minor();
+  void set_has_patch();
+  void clear_has_patch();
+  void set_has_suffix();
+  void clear_has_suffix();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::HasBits<1> _has_bits_;
+  mutable int _cached_size_;
+  ::google::protobuf::internal::ArenaStringPtr suffix_;
+  ::google::protobuf::int32 major_;
+  ::google::protobuf::int32 minor_;
+  ::google::protobuf::int32 patch_;
+  friend void LIBPROTOC_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl();
+  friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl();
+  friend const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+};
+// -------------------------------------------------------------------
+
 class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ {
  public:
   CodeGeneratorRequest();
@@ -244,10 +380,21 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
   const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
       proto_file() const;
 
+  // optional .google.protobuf.compiler.Version compiler_version = 3;
+  bool has_compiler_version() const;
+  void clear_compiler_version();
+  static const int kCompilerVersionFieldNumber = 3;
+  const ::google::protobuf::compiler::Version& compiler_version() const;
+  ::google::protobuf::compiler::Version* mutable_compiler_version();
+  ::google::protobuf::compiler::Version* release_compiler_version();
+  void set_allocated_compiler_version(::google::protobuf::compiler::Version* compiler_version);
+
   // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
  private:
   void set_has_parameter();
   void clear_has_parameter();
+  void set_has_compiler_version();
+  void clear_has_compiler_version();
 
   ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
   ::google::protobuf::internal::HasBits<1> _has_bits_;
@@ -255,6 +402,7 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
   ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
   ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
   ::google::protobuf::internal::ArenaStringPtr parameter_;
+  ::google::protobuf::compiler::Version* compiler_version_;
   friend void LIBPROTOC_EXPORT protobuf_InitDefaults_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl();
   friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto_impl();
   friend const ::google::protobuf::uint32* protobuf_Offsets_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
@@ -518,6 +666,136 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
 // ===================================================================
 
 #if !PROTOBUF_INLINE_NOT_IN_HEADERS
+// Version
+
+// optional int32 major = 1;
+inline bool Version::has_major() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void Version::set_has_major() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void Version::clear_has_major() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void Version::clear_major() {
+  major_ = 0;
+  clear_has_major();
+}
+inline ::google::protobuf::int32 Version::major() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major)
+  return major_;
+}
+inline void Version::set_major(::google::protobuf::int32 value) {
+  set_has_major();
+  major_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major)
+}
+
+// optional int32 minor = 2;
+inline bool Version::has_minor() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void Version::set_has_minor() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void Version::clear_has_minor() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void Version::clear_minor() {
+  minor_ = 0;
+  clear_has_minor();
+}
+inline ::google::protobuf::int32 Version::minor() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor)
+  return minor_;
+}
+inline void Version::set_minor(::google::protobuf::int32 value) {
+  set_has_minor();
+  minor_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor)
+}
+
+// optional int32 patch = 3;
+inline bool Version::has_patch() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void Version::set_has_patch() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void Version::clear_has_patch() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void Version::clear_patch() {
+  patch_ = 0;
+  clear_has_patch();
+}
+inline ::google::protobuf::int32 Version::patch() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch)
+  return patch_;
+}
+inline void Version::set_patch(::google::protobuf::int32 value) {
+  set_has_patch();
+  patch_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch)
+}
+
+// optional string suffix = 4;
+inline bool Version::has_suffix() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void Version::set_has_suffix() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void Version::clear_has_suffix() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void Version::clear_suffix() {
+  suffix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_suffix();
+}
+inline const ::std::string& Version::suffix() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix)
+  return suffix_.GetNoArena();
+}
+inline void Version::set_suffix(const ::std::string& value) {
+  set_has_suffix();
+  suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
+}
+inline void Version::set_suffix(const char* value) {
+  set_has_suffix();
+  suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix)
+}
+inline void Version::set_suffix(const char* value, size_t size) {
+  set_has_suffix();
+  suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.Version.suffix)
+}
+inline ::std::string* Version::mutable_suffix() {
+  set_has_suffix();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix)
+  return suffix_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Version::release_suffix() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix)
+  clear_has_suffix();
+  return suffix_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Version::set_allocated_suffix(::std::string* suffix) {
+  if (suffix != NULL) {
+    set_has_suffix();
+  } else {
+    clear_has_suffix();
+  }
+  suffix_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), suffix);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix)
+}
+
+// -------------------------------------------------------------------
+
 // CodeGeneratorRequest
 
 // repeated string file_to_generate = 1;
@@ -659,6 +937,51 @@ CodeGeneratorRequest::proto_file() const {
   return proto_file_;
 }
 
+// optional .google.protobuf.compiler.Version compiler_version = 3;
+inline bool CodeGeneratorRequest::has_compiler_version() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorRequest::set_has_compiler_version() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_has_compiler_version() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_compiler_version() {
+  if (compiler_version_ != NULL) compiler_version_->::google::protobuf::compiler::Version::Clear();
+  clear_has_compiler_version();
+}
+inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+  return compiler_version_ != NULL ? *compiler_version_
+                         : *::google::protobuf::compiler::Version::internal_default_instance();
+}
+inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() {
+  set_has_compiler_version();
+  if (compiler_version_ == NULL) {
+    compiler_version_ = new ::google::protobuf::compiler::Version;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+  return compiler_version_;
+}
+inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::release_compiler_version() {
+  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+  clear_has_compiler_version();
+  ::google::protobuf::compiler::Version* temp = compiler_version_;
+  compiler_version_ = NULL;
+  return temp;
+}
+inline void CodeGeneratorRequest::set_allocated_compiler_version(::google::protobuf::compiler::Version* compiler_version) {
+  delete compiler_version_;
+  compiler_version_ = compiler_version;
+  if (compiler_version) {
+    set_has_compiler_version();
+  } else {
+    clear_has_compiler_version();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
+}
+
 // -------------------------------------------------------------------
 
 // CodeGeneratorResponse_File
@@ -918,6 +1241,8 @@ CodeGeneratorResponse::file() const {
 
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 

+ 13 - 0
src/google/protobuf/compiler/plugin.proto

@@ -53,6 +53,16 @@ option go_package = "plugin_go";
 
 import "google/protobuf/descriptor.proto";
 
+// The version number of protocol compiler.
+message Version {
+  optional int32 major = 1;
+  optional int32 minor = 2;
+  optional int32 patch = 3;
+  // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
+  // be empty for mainline stable releases.
+  optional string suffix = 4;
+}
+
 // An encoded CodeGeneratorRequest is written to the plugin's stdin.
 message CodeGeneratorRequest {
   // The .proto files that were explicitly listed on the command-line.  The
@@ -75,6 +85,9 @@ message CodeGeneratorRequest {
   // is not similarly optimized on protoc's end -- it will store all fields in
   // memory at once before sending them to the plugin.
   repeated FileDescriptorProto proto_file = 15;
+
+  // The version number of protocol compiler.
+  optional Version compiler_version = 3;
 }
 
 // The plugin writes an encoded CodeGeneratorResponse to stdout.

+ 3 - 0
src/google/protobuf/stubs/common.h

@@ -98,6 +98,9 @@ namespace internal {
 // easier:  major * 10^6 + minor * 10^3 + micro
 #define GOOGLE_PROTOBUF_VERSION 3001000
 
+// A suffix string for alpha, beta or rc releases. Empty for stable releases.
+#define GOOGLE_PROTOBUF_VERSION_SUFFIX ""
+
 // The minimum library version which works with the current version of the
 // headers.
 #define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3001000