// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// source: google/protobuf/compiler/plugin.proto
// Protobuf C++ Version: 5.28.0-dev

#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 <utility>

#include "google/protobuf/runtime_version.h"
#if PROTOBUF_VERSION != 5028000
#error "Protobuf C++ gencode is built with an incompatible version of"
#error "Protobuf C++ headers/runtime. See"
#error "https://protobuf.dev/support/cross-version-runtime-guarantee/#cpp"
#endif
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/arena.h"
#include "google/protobuf/arenastring.h"
#include "google/protobuf/generated_message_tctable_decl.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

namespace google {
namespace protobuf {
namespace internal {
class AnyMetadata;
}  // namespace internal
}  // namespace protobuf
}  // namespace google

// 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 ::google::protobuf::internal::DescriptorTable
    descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
namespace google {
namespace protobuf {
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
}  // namespace protobuf
}  // namespace google

namespace google {
namespace protobuf {
namespace compiler {
enum CodeGeneratorResponse_Feature : int {
  CodeGeneratorResponse_Feature_FEATURE_NONE = 0,
  CodeGeneratorResponse_Feature_FEATURE_PROTO3_OPTIONAL = 1,
  CodeGeneratorResponse_Feature_FEATURE_SUPPORTS_EDITIONS = 2,
};

PROTOC_EXPORT bool CodeGeneratorResponse_Feature_IsValid(int value);
PROTOC_EXPORT extern const uint32_t CodeGeneratorResponse_Feature_internal_data_[];
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MIN = static_cast<CodeGeneratorResponse_Feature>(0);
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse_Feature_Feature_MAX = static_cast<CodeGeneratorResponse_Feature>(2);
constexpr int CodeGeneratorResponse_Feature_Feature_ARRAYSIZE = 2 + 1;
PROTOC_EXPORT const ::google::protobuf::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 ::google::protobuf::internal::NameOfDenseEnum<CodeGeneratorResponse_Feature_descriptor,
                                                 0, 2>(
      static_cast<int>(value));
}
inline bool CodeGeneratorResponse_Feature_Parse(absl::string_view name, CodeGeneratorResponse_Feature* value) {
  return ::google::protobuf::internal::ParseNamedEnum<CodeGeneratorResponse_Feature>(
      CodeGeneratorResponse_Feature_descriptor(), name, value);
}

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


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

class PROTOC_EXPORT Version final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.Version) */ {
 public:
  inline Version() : Version(nullptr) {}
  ~Version() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR Version(
      ::google::protobuf::internal::ConstantInitialized);

  inline Version(const Version& from) : Version(nullptr, from) {}
  inline Version(Version&& from) noexcept
      : Version(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Version* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  Version* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<Version>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const Version& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const Version& from) { Version::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(Version* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.Version"; }

 protected:
  explicit Version(::google::protobuf::Arena* arena);
  Version(::google::protobuf::Arena* arena, const Version& from);
  Version(::google::protobuf::Arena* arena, Version&& from) noexcept
      : Version(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 Arg_ = const std::string&, typename... Args_>
  void set_suffix(Arg_&& arg, Args_... args);
  std::string* mutable_suffix();
  PROTOBUF_NODISCARD std::string* release_suffix();
  void set_allocated_suffix(std::string* value);

  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;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 4, 0,
      47, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_Version_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const Version& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr suffix_;
    ::int32_t major_;
    ::int32_t minor_;
    ::int32_t patch_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// -------------------------------------------------------------------

class PROTOC_EXPORT CodeGeneratorResponse_File final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse.File) */ {
 public:
  inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {}
  ~CodeGeneratorResponse_File() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(
      ::google::protobuf::internal::ConstantInitialized);

  inline CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) : CodeGeneratorResponse_File(nullptr, from) {}
  inline CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept
      : CodeGeneratorResponse_File(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CodeGeneratorResponse_File* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  CodeGeneratorResponse_File* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<CodeGeneratorResponse_File>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const CodeGeneratorResponse_File& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const CodeGeneratorResponse_File& from) { CodeGeneratorResponse_File::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(CodeGeneratorResponse_File* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse.File"; }

 protected:
  explicit CodeGeneratorResponse_File(::google::protobuf::Arena* arena);
  CodeGeneratorResponse_File(::google::protobuf::Arena* arena, const CodeGeneratorResponse_File& from);
  CodeGeneratorResponse_File(::google::protobuf::Arena* arena, CodeGeneratorResponse_File&& from) noexcept
      : CodeGeneratorResponse_File(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // 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 Arg_ = const std::string&, typename... Args_>
  void set_name(Arg_&& arg, Args_... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* value);

  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 Arg_ = const std::string&, typename... Args_>
  void set_insertion_point(Arg_&& arg, Args_... args);
  std::string* mutable_insertion_point();
  PROTOBUF_NODISCARD std::string* release_insertion_point();
  void set_allocated_insertion_point(std::string* value);

  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 Arg_ = const std::string&, typename... Args_>
  void set_content(Arg_&& arg, Args_... args);
  std::string* mutable_content();
  PROTOBUF_NODISCARD std::string* release_content();
  void set_allocated_content(std::string* value);

  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 ::google::protobuf::GeneratedCodeInfo& generated_code_info() const;
  PROTOBUF_NODISCARD ::google::protobuf::GeneratedCodeInfo* release_generated_code_info();
  ::google::protobuf::GeneratedCodeInfo* mutable_generated_code_info();
  void set_allocated_generated_code_info(::google::protobuf::GeneratedCodeInfo* value);
  void unsafe_arena_set_allocated_generated_code_info(::google::protobuf::GeneratedCodeInfo* value);
  ::google::protobuf::GeneratedCodeInfo* unsafe_arena_release_generated_code_info();

  private:
  const ::google::protobuf::GeneratedCodeInfo& _internal_generated_code_info() const;
  ::google::protobuf::GeneratedCodeInfo* _internal_mutable_generated_code_info();

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      2, 4, 1,
      86, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_CodeGeneratorResponse_File_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const CodeGeneratorResponse_File& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::internal::ArenaStringPtr name_;
    ::google::protobuf::internal::ArenaStringPtr insertion_point_;
    ::google::protobuf::internal::ArenaStringPtr content_;
    ::google::protobuf::GeneratedCodeInfo* generated_code_info_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// -------------------------------------------------------------------

class PROTOC_EXPORT CodeGeneratorResponse final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorResponse) */ {
 public:
  inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {}
  ~CodeGeneratorResponse() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(
      ::google::protobuf::internal::ConstantInitialized);

  inline CodeGeneratorResponse(const CodeGeneratorResponse& from) : CodeGeneratorResponse(nullptr, from) {}
  inline CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept
      : CodeGeneratorResponse(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CodeGeneratorResponse* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  CodeGeneratorResponse* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<CodeGeneratorResponse>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const CodeGeneratorResponse& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const CodeGeneratorResponse& from) { CodeGeneratorResponse::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return true;
  }
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(CodeGeneratorResponse* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse"; }

 protected:
  explicit CodeGeneratorResponse(::google::protobuf::Arena* arena);
  CodeGeneratorResponse(::google::protobuf::Arena* arena, const CodeGeneratorResponse& from);
  CodeGeneratorResponse(::google::protobuf::Arena* arena, CodeGeneratorResponse&& from) noexcept
      : CodeGeneratorResponse(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------
  using File = CodeGeneratorResponse_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 constexpr Feature FEATURE_SUPPORTS_EDITIONS = CodeGeneratorResponse_Feature_FEATURE_SUPPORTS_EDITIONS;
  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 ::google::protobuf::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,
    kMinimumEditionFieldNumber = 3,
    kMaximumEditionFieldNumber = 4,
  };
  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
  int file_size() const;
  private:
  int _internal_file_size() const;

  public:
  void clear_file() ;
  ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>* mutable_file();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>& _internal_file() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>* _internal_mutable_file();
  public:
  const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
  ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>& file() const;
  // optional string error = 1;
  bool has_error() const;
  void clear_error() ;
  const std::string& error() const;
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_error(Arg_&& arg, Args_... args);
  std::string* mutable_error();
  PROTOBUF_NODISCARD std::string* release_error();
  void set_allocated_error(std::string* value);

  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:
  // optional int32 minimum_edition = 3;
  bool has_minimum_edition() const;
  void clear_minimum_edition() ;
  ::int32_t minimum_edition() const;
  void set_minimum_edition(::int32_t value);

  private:
  ::int32_t _internal_minimum_edition() const;
  void _internal_set_minimum_edition(::int32_t value);

  public:
  // optional int32 maximum_edition = 4;
  bool has_maximum_edition() const;
  void clear_maximum_edition() ;
  ::int32_t maximum_edition() const;
  void set_maximum_edition(::int32_t value);

  private:
  ::int32_t _internal_maximum_edition() const;
  void _internal_set_maximum_edition(::int32_t value);

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 1,
      60, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_CodeGeneratorResponse_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const CodeGeneratorResponse& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_;
    ::google::protobuf::internal::ArenaStringPtr error_;
    ::uint64_t supported_features_;
    ::int32_t minimum_edition_;
    ::int32_t maximum_edition_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  union { Impl_ _impl_; };
  friend struct ::TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto;
};
// -------------------------------------------------------------------

class PROTOC_EXPORT CodeGeneratorRequest final : public ::google::protobuf::Message
/* @@protoc_insertion_point(class_definition:google.protobuf.compiler.CodeGeneratorRequest) */ {
 public:
  inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {}
  ~CodeGeneratorRequest() PROTOBUF_FINAL;
  template <typename = void>
  explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(
      ::google::protobuf::internal::ConstantInitialized);

  inline CodeGeneratorRequest(const CodeGeneratorRequest& from) : CodeGeneratorRequest(nullptr, from) {}
  inline CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept
      : CodeGeneratorRequest(nullptr, 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 (GetArena() == from.GetArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
        && GetArena() != nullptr
#endif  // !PROTOBUF_FORCE_COPY_IN_MOVE
    ) {
      InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

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

  static const ::google::protobuf::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::google::protobuf::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::google::protobuf::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 (GetArena() != nullptr && GetArena() == other->GetArena()) {
#else   // PROTOBUF_FORCE_COPY_IN_SWAP
    if (GetArena() == other->GetArena()) {
#endif  // !PROTOBUF_FORCE_COPY_IN_SWAP
      InternalSwap(other);
    } else {
      ::google::protobuf::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CodeGeneratorRequest* other) {
    if (other == this) return;
    ABSL_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

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

  CodeGeneratorRequest* New(::google::protobuf::Arena* arena = nullptr) const PROTOBUF_FINAL {
    return ::google::protobuf::Message::DefaultConstruct<CodeGeneratorRequest>(arena);
  }
  using ::google::protobuf::Message::CopyFrom;
  void CopyFrom(const CodeGeneratorRequest& from);
  using ::google::protobuf::Message::MergeFrom;
  void MergeFrom(const CodeGeneratorRequest& from) { CodeGeneratorRequest::MergeImpl(*this, from); }

  private:
  static void MergeImpl(
      ::google::protobuf::MessageLite& to_msg,
      const ::google::protobuf::MessageLite& from_msg);

  public:
  bool IsInitialized() const {
    return IsInitializedImpl(*this);
  }

  private:
  static bool IsInitializedImpl(const MessageLite& msg);

  public:
  ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL;
  ::size_t ByteSizeLong() const PROTOBUF_FINAL;
  ::uint8_t* _InternalSerialize(::uint8_t* target,
                              ::google::protobuf::io::EpsCopyOutputStream*
                                  stream) const PROTOBUF_FINAL;
  int GetCachedSize() const { return _impl_._cached_size_.Get(); }

  private:
  void SharedCtor(::google::protobuf::Arena* arena);
  void SharedDtor();
  void InternalSwap(CodeGeneratorRequest* other);
 private:
  friend class ::google::protobuf::internal::AnyMetadata;
  static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorRequest"; }

 protected:
  explicit CodeGeneratorRequest(::google::protobuf::Arena* arena);
  CodeGeneratorRequest(::google::protobuf::Arena* arena, const CodeGeneratorRequest& from);
  CodeGeneratorRequest(::google::protobuf::Arena* arena, CodeGeneratorRequest&& from) noexcept
      : CodeGeneratorRequest(arena) {
    *this = ::std::move(from);
  }
  const ::google::protobuf::Message::ClassData* GetClassData() const PROTOBUF_FINAL;
  static const ::google::protobuf::Message::ClassDataFull _class_data_;

 public:
  ::google::protobuf::Metadata GetMetadata() const;
  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------
  enum : int {
    kFileToGenerateFieldNumber = 1,
    kProtoFileFieldNumber = 15,
    kSourceFileDescriptorsFieldNumber = 17,
    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);
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_file_to_generate(int index, Arg_&& value, Args_... args);
  std::string* add_file_to_generate();
  template <typename Arg_ = const std::string&, typename... Args_>
  void add_file_to_generate(Arg_&& value, Args_... args);
  const ::google::protobuf::RepeatedPtrField<std::string>& file_to_generate() const;
  ::google::protobuf::RepeatedPtrField<std::string>* mutable_file_to_generate();

  private:
  const ::google::protobuf::RepeatedPtrField<std::string>& _internal_file_to_generate() const;
  ::google::protobuf::RepeatedPtrField<std::string>* _internal_mutable_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() ;
  ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* mutable_proto_file();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& _internal_proto_file() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* _internal_mutable_proto_file();
  public:
  const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
  ::google::protobuf::FileDescriptorProto* add_proto_file();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& proto_file() const;
  // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17;
  int source_file_descriptors_size() const;
  private:
  int _internal_source_file_descriptors_size() const;

  public:
  void clear_source_file_descriptors() ;
  ::google::protobuf::FileDescriptorProto* mutable_source_file_descriptors(int index);
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* mutable_source_file_descriptors();

  private:
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& _internal_source_file_descriptors() const;
  ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* _internal_mutable_source_file_descriptors();
  public:
  const ::google::protobuf::FileDescriptorProto& source_file_descriptors(int index) const;
  ::google::protobuf::FileDescriptorProto* add_source_file_descriptors();
  const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& source_file_descriptors() const;
  // optional string parameter = 2;
  bool has_parameter() const;
  void clear_parameter() ;
  const std::string& parameter() const;
  template <typename Arg_ = const std::string&, typename... Args_>
  void set_parameter(Arg_&& arg, Args_... args);
  std::string* mutable_parameter();
  PROTOBUF_NODISCARD std::string* release_parameter();
  void set_allocated_parameter(std::string* value);

  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 ::google::protobuf::compiler::Version& compiler_version() const;
  PROTOBUF_NODISCARD ::google::protobuf::compiler::Version* release_compiler_version();
  ::google::protobuf::compiler::Version* mutable_compiler_version();
  void set_allocated_compiler_version(::google::protobuf::compiler::Version* value);
  void unsafe_arena_set_allocated_compiler_version(::google::protobuf::compiler::Version* value);
  ::google::protobuf::compiler::Version* unsafe_arena_release_compiler_version();

  private:
  const ::google::protobuf::compiler::Version& _internal_compiler_version() const;
  ::google::protobuf::compiler::Version* _internal_mutable_compiler_version();

  public:
  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
 private:
  class _Internal;
  friend class ::google::protobuf::internal::TcParser;
  static const ::google::protobuf::internal::TcParseTable<
      3, 5, 3,
      79, 2>
      _table_;

  static constexpr const void* _raw_default_instance_ =
      &_CodeGeneratorRequest_default_instance_;

  friend class ::google::protobuf::MessageLite;
  friend class ::google::protobuf::Arena;
  template <typename T>
  friend class ::google::protobuf::Arena::InternalHelper;
  using InternalArenaConstructable_ = void;
  using DestructorSkippable_ = void;
  struct Impl_ {
    inline explicit constexpr Impl_(
        ::google::protobuf::internal::ConstantInitialized) noexcept;
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena);
    inline explicit Impl_(::google::protobuf::internal::InternalVisibility visibility,
                          ::google::protobuf::Arena* arena, const Impl_& from,
                          const CodeGeneratorRequest& from_msg);
    ::google::protobuf::internal::HasBits<1> _has_bits_;
    mutable ::google::protobuf::internal::CachedSize _cached_size_;
    ::google::protobuf::RepeatedPtrField<std::string> file_to_generate_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
    ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > source_file_descriptors_;
    ::google::protobuf::internal::ArenaStringPtr parameter_;
    ::google::protobuf::compiler::Version* compiler_version_;
    PROTOBUF_TSAN_DECLARE_MEMBER
  };
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.major_ = 0;
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline ::int32_t Version::major() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.major)
  return _internal_major();
}
inline void Version::set_major(::int32_t value) {
  _internal_set_major(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.major)
}
inline ::int32_t Version::_internal_major() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.major_;
}
inline void Version::_internal_set_major(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.major_ = value;
}

// 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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.minor_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::int32_t Version::minor() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.minor)
  return _internal_minor();
}
inline void Version::set_minor(::int32_t value) {
  _internal_set_minor(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.minor)
}
inline ::int32_t Version::_internal_minor() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.minor_;
}
inline void Version::_internal_set_minor(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.minor_ = value;
}

// 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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.patch_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::int32_t Version::patch() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.patch)
  return _internal_patch();
}
inline void Version::set_patch(::int32_t value) {
  _internal_set_patch(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.patch)
}
inline ::int32_t Version::_internal_patch() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.patch_;
}
inline void Version::_internal_set_patch(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.patch_ = value;
}

// 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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.suffix_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& Version::suffix() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.Version.suffix)
  return _internal_suffix();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void Version::set_suffix(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.suffix_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.Version.suffix)
}
inline std::string* Version::mutable_suffix() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.suffix_.Get();
}
inline void Version::_internal_set_suffix(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.suffix_.Set(value, GetArena());
}
inline std::string* Version::_internal_mutable_suffix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.suffix_.Mutable( GetArena());
}
inline std::string* Version::release_suffix() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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* released = _impl_.suffix_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.suffix_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void Version::set_allocated_suffix(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.suffix_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.suffix_.IsDefault()) {
          _impl_.suffix_.Set("", GetArena());
        }
  #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 _internal_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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.file_to_generate_.Clear();
}
inline std::string* CodeGeneratorRequest::add_file_to_generate() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  std::string* _s = _internal_mutable_file_to_generate()->Add();
  // @@protoc_insertion_point(field_add_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _s;
}
inline const std::string& CodeGeneratorRequest::file_to_generate(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _internal_file_to_generate().Get(index);
}
inline std::string* CodeGeneratorRequest::mutable_file_to_generate(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _internal_mutable_file_to_generate()->Mutable(index);
}
template <typename Arg_, typename... Args_>
inline void CodeGeneratorRequest::set_file_to_generate(int index, Arg_&& value, Args_... args) {
  ::google::protobuf::internal::AssignToString(
      *_internal_mutable_file_to_generate()->Mutable(index),
      std::forward<Arg_>(value), args... );
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
template <typename Arg_, typename... Args_>
inline void CodeGeneratorRequest::add_file_to_generate(Arg_&& value, Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::internal::AddToRepeatedPtrField(*_internal_mutable_file_to_generate(),
                               std::forward<Arg_>(value),
                               args... );
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
CodeGeneratorRequest::file_to_generate() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  return _internal_file_to_generate();
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
CodeGeneratorRequest::mutable_file_to_generate() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_file_to_generate();
}
inline const ::google::protobuf::RepeatedPtrField<std::string>&
CodeGeneratorRequest::_internal_file_to_generate() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.file_to_generate_;
}
inline ::google::protobuf::RepeatedPtrField<std::string>*
CodeGeneratorRequest::_internal_mutable_file_to_generate() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.parameter_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CodeGeneratorRequest::parameter() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
  return _internal_parameter();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorRequest::set_parameter(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.parameter_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
}
inline std::string* CodeGeneratorRequest::mutable_parameter() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.parameter_.Get();
}
inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.parameter_.Set(value, GetArena());
}
inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.parameter_.Mutable( GetArena());
}
inline std::string* CodeGeneratorRequest::release_parameter() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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* released = _impl_.parameter_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.parameter_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void CodeGeneratorRequest::set_allocated_parameter(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.parameter_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.parameter_.IsDefault()) {
          _impl_.parameter_.Set("", GetArena());
        }
  #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 _internal_proto_file().size();
}
inline int CodeGeneratorRequest::proto_file_size() const {
  return _internal_proto_file_size();
}
inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _internal_mutable_proto_file()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* CodeGeneratorRequest::mutable_proto_file()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_proto_file();
}
inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _internal_proto_file().Get(index);
}
inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::FileDescriptorProto* _add = _internal_mutable_proto_file()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& CodeGeneratorRequest::proto_file() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
  return _internal_proto_file();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>&
CodeGeneratorRequest::_internal_proto_file() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.proto_file_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>*
CodeGeneratorRequest::_internal_mutable_proto_file() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.proto_file_;
}

// repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17;
inline int CodeGeneratorRequest::_internal_source_file_descriptors_size() const {
  return _internal_source_file_descriptors().size();
}
inline int CodeGeneratorRequest::source_file_descriptors_size() const {
  return _internal_source_file_descriptors_size();
}
inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_source_file_descriptors(int index)
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.source_file_descriptors)
  return _internal_mutable_source_file_descriptors()->Mutable(index);
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* CodeGeneratorRequest::mutable_source_file_descriptors()
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.source_file_descriptors)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  return _internal_mutable_source_file_descriptors();
}
inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::source_file_descriptors(int index) const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.source_file_descriptors)
  return _internal_source_file_descriptors().Get(index);
}
inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_source_file_descriptors() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::google::protobuf::FileDescriptorProto* _add = _internal_mutable_source_file_descriptors()->Add();
  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.source_file_descriptors)
  return _add;
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& CodeGeneratorRequest::source_file_descriptors() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.source_file_descriptors)
  return _internal_source_file_descriptors();
}
inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>&
CodeGeneratorRequest::_internal_source_file_descriptors() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.source_file_descriptors_;
}
inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>*
CodeGeneratorRequest::_internal_mutable_source_file_descriptors() {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return &_impl_.source_file_descriptors_;
}

// 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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.compiler_version_ != nullptr) _impl_.compiler_version_->Clear();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::_internal_compiler_version() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::compiler::Version* p = _impl_.compiler_version_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::compiler::Version&>(::google::protobuf::compiler::_Version_default_instance_);
}
inline const ::google::protobuf::compiler::Version& CodeGeneratorRequest::compiler_version() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)
  return _internal_compiler_version();
}
inline void CodeGeneratorRequest::unsafe_arena_set_allocated_compiler_version(::google::protobuf::compiler::Version* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.compiler_version_);
  }
  _impl_.compiler_version_ = reinterpret_cast<::google::protobuf::compiler::Version*>(value);
  if (value != nullptr) {
    _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 ::google::protobuf::compiler::Version* CodeGeneratorRequest::release_compiler_version() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::compiler::Version* released = _impl_.compiler_version_;
  _impl_.compiler_version_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::unsafe_arena_release_compiler_version() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.compiler_version)

  _impl_._has_bits_[0] &= ~0x00000002u;
  ::google::protobuf::compiler::Version* temp = _impl_.compiler_version_;
  _impl_.compiler_version_ = nullptr;
  return temp;
}
inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::_internal_mutable_compiler_version() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.compiler_version_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::compiler::Version>(GetArena());
    _impl_.compiler_version_ = reinterpret_cast<::google::protobuf::compiler::Version*>(p);
  }
  return _impl_.compiler_version_;
}
inline ::google::protobuf::compiler::Version* CodeGeneratorRequest::mutable_compiler_version() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000002u;
  ::google::protobuf::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(::google::protobuf::compiler::Version* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete (_impl_.compiler_version_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = (value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }

  _impl_.compiler_version_ = reinterpret_cast<::google::protobuf::compiler::Version*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.name_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CodeGeneratorResponse_File::name() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
  return _internal_name();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_name(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
}
inline std::string* CodeGeneratorResponse_File::mutable_name() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.name_.Get();
}
inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.name_.Set(value, GetArena());
}
inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.name_.Mutable( GetArena());
}
inline std::string* CodeGeneratorResponse_File::release_name() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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* released = _impl_.name_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.name_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void CodeGeneratorResponse_File::set_allocated_name(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.name_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.name_.IsDefault()) {
          _impl_.name_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.insertion_point_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000002u;
}
inline const std::string& CodeGeneratorResponse_File::insertion_point() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
  return _internal_insertion_point();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_insertion_point(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.insertion_point_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
}
inline std::string* CodeGeneratorResponse_File::mutable_insertion_point() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.insertion_point_.Get();
}
inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  _impl_.insertion_point_.Set(value, GetArena());
}
inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000002u;
  return _impl_.insertion_point_.Mutable( GetArena());
}
inline std::string* CodeGeneratorResponse_File::release_insertion_point() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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* released = _impl_.insertion_point_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.insertion_point_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void CodeGeneratorResponse_File::set_allocated_insertion_point(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000002u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000002u;
  }
  _impl_.insertion_point_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.insertion_point_.IsDefault()) {
          _impl_.insertion_point_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.content_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline const std::string& CodeGeneratorResponse_File::content() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
  return _internal_content();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse_File::set_content(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.content_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
}
inline std::string* CodeGeneratorResponse_File::mutable_content() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.content_.Get();
}
inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  _impl_.content_.Set(value, GetArena());
}
inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000004u;
  return _impl_.content_.Mutable( GetArena());
}
inline std::string* CodeGeneratorResponse_File::release_content() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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* released = _impl_.content_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.content_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void CodeGeneratorResponse_File::set_allocated_content(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000004u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000004u;
  }
  _impl_.content_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.content_.IsDefault()) {
          _impl_.content_.Set("", GetArena());
        }
  #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 ::google::protobuf::GeneratedCodeInfo& CodeGeneratorResponse_File::_internal_generated_code_info() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  const ::google::protobuf::GeneratedCodeInfo* p = _impl_.generated_code_info_;
  return p != nullptr ? *p : reinterpret_cast<const ::google::protobuf::GeneratedCodeInfo&>(::google::protobuf::_GeneratedCodeInfo_default_instance_);
}
inline const ::google::protobuf::GeneratedCodeInfo& CodeGeneratorResponse_File::generated_code_info() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@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(::google::protobuf::GeneratedCodeInfo* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.generated_code_info_);
  }
  _impl_.generated_code_info_ = reinterpret_cast<::google::protobuf::GeneratedCodeInfo*>(value);
  if (value != nullptr) {
    _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 ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::release_generated_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);

  _impl_._has_bits_[0] &= ~0x00000008u;
  ::google::protobuf::GeneratedCodeInfo* released = _impl_.generated_code_info_;
  _impl_.generated_code_info_ = nullptr;
#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
  auto* old = reinterpret_cast<::google::protobuf::MessageLite*>(released);
  released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  if (GetArena() == nullptr) {
    delete old;
  }
#else   // PROTOBUF_FORCE_COPY_IN_RELEASE
  if (GetArena() != nullptr) {
    released = ::google::protobuf::internal::DuplicateIfNonNull(released);
  }
#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
  return released;
}
inline ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::unsafe_arena_release_generated_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info)

  _impl_._has_bits_[0] &= ~0x00000008u;
  ::google::protobuf::GeneratedCodeInfo* temp = _impl_.generated_code_info_;
  _impl_.generated_code_info_ = nullptr;
  return temp;
}
inline ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::_internal_mutable_generated_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.generated_code_info_ == nullptr) {
    auto* p = ::google::protobuf::Message::DefaultConstruct<::google::protobuf::GeneratedCodeInfo>(GetArena());
    _impl_.generated_code_info_ = reinterpret_cast<::google::protobuf::GeneratedCodeInfo*>(p);
  }
  return _impl_.generated_code_info_;
}
inline ::google::protobuf::GeneratedCodeInfo* CodeGeneratorResponse_File::mutable_generated_code_info() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  _impl_._has_bits_[0] |= 0x00000008u;
  ::google::protobuf::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(::google::protobuf::GeneratedCodeInfo* value) {
  ::google::protobuf::Arena* message_arena = GetArena();
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (message_arena == nullptr) {
    delete reinterpret_cast<::google::protobuf::MessageLite*>(_impl_.generated_code_info_);
  }

  if (value != nullptr) {
    ::google::protobuf::Arena* submessage_arena = reinterpret_cast<::google::protobuf::MessageLite*>(value)->GetArena();
    if (message_arena != submessage_arena) {
      value = ::google::protobuf::internal::GetOwnedMessage(message_arena, value, submessage_arena);
    }
    _impl_._has_bits_[0] |= 0x00000008u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000008u;
  }

  _impl_.generated_code_info_ = reinterpret_cast<::google::protobuf::GeneratedCodeInfo*>(value);
  // @@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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.error_.ClearToEmpty();
  _impl_._has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CodeGeneratorResponse::error() const
    ABSL_ATTRIBUTE_LIFETIME_BOUND {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
  return _internal_error();
}
template <typename Arg_, typename... Args_>
inline PROTOBUF_ALWAYS_INLINE void CodeGeneratorResponse::set_error(Arg_&& arg,
                                                     Args_... args) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.error_.Set(static_cast<Arg_&&>(arg), args..., GetArena());
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
}
inline std::string* CodeGeneratorResponse::mutable_error() ABSL_ATTRIBUTE_LIFETIME_BOUND {
  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 {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.error_.Get();
}
inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  _impl_.error_.Set(value, GetArena());
}
inline std::string* CodeGeneratorResponse::_internal_mutable_error() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_._has_bits_[0] |= 0x00000001u;
  return _impl_.error_.Mutable( GetArena());
}
inline std::string* CodeGeneratorResponse::release_error() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  // @@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* released = _impl_.error_.Release();
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
  _impl_.error_.Set("", GetArena());
  #endif  // PROTOBUF_FORCE_COPY_DEFAULT_STRING
  return released;
}
inline void CodeGeneratorResponse::set_allocated_error(std::string* value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (value != nullptr) {
    _impl_._has_bits_[0] |= 0x00000001u;
  } else {
    _impl_._has_bits_[0] &= ~0x00000001u;
  }
  _impl_.error_.SetAllocated(value, GetArena());
  #ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
        if (_impl_.error_.IsDefault()) {
          _impl_.error_.Set("", GetArena());
        }
  #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() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.supported_features_ = ::uint64_t{0u};
  _impl_._has_bits_[0] &= ~0x00000002u;
}
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::set_supported_features(::uint64_t value) {
  _internal_set_supported_features(value);
  _impl_._has_bits_[0] |= 0x00000002u;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.supported_features)
}
inline ::uint64_t CodeGeneratorResponse::_internal_supported_features() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.supported_features_;
}
inline void CodeGeneratorResponse::_internal_set_supported_features(::uint64_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.supported_features_ = value;
}

// optional int32 minimum_edition = 3;
inline bool CodeGeneratorResponse::has_minimum_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline void CodeGeneratorResponse::clear_minimum_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.minimum_edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000004u;
}
inline ::int32_t CodeGeneratorResponse::minimum_edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.minimum_edition)
  return _internal_minimum_edition();
}
inline void CodeGeneratorResponse::set_minimum_edition(::int32_t value) {
  _internal_set_minimum_edition(value);
  _impl_._has_bits_[0] |= 0x00000004u;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.minimum_edition)
}
inline ::int32_t CodeGeneratorResponse::_internal_minimum_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.minimum_edition_;
}
inline void CodeGeneratorResponse::_internal_set_minimum_edition(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.minimum_edition_ = value;
}

// optional int32 maximum_edition = 4;
inline bool CodeGeneratorResponse::has_maximum_edition() const {
  bool value = (_impl_._has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline void CodeGeneratorResponse::clear_maximum_edition() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.maximum_edition_ = 0;
  _impl_._has_bits_[0] &= ~0x00000008u;
}
inline ::int32_t CodeGeneratorResponse::maximum_edition() const {
  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.maximum_edition)
  return _internal_maximum_edition();
}
inline void CodeGeneratorResponse::set_maximum_edition(::int32_t value) {
  _internal_set_maximum_edition(value);
  _impl_._has_bits_[0] |= 0x00000008u;
  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.maximum_edition)
}
inline ::int32_t CodeGeneratorResponse::_internal_maximum_edition() const {
  ::google::protobuf::internal::TSanRead(&_impl_);
  return _impl_.maximum_edition_;
}
inline void CodeGeneratorResponse::_internal_set_maximum_edition(::int32_t value) {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.maximum_edition_ = value;
}

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

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

// @@protoc_insertion_point(namespace_scope)
}  // namespace compiler
}  // namespace protobuf
}  // namespace google


namespace google {
namespace protobuf {

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

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#include "google/protobuf/port_undef.inc"

#endif  // GOOGLE_PROTOBUF_INCLUDED_google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh
