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

#include "google/protobuf/cpp_features.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/generated_message_util.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 pb {

inline constexpr CppFeatures::Impl_::Impl_(
    ::_pbi::ConstantInitialized) noexcept
      : _cached_size_{0},
        string_type_{static_cast< ::pb::CppFeatures_StringType >(0)},
        legacy_closed_enum_{false},
        enum_name_uses_string_view_{false} {}

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

PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CppFeaturesDefaultTypeInternal _CppFeatures_default_instance_;
}  // namespace pb
static const ::_pb::EnumDescriptor* PROTOBUF_NONNULL
    file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto[1];
static constexpr const ::_pb::ServiceDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE
    file_level_service_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto = nullptr;
const ::uint32_t
    TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto::offsets[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
        protodesc_cold) = {
        0x081, // bitmap
        PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_._has_bits_),
        6, // hasbit index offset
        PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_.legacy_closed_enum_),
        PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_.string_type_),
        PROTOBUF_FIELD_OFFSET(::pb::CppFeatures, _impl_.enum_name_uses_string_view_),
        1,
        0,
        2,
};

static const ::_pbi::MigrationSchema
    schemas[] ABSL_ATTRIBUTE_SECTION_VARIABLE(protodesc_cold) = {
        {0, sizeof(::pb::CppFeatures)},
};
static const ::_pb::Message* PROTOBUF_NONNULL const file_default_instances[] = {
    &::pb::_CppFeatures_default_instance_._instance,
};
const char descriptor_table_protodef_google_2fprotobuf_2fcpp_5ffeatures_2eproto[] ABSL_ATTRIBUTE_SECTION_VARIABLE(
    protodesc_cold) = {
    "\n\"google/protobuf/cpp_features.proto\022\002pb"
    "\032 google/protobuf/descriptor.proto\"\374\003\n\013C"
    "ppFeatures\022\373\001\n\022legacy_closed_enum\030\001 \001(\010B"
    "\336\001\210\001\001\230\001\004\230\001\001\242\001\t\022\004true\030\204\007\242\001\n\022\005false\030\347\007\262\001\270\001"
    "\010\350\007\020\350\007\032\257\001The legacy closed enum behavior"
    " in C++ is deprecated and is scheduled t"
    "o be removed in edition 2025.  See http:"
    "//protobuf.dev/programming-guides/enum/#"
    "cpp for more information\022Z\n\013string_type\030"
    "\002 \001(\0162\032.pb.CppFeatures.StringTypeB)\210\001\001\230\001"
    "\004\230\001\001\242\001\013\022\006STRING\030\204\007\242\001\t\022\004VIEW\030\351\007\262\001\003\010\350\007\022L\n\032"
    "enum_name_uses_string_view\030\003 \001(\010B(\210\001\001\230\001\006"
    "\230\001\001\242\001\n\022\005false\030\204\007\242\001\t\022\004true\030\351\007\262\001\003\010\351\007\"E\n\nSt"
    "ringType\022\027\n\023STRING_TYPE_UNKNOWN\020\000\022\010\n\004VIE"
    "W\020\001\022\010\n\004CORD\020\002\022\n\n\006STRING\020\003::\n\003cpp\022\033.googl"
    "e.protobuf.FeatureSet\030\350\007 \001(\0132\017.pb.CppFea"
    "tures"
};
static const ::_pbi::DescriptorTable* PROTOBUF_NONNULL const
    descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_deps[1] = {
        &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto,
};
static ::absl::once_flag descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once;
PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto = {
    false,
    false,
    645,
    descriptor_table_protodef_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
    "google/protobuf/cpp_features.proto",
    &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_once,
    descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto_deps,
    1,
    1,
    schemas,
    file_default_instances,
    TableStruct_google_2fprotobuf_2fcpp_5ffeatures_2eproto::offsets,
    file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
    file_level_service_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
};
namespace pb {
const ::google::protobuf::EnumDescriptor* PROTOBUF_NONNULL CppFeatures_StringType_descriptor() {
  ::google::protobuf::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto);
  return file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto[0];
}
PROTOBUF_CONSTINIT const uint32_t CppFeatures_StringType_internal_data_[] = {
    262144u, 0u, };
// ===================================================================

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

CppFeatures::CppFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, CppFeatures_class_data_.base()) {
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena) {
#endif  // PROTOBUF_CUSTOM_VTABLE
  SharedCtor(arena);
  // @@protoc_insertion_point(arena_constructor:pb.CppFeatures)
}
CppFeatures::CppFeatures(
    ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CppFeatures& from)
#if defined(PROTOBUF_CUSTOM_VTABLE)
    : ::google::protobuf::Message(arena, CppFeatures_class_data_.base()),
#else   // PROTOBUF_CUSTOM_VTABLE
    : ::google::protobuf::Message(arena),
#endif  // PROTOBUF_CUSTOM_VTABLE
      _impl_(from._impl_) {
  _internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
}
PROTOBUF_NDEBUG_INLINE CppFeatures::Impl_::Impl_(
    [[maybe_unused]] ::google::protobuf::internal::InternalVisibility visibility,
    [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena)
      : _cached_size_{0} {}

inline void CppFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) {
  new (&_impl_) Impl_(internal_visibility(), arena);
  ::memset(reinterpret_cast<char*>(&_impl_) +
               offsetof(Impl_, string_type_),
           0,
           offsetof(Impl_, enum_name_uses_string_view_) -
               offsetof(Impl_, string_type_) +
               sizeof(Impl_::enum_name_uses_string_view_));
}
CppFeatures::~CppFeatures() {
  // @@protoc_insertion_point(destructor:pb.CppFeatures)
  SharedDtor(*this);
}
inline void CppFeatures::SharedDtor(MessageLite& self) {
  CppFeatures& this_ = static_cast<CppFeatures&>(self);
  if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
    this_.CheckHasBitConsistency();
  }
  this_._internal_metadata_.Delete<::google::protobuf::UnknownFieldSet>();
  ABSL_DCHECK(this_.GetArena() == nullptr);
  this_._impl_.~Impl_();
}

inline void* PROTOBUF_NONNULL CppFeatures::PlacementNew_(
    const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem,
    ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {
  return ::new (mem) CppFeatures(arena);
}
constexpr auto CppFeatures::InternalNewImpl_() {
  return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(CppFeatures),
                                            alignof(CppFeatures));
}
constexpr auto CppFeatures::InternalGenerateClassData_() {
  return ::google::protobuf::internal::ClassDataFull{
      ::google::protobuf::internal::ClassData{
          &_CppFeatures_default_instance_._instance,
          &_table_.header,
          nullptr,  // OnDemandRegisterArenaDtor
          nullptr,  // IsInitialized
          &CppFeatures::MergeImpl,
          ::google::protobuf::Message::GetNewImpl<CppFeatures>(),
#if defined(PROTOBUF_CUSTOM_VTABLE)
          &CppFeatures::SharedDtor,
          ::google::protobuf::Message::GetClearImpl<CppFeatures>(), &CppFeatures::ByteSizeLong,
              &CppFeatures::_InternalSerialize,
#endif  // PROTOBUF_CUSTOM_VTABLE
          PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._cached_size_),
          false,
      },
      &CppFeatures::kDescriptorMethods,
      &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto,
      nullptr,  // tracker
  };
}

PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const
    ::google::protobuf::internal::ClassDataFull CppFeatures_class_data_ =
        CppFeatures::InternalGenerateClassData_();

PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL
CppFeatures::GetClassData() const {
  ::google::protobuf::internal::PrefetchToLocalCache(&CppFeatures_class_data_);
  ::google::protobuf::internal::PrefetchToLocalCache(CppFeatures_class_data_.tc_table);
  return CppFeatures_class_data_.base();
}
PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1
const ::_pbi::TcParseTable<2, 3, 1, 0, 2>
CppFeatures::_table_ = {
  {
    PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._has_bits_),
    0, // no _extensions_
    3, 24,  // max_field_number, fast_idx_mask
    offsetof(decltype(_table_), field_lookup_table),
    4294967288,  // skipmap
    offsetof(decltype(_table_), field_entries),
    3,  // num_field_entries
    1,  // num_aux_entries
    offsetof(decltype(_table_), aux_entries),
    CppFeatures_class_data_.base(),
    nullptr,  // post_loop_handler
    ::_pbi::TcParser::GenericFallback,  // fallback
    #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
    ::_pbi::TcParser::GetTable<::pb::CppFeatures>(),  // to_prefetch
    #endif  // PROTOBUF_PREFETCH_PARSE_TABLE
  }, {{
    {::_pbi::TcParser::MiniParse, {}},
    // optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
    {::_pbi::TcParser::SingularVarintNoZag1<bool, offsetof(CppFeatures, _impl_.legacy_closed_enum_), 1>(),
     {8, 1, 0,
      PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.legacy_closed_enum_)}},
    // optional .pb.CppFeatures.StringType string_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
    {::_pbi::TcParser::FastEr0S1,
     {16, 0, 3,
      PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.string_type_)}},
    // optional bool enum_name_uses_string_view = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
    {::_pbi::TcParser::SingularVarintNoZag1<bool, offsetof(CppFeatures, _impl_.enum_name_uses_string_view_), 2>(),
     {24, 2, 0,
      PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.enum_name_uses_string_view_)}},
  }}, {{
    65535, 65535
  }}, {{
    // optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
    {PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.legacy_closed_enum_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)},
    // optional .pb.CppFeatures.StringType string_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
    {PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.string_type_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)},
    // optional bool enum_name_uses_string_view = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
    {PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.enum_name_uses_string_view_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)},
  }},
  {{
      {0, 3},
  }},
  {{
  }},
};
PROTOBUF_NOINLINE void CppFeatures::Clear() {
// @@protoc_insertion_point(message_clear_start:pb.CppFeatures)
  ::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 (BatchCheckHasBit(cached_has_bits, 0x00000007U)) {
    ::memset(&_impl_.string_type_, 0, static_cast<::size_t>(
        reinterpret_cast<char*>(&_impl_.enum_name_uses_string_view_) -
        reinterpret_cast<char*>(&_impl_.string_type_)) + sizeof(_impl_.enum_name_uses_string_view_));
  }
  _impl_._has_bits_.Clear();
  _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>();
}

#if defined(PROTOBUF_CUSTOM_VTABLE)
::uint8_t* PROTOBUF_NONNULL CppFeatures::_InternalSerialize(
    const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target,
    ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) {
  const CppFeatures& this_ = static_cast<const CppFeatures&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
::uint8_t* PROTOBUF_NONNULL CppFeatures::_InternalSerialize(
    ::uint8_t* PROTOBUF_NONNULL target,
    ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const {
  const CppFeatures& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
  if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
    this_.CheckHasBitConsistency();
  }
  // @@protoc_insertion_point(serialize_to_array_start:pb.CppFeatures)
  ::uint32_t cached_has_bits = 0;
  (void)cached_has_bits;

  cached_has_bits = this_._impl_._has_bits_[0];
  // optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
  if (CheckHasBit(cached_has_bits, 0x00000002U)) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(
        1, this_._internal_legacy_closed_enum(), target);
  }

  // optional .pb.CppFeatures.StringType string_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
  if (CheckHasBit(cached_has_bits, 0x00000001U)) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteEnumToArray(
        2, this_._internal_string_type(), target);
  }

  // optional bool enum_name_uses_string_view = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = {
  if (CheckHasBit(cached_has_bits, 0x00000004U)) {
    target = stream->EnsureSpace(target);
    target = ::_pbi::WireFormatLite::WriteBoolToArray(
        3, this_._internal_enum_name_uses_string_view(), target);
  }

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

#if defined(PROTOBUF_CUSTOM_VTABLE)
::size_t CppFeatures::ByteSizeLong(const MessageLite& base) {
  const CppFeatures& this_ = static_cast<const CppFeatures&>(base);
#else   // PROTOBUF_CUSTOM_VTABLE
::size_t CppFeatures::ByteSizeLong() const {
  const CppFeatures& this_ = *this;
#endif  // PROTOBUF_CUSTOM_VTABLE
  // @@protoc_insertion_point(message_byte_size_start:pb.CppFeatures)
  ::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(&this_);
  cached_has_bits = this_._impl_._has_bits_[0];
  total_size += ::absl::popcount(0x00000006U & cached_has_bits) * 2;
   {
    // optional .pb.CppFeatures.StringType string_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = {
    if (CheckHasBit(cached_has_bits, 0x00000001U)) {
      total_size += 1 +
                    ::_pbi::WireFormatLite::EnumSize(this_._internal_string_type());
    }
  }
  return this_.MaybeComputeUnknownFieldsSize(total_size,
                                             &this_._impl_._cached_size_);
}

void CppFeatures::MergeImpl(::google::protobuf::MessageLite& to_msg,
                            const ::google::protobuf::MessageLite& from_msg) {
   auto* const _this =
      static_cast<CppFeatures*>(&to_msg);
  auto& from = static_cast<const CppFeatures&>(from_msg);
  if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) {
    from.CheckHasBitConsistency();
  }
  // @@protoc_insertion_point(class_specific_merge_from_start:pb.CppFeatures)
  ABSL_DCHECK_NE(&from, _this);
  ::uint32_t cached_has_bits = 0;
  (void)cached_has_bits;

  cached_has_bits = from._impl_._has_bits_[0];
  if (BatchCheckHasBit(cached_has_bits, 0x00000007U)) {
    if (CheckHasBit(cached_has_bits, 0x00000001U)) {
      _this->_impl_.string_type_ = from._impl_.string_type_;
    }
    if (CheckHasBit(cached_has_bits, 0x00000002U)) {
      _this->_impl_.legacy_closed_enum_ = from._impl_.legacy_closed_enum_;
    }
    if (CheckHasBit(cached_has_bits, 0x00000004U)) {
      _this->_impl_.enum_name_uses_string_view_ = from._impl_.enum_name_uses_string_view_;
    }
  }
  _this->_impl_._has_bits_[0] |= cached_has_bits;
  _this->_internal_metadata_.MergeFrom<::google::protobuf::UnknownFieldSet>(
      from._internal_metadata_);
}

void CppFeatures::CopyFrom(const CppFeatures& from) {
  // @@protoc_insertion_point(class_specific_copy_from_start:pb.CppFeatures)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}


void CppFeatures::InternalSwap(CppFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) {
  using ::std::swap;
  _internal_metadata_.InternalSwap(&other->_internal_metadata_);
  swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]);
  ::google::protobuf::internal::memswap<
      PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.enum_name_uses_string_view_)
      + sizeof(CppFeatures::_impl_.enum_name_uses_string_view_)
      - PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.string_type_)>(
          reinterpret_cast<char*>(&_impl_.string_type_),
          reinterpret_cast<char*>(&other->_impl_.string_type_));
}

::google::protobuf::Metadata CppFeatures::GetMetadata() const {
  return ::google::protobuf::Message::GetMetadataImpl(GetClassData()->full());
}
PROTOBUF_CONSTINIT PROTOBUF_EXPORT
    PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier<
        ::google::protobuf::FeatureSet, ::_pbi::MessageTypeTraits< ::pb::CppFeatures >, 11, false>
        cpp(kCppFieldNumber, &::pb::_CppFeatures_default_instance_);
// @@protoc_insertion_point(namespace_scope)
}  // namespace pb
namespace google {
namespace protobuf {
}  // namespace protobuf
}  // namespace google
// @@protoc_insertion_point(global_scope)
#include "google/protobuf/port_undef.inc"
