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

#ifndef GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
#define GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh

#include <limits>
#include <string>
#include <type_traits>

#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  // PROTOBUF_VERSION

#if 3021009 < 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  // PROTOBUF_MIN_PROTOC_VERSION
#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)

// Must be included last.
#include "google/protobuf/port_def.inc"

#define PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2fcompiler_2fplugin_2eproto PROTOC_EXPORT
#ifdef major
#undef major
#endif  // major
#ifdef minor
#undef minor
#endif  // minor

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
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 = static_cast<CodeGeneratorResponse_Feature>(0);
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = static_cast<CodeGeneratorResponse_Feature>(1);
constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = 1 + 1;
PROTOC_EXPORT const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
CodeGeneratorResponse_Feature_descriptor();
template <typename T>
const std::string& CodeGeneratorResponse_Feature_Name(T value) {
  static_assert(std::is_same<T, CodeGeneratorResponse_Feature>::value ||
                    std::is_integral<T>::value,
                "Incorrect type passed to Feature_Name().");
  return CodeGeneratorResponse_Feature_Name(static_cast<CodeGeneratorResponse_Feature>(value));
}
template <>
inline const std::string& CodeGeneratorResponse_Feature_Name(CodeGeneratorResponse_Feature value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfDenseEnum<CodeGeneratorResponse_Feature_descriptor,
                                                 0, 1>(
      static_cast<int>(value));
}
inline bool CodeGeneratorResponse_Feature_Parse(absl::string_view 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 ::absl::string_view 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;
  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;
  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;
  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;
  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 ::absl::string_view 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;
  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;
  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 ::absl::string_view 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;
  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;
  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;
  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;
  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 ::absl::string_view 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;

  using Feature = CodeGeneratorResponse_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 value) {
    return CodeGeneratorResponse_Feature_Name(value);
  }
  static inline bool Feature_Parse(absl::string_view 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;
  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;
  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::has_major() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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::has_minor() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
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::has_patch() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
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::has_suffix() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.suffix_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _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::has_parameter() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.parameter_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _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::has_compiler_version() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.compiler_version_ != nullptr);
  return value;
}
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::has_name() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.name_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _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::has_insertion_point() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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 ((_impl_._has_bits_[0] & 0x00000002u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000002u;
  auto* p = _impl_.insertion_point_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _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::has_content() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
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 ((_impl_._has_bits_[0] & 0x00000004u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000004u;
  auto* p = _impl_.content_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _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::has_generated_code_info() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || _impl_.generated_code_info_ != nullptr);
  return value;
}
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::has_error() const {
  bool value = (_impl_._has_bits_[0] & 0x00000001u) != 0;
  return value;
}
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 ((_impl_._has_bits_[0] & 0x00000001u) == 0) {
    return nullptr;
  }
  _impl_._has_bits_[0] &= ~0x00000001u;
  auto* p = _impl_.error_.Release();
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _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::has_supported_features() const {
  bool value = (_impl_._has_bits_[0] & 0x00000002u) != 0;
  return value;
}
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_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
