File indexing completed on 2025-01-31 10:12:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
0013 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_DECL_H__
0014
0015 #include <array>
0016 #include <atomic>
0017 #include <cstddef>
0018 #include <cstdint>
0019 #include <type_traits>
0020
0021 #include "absl/types/span.h"
0022 #include "google/protobuf/message_lite.h"
0023 #include "google/protobuf/parse_context.h"
0024
0025
0026 #include "google/protobuf/port_def.inc"
0027
0028 namespace google {
0029 namespace protobuf {
0030 namespace internal {
0031
0032
0033 struct TcFieldData {
0034 constexpr TcFieldData() : data(0) {}
0035 explicit constexpr TcFieldData(uint64_t data) : data(data) {}
0036
0037
0038 constexpr TcFieldData(uint16_t coded_tag, uint8_t hasbit_idx, uint8_t aux_idx,
0039 uint16_t offset)
0040 : data(uint64_t{offset} << 48 |
0041 uint64_t{aux_idx} << 24 |
0042 uint64_t{hasbit_idx} << 16 |
0043 uint64_t{coded_tag}) {}
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 struct DefaultInit {};
0061 TcFieldData(DefaultInit) {}
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 template <typename TagType = uint16_t>
0079 TagType coded_tag() const {
0080 return static_cast<TagType>(data);
0081 }
0082 uint8_t hasbit_idx() const { return static_cast<uint8_t>(data >> 16); }
0083 uint8_t aux_idx() const { return static_cast<uint8_t>(data >> 24); }
0084 uint16_t offset() const { return static_cast<uint16_t>(data >> 48); }
0085
0086
0087
0088 constexpr TcFieldData(uint16_t coded_tag, uint16_t nonfield_info)
0089 : data(uint64_t{nonfield_info} << 16 |
0090 uint64_t{coded_tag}) {}
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 uint16_t decoded_tag() const { return static_cast<uint16_t>(data >> 16); }
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 uint32_t tag() const { return static_cast<uint32_t>(data); }
0120 uint32_t entry_offset() const { return static_cast<uint32_t>(data >> 32); }
0121
0122 union {
0123 uint64_t data;
0124 };
0125 };
0126
0127 struct TcParseTableBase;
0128
0129
0130 typedef PROTOBUF_CC const char* (*TailCallParseFunc)(PROTOBUF_TC_PARAM_DECL);
0131
0132 namespace field_layout {
0133 struct Offset {
0134 uint32_t off;
0135 };
0136 }
0137
0138 #if defined(_MSC_VER) && !defined(_WIN64)
0139 #pragma warning(push)
0140
0141 #pragma warning(disable : 4324)
0142 #endif
0143
0144 struct FieldAuxDefaultMessage {};
0145 struct FieldAuxEnumData {};
0146
0147
0148
0149
0150 class MapTypeCard {
0151 public:
0152 enum CppType { kBool, k32, k64, kString, kMessage };
0153 MapTypeCard() = default;
0154 constexpr MapTypeCard(WireFormatLite::WireType wiretype, CppType cpp_type,
0155 bool is_zigzag_utf8, bool is_signed)
0156 : data_(static_cast<uint8_t>((static_cast<uint8_t>(wiretype) << 0) |
0157 (static_cast<uint8_t>(cpp_type) << 3) |
0158 (static_cast<uint8_t>(is_zigzag_utf8) << 6) |
0159 (static_cast<uint8_t>(is_signed) << 7))) {}
0160
0161 WireFormatLite::WireType wiretype() const {
0162 return static_cast<WireFormatLite::WireType>((data_ >> 0) & 0x7);
0163 }
0164
0165 CppType cpp_type() const { return static_cast<CppType>((data_ >> 3) & 0x7); }
0166
0167 bool is_signed() const {
0168 ABSL_DCHECK(cpp_type() == CppType::k32 || cpp_type() == CppType::k64);
0169 return static_cast<bool>(data_ >> 7);
0170 }
0171
0172 bool is_zigzag() const {
0173 ABSL_DCHECK(wiretype() == WireFormatLite::WIRETYPE_VARINT);
0174 ABSL_DCHECK(cpp_type() == CppType::k32 || cpp_type() == CppType::k64);
0175 return is_zigzag_utf8();
0176 }
0177 bool is_utf8() const {
0178 ABSL_DCHECK(wiretype() == WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
0179 ABSL_DCHECK(cpp_type() == CppType::kString);
0180 return is_zigzag_utf8();
0181 }
0182
0183 private:
0184 bool is_zigzag_utf8() const { return static_cast<bool>((data_ >> 6) & 0x1); }
0185 uint8_t data_;
0186 };
0187 static_assert(sizeof(MapTypeCard) == sizeof(uint8_t), "");
0188
0189
0190 constexpr MapTypeCard MakeMapTypeCard(WireFormatLite::FieldType type) {
0191 switch (type) {
0192 case WireFormatLite::TYPE_FLOAT:
0193 return {WireFormatLite::WIRETYPE_FIXED32, MapTypeCard::k32, false, true};
0194 case WireFormatLite::TYPE_FIXED32:
0195 return {WireFormatLite::WIRETYPE_FIXED32, MapTypeCard::k32, false, false};
0196 case WireFormatLite::TYPE_SFIXED32:
0197 return {WireFormatLite::WIRETYPE_FIXED32, MapTypeCard::k32, false, true};
0198
0199 case WireFormatLite::TYPE_DOUBLE:
0200 return {WireFormatLite::WIRETYPE_FIXED64, MapTypeCard::k64, false, true};
0201 case WireFormatLite::TYPE_FIXED64:
0202 return {WireFormatLite::WIRETYPE_FIXED64, MapTypeCard::k64, false, false};
0203 case WireFormatLite::TYPE_SFIXED64:
0204 return {WireFormatLite::WIRETYPE_FIXED64, MapTypeCard::k64, false, true};
0205
0206 case WireFormatLite::TYPE_BOOL:
0207 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::kBool, false,
0208 false};
0209
0210 case WireFormatLite::TYPE_ENUM:
0211
0212 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k32, false, true};
0213 case WireFormatLite::TYPE_INT32:
0214 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k32, false, true};
0215 case WireFormatLite::TYPE_UINT32:
0216 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k32, false, false};
0217
0218 case WireFormatLite::TYPE_INT64:
0219 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k64, false, true};
0220 case WireFormatLite::TYPE_UINT64:
0221 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k64, false, false};
0222
0223 case WireFormatLite::TYPE_SINT32:
0224 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k32, true, true};
0225 case WireFormatLite::TYPE_SINT64:
0226 return {WireFormatLite::WIRETYPE_VARINT, MapTypeCard::k64, true, true};
0227
0228 case WireFormatLite::TYPE_STRING:
0229 return {WireFormatLite::WIRETYPE_LENGTH_DELIMITED, MapTypeCard::kString,
0230 true, false};
0231 case WireFormatLite::TYPE_BYTES:
0232 return {WireFormatLite::WIRETYPE_LENGTH_DELIMITED, MapTypeCard::kString,
0233 false, false};
0234
0235 case WireFormatLite::TYPE_MESSAGE:
0236 return {WireFormatLite::WIRETYPE_LENGTH_DELIMITED, MapTypeCard::kMessage,
0237 false, false};
0238
0239 case WireFormatLite::TYPE_GROUP:
0240 default:
0241 Unreachable();
0242 }
0243 }
0244
0245 enum class MapNodeSizeInfoT : uint32_t;
0246
0247
0248 struct MapAuxInfo {
0249 MapTypeCard key_type_card;
0250 MapTypeCard value_type_card;
0251
0252
0253 uint8_t is_supported : 1;
0254
0255
0256 uint8_t use_lite : 1;
0257
0258 uint8_t fail_on_utf8_failure : 1;
0259
0260 uint8_t log_debug_utf8_failure : 1;
0261
0262 uint8_t value_is_validated_enum : 1;
0263
0264 MapNodeSizeInfoT node_size_info;
0265 };
0266 static_assert(sizeof(MapAuxInfo) <= 8, "");
0267
0268
0269 struct alignas(uint64_t) TcParseTableBase {
0270
0271 uint16_t has_bits_offset;
0272 uint16_t extension_offset;
0273 uint32_t max_field_number;
0274 uint8_t fast_idx_mask;
0275
0276
0277
0278 uint8_t has_post_loop_handler : 1;
0279 uint16_t lookup_table_offset;
0280 uint32_t skipmap32;
0281 uint32_t field_entries_offset;
0282 uint16_t num_field_entries;
0283
0284 uint16_t num_aux_entries;
0285 uint32_t aux_offset;
0286
0287 const MessageLite::ClassData* class_data;
0288 using PostLoopHandler = const char* (*)(MessageLite* msg, const char* ptr,
0289 ParseContext* ctx);
0290 PostLoopHandler post_loop_handler;
0291
0292
0293 TailCallParseFunc fallback;
0294
0295
0296 #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
0297 const TcParseTableBase* to_prefetch;
0298 #endif
0299
0300
0301
0302
0303
0304
0305 constexpr TcParseTableBase(uint16_t has_bits_offset,
0306 uint16_t extension_offset,
0307 uint32_t max_field_number, uint8_t fast_idx_mask,
0308 uint16_t lookup_table_offset, uint32_t skipmap32,
0309 uint32_t field_entries_offset,
0310 uint16_t num_field_entries,
0311 uint16_t num_aux_entries, uint32_t aux_offset,
0312 const MessageLite::ClassData* class_data,
0313 PostLoopHandler post_loop_handler,
0314 TailCallParseFunc fallback
0315 #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
0316 ,
0317 const TcParseTableBase* to_prefetch
0318 #endif
0319 )
0320 : has_bits_offset(has_bits_offset),
0321 extension_offset(extension_offset),
0322 max_field_number(max_field_number),
0323 fast_idx_mask(fast_idx_mask),
0324 has_post_loop_handler(post_loop_handler != nullptr),
0325 lookup_table_offset(lookup_table_offset),
0326 skipmap32(skipmap32),
0327 field_entries_offset(field_entries_offset),
0328 num_field_entries(num_field_entries),
0329 num_aux_entries(num_aux_entries),
0330 aux_offset(aux_offset),
0331 class_data(class_data),
0332 post_loop_handler(post_loop_handler),
0333 fallback(fallback)
0334 #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
0335 ,
0336 to_prefetch(to_prefetch)
0337 #endif
0338 {
0339 }
0340
0341
0342 struct FastFieldEntry {
0343
0344 mutable std::atomic<TailCallParseFunc> target_atomic;
0345
0346
0347 TcFieldData bits;
0348
0349
0350 FastFieldEntry() = default;
0351
0352
0353 constexpr FastFieldEntry(TailCallParseFunc func, TcFieldData bits)
0354 : target_atomic(func), bits(bits) {}
0355
0356
0357
0358 FastFieldEntry(const FastFieldEntry& rhs) noexcept
0359 : FastFieldEntry(rhs.target(), rhs.bits) {}
0360 FastFieldEntry& operator=(const FastFieldEntry& rhs) noexcept {
0361 SetTarget(rhs.target());
0362 bits = rhs.bits;
0363 return *this;
0364 }
0365
0366
0367 TailCallParseFunc target() const {
0368 return target_atomic.load(std::memory_order_relaxed);
0369 }
0370 void SetTarget(TailCallParseFunc func) const {
0371 return target_atomic.store(func, std::memory_order_relaxed);
0372 }
0373 };
0374
0375 const FastFieldEntry* fast_entry(size_t idx) const {
0376 return reinterpret_cast<const FastFieldEntry*>(this + 1) + idx;
0377 }
0378 FastFieldEntry* fast_entry(size_t idx) {
0379 return reinterpret_cast<FastFieldEntry*>(this + 1) + idx;
0380 }
0381
0382
0383 const uint16_t* field_lookup_begin() const {
0384 return reinterpret_cast<const uint16_t*>(reinterpret_cast<uintptr_t>(this) +
0385 lookup_table_offset);
0386 }
0387 uint16_t* field_lookup_begin() {
0388 return reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(this) +
0389 lookup_table_offset);
0390 }
0391
0392
0393 struct FieldEntry {
0394 uint32_t offset;
0395 int32_t has_idx;
0396 uint16_t aux_idx;
0397 uint16_t type_card;
0398
0399 static constexpr uint16_t kNoAuxIdx = 0xFFFF;
0400 };
0401
0402
0403 const FieldEntry* field_entries_begin() const {
0404 return reinterpret_cast<const FieldEntry*>(
0405 reinterpret_cast<uintptr_t>(this) + field_entries_offset);
0406 }
0407 absl::Span<const FieldEntry> field_entries() const {
0408 return {field_entries_begin(), num_field_entries};
0409 }
0410 FieldEntry* field_entries_begin() {
0411 return reinterpret_cast<FieldEntry*>(reinterpret_cast<uintptr_t>(this) +
0412 field_entries_offset);
0413 }
0414
0415
0416 union FieldAux {
0417 constexpr FieldAux() : message_default_p(nullptr) {}
0418 constexpr FieldAux(FieldAuxEnumData, const uint32_t* enum_data)
0419 : enum_data(enum_data) {}
0420 constexpr FieldAux(field_layout::Offset off) : offset(off.off) {}
0421 constexpr FieldAux(int16_t range_start, uint16_t range_length)
0422 : enum_range{range_start, range_length} {}
0423 constexpr FieldAux(const MessageLite* msg) : message_default_p(msg) {}
0424 constexpr FieldAux(FieldAuxDefaultMessage, const void* msg)
0425 : message_default_p(msg) {}
0426 constexpr FieldAux(const TcParseTableBase* table) : table(table) {}
0427 constexpr FieldAux(MapAuxInfo map_info) : map_info(map_info) {}
0428 constexpr FieldAux(void (*create_in_arena)(Arena*, void*))
0429 : create_in_arena(create_in_arena) {}
0430 constexpr FieldAux(LazyEagerVerifyFnType verify_func)
0431 : verify_func(verify_func) {}
0432 struct {
0433 int16_t start;
0434 uint16_t length;
0435 } enum_range;
0436 uint32_t offset;
0437 const void* message_default_p;
0438 const uint32_t* enum_data;
0439 const TcParseTableBase* table;
0440 MapAuxInfo map_info;
0441 void (*create_in_arena)(Arena*, void*);
0442 LazyEagerVerifyFnType verify_func;
0443
0444 const MessageLite* message_default() const {
0445 return static_cast<const MessageLite*>(message_default_p);
0446 }
0447 const MessageLite* message_default_weak() const {
0448 return *static_cast<const MessageLite* const*>(message_default_p);
0449 }
0450 };
0451 const FieldAux* field_aux(uint32_t idx) const {
0452 return reinterpret_cast<const FieldAux*>(reinterpret_cast<uintptr_t>(this) +
0453 aux_offset) +
0454 idx;
0455 }
0456 FieldAux* field_aux(uint32_t idx) {
0457 return reinterpret_cast<FieldAux*>(reinterpret_cast<uintptr_t>(this) +
0458 aux_offset) +
0459 idx;
0460 }
0461 const FieldAux* field_aux(const FieldEntry* entry) const {
0462 return field_aux(entry->aux_idx);
0463 }
0464
0465
0466 const char* name_data() const {
0467 return reinterpret_cast<const char*>(reinterpret_cast<uintptr_t>(this) +
0468 aux_offset +
0469 num_aux_entries * sizeof(FieldAux));
0470 }
0471 char* name_data() {
0472 return reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(this) +
0473 aux_offset +
0474 num_aux_entries * sizeof(FieldAux));
0475 }
0476
0477 const MessageLite* default_instance() const { return class_data->prototype; }
0478 };
0479
0480 #if defined(_MSC_VER) && !defined(_WIN64)
0481 #pragma warning(pop)
0482 #endif
0483
0484 static_assert(sizeof(TcParseTableBase::FastFieldEntry) <= 16,
0485 "Fast field entry is too big.");
0486 static_assert(sizeof(TcParseTableBase::FieldEntry) <= 16,
0487 "Field entry is too big.");
0488
0489 template <size_t kFastTableSizeLog2, size_t kNumFieldEntries = 0,
0490 size_t kNumFieldAux = 0, size_t kNameTableSize = 0,
0491 size_t kFieldLookupSize = 2>
0492 struct TcParseTable {
0493 TcParseTableBase header;
0494
0495
0496
0497
0498
0499
0500
0501 std::array<TcParseTableBase::FastFieldEntry, (1 << kFastTableSizeLog2)>
0502 fast_entries;
0503
0504
0505 std::array<uint16_t, kFieldLookupSize> field_lookup_table;
0506
0507 std::array<TcParseTableBase::FieldEntry, kNumFieldEntries> field_entries;
0508 std::array<TcParseTableBase::FieldAux, kNumFieldAux> aux_entries;
0509 std::array<char, kNameTableSize == 0 ? 1 : kNameTableSize> field_names;
0510 };
0511
0512
0513
0514
0515
0516 template <size_t kFastTableSizeLog2, size_t kNumFieldEntries,
0517 size_t kNameTableSize, size_t kFieldLookupSize>
0518 struct TcParseTable<kFastTableSizeLog2, kNumFieldEntries, 0, kNameTableSize,
0519 kFieldLookupSize> {
0520 TcParseTableBase header;
0521 std::array<TcParseTableBase::FastFieldEntry, (1 << kFastTableSizeLog2)>
0522 fast_entries;
0523 std::array<uint16_t, kFieldLookupSize> field_lookup_table;
0524 std::array<TcParseTableBase::FieldEntry, kNumFieldEntries> field_entries;
0525 std::array<char, kNameTableSize == 0 ? 1 : kNameTableSize> field_names;
0526 };
0527
0528
0529
0530 template <size_t kNameTableSize, size_t kFieldLookupSize>
0531 struct TcParseTable<0, 0, 0, kNameTableSize, kFieldLookupSize> {
0532 TcParseTableBase header;
0533
0534
0535 std::array<TcParseTableBase::FastFieldEntry, 1> fast_entries;
0536 std::array<uint16_t, kFieldLookupSize> field_lookup_table;
0537 std::array<char, kNameTableSize == 0 ? 1 : kNameTableSize> field_names;
0538 };
0539
0540 static_assert(std::is_standard_layout<TcParseTable<1>>::value,
0541 "TcParseTable must be standard layout.");
0542
0543 static_assert(offsetof(TcParseTable<1>, fast_entries) ==
0544 sizeof(TcParseTableBase),
0545 "Table entries must be laid out after TcParseTableBase.");
0546
0547 template <typename T,
0548 PROTOBUF_CC const char* (*func)(T*, const char*, ParseContext*)>
0549 PROTOBUF_CC const char* StubParseImpl(PROTOBUF_TC_PARAM_DECL) {
0550 return func(static_cast<T*>(msg), ptr, ctx);
0551 }
0552
0553 template <typename T,
0554 PROTOBUF_CC const char* (*func)(T*, const char*, ParseContext*),
0555 typename ClassData>
0556 constexpr TcParseTable<0> CreateStubTcParseTable(
0557 const ClassData* class_data,
0558 TcParseTableBase::PostLoopHandler post_loop_handler = nullptr) {
0559 return {
0560 {
0561 0,
0562 0,
0563 0,
0564 0,
0565 0,
0566 0,
0567 0,
0568 0,
0569 0,
0570 0,
0571 class_data,
0572 post_loop_handler,
0573 nullptr,
0574 #ifdef PROTOBUF_PREFETCH_PARSE_TABLE
0575 nullptr,
0576 #endif
0577 },
0578 {{{StubParseImpl<T, func>, {}}}},
0579 };
0580 }
0581
0582 }
0583 }
0584 }
0585
0586 #include "google/protobuf/port_undef.inc"
0587
0588 #endif