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

#include "google/protobuf/compiler/plugin.pb.h"

#include <algorithm>
#include <type_traits>
#include "google/protobuf/io/coded_stream.h"
#include "google/protobuf/generated_message_tctable_impl.h"
#include "google/protobuf/extension_set.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/generated_message_reflection.h"
#include "google/protobuf/reflection_ops.h"
#include "google/protobuf/wire_format.h"
// @@protoc_insertion_point(includes)

// Must be included last.
#include "google/protobuf/port_def.inc"
PROTOBUF_PRAGMA_INIT_SEG
namespace _pb = ::google::protobuf;
namespace _pbi = ::google::protobuf::internal;
namespace _fl = ::google::protobuf::internal::field_layout;
namespace google {
namespace protobuf {
namespace compiler {

inline constexpr Version::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : _cached_size_{0},
        suffix_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        major_{0},
        minor_{0},
        patch_{0} {}

template <typename>
PROTOBUF_CONSTEXPR Version::Version(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct VersionDefaultTypeInternal {
  PROTOBUF_CONSTEXPR VersionDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~VersionDefaultTypeInternal() {}
  union {
    Version _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 VersionDefaultTypeInternal _Version_default_instance_;

inline constexpr CodeGeneratorResponse_File::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : _cached_size_{0},
        name_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        insertion_point_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        content_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        generated_code_info_{nullptr} {}

template <typename>
PROTOBUF_CONSTEXPR CodeGeneratorResponse_File::CodeGeneratorResponse_File(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct CodeGeneratorResponse_FileDefaultTypeInternal {
  PROTOBUF_CONSTEXPR CodeGeneratorResponse_FileDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~CodeGeneratorResponse_FileDefaultTypeInternal() {}
  union {
    CodeGeneratorResponse_File _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_;

inline constexpr CodeGeneratorResponse::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : _cached_size_{0},
        file_{},
        error_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        supported_features_{::uint64_t{0u}},
        minimum_edition_{0},
        maximum_edition_{0} {}

template <typename>
PROTOBUF_CONSTEXPR CodeGeneratorResponse::CodeGeneratorResponse(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct CodeGeneratorResponseDefaultTypeInternal {
  PROTOBUF_CONSTEXPR CodeGeneratorResponseDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~CodeGeneratorResponseDefaultTypeInternal() {}
  union {
    CodeGeneratorResponse _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponseDefaultTypeInternal _CodeGeneratorResponse_default_instance_;

inline constexpr CodeGeneratorRequest::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : _cached_size_{0},
        file_to_generate_{},
        proto_file_{},
        source_file_descriptors_{},
        parameter_(
            &::google::protobuf::internal::fixed_address_empty_string,
            ::_pbi::ConstantInitialized()),
        compiler_version_{nullptr} {}

template <typename>
PROTOBUF_CONSTEXPR CodeGeneratorRequest::CodeGeneratorRequest(::_pbi::ConstantInitialized)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(::_pbi::ConstantInitialized()) {
}
struct CodeGeneratorRequestDefaultTypeInternal {
  PROTOBUF_CONSTEXPR CodeGeneratorRequestDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {}
  ~CodeGeneratorRequestDefaultTypeInternal() {}
  union {
    CodeGeneratorRequest _instance;
  };
};

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_;
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
static const ::_pb::EnumDescriptor* file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[1];
static constexpr const ::_pb::ServiceDescriptor**
    file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto = nullptr;
const ::uint32_t
    TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
        protodesc_cold) = {
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_._has_bits_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _internal_metadata_),
        ~0u,  // no _extensions_
        ~0u,  // no _oneof_case_
        ~0u,  // no _weak_field_map_
        ~0u,  // no _inlined_string_donated_
        ~0u,  // no _split_
        ~0u,  // no sizeof(Split)
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.major_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.minor_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.patch_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::Version, _impl_.suffix_),
        1,
        2,
        3,
        0,
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_._has_bits_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _internal_metadata_),
        ~0u,  // no _extensions_
        ~0u,  // no _oneof_case_
        ~0u,  // no _weak_field_map_
        ~0u,  // no _inlined_string_donated_
        ~0u,  // no _split_
        ~0u,  // no sizeof(Split)
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.file_to_generate_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.parameter_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.proto_file_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.source_file_descriptors_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorRequest, _impl_.compiler_version_),
        ~0u,
        0,
        ~0u,
        ~0u,
        1,
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_._has_bits_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _internal_metadata_),
        ~0u,  // no _extensions_
        ~0u,  // no _oneof_case_
        ~0u,  // no _weak_field_map_
        ~0u,  // no _inlined_string_donated_
        ~0u,  // no _split_
        ~0u,  // no sizeof(Split)
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.name_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.insertion_point_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.content_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse_File, _impl_.generated_code_info_),
        0,
        1,
        2,
        3,
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_._has_bits_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _internal_metadata_),
        ~0u,  // no _extensions_
        ~0u,  // no _oneof_case_
        ~0u,  // no _weak_field_map_
        ~0u,  // no _inlined_string_donated_
        ~0u,  // no _split_
        ~0u,  // no sizeof(Split)
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.error_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.supported_features_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.minimum_edition_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.maximum_edition_),
        PROTOBUF_FIELD_OFFSET(::google::protobuf::compiler::CodeGeneratorResponse, _impl_.file_),
        0,
        1,
        2,
        3,
        ~0u,
};

static const ::_pbi::MigrationSchema
    schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
        {0, 12, -1, sizeof(::google::protobuf::compiler::Version)},
        {16, 29, -1, sizeof(::google::protobuf::compiler::CodeGeneratorRequest)},
        {34, 46, -1, sizeof(::google::protobuf::compiler::CodeGeneratorResponse_File)},
        {50, 63, -1, sizeof(::google::protobuf::compiler::CodeGeneratorResponse)},
};
static const ::_pb::Message* const file_default_instances[] = {
    &::google::protobuf::compiler::_Version_default_instance_._instance,
    &::google::protobuf::compiler::_CodeGeneratorRequest_default_instance_._instance,
    &::google::protobuf::compiler::_CodeGeneratorResponse_File_default_instance_._instance,
    &::google::protobuf::compiler::_CodeGeneratorResponse_default_instance_._instance,
};
const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
    protodesc_cold) = {
    "\n%google/protobuf/compiler/plugin.proto\022"
    "\030google.protobuf.compiler\032 google/protob"
    "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"
    "\001 \001(\005\022\r\n\005minor\030\002 \001(\005\022\r\n\005patch\030\003 \001(\005\022\016\n\006s"
    "uffix\030\004 \001(\t\"\201\002\n\024CodeGeneratorRequest\022\030\n\020"
    "file_to_generate\030\001 \003(\t\022\021\n\tparameter\030\002 \001("
    "\t\0228\n\nproto_file\030\017 \003(\0132$.google.protobuf."
    "FileDescriptorProto\022E\n\027source_file_descr"
    "iptors\030\021 \003(\0132$.google.protobuf.FileDescr"
    "iptorProto\022;\n\020compiler_version\030\003 \001(\0132!.g"
    "oogle.protobuf.compiler.Version\"\222\003\n\025Code"
    "GeneratorResponse\022\r\n\005error\030\001 \001(\t\022\032\n\022supp"
    "orted_features\030\002 \001(\004\022\027\n\017minimum_edition\030"
    "\003 \001(\005\022\027\n\017maximum_edition\030\004 \001(\005\022B\n\004file\030\017"
    " \003(\01324.google.protobuf.compiler.CodeGene"
    "ratorResponse.File\032\177\n\004File\022\014\n\004name\030\001 \001(\t"
    "\022\027\n\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001"
    "(\t\022\?\n\023generated_code_info\030\020 \001(\0132\".google"
    ".protobuf.GeneratedCodeInfo\"W\n\007Feature\022\020"
    "\n\014FEATURE_NONE\020\000\022\033\n\027FEATURE_PROTO3_OPTIO"
    "NAL\020\001\022\035\n\031FEATURE_SUPPORTS_EDITIONS\020\002Br\n\034"
    "com.google.protobuf.compilerB\014PluginProt"
    "osZ)google.golang.org/protobuf/types/plu"
    "ginpb\252\002\030Google.Protobuf.Compiler"
};
static const ::_pbi::DescriptorTable* const descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps[1] =
    {
        &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
};
static ::absl::once_flag descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once;
PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto = {
    false,
    false,
    952,
    descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
    "google/protobuf/compiler/plugin.proto",
    &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_once,
    descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto_deps,
    1,
    4,
    schemas,
    file_default_instances,
    TableStruct_google_2fprotobuf_2fcompiler_2fplugin_2eproto::offsets,
    file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
    file_level_service_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
};
namespace google {
namespace protobuf {
namespace compiler {
const ::google::protobuf::EnumDescriptor* CodeGeneratorResponse_Feature_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fplugin_2eproto[0];
}
PROTOBUF_CONSTINIT const uint32_t CodeGeneratorResponse_Feature_internal_data_[] = {
    196608u, 0u, };
bool CodeGeneratorResponse_Feature_IsValid(int value) {
  return 0 <= value && value <= 2;
}
#if (__cplusplus < 201703) && \
  (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))

constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_NONE;
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL;
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::FEATURE_SUPPORTS_EDITIONS;
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MIN;
constexpr CodeGeneratorResponse_Feature CodeGeneratorResponse::Feature_MAX;
constexpr int CodeGeneratorResponse::Feature_ARRAYSIZE;

#endif  // (__cplusplus < 201703) &&
        // (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
// ===================================================================

class Version::_Internal {
 public:
  using HasBits =
      decltype(std::declval<Version>()._impl_._has_bits_);
  static constexpr ::int32_t kHasBitsOffset =
      8 * PROTOBUF_FIELD_OFFSET(Version, _impl_._has_bits_);
};

Version::Version(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version)
}
inline PROTOBUF_NDEBUG_INLINE Version::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::compiler::Version& from_msg)
      : _has_bits_{from._has_bits_},
        _cached_size_{0},
        suffix_(arena, from.suffix_) {}

Version::Version(
    ::google::protobuf::Arena* arena,
    const Version& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  Version* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
  ::memcpy(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, major_),
           reinterpret_cast<const char *>(&from._impl_) +
               offsetof(Impl_, major_),
           offsetof(Impl_, patch_) -
               offsetof(Impl_, major_) +
               sizeof(Impl_::patch_));

  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.Version)
}
inline PROTOBUF_NDEBUG_INLINE Version::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : _cached_size_{0},
        suffix_(arena) {}

inline void Version::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  ::memset(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, major_),
           0,
           offsetof(Impl_, patch_) -
               offsetof(Impl_, major_) +
               sizeof(Impl_::patch_));
}
Version::~Version() {
  // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void Version::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.suffix_.Destroy();
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    Version::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            nullptr,  // IsInitialized
            &Version::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<Version>(),
            ::google::protobuf::Message::GetNewImpl<Version>(),
            ::google::protobuf::Message::GetClearImpl<Version>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<Version>(),
                ::google::protobuf::Message::GetSerializeImpl<Version>(),
#endif  // PROTOBUF_CUSTOM_VTABLE
            PROTOBUF_FIELD_OFFSET(Version, _impl_._cached_size_),
            false,
        },
        &Version::kDescriptorMethods,
        &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
        nullptr,  // tracker
};
const ::google::protobuf::MessageLite::ClassData* Version::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<2, 4, 0, 47, 2> Version::_table_ = {
  {
    PROTOBUF_FIELD_OFFSET(Version, _impl_._has_bits_),
    0, // no _extensions_
    4, 24,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294967280,  // skipmap
    offsetof(decltype(_table_), field_entries),
    4,  // num_field_entries
    0,  // num_aux_entries
    offsetof(decltype(_table_), field_names),  // no aux_entries
    &_Version_default_instance_._instance,
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::compiler::Version>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    // optional string suffix = 4;
    {::_pbi::TcParser::FastSS1,
     {34, 0, 0, PROTOBUF_FIELD_OFFSET(Version, _impl_.suffix_)}},
    // optional int32 major = 1;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Version, _impl_.major_), 1>(),
     {8, 1, 0, PROTOBUF_FIELD_OFFSET(Version, _impl_.major_)}},
    // optional int32 minor = 2;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Version, _impl_.minor_), 2>(),
     {16, 2, 0, PROTOBUF_FIELD_OFFSET(Version, _impl_.minor_)}},
    // optional int32 patch = 3;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(Version, _impl_.patch_), 3>(),
     {24, 3, 0, PROTOBUF_FIELD_OFFSET(Version, _impl_.patch_)}},
  }}, {{
    65535, 65535
  }}, {{
    // optional int32 major = 1;
    {PROTOBUF_FIELD_OFFSET(Version, _impl_.major_), _Internal::kHasBitsOffset + 1, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kInt32)},
    // optional int32 minor = 2;
    {PROTOBUF_FIELD_OFFSET(Version, _impl_.minor_), _Internal::kHasBitsOffset + 2, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kInt32)},
    // optional int32 patch = 3;
    {PROTOBUF_FIELD_OFFSET(Version, _impl_.patch_), _Internal::kHasBitsOffset + 3, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kInt32)},
    // optional string suffix = 4;
    {PROTOBUF_FIELD_OFFSET(Version, _impl_.suffix_), _Internal::kHasBitsOffset + 0, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kRawString | ::_fl::kRepAString)},
  }},
  // no aux_entries
  {{
    "\40\0\0\0\6\0\0\0"
    "google.protobuf.compiler.Version"
    "suffix"
  }},
};

PROTOBUF_NOINLINE void Version::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    _impl_.suffix_.ClearNonDefaultToEmpty();
  }
  if (cached_has_bits & 0x0000000eu) {
    ::memset(&_impl_.major_, 0, static_cast<::size_t>(
        reinterpret_cast<char*>(&_impl_.patch_) -
        reinterpret_cast<char*>(&_impl_.major_)) + sizeof(_impl_.patch_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

::uint8_t* Version::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version)
  ::uint32_t cached_has_bits = 0;
  (void)cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional int32 major = 1;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::
        WriteInt32ToArrayWithField<1>(
            stream, this->_internal_major(), target);
  }

  // optional int32 minor = 2;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::
        WriteInt32ToArrayWithField<2>(
            stream, this->_internal_minor(), target);
  }

  // optional int32 patch = 3;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::
        WriteInt32ToArrayWithField<3>(
            stream, this->_internal_patch(), target);
  }

  // optional string suffix = 4;
  if (cached_has_bits & 0x00000001u) {
    const std::string& _s = this->_internal_suffix();
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.Version.suffix");
    target = stream->WriteStringMaybeAliased(4, _s, target);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.Version)
  return target;
}

::size_t Version::ByteSizeLong() const {
  // @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.Version)
  ::size_t total_size = 0;

  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void)cached_has_bits;

  ::_pbi::Prefetch5LinesFrom7Lines(
      reinterpret_cast<const void*>(this));
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    // optional string suffix = 4;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                      this->_internal_suffix());
    }
    // optional int32 major = 1;
    if (cached_has_bits & 0x00000002u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
          this->_internal_major());
    }
    // optional int32 minor = 2;
    if (cached_has_bits & 0x00000004u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
          this->_internal_minor());
    }
    // optional int32 patch = 3;
    if (cached_has_bits & 0x00000008u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
          this->_internal_patch());
    }
  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

void Version::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
  auto* const _this = static_cast<Version*>(&to_msg);
  auto& from = static_cast<const Version&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version)
  ABSL_DCHECK_NE(&from, _this);
  ::uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_suffix(from._internal_suffix());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.major_ = from._impl_.major_;
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.minor_ = from._impl_.minor_;
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_impl_.patch_ = from._impl_.patch_;
    }
  }
  _this->_impl_._has_bits_[0] |= cached_has_bits;
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

void Version::CopyFrom(const Version& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.Version)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}


void Version::InternalSwap(Version* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.suffix_, &other->_impl_.suffix_, arena);
  ::google::protobuf::internal::memswap<
      PROTOBUF_FIELD_OFFSET(Version, _impl_.patch_)
      + sizeof(Version::_impl_.patch_)
      - PROTOBUF_FIELD_OFFSET(Version, _impl_.major_)>(
          reinterpret_cast<char*>(&_impl_.major_),
          reinterpret_cast<char*>(&other->_impl_.major_));
}

::google::protobuf::Metadata Version::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// ===================================================================

class CodeGeneratorRequest::_Internal {
 public:
  using HasBits =
      decltype(std::declval<CodeGeneratorRequest>()._impl_._has_bits_);
  static constexpr ::int32_t kHasBitsOffset =
      8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._has_bits_);
};

void CodeGeneratorRequest::clear_proto_file() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.proto_file_.Clear();
}
void CodeGeneratorRequest::clear_source_file_descriptors() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  _impl_.source_file_descriptors_.Clear();
}
CodeGeneratorRequest::CodeGeneratorRequest(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
inline PROTOBUF_NDEBUG_INLINE CodeGeneratorRequest::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::compiler::CodeGeneratorRequest& from_msg)
      : _has_bits_{from._has_bits_},
        _cached_size_{0},
        file_to_generate_{visibility, arena, from.file_to_generate_},
        proto_file_{visibility, arena, from.proto_file_},
        source_file_descriptors_{visibility, arena, from.source_file_descriptors_},
        parameter_(arena, from.parameter_) {}

CodeGeneratorRequest::CodeGeneratorRequest(
    ::google::protobuf::Arena* arena,
    const CodeGeneratorRequest& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  CodeGeneratorRequest* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
  ::uint32_t cached_has_bits = _impl_._has_bits_[0];
  _impl_.compiler_version_ = (cached_has_bits & 0x00000002u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::compiler::Version>(
                              arena, *from._impl_.compiler_version_)
                        : nullptr;

  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
}
inline PROTOBUF_NDEBUG_INLINE CodeGeneratorRequest::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : _cached_size_{0},
        file_to_generate_{visibility, arena},
        proto_file_{visibility, arena},
        source_file_descriptors_{visibility, arena},
        parameter_(arena) {}

inline void CodeGeneratorRequest::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  _impl_.compiler_version_ = {};
}
CodeGeneratorRequest::~CodeGeneratorRequest() {
  // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void CodeGeneratorRequest::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.parameter_.Destroy();
  delete _impl_.compiler_version_;
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    CodeGeneratorRequest::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            CodeGeneratorRequest::IsInitializedImpl,
            &CodeGeneratorRequest::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<CodeGeneratorRequest>(),
            ::google::protobuf::Message::GetNewImpl<CodeGeneratorRequest>(),
            ::google::protobuf::Message::GetClearImpl<CodeGeneratorRequest>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<CodeGeneratorRequest>(),
                ::google::protobuf::Message::GetSerializeImpl<CodeGeneratorRequest>(),
#endif  // PROTOBUF_CUSTOM_VTABLE
            PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._cached_size_),
            false,
        },
        &CodeGeneratorRequest::kDescriptorMethods,
        &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
        nullptr,  // tracker
};
const ::google::protobuf::MessageLite::ClassData* CodeGeneratorRequest::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<3, 5, 3, 79, 2> CodeGeneratorRequest::_table_ = {
  {
    PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._has_bits_),
    0, // no _extensions_
    17, 56,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294885368,  // skipmap
    offsetof(decltype(_table_), field_entries),
    5,  // num_field_entries
    3,  // num_aux_entries
    offsetof(decltype(_table_), aux_entries),
    &_CodeGeneratorRequest_default_instance_._instance,
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorRequest>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    {::_pbi::TcParser::MiniParse, {}},
    // repeated string file_to_generate = 1;
    {::_pbi::TcParser::FastSR1,
     {10, 63, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.file_to_generate_)}},
    // optional string parameter = 2;
    {::_pbi::TcParser::FastSS1,
     {18, 0, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.parameter_)}},
    // optional .google.protobuf.compiler.Version compiler_version = 3;
    {::_pbi::TcParser::FastMtS1,
     {26, 1, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.compiler_version_)}},
    {::_pbi::TcParser::MiniParse, {}},
    {::_pbi::TcParser::MiniParse, {}},
    {::_pbi::TcParser::MiniParse, {}},
    // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
    {::_pbi::TcParser::FastMtR1,
     {122, 63, 1, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.proto_file_)}},
  }}, {{
    65535, 65535
  }}, {{
    // repeated string file_to_generate = 1;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.file_to_generate_), -1, 0,
    (0 | ::_fl::kFcRepeated | ::_fl::kRawString | ::_fl::kRepSString)},
    // optional string parameter = 2;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.parameter_), _Internal::kHasBitsOffset + 0, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kRawString | ::_fl::kRepAString)},
    // optional .google.protobuf.compiler.Version compiler_version = 3;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.compiler_version_), _Internal::kHasBitsOffset + 1, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)},
    // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.proto_file_), -1, 1,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
    // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.source_file_descriptors_), -1, 2,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
  }}, {{
    {::_pbi::TcParser::GetTable<::google::protobuf::compiler::Version>()},
    {::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorProto>()},
    {::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorProto>()},
  }}, {{
    "\55\20\11\0\0\0\0\0"
    "google.protobuf.compiler.CodeGeneratorRequest"
    "file_to_generate"
    "parameter"
  }},
};

PROTOBUF_NOINLINE void CodeGeneratorRequest::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.file_to_generate_.Clear();
  _impl_.proto_file_.Clear();
  _impl_.source_file_descriptors_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.parameter_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      ABSL_DCHECK(_impl_.compiler_version_ != nullptr);
      _impl_.compiler_version_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

::uint8_t* CodeGeneratorRequest::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest)
  ::uint32_t cached_has_bits = 0;
  (void)cached_has_bits;

  // repeated string file_to_generate = 1;
  for (int i = 0, n = this->_internal_file_to_generate_size(); i < n; ++i) {
    const auto& s = this->_internal_file_to_generate().Get(i);
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(s.data(), static_cast<int>(s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
    target = stream->WriteString(1, s, target);
  }

  cached_has_bits = _impl_._has_bits_[0];
  // optional string parameter = 2;
  if (cached_has_bits & 0x00000001u) {
    const std::string& _s = this->_internal_parameter();
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.CodeGeneratorRequest.parameter");
    target = stream->WriteStringMaybeAliased(2, _s, target);
  }

  // optional .google.protobuf.compiler.Version compiler_version = 3;
  if (cached_has_bits & 0x00000002u) {
    target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
        3, *_impl_.compiler_version_, _impl_.compiler_version_->GetCachedSize(), target, stream);
  }

  // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
  for (unsigned i = 0, n = static_cast<unsigned>(
                           this->_internal_proto_file_size());
       i < n; i++) {
    const auto& repfield = this->_internal_proto_file().Get(i);
    target =
        ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
            15, repfield, repfield.GetCachedSize(),
            target, stream);
  }

  // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17;
  for (unsigned i = 0, n = static_cast<unsigned>(
                           this->_internal_source_file_descriptors_size());
       i < n; i++) {
    const auto& repfield = this->_internal_source_file_descriptors().Get(i);
    target =
        ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
            17, repfield, repfield.GetCachedSize(),
            target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest)
  return target;
}

::size_t CodeGeneratorRequest::ByteSizeLong() const {
  // @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorRequest)
  ::size_t total_size = 0;

  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void)cached_has_bits;

  ::_pbi::Prefetch5LinesFrom7Lines(
      reinterpret_cast<const void*>(this));
   {
    // repeated string file_to_generate = 1;
     {
      total_size += 1 * ::google::protobuf::internal::FromIntSize(_internal_file_to_generate().size());
      for (int i = 0, n = _internal_file_to_generate().size(); i < n; ++i) {
        total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
            _internal_file_to_generate().Get(i));
      }
    }
    // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
     {
      total_size += 1UL * this->_internal_proto_file_size();
      for (const auto& msg : this->_internal_proto_file()) {
        total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
      }
    }
    // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17;
     {
      total_size += 2UL * this->_internal_source_file_descriptors_size();
      for (const auto& msg : this->_internal_source_file_descriptors()) {
        total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
      }
    }
  }
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    // optional string parameter = 2;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                      this->_internal_parameter());
    }
    // optional .google.protobuf.compiler.Version compiler_version = 3;
    if (cached_has_bits & 0x00000002u) {
      total_size +=
          1 + ::google::protobuf::internal::WireFormatLite::MessageSize(*_impl_.compiler_version_);
    }
  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

void CodeGeneratorRequest::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
  auto* const _this = static_cast<CodeGeneratorRequest*>(&to_msg);
  auto& from = static_cast<const CodeGeneratorRequest&>(from_msg);
  ::google::protobuf::Arena* arena = _this->GetArena();
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
  ABSL_DCHECK_NE(&from, _this);
  ::uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_internal_mutable_file_to_generate()->MergeFrom(from._internal_file_to_generate());
  _this->_internal_mutable_proto_file()->MergeFrom(
      from._internal_proto_file());
  _this->_internal_mutable_source_file_descriptors()->MergeFrom(
      from._internal_source_file_descriptors());
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x00000003u) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_parameter(from._internal_parameter());
    }
    if (cached_has_bits & 0x00000002u) {
      ABSL_DCHECK(from._impl_.compiler_version_ != nullptr);
      if (_this->_impl_.compiler_version_ == nullptr) {
        _this->_impl_.compiler_version_ =
            ::google::protobuf::Message::CopyConstruct<::google::protobuf::compiler::Version>(arena, *from._impl_.compiler_version_);
      } else {
        _this->_impl_.compiler_version_->MergeFrom(*from._impl_.compiler_version_);
      }
    }
  }
  _this->_impl_._has_bits_[0] |= cached_has_bits;
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorRequest)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

PROTOBUF_NOINLINE bool CodeGeneratorRequest::IsInitializedImpl(
    const MessageLite& msg) {
  auto& this_ = static_cast<const CodeGeneratorRequest&>(msg);
  if (!::google::protobuf::internal::AllAreInitialized(this_._internal_proto_file()))
    return false;
  if (!::google::protobuf::internal::AllAreInitialized(this_._internal_source_file_descriptors()))
    return false;
  return true;
}

void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.file_to_generate_.InternalSwap(&other->_impl_.file_to_generate_);
  _impl_.proto_file_.InternalSwap(&other->_impl_.proto_file_);
  _impl_.source_file_descriptors_.InternalSwap(&other->_impl_.source_file_descriptors_);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.parameter_, &other->_impl_.parameter_, arena);
  swap(_impl_.compiler_version_, other->_impl_.compiler_version_);
}

::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// ===================================================================

class CodeGeneratorResponse_File::_Internal {
 public:
  using HasBits =
      decltype(std::declval<CodeGeneratorResponse_File>()._impl_._has_bits_);
  static constexpr ::int32_t kHasBitsOffset =
      8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._has_bits_);
};

void CodeGeneratorResponse_File::clear_generated_code_info() {
  ::google::protobuf::internal::TSanWrite(&_impl_);
  if (_impl_.generated_code_info_ != nullptr) _impl_.generated_code_info_->Clear();
  _impl_._has_bits_[0] &= ~0x00000008u;
}
CodeGeneratorResponse_File::CodeGeneratorResponse_File(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
inline PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse_File::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::compiler::CodeGeneratorResponse_File& from_msg)
      : _has_bits_{from._has_bits_},
        _cached_size_{0},
        name_(arena, from.name_),
        insertion_point_(arena, from.insertion_point_),
        content_(arena, from.content_) {}

CodeGeneratorResponse_File::CodeGeneratorResponse_File(
    ::google::protobuf::Arena* arena,
    const CodeGeneratorResponse_File& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  CodeGeneratorResponse_File* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
  ::uint32_t cached_has_bits = _impl_._has_bits_[0];
  _impl_.generated_code_info_ = (cached_has_bits & 0x00000008u) ? ::google::protobuf::Message::CopyConstruct<::google::protobuf::GeneratedCodeInfo>(
                              arena, *from._impl_.generated_code_info_)
                        : nullptr;

  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
}
inline PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse_File::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : _cached_size_{0},
        name_(arena),
        insertion_point_(arena),
        content_(arena) {}

inline void CodeGeneratorResponse_File::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  _impl_.generated_code_info_ = {};
}
CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
  // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void CodeGeneratorResponse_File::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.name_.Destroy();
  _impl_.insertion_point_.Destroy();
  _impl_.content_.Destroy();
  delete _impl_.generated_code_info_;
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    CodeGeneratorResponse_File::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            nullptr,  // IsInitialized
            &CodeGeneratorResponse_File::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<CodeGeneratorResponse_File>(),
            ::google::protobuf::Message::GetNewImpl<CodeGeneratorResponse_File>(),
            ::google::protobuf::Message::GetClearImpl<CodeGeneratorResponse_File>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<CodeGeneratorResponse_File>(),
                ::google::protobuf::Message::GetSerializeImpl<CodeGeneratorResponse_File>(),
#endif  // PROTOBUF_CUSTOM_VTABLE
            PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._cached_size_),
            false,
        },
        &CodeGeneratorResponse_File::kDescriptorMethods,
        &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
        nullptr,  // tracker
};
const ::google::protobuf::MessageLite::ClassData* CodeGeneratorResponse_File::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<2, 4, 1, 86, 2> CodeGeneratorResponse_File::_table_ = {
  {
    PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._has_bits_),
    0, // no _extensions_
    16, 24,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294918140,  // skipmap
    offsetof(decltype(_table_), field_entries),
    4,  // num_field_entries
    1,  // num_aux_entries
    offsetof(decltype(_table_), aux_entries),
    &_CodeGeneratorResponse_File_default_instance_._instance,
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorResponse_File>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
    {::_pbi::TcParser::FastMtS2,
     {386, 3, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.generated_code_info_)}},
    // optional string name = 1;
    {::_pbi::TcParser::FastSS1,
     {10, 0, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.name_)}},
    // optional string insertion_point = 2;
    {::_pbi::TcParser::FastSS1,
     {18, 1, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.insertion_point_)}},
    // optional string content = 15;
    {::_pbi::TcParser::FastSS1,
     {122, 2, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.content_)}},
  }}, {{
    65535, 65535
  }}, {{
    // optional string name = 1;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.name_), _Internal::kHasBitsOffset + 0, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kRawString | ::_fl::kRepAString)},
    // optional string insertion_point = 2;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.insertion_point_), _Internal::kHasBitsOffset + 1, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kRawString | ::_fl::kRepAString)},
    // optional string content = 15;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.content_), _Internal::kHasBitsOffset + 2, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kRawString | ::_fl::kRepAString)},
    // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.generated_code_info_), _Internal::kHasBitsOffset + 3, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)},
  }}, {{
    {::_pbi::TcParser::GetTable<::google::protobuf::GeneratedCodeInfo>()},
  }}, {{
    "\63\4\17\7\0\0\0\0"
    "google.protobuf.compiler.CodeGeneratorResponse.File"
    "name"
    "insertion_point"
    "content"
  }},
};

PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    if (cached_has_bits & 0x00000001u) {
      _impl_.name_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000002u) {
      _impl_.insertion_point_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000004u) {
      _impl_.content_.ClearNonDefaultToEmpty();
    }
    if (cached_has_bits & 0x00000008u) {
      ABSL_DCHECK(_impl_.generated_code_info_ != nullptr);
      _impl_.generated_code_info_->Clear();
    }
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

::uint8_t* CodeGeneratorResponse_File::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
  ::uint32_t cached_has_bits = 0;
  (void)cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string name = 1;
  if (cached_has_bits & 0x00000001u) {
    const std::string& _s = this->_internal_name();
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.CodeGeneratorResponse.File.name");
    target = stream->WriteStringMaybeAliased(1, _s, target);
  }

  // optional string insertion_point = 2;
  if (cached_has_bits & 0x00000002u) {
    const std::string& _s = this->_internal_insertion_point();
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
    target = stream->WriteStringMaybeAliased(2, _s, target);
  }

  // optional string content = 15;
  if (cached_has_bits & 0x00000004u) {
    const std::string& _s = this->_internal_content();
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.CodeGeneratorResponse.File.content");
    target = stream->WriteStringMaybeAliased(15, _s, target);
  }

  // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
        16, *_impl_.generated_code_info_, _impl_.generated_code_info_->GetCachedSize(), target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File)
  return target;
}

::size_t CodeGeneratorResponse_File::ByteSizeLong() const {
  // @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorResponse.File)
  ::size_t total_size = 0;

  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void)cached_has_bits;

  ::_pbi::Prefetch5LinesFrom7Lines(
      reinterpret_cast<const void*>(this));
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    // optional string name = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                      this->_internal_name());
    }
    // optional string insertion_point = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                      this->_internal_insertion_point());
    }
    // optional string content = 15;
    if (cached_has_bits & 0x00000004u) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                      this->_internal_content());
    }
    // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16;
    if (cached_has_bits & 0x00000008u) {
      total_size +=
          2 + ::google::protobuf::internal::WireFormatLite::MessageSize(*_impl_.generated_code_info_);
    }
  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

void CodeGeneratorResponse_File::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
  auto* const _this = static_cast<CodeGeneratorResponse_File*>(&to_msg);
  auto& from = static_cast<const CodeGeneratorResponse_File&>(from_msg);
  ::google::protobuf::Arena* arena = _this->GetArena();
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
  ABSL_DCHECK_NE(&from, _this);
  ::uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_name(from._internal_name());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_internal_set_insertion_point(from._internal_insertion_point());
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_internal_set_content(from._internal_content());
    }
    if (cached_has_bits & 0x00000008u) {
      ABSL_DCHECK(from._impl_.generated_code_info_ != nullptr);
      if (_this->_impl_.generated_code_info_ == nullptr) {
        _this->_impl_.generated_code_info_ =
            ::google::protobuf::Message::CopyConstruct<::google::protobuf::GeneratedCodeInfo>(arena, *from._impl_.generated_code_info_);
      } else {
        _this->_impl_.generated_code_info_->MergeFrom(*from._impl_.generated_code_info_);
      }
    }
  }
  _this->_impl_._has_bits_[0] |= cached_has_bits;
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}


void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.insertion_point_, &other->_impl_.insertion_point_, arena);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.content_, &other->_impl_.content_, arena);
  swap(_impl_.generated_code_info_, other->_impl_.generated_code_info_);
}

::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// ===================================================================

class CodeGeneratorResponse::_Internal {
 public:
  using HasBits =
      decltype(std::declval<CodeGeneratorResponse>()._impl_._has_bits_);
  static constexpr ::int32_t kHasBitsOffset =
      8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._has_bits_);
};

CodeGeneratorResponse::CodeGeneratorResponse(::google::protobuf::Arena* arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
inline PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility, ::google::protobuf::Arena* arena,
    const Impl_& from, const ::google::protobuf::compiler::CodeGeneratorResponse& from_msg)
      : _has_bits_{from._has_bits_},
        _cached_size_{0},
        file_{visibility, arena, from.file_},
        error_(arena, from.error_) {}

CodeGeneratorResponse::CodeGeneratorResponse(
    ::google::protobuf::Arena* arena,
    const CodeGeneratorResponse& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, _class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  CodeGeneratorResponse* const _this = this;
  (void)_this;
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
  new (&_impl_) Impl_(internal_visibility(), arena, from._impl_, from);
  ::memcpy(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, supported_features_),
           reinterpret_cast<const char *>(&from._impl_) +
               offsetof(Impl_, supported_features_),
           offsetof(Impl_, maximum_edition_) -
               offsetof(Impl_, supported_features_) +
               sizeof(Impl_::maximum_edition_));

  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse)
}
inline PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse::Impl_::Impl_(
    ::google::protobuf::internal::InternalVisibility visibility,
    ::google::protobuf::Arena* arena)
      : _cached_size_{0},
        file_{visibility, arena},
        error_(arena) {}

inline void CodeGeneratorResponse::SharedCtor(::_pb::Arena* arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  ::memset(reinterpret_cast<char *>(&_impl_) +
               offsetof(Impl_, supported_features_),
           0,
           offsetof(Impl_, maximum_edition_) -
               offsetof(Impl_, supported_features_) +
               sizeof(Impl_::maximum_edition_));
}
CodeGeneratorResponse::~CodeGeneratorResponse() {
  // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse)
  _internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  SharedDtor();
}
inline void CodeGeneratorResponse::SharedDtor() {
  ABSL_DCHECK(GetArena() == nullptr);
  _impl_.error_.Destroy();
  _impl_.~Impl_();
}

PROTOBUF_CONSTINIT
PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::google::protobuf::MessageLite::ClassDataFull
    CodeGeneratorResponse::_class_data_ = {
        ::google::protobuf::Message::ClassData{
            &_table_.header,
            nullptr,  // OnDemandRegisterArenaDtor
            nullptr,  // IsInitialized
            &CodeGeneratorResponse::MergeImpl,
#if defined(PROTOBUF_CUSTOM_VTABLE)
            ::google::protobuf::Message::GetDeleteImpl<CodeGeneratorResponse>(),
            ::google::protobuf::Message::GetNewImpl<CodeGeneratorResponse>(),
            ::google::protobuf::Message::GetClearImpl<CodeGeneratorResponse>(),
                ::google::protobuf::Message::GetByteSizeLongImpl<CodeGeneratorResponse>(),
                ::google::protobuf::Message::GetSerializeImpl<CodeGeneratorResponse>(),
#endif  // PROTOBUF_CUSTOM_VTABLE
            PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._cached_size_),
            false,
        },
        &CodeGeneratorResponse::kDescriptorMethods,
        &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto,
        nullptr,  // tracker
};
const ::google::protobuf::MessageLite::ClassData* CodeGeneratorResponse::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(_class_data_.tc_table);
  return _class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<3, 5, 1, 60, 2> CodeGeneratorResponse::_table_ = {
  {
    PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._has_bits_),
    0, // no _extensions_
    15, 56,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294950896,  // skipmap
    offsetof(decltype(_table_), field_entries),
    5,  // num_field_entries
    1,  // num_aux_entries
    offsetof(decltype(_table_), aux_entries),
    &_CodeGeneratorResponse_default_instance_._instance,
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorResponse>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    {::_pbi::TcParser::MiniParse, {}},
    // optional string error = 1;
    {::_pbi::TcParser::FastSS1,
     {10, 0, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.error_)}},
    // optional uint64 supported_features = 2;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint64_t, offsetof(CodeGeneratorResponse, _impl_.supported_features_), 1>(),
     {16, 1, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.supported_features_)}},
    // optional int32 minimum_edition = 3;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(CodeGeneratorResponse, _impl_.minimum_edition_), 2>(),
     {24, 2, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.minimum_edition_)}},
    // optional int32 maximum_edition = 4;
    {::_pbi::TcParser::SingularVarintNoZag1<::uint32_t, offsetof(CodeGeneratorResponse, _impl_.maximum_edition_), 3>(),
     {32, 3, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_)}},
    {::_pbi::TcParser::MiniParse, {}},
    {::_pbi::TcParser::MiniParse, {}},
    // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
    {::_pbi::TcParser::FastMtR1,
     {122, 63, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_)}},
  }}, {{
    65535, 65535
  }}, {{
    // optional string error = 1;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.error_), _Internal::kHasBitsOffset + 0, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kRawString | ::_fl::kRepAString)},
    // optional uint64 supported_features = 2;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.supported_features_), _Internal::kHasBitsOffset + 1, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kUInt64)},
    // optional int32 minimum_edition = 3;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.minimum_edition_), _Internal::kHasBitsOffset + 2, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kInt32)},
    // optional int32 maximum_edition = 4;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_), _Internal::kHasBitsOffset + 3, 0,
    (0 | ::_fl::kFcOptional | ::_fl::kInt32)},
    // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
    {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_), -1, 0,
    (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)},
  }}, {{
    {::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorResponse_File>()},
  }}, {{
    "\56\5\0\0\0\0\0\0"
    "google.protobuf.compiler.CodeGeneratorResponse"
    "error"
  }},
};

PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() {
// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse)
  ::google::protobuf::internal::TSanWrite(&_impl_);
  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void) cached_has_bits;

  _impl_.file_.Clear();
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x00000001u) {
    _impl_.error_.ClearNonDefaultToEmpty();
  }
  if (cached_has_bits & 0x0000000eu) {
    ::memset(&_impl_.supported_features_, 0, static_cast<::size_t>(
        reinterpret_cast<char*>(&_impl_.maximum_edition_) -
        reinterpret_cast<char*>(&_impl_.supported_features_)) + sizeof(_impl_.maximum_edition_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

::uint8_t* CodeGeneratorResponse::_InternalSerialize(
    ::uint8_t* target,
    ::google::protobuf::io::EpsCopyOutputStream* stream) const {
  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
  ::uint32_t cached_has_bits = 0;
  (void)cached_has_bits;

  cached_has_bits = _impl_._has_bits_[0];
  // optional string error = 1;
  if (cached_has_bits & 0x00000001u) {
    const std::string& _s = this->_internal_error();
    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(_s.data(), static_cast<int>(_s.length()), ::google::protobuf::internal::WireFormat::SERIALIZE,
                                "google.protobuf.compiler.CodeGeneratorResponse.error");
    target = stream->WriteStringMaybeAliased(1, _s, target);
  }

  // optional uint64 supported_features = 2;
  if (cached_has_bits & 0x00000002u) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteUInt64ToArray(
        2, this->_internal_supported_features(), target);
  }

  // optional int32 minimum_edition = 3;
  if (cached_has_bits & 0x00000004u) {
    target = ::google::protobuf::internal::WireFormatLite::
        WriteInt32ToArrayWithField<3>(
            stream, this->_internal_minimum_edition(), target);
  }

  // optional int32 maximum_edition = 4;
  if (cached_has_bits & 0x00000008u) {
    target = ::google::protobuf::internal::WireFormatLite::
        WriteInt32ToArrayWithField<4>(
            stream, this->_internal_maximum_edition(), target);
  }

  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
  for (unsigned i = 0, n = static_cast<unsigned>(
                           this->_internal_file_size());
       i < n; i++) {
    const auto& repfield = this->_internal_file().Get(i);
    target =
        ::google::protobuf::internal::WireFormatLite::InternalWriteMessage(
            15, repfield, repfield.GetCachedSize(),
            target, stream);
  }

  if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
    target =
        ::_pbi::WireFormat::InternalSerializeUnknownFieldsToArray(
            _internal_metadata_.unknown_fields<::google::protobuf::UnknownFieldSet>(::google::protobuf::UnknownFieldSet::default_instance), target, stream);
  }
  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse)
  return target;
}

::size_t CodeGeneratorResponse::ByteSizeLong() const {
  // @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.CodeGeneratorResponse)
  ::size_t total_size = 0;

  ::uint32_t cached_has_bits = 0;
  // Prevent compiler warnings about cached_has_bits being unused
  (void)cached_has_bits;

  ::_pbi::Prefetch5LinesFrom7Lines(
      reinterpret_cast<const void*>(this));
   {
    // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
     {
      total_size += 1UL * this->_internal_file_size();
      for (const auto& msg : this->_internal_file()) {
        total_size += ::google::protobuf::internal::WireFormatLite::MessageSize(msg);
      }
    }
  }
  cached_has_bits = _impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    // optional string error = 1;
    if (cached_has_bits & 0x00000001u) {
      total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize(
                                      this->_internal_error());
    }
    // optional uint64 supported_features = 2;
    if (cached_has_bits & 0x00000002u) {
      total_size += ::_pbi::WireFormatLite::UInt64SizePlusOne(
          this->_internal_supported_features());
    }
    // optional int32 minimum_edition = 3;
    if (cached_has_bits & 0x00000004u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
          this->_internal_minimum_edition());
    }
    // optional int32 maximum_edition = 4;
    if (cached_has_bits & 0x00000008u) {
      total_size += ::_pbi::WireFormatLite::Int32SizePlusOne(
          this->_internal_maximum_edition());
    }
  }
  return MaybeComputeUnknownFieldsSize(total_size, &_impl_._cached_size_);
}

void CodeGeneratorResponse::MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg) {
  auto* const _this = static_cast<CodeGeneratorResponse*>(&to_msg);
  auto& from = static_cast<const CodeGeneratorResponse&>(from_msg);
  // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
  ABSL_DCHECK_NE(&from, _this);
  ::uint32_t cached_has_bits = 0;
  (void) cached_has_bits;

  _this->_internal_mutable_file()->MergeFrom(
      from._internal_file());
  cached_has_bits = from._impl_._has_bits_[0];
  if (cached_has_bits & 0x0000000fu) {
    if (cached_has_bits & 0x00000001u) {
      _this->_internal_set_error(from._internal_error());
    }
    if (cached_has_bits & 0x00000002u) {
      _this->_impl_.supported_features_ = from._impl_.supported_features_;
    }
    if (cached_has_bits & 0x00000004u) {
      _this->_impl_.minimum_edition_ = from._impl_.minimum_edition_;
    }
    if (cached_has_bits & 0x00000008u) {
      _this->_impl_.maximum_edition_ = from._impl_.maximum_edition_;
    }
  }
  _this->_impl_._has_bits_[0] |= cached_has_bits;
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(from._internal_metadata_);
}

void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.CodeGeneratorResponse)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}


void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* PROTOBUF_RESTRICT other) {
  using std::swap;
  auto* arena = GetArena();
  ABSL_DCHECK_EQ(arena, other->GetArena());
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  _impl_.file_.InternalSwap(&other->_impl_.file_);
  ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.error_, &other->_impl_.error_, arena);
  ::google::protobuf::internal::memswap<
      PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_)
      + sizeof(CodeGeneratorResponse::_impl_.maximum_edition_)
      - PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.supported_features_)>(
          reinterpret_cast<char*>(&_impl_.supported_features_),
          reinterpret_cast<char*>(&other->_impl_.supported_features_));
}

::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
// @@protoc_insertion_point(namespace_scope)
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
namespace google {
namespace protobuf {
}  // namespace protobuf
}  // namespace google
// @@protoc_insertion_point(global_scope)
PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type
    _static_init2_ PROTOBUF_UNUSED =
        (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto),
         ::std::false_type{});
#include "google/protobuf/port_undef.inc"
