// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/compiler/plugin.proto

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3021000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3021010 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/descriptor.pb.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto PROTOC_EXPORT
#ifdef major
#undef major
#endif
#ifdef minor
#undef minor
#endif
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct PROTOC_EXPORT TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
  static const uint32_t offsets[];
};
PROTOC_EXPORT extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
PROTOBUF_NAMESPACE_OPEN
namespace compiler {
class CodeGeneratorRequest;
struct CodeGeneratorRequestDefaultTypeInternal;
PROTOC_EXPORT extern CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_;
class CodeGeneratorResponse;
struct CodeGeneratorResponseDefaultTypeInternal;
PROTOC_EXPORT extern CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_;
class CodeGeneratorResponse_File;
struct CodeGeneratorResponse_FileDefaultTypeInternal;
PROTOC_EXPORT extern CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_;
class Version;
struct VersionDefaultTypeInternal;
PROTOC_EXPORT extern VersionDefaultTypeInternal _Version_default_instance_;
}  // namespace compiler
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorRequest>(Arena*);
template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse>(Arena*);
template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File>(Arena*);
template<> PROTOC_EXPORT ::PROTOBUF_NAMESPACE_ID::compiler::Version* Arena::CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::Version>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
PROTOBUF_NAMESPACE_OPEN
namespace compiler {

enum CodeGeneratorResponse_Feature : int {
  CodeGeneratorResponse_Feature_FEATURE_NONE = 0,
  CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL = 1
};
PROTOC_EXPORT bool CodeGeneratorResponse_Feature_IsValid(int value);
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MIN = CodeGeneratorResponse_Feature_FEATURE_NONE;
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL;
constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = CodeGeneratorResponse_Feature_Feature_MAX + 1;

PROTOC_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor();
template<typename T>
inline const std::string& CodeGeneratorResponse_Feature_Name(T enum_t_value) {
  static_assert(::std::is_same<T, CodeGeneratorResponse_Feature>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function CodeGeneratorResponse_Feature_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    CodeGeneratorResponse_Feature_descriptor(), enum_t_value);
}
inline bool CodeGeneratorResponse_Feature_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CodeGeneratorResponse_Feature* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<CodeGeneratorResponse_Feature>(
    CodeGeneratorResponse_Feature_descriptor(), name, value);
}
// ===================================================================

class PROTOC_EXPORT Version final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ {
 public:
  inline Version() : Version(nullptr) {}
  ~Version() override;
  explicit PROTOBUF_CONSTEXPR Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  Version(const Version& from);
  Version(Version&& from) noexcept
    : Version() {
    *this = ::std::move(from);
  }

  inline Version& operator=(const Version& from) {
    CopyFrom(from);
    return *this;
  }
  inline Version& operator=(Version&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Version& default_instance() {
    return *internal_default_instance();
  }
  static inline const Version* internal_default_instance() {
    return reinterpret_cast<const Version*>(
               &_Version_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(Version& a, Version& b) {
    a.Swap(&b);
  }
  inline void Swap(Version* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Version* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  Version* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<Version>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const Version& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const Version& from) {
    Version::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Version* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.compiler.Version";
  }
  protected:
  explicit Version(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kSuffixFieldNumber = 4,
    kMajorFieldNumber = 1,
    kMinorFieldNumber = 2,
    kPatchFieldNumber = 3,
  };
  // optional string suffix = 4;
  bool has_suffix() const;
  private:
  bool _internal_has_suffix() const;
  public:
  void clear_suffix();
  const std::string& suffix() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_suffix(ArgT0&& arg0, ArgT... args);
  std::string* mutable_suffix();
  PROTOBUF_NODISCARD std::string* release_suffix();
  void set_allocated_suffix(std::string* suffix);
  private:
  const std::string& _internal_suffix() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_suffix(const std::string& value);
  std::string* _internal_mutable_suffix();
  public:

  // optional int32 major = 1;
  bool has_major() const;
  private:
  bool _internal_has_major() const;
  public:
  void clear_major();
  int32_t major() const;
  void set_major(int32_t value);
  private:
  int32_t _internal_major() const;
  void _internal_set_major(int32_t value);
  public:

  // optional int32 minor = 2;
  bool has_minor() const;
  private:
  bool _internal_has_minor() const;
  public:
  void clear_minor();
  int32_t minor() const;
  void set_minor(int32_t value);
  private:
  int32_t _internal_minor() const;
  void _internal_set_minor(int32_t value);
  public:

  // optional int32 patch = 3;
  bool has_patch() const;
  private:
  bool _internal_has_patch() const;
  public:
  void clear_patch();
  int32_t patch() const;
  void set_patch(int32_t value);
  private:
  int32_t _internal_patch() const;
  void _internal_set_patch(int32_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.Version)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr suffix_;
    int32_t major_;
    int32_t minor_;
    int32_t patch_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// -------------------------------------------------------------------

class PROTOC_EXPORT CodeGeneratorRequest final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ {
 public:
  inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {}
  ~CodeGeneratorRequest() override;
  explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CodeGeneratorRequest(const CodeGeneratorRequest& from);
  CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept
    : CodeGeneratorRequest() {
    *this = ::std::move(from);
  }

  inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) {
    CopyFrom(from);
    return *this;
  }
  inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CodeGeneratorRequest& default_instance() {
    return *internal_default_instance();
  }
  static inline const CodeGeneratorRequest* internal_default_instance() {
    return reinterpret_cast<const CodeGeneratorRequest*>(
               &_CodeGeneratorRequest_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(CodeGeneratorRequest& a, CodeGeneratorRequest& b) {
    a.Swap(&b);
  }
  inline void Swap(CodeGeneratorRequest* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CodeGeneratorRequest* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  CodeGeneratorRequest* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<CodeGeneratorRequest>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const CodeGeneratorRequest& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const CodeGeneratorRequest& from) {
    CodeGeneratorRequest::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CodeGeneratorRequest* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.compiler.CodeGeneratorRequest";
  }
  protected:
  explicit CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFileToGenerateFieldNumber = 1,
    kProtoFileFieldNumber = 15,
    kParameterFieldNumber = 2,
    kCompilerVersionFieldNumber = 3,
  };
  // repeated string file_to_generate = 1;
  int file_to_generate_size() const;
  private:
  int _internal_file_to_generate_size() const;
  public:
  void clear_file_to_generate();
  const std::string& file_to_generate(int index) const;
  std::string* mutable_file_to_generate(int index);
  void set_file_to_generate(int index, const std::string& value);
  void set_file_to_generate(int index, std::string&& value);
  void set_file_to_generate(int index, const char* value);
  void set_file_to_generate(int index, const char* value, size_t size);
  std::string* add_file_to_generate();
  void add_file_to_generate(const std::string& value);
  void add_file_to_generate(std::string&& value);
  void add_file_to_generate(const char* value);
  void add_file_to_generate(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& file_to_generate() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_file_to_generate();
  private:
  const std::string& _internal_file_to_generate(int index) const;
  std::string* _internal_add_file_to_generate();
  public:

  // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
  int proto_file_size() const;
  private:
  int _internal_proto_file_size() const;
  public:
  void clear_proto_file();
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* mutable_proto_file(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
      mutable_proto_file();
  private:
  const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& _internal_proto_file(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _internal_add_proto_file();
  public:
  const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& proto_file(int index) const;
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* add_proto_file();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
      proto_file() const;

  // optional string parameter = 2;
  bool has_parameter() const;
  private:
  bool _internal_has_parameter() const;
  public:
  void clear_parameter();
  const std::string& parameter() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_parameter(ArgT0&& arg0, ArgT... args);
  std::string* mutable_parameter();
  PROTOBUF_NODISCARD std::string* release_parameter();
  void set_allocated_parameter(std::string* parameter);
  private:
  const std::string& _internal_parameter() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_parameter(const std::string& value);
  std::string* _internal_mutable_parameter();
  public:

  // optional .google.protobuf.compiler.Version compiler_version = 3;
  bool has_compiler_version() const;
  private:
  bool _internal_has_compiler_version() const;
  public:
  void clear_compiler_version();
  const ::PROTOBUF_NAMESPACE_ID::compiler::Version& compiler_version() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::compiler::Version* release_compiler_version();
  ::PROTOBUF_NAMESPACE_ID::compiler::Version* mutable_compiler_version();
  void set_allocated_compiler_version(::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version);
  private:
  const ::PROTOBUF_NAMESPACE_ID::compiler::Version& _internal_compiler_version() const;
  ::PROTOBUF_NAMESPACE_ID::compiler::Version* _internal_mutable_compiler_version();
  public:
  void unsafe_arena_set_allocated_compiler_version(
      ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version);
  ::PROTOBUF_NAMESPACE_ID::compiler::Version* unsafe_arena_release_compiler_version();

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> file_to_generate_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto > proto_file_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr parameter_;
    ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// -------------------------------------------------------------------

class PROTOC_EXPORT CodeGeneratorResponse_File final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ {
 public:
  inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {}
  ~CodeGeneratorResponse_File() override;
  explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from);
  CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept
    : CodeGeneratorResponse_File() {
    *this = ::std::move(from);
  }

  inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) {
    CopyFrom(from);
    return *this;
  }
  inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CodeGeneratorResponse_File& default_instance() {
    return *internal_default_instance();
  }
  static inline const CodeGeneratorResponse_File* internal_default_instance() {
    return reinterpret_cast<const CodeGeneratorResponse_File*>(
               &_CodeGeneratorResponse_File_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(CodeGeneratorResponse_File& a, CodeGeneratorResponse_File& b) {
    a.Swap(&b);
  }
  inline void Swap(CodeGeneratorResponse_File* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CodeGeneratorResponse_File* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  CodeGeneratorResponse_File* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<CodeGeneratorResponse_File>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const CodeGeneratorResponse_File& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const CodeGeneratorResponse_File& from) {
    CodeGeneratorResponse_File::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CodeGeneratorResponse_File* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.compiler.CodeGeneratorResponse.File";
  }
  protected:
  explicit CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kNameFieldNumber = 1,
    kInsertionPointFieldNumber = 2,
    kContentFieldNumber = 15,
    kGeneratedCodeInfoFieldNumber = 16,
  };
  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional string insertion_point = 2;
  bool has_insertion_point() const;
  private:
  bool _internal_has_insertion_point() const;
  public:
  void clear_insertion_point();
  const std::string& insertion_point() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_insertion_point(ArgT0&& arg0, ArgT... args);
  std::string* mutable_insertion_point();
  PROTOBUF_NODISCARD std::string* release_insertion_point();
  void set_allocated_insertion_point(std::string* insertion_point);
  private:
  const std::string& _internal_insertion_point() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_insertion_point(const std::string& value);
  std::string* _internal_mutable_insertion_point();
  public:

  // optional string content = 15;
  bool has_content() const;
  private:
  bool _internal_has_content() const;
  public:
  void clear_content();
  const std::string& content() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_content(ArgT0&& arg0, ArgT... args);
  std::string* mutable_content();
  PROTOBUF_NODISCARD std::string* release_content();
  void set_allocated_content(std::string* content);
  private:
  const std::string& _internal_content() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_content(const std::string& value);
  std::string* _internal_mutable_content();
  public:

  // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
  bool has_generated_code_info() const;
  private:
  bool _internal_has_generated_code_info() const;
  public:
  void clear_generated_code_info();
  const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& generated_code_info() const;
  PROTOBUF_NODISCARD ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* release_generated_code_info();
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* mutable_generated_code_info();
  void set_allocated_generated_code_info(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
  private:
  const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& _internal_generated_code_info() const;
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _internal_mutable_generated_code_info();
  public:
  void unsafe_arena_set_allocated_generated_code_info(
      ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info);
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* unsafe_arena_release_generated_code_info();

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr insertion_point_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr content_;
    ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// -------------------------------------------------------------------

class PROTOC_EXPORT CodeGeneratorResponse final :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ {
 public:
  inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {}
  ~CodeGeneratorResponse() override;
  explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CodeGeneratorResponse(const CodeGeneratorResponse& from);
  CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept
    : CodeGeneratorResponse() {
    *this = ::std::move(from);
  }

  inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) {
    CopyFrom(from);
    return *this;
  }
  inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& from) noexcept {
    if (this == &from) return *this;
    if (GetOwningArena() == from.GetOwningArena()
  #ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetOwningArena() != nullptr
  #endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CodeGeneratorResponse& default_instance() {
    return *internal_default_instance();
  }
  static inline const CodeGeneratorResponse* internal_default_instance() {
    return reinterpret_cast<const CodeGeneratorResponse*>(
               &_CodeGeneratorResponse_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  friend void swap(CodeGeneratorResponse& a, CodeGeneratorResponse& b) {
    a.Swap(&b);
  }
  inline void Swap(CodeGeneratorResponse* other) {
    if (other == this) return;
  #ifdef PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() != nullptr &&
        GetOwningArena() == other->GetOwningArena()) {
   #else  // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetOwningArena() == other->GetOwningArena()) {
  #endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CodeGeneratorResponse* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  CodeGeneratorResponse* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
    return CreateMaybeMessage<CodeGeneratorResponse>(arena);
  }
  using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
  void CopyFrom(const CodeGeneratorResponse& from);
  using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
  void MergeFrom( const CodeGeneratorResponse& from) {
    CodeGeneratorResponse::MergeImpl(*this, from);
  }
  private:
  static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message& to_msg, const ::PROTOBUF_NAMESPACE_ID::Message& from_msg);
  public:
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  uint8_t* _InternalSerialize(
      uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::PROTOBUF_NAMESPACE_ID::Arena* arena, bool is_message_owned);
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CodeGeneratorResponse* other);

  private:
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "google.protobuf.compiler.CodeGeneratorResponse";
  }
  protected:
  explicit CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                       bool is_message_owned = false);
  public:

  static const ClassData _class_data_;
  const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  typedef CodeGeneratorResponse_File File;

  typedef CodeGeneratorResponse_Feature Feature;
  static constexpr Feature FEATURE_NONE =
    CodeGeneratorResponse_Feature_FEATURE_NONE;
  static constexpr Feature FEATURE_PROTO3_OPTIONAL =
    CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL;
  static inline bool Feature_IsValid(int value) {
    return CodeGeneratorResponse_Feature_IsValid(value);
  }
  static constexpr Feature Feature_MIN =
    CodeGeneratorResponse_Feature_Feature_MIN;
  static constexpr Feature Feature_MAX =
    CodeGeneratorResponse_Feature_Feature_MAX;
  static constexpr int Feature_ARRAYSIZE =
    CodeGeneratorResponse_Feature_Feature_ARRAYSIZE;
  static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
  Feature_descriptor() {
    return CodeGeneratorResponse_Feature_descriptor();
  }
  template<typename T>
  static inline const std::string& Feature_Name(T enum_t_value) {
    static_assert(::std::is_same<T, Feature>::value ||
      ::std::is_integral<T>::value,
      "Incorrect type passed to function Feature_Name.");
    return CodeGeneratorResponse_Feature_Name(enum_t_value);
  }
  static inline bool Feature_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
      Feature* value) {
    return CodeGeneratorResponse_Feature_Parse(name, value);
  }

  // accessors -------------------------------------------------------

  enum : int {
    kFileFieldNumber = 15,
    kErrorFieldNumber = 1,
    kSupportedFeaturesFieldNumber = 2,
  };
  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
  int file_size() const;
  private:
  int _internal_file_size() const;
  public:
  void clear_file();
  ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* mutable_file(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >*
      mutable_file();
  private:
  const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& _internal_file(int index) const;
  ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* _internal_add_file();
  public:
  const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& file(int index) const;
  ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* add_file();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >&
      file() const;

  // optional string error = 1;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const std::string& error() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_error(ArgT0&& arg0, ArgT... args);
  std::string* mutable_error();
  PROTOBUF_NODISCARD std::string* release_error();
  void set_allocated_error(std::string* error);
  private:
  const std::string& _internal_error() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_error(const std::string& value);
  std::string* _internal_mutable_error();
  public:

  // optional uint64 supported_features = 2;
  bool has_supported_features() const;
  private:
  bool _internal_has_supported_features() const;
  public:
  void clear_supported_features();
  uint64_t supported_features() const;
  void set_supported_features(uint64_t value);
  private:
  uint64_t _internal_supported_features() const;
  void _internal_set_supported_features(uint64_t value);
  public:

  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  struct Impl_ {
    ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
    mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
    ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File > file_;
    ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr error_;
    uint64_t supported_features_;
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// ===================================================================


// ===================================================================

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// Version

// optional int32 major = 1;
inline bool Version::_internal_has_major() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool Version::has_major() const {
  return _internal_has_major();
}
inline void Version::clear_major() {
  _impl_.major_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline int32_t Version::_internal_major() const {
  return _impl_.major_;
}
inline int32_t Version::major() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major)
  return _internal_major();
}
inline void Version::_internal_set_major(int32_t value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.major_ = value;
}
inline void Version::set_major(int32_t value) {
  _internal_set_major(value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major)
}

// optional int32 minor = 2;
inline bool Version::_internal_has_minor() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool Version::has_minor() const {
  return _internal_has_minor();
}
inline void Version::clear_minor() {
  _impl_.minor_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline int32_t Version::_internal_minor() const {
  return _impl_.minor_;
}
inline int32_t Version::minor() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor)
  return _internal_minor();
}
inline void Version::_internal_set_minor(int32_t value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.minor_ = value;
}
inline void Version::set_minor(int32_t value) {
  _internal_set_minor(value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor)
}

// optional int32 patch = 3;
inline bool Version::_internal_has_patch() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool Version::has_patch() const {
  return _internal_has_patch();
}
inline void Version::clear_patch() {
  _impl_.patch_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline int32_t Version::_internal_patch() const {
  return _impl_.patch_;
}
inline int32_t Version::patch() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch)
  return _internal_patch();
}
inline void Version::_internal_set_patch(int32_t value) {
  _impl_._has_bits_[0] |= 0x00000008u;
  _impl_.patch_ = value;
}
inline void Version::set_patch(int32_t value) {
  _internal_set_patch(value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch)
}

// optional string suffix = 4;
inline bool Version::_internal_has_suffix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool Version::has_suffix() const {
  return _internal_has_suffix();
}
inline void Version::clear_suffix() {
  _impl_.suffix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& Version::suffix() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix)
  return _internal_suffix();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void Version::set_suffix(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.suffix_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
}
inline std::string* Version::mutable_suffix() {
  std::string* _s = _internal_mutable_suffix();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.Version.suffix)
  return _s;
}
inline const std::string& Version::_internal_suffix() const {
  return _impl_.suffix_.Get();
}
inline void Version::_internal_set_suffix(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.suffix_.Set(value, GetArenaForAllocation());
}
inline std::string* Version::_internal_mutable_suffix() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.suffix_.Mutable(GetArenaForAllocation());
}
inline std::string* Version::release_suffix() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix)
  if (!_internal_has_suffix()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.suffix_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.suffix_.IsDefault()) {
    _impl_.suffix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void Version::set_allocated_suffix(std::string* suffix) {
  if (suffix != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.suffix_.SetAllocated(suffix, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.suffix_.IsDefault()) {
    _impl_.suffix_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.Version.suffix)
}

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

// CodeGeneratorRequest

// repeated string file_to_generate = 1;
inline int CodeGeneratorRequest::_internal_file_to_generate_size() const {
  return _impl_.file_to_generate_.size();
}
inline int CodeGeneratorRequest::file_to_generate_size() const {
  return _internal_file_to_generate_size();
}
inline void CodeGeneratorRequest::clear_file_to_generate() {
  _impl_.file_to_generate_.Clear();
}
inline std::string* CodeGeneratorRequest::add_file_to_generate() {
  std::string* _s = _internal_add_file_to_generate();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _s;
}
inline const std::string& CodeGeneratorRequest::_internal_file_to_generate(int index) const {
  return _impl_.file_to_generate_.Get(index);
}
inline const std::string& CodeGeneratorRequest::file_to_generate(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _internal_file_to_generate(index);
}
inline std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _impl_.file_to_generate_.Mutable(index);
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const std::string& value) {
  _impl_.file_to_generate_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, std::string&& value) {
  _impl_.file_to_generate_.Mutable(index)->assign(std::move(value));
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.file_to_generate_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) {
  _impl_.file_to_generate_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline std::string* CodeGeneratorRequest::_internal_add_file_to_generate() {
  return _impl_.file_to_generate_.Add();
}
inline void CodeGeneratorRequest::add_file_to_generate(const std::string& value) {
  _impl_.file_to_generate_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::add_file_to_generate(std::string&& value) {
  _impl_.file_to_generate_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  _impl_.file_to_generate_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) {
  _impl_.file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
CodeGeneratorRequest::file_to_generate() const {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _impl_.file_to_generate_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
CodeGeneratorRequest::mutable_file_to_generate() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return &_impl_.file_to_generate_;
}

// optional string parameter = 2;
inline bool CodeGeneratorRequest::_internal_has_parameter() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CodeGeneratorRequest::has_parameter() const {
  return _internal_has_parameter();
}
inline void CodeGeneratorRequest::clear_parameter() {
  _impl_.parameter_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CodeGeneratorRequest::parameter() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
  return _internal_parameter();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void CodeGeneratorRequest::set_parameter(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.parameter_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline std::string* CodeGeneratorRequest::mutable_parameter() {
  std::string* _s = _internal_mutable_parameter();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
  return _s;
}
inline const std::string& CodeGeneratorRequest::_internal_parameter() const {
  return _impl_.parameter_.Get();
}
inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.parameter_.Set(value, GetArenaForAllocation());
}
inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.parameter_.Mutable(GetArenaForAllocation());
}
inline std::string* CodeGeneratorRequest::release_parameter() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter)
  if (!_internal_has_parameter()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.parameter_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.parameter_.IsDefault()) {
    _impl_.parameter_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void CodeGeneratorRequest::set_allocated_parameter(std::string* parameter) {
  if (parameter != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.parameter_.SetAllocated(parameter, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.parameter_.IsDefault()) {
    _impl_.parameter_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}

// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
inline int CodeGeneratorRequest::_internal_proto_file_size() const {
  return _impl_.proto_file_.size();
}
inline int CodeGeneratorRequest::proto_file_size() const {
  return _internal_proto_file_size();
}
inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _impl_.proto_file_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >*
CodeGeneratorRequest::mutable_proto_file() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return &_impl_.proto_file_;
}
inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& CodeGeneratorRequest::_internal_proto_file(int index) const {
  return _impl_.proto_file_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _internal_proto_file(index);
}
inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::_internal_add_proto_file() {
  return _impl_.proto_file_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
  ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto* _add = _internal_add_proto_file();
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::FileDescriptorProto >&
CodeGeneratorRequest::proto_file() const {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _impl_.proto_file_;
}

// optional .google.protobuf.compiler.Version compiler_version = 3;
inline bool CodeGeneratorRequest::_internal_has_compiler_version() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.compiler_version_ != nullptr);
  return value;
}
inline bool CodeGeneratorRequest::has_compiler_version() const {
  return _internal_has_compiler_version();
}
inline void CodeGeneratorRequest::clear_compiler_version() {
  if (_impl_.compiler_version_ != nullptr) _impl_.compiler_version_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const {
  const ::PROTOBUF_NAMESPACE_ID::compiler::Version* p = _impl_.compiler_version_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::compiler::Version&>(
      ::PROTOBUF_NAMESPACE_ID::compiler::_Version_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::compiler::Version& CodeGeneratorRequest::compiler_version() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
  return _internal_compiler_version();
}
inline void CodeGeneratorRequest::unsafe_arena_set_allocated_compiler_version(
    ::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.compiler_version_);
  }
  _impl_.compiler_version_ = compiler_version;
  if (compiler_version) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::release_compiler_version() {
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = _impl_.compiler_version_;
  _impl_.compiler_version_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::unsafe_arena_release_compiler_version() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
  _impl_._has_bits_[0] &= ~0x00000002u;
  ::PROTOBUF_NAMESPACE_ID::compiler::Version* temp = _impl_.compiler_version_;
  _impl_.compiler_version_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::_internal_mutable_compiler_version() {
  _impl_._has_bits_[0] |= 0x00000002u;
  if (_impl_.compiler_version_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::compiler::Version>(GetArenaForAllocation());
    _impl_.compiler_version_ = p;
  }
  return _impl_.compiler_version_;
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() {
  ::PROTOBUF_NAMESPACE_ID::compiler::Version* _msg = _internal_mutable_compiler_version();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
  return _msg;
}
inline void CodeGeneratorRequest::set_allocated_compiler_version(::PROTOBUF_NAMESPACE_ID::compiler::Version* compiler_version) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete _impl_.compiler_version_;
  }
  if (compiler_version) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(compiler_version);
    if (message_arena != submessage_arena) {
      compiler_version = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, compiler_version, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.compiler_version_ = compiler_version;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
}

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

// CodeGeneratorResponse_File

// optional string name = 1;
inline bool CodeGeneratorResponse_File::_internal_has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CodeGeneratorResponse_File::has_name() const {
  return _internal_has_name();
}
inline void CodeGeneratorResponse_File::clear_name() {
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CodeGeneratorResponse_File::name() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void CodeGeneratorResponse_File::set_name(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.name_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline std::string* CodeGeneratorResponse_File::mutable_name() {
  std::string* _s = _internal_mutable_name();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
  return _s;
}
inline const std::string& CodeGeneratorResponse_File::_internal_name() const {
  return _impl_.name_.Get();
}
inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable(GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse_File::release_name() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void CodeGeneratorResponse_File::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(name, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.name_.IsDefault()) {
    _impl_.name_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}

// optional string insertion_point = 2;
inline bool CodeGeneratorResponse_File::_internal_has_insertion_point() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool CodeGeneratorResponse_File::has_insertion_point() const {
  return _internal_has_insertion_point();
}
inline void CodeGeneratorResponse_File::clear_insertion_point() {
  _impl_.insertion_point_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& CodeGeneratorResponse_File::insertion_point() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
  return _internal_insertion_point();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void CodeGeneratorResponse_File::set_insertion_point(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000002u;
 _impl_.insertion_point_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
  std::string* _s = _internal_mutable_insertion_point();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
  return _s;
}
inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point() const {
  return _impl_.insertion_point_.Get();
}
inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.insertion_point_.Set(value, GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() {
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.insertion_point_.Mutable(GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse_File::release_insertion_point() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
  if (!_internal_has_insertion_point()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.insertion_point_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.insertion_point_.IsDefault()) {
    _impl_.insertion_point_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::string* insertion_point) {
  if (insertion_point != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.insertion_point_.SetAllocated(insertion_point, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.insertion_point_.IsDefault()) {
    _impl_.insertion_point_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}

// optional string content = 15;
inline bool CodeGeneratorResponse_File::_internal_has_content() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool CodeGeneratorResponse_File::has_content() const {
  return _internal_has_content();
}
inline void CodeGeneratorResponse_File::clear_content() {
  _impl_.content_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& CodeGeneratorResponse_File::content() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
  return _internal_content();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void CodeGeneratorResponse_File::set_content(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000004u;
 _impl_.content_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline std::string* CodeGeneratorResponse_File::mutable_content() {
  std::string* _s = _internal_mutable_content();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
  return _s;
}
inline const std::string& CodeGeneratorResponse_File::_internal_content() const {
  return _impl_.content_.Get();
}
inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.content_.Set(value, GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() {
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.content_.Mutable(GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse_File::release_content() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content)
  if (!_internal_has_content()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.content_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.content_.IsDefault()) {
    _impl_.content_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void CodeGeneratorResponse_File::set_allocated_content(std::string* content) {
  if (content != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.content_.SetAllocated(content, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.content_.IsDefault()) {
    _impl_.content_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}

// optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
inline bool CodeGeneratorResponse_File::_internal_has_generated_code_info() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.generated_code_info_ != nullptr);
  return value;
}
inline bool CodeGeneratorResponse_File::has_generated_code_info() const {
  return _internal_has_generated_code_info();
}
inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const {
  const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* p = _impl_.generated_code_info_;
  return p != nullptr ? *p : reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo&>(
      ::PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_);
}
inline const ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo& CodeGeneratorResponse_File::generated_code_info() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
  return _internal_generated_code_info();
}
inline void CodeGeneratorResponse_File::unsafe_arena_set_allocated_generated_code_info(
    ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
  if (GetArenaForAllocation() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.generated_code_info_);
  }
  _impl_.generated_code_info_ = generated_code_info;
  if (generated_code_info) {
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() {
  _impl_._has_bits_[0] &= ~0x00000008u;
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = _impl_.generated_code_info_;
  _impl_.generated_code_info_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  if (GetArenaForAllocation() == nullptr) { delete old; }
#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArenaForAllocation() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
  _impl_._has_bits_[0] &= ~0x00000008u;
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* temp = _impl_.generated_code_info_;
  _impl_.generated_code_info_ = nullptr;
  return temp;
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() {
  _impl_._has_bits_[0] |= 0x00000008u;
  if (_impl_.generated_code_info_ == nullptr) {
    auto* p = CreateMaybeMessage<::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo>(GetArenaForAllocation());
    _impl_.generated_code_info_ = p;
  }
  return _impl_.generated_code_info_;
}
inline ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() {
  ::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* _msg = _internal_mutable_generated_code_info();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
  return _msg;
}
inline void CodeGeneratorResponse_File::set_allocated_generated_code_info(::PROTOBUF_NAMESPACE_ID::GeneratedCodeInfo* generated_code_info) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(_impl_.generated_code_info_);
  }
  if (generated_code_info) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
        ::PROTOBUF_NAMESPACE_ID::Arena::InternalGetOwningArena(
                reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(generated_code_info));
    if (message_arena != submessage_arena) {
      generated_code_info = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, generated_code_info, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }
  _impl_.generated_code_info_ = generated_code_info;
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)
}

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

// CodeGeneratorResponse

// optional string error = 1;
inline bool CodeGeneratorResponse::_internal_has_error() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CodeGeneratorResponse::has_error() const {
  return _internal_has_error();
}
inline void CodeGeneratorResponse::clear_error() {
  _impl_.error_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CodeGeneratorResponse::error() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
  return _internal_error();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void CodeGeneratorResponse::set_error(ArgT0&& arg0, ArgT... args) {
 _impl_._has_bits_[0] |= 0x00000001u;
 _impl_.error_.Set(static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline std::string* CodeGeneratorResponse::mutable_error() {
  std::string* _s = _internal_mutable_error();
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
  return _s;
}
inline const std::string& CodeGeneratorResponse::_internal_error() const {
  return _impl_.error_.Get();
}
inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) {
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.error_.Set(value, GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse::_internal_mutable_error() {
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.error_.Mutable(GetArenaForAllocation());
}
inline std::string* CodeGeneratorResponse::release_error() {
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error)
  if (!_internal_has_error()) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.error_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.error_.IsDefault()) {
    _impl_.error_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return p;
}
inline void CodeGeneratorResponse::set_allocated_error(std::string* error) {
  if (error != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.error_.SetAllocated(error, GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  if (_impl_.error_.IsDefault()) {
    _impl_.error_.Set("", GetArenaForAllocation());
  }
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
}

// optional uint64 supported_features = 2;
inline bool CodeGeneratorResponse::_internal_has_supported_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool CodeGeneratorResponse::has_supported_features() const {
  return _internal_has_supported_features();
}
inline void CodeGeneratorResponse::clear_supported_features() {
  _impl_.supported_features_ = uint64_t{0u};
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline uint64_t CodeGeneratorResponse::_internal_supported_features() const {
  return _impl_.supported_features_;
}
inline uint64_t CodeGeneratorResponse::supported_features() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.supported_features)
  return _internal_supported_features();
}
inline void CodeGeneratorResponse::_internal_set_supported_features(uint64_t value) {
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.supported_features_ = value;
}
inline void CodeGeneratorResponse::set_supported_features(uint64_t value) {
  _internal_set_supported_features(value);
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.supported_features)
}

// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
inline int CodeGeneratorResponse::_internal_file_size() const {
  return _impl_.file_.size();
}
inline int CodeGeneratorResponse::file_size() const {
  return _internal_file_size();
}
inline void CodeGeneratorResponse::clear_file() {
  _impl_.file_.Clear();
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
  return _impl_.file_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >*
CodeGeneratorResponse::mutable_file() {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
  return &_impl_.file_;
}
inline const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::_internal_file(int index) const {
  return _impl_.file_.Get(index);
}
inline const ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
  return _internal_file(index);
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::_internal_add_file() {
  return _impl_.file_.Add();
}
inline ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
  ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File* _add = _internal_add_file();
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
  return _add;
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_File >&
CodeGeneratorResponse::file() const {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
  return _impl_.file_;
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace compiler
PROTOBUF_NAMESPACE_CLOSE

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature>() {
  return ::PROTOBUF_NAMESPACE_ID::compiler::CodeGeneratorResponse_Feature_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto
