Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-18 09:16:04

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // This file contains routines to generate tail-call table parsing tables.
0009 // Everything in this file is for internal use only.
0010 
0011 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_GEN_H__
0012 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_GEN_H__
0013 
0014 #include <cstddef>
0015 #include <cstdint>
0016 #include <optional>
0017 #include <vector>
0018 
0019 #include "absl/types/span.h"
0020 #include "google/protobuf/descriptor.h"
0021 #include "google/protobuf/descriptor.pb.h"
0022 
0023 // Must come last:
0024 #include "google/protobuf/port_def.inc"
0025 
0026 namespace google {
0027 namespace protobuf {
0028 namespace internal {
0029 enum class TcParseFunction : uint8_t;
0030 
0031 namespace field_layout {
0032 enum TransformValidation : uint16_t;
0033 }  // namespace field_layout
0034 
0035 PROTOBUF_EXPORT uint32_t
0036 GetRecodedTagForFastParsing(const FieldDescriptor* field);
0037 
0038 PROTOBUF_EXPORT std::optional<uint32_t> GetEndGroupTag(
0039     const Descriptor* descriptor);
0040 
0041 PROTOBUF_EXPORT uint32_t
0042 FastParseTableSize(size_t num_fields, std::optional<uint32_t> end_group_tag);
0043 
0044 PROTOBUF_EXPORT bool IsFieldTypeEligibleForFastParsing(
0045     const FieldDescriptor* field);
0046 
0047 // Helper class for generating tailcall parsing functions.
0048 struct PROTOBUF_EXPORT TailCallTableInfo {
0049   // The tailcall parser can only update the first 32 hasbits. Fields with
0050   // has-bits beyond the first 32 are handled by mini parsing/fallback.
0051   static constexpr int kMaxFastFieldHasbitIndex = 31;
0052 
0053   struct MessageOptions {
0054     bool is_lite;
0055     bool uses_codegen;
0056   };
0057   struct FieldOptions {
0058     const FieldDescriptor* field;
0059     int has_bit_index;
0060     // For presence awareness (e.g. PDProto).
0061     float presence_probability;
0062     // kTvEager, kTvLazy, or 0
0063     field_layout::TransformValidation lazy_opt;
0064     // Whether to use the InlinedStringField representation.
0065     // This choice comes from the profile data.
0066     // If on, inlined_string_index should be set.
0067     // Incompatible with `use_micro_string`.
0068     bool is_string_inlined;
0069     bool is_implicitly_weak;
0070     bool use_direct_tcparser_table;
0071     bool should_split;
0072     int inlined_string_index;
0073     // Whether to use the MicroString representation.
0074     // This choice comes from the temporary opt-in data.
0075     // Incompatible with `is_string_inlined`.
0076     bool use_micro_string;
0077   };
0078 
0079   struct FieldEntryInfo;
0080   struct AuxEntry;
0081 
0082   static std::vector<FieldEntryInfo> BuildFieldEntries(
0083       const Descriptor* descriptor, const MessageOptions& message_options,
0084       absl::Span<const FieldOptions> ordered_fields,
0085       std::vector<AuxEntry>& aux_entries);
0086 
0087   TailCallTableInfo(const Descriptor* descriptor,
0088                     const MessageOptions& message_options,
0089                     absl::Span<const FieldOptions> ordered_fields);
0090 
0091   TcParseFunction fallback_function;
0092 
0093   // Fields parsed by the table fast-path.
0094   struct FastFieldInfo {
0095     struct Empty {};
0096     struct Field {
0097       TcParseFunction func;
0098       const FieldDescriptor* field;
0099       uint16_t coded_tag;
0100       uint8_t hasbit_idx;
0101       uint8_t aux_idx;
0102 
0103       // For internal caching.
0104       float presence_probability;
0105     };
0106     struct NonField {
0107       TcParseFunction func;
0108       uint16_t coded_tag;
0109       uint16_t nonfield_info;
0110     };
0111     std::variant<Empty, Field, NonField> data;
0112 
0113     bool is_empty() const { return std::holds_alternative<Empty>(data); }
0114     const Field* AsField() const { return std::get_if<Field>(&data); }
0115     const NonField* AsNonField() const { return std::get_if<NonField>(&data); }
0116   };
0117   std::vector<FastFieldInfo> fast_path_fields;
0118 
0119   // Fields parsed by mini parsing routines.
0120   struct FieldEntryInfo {
0121     const FieldDescriptor* field;
0122     int hasbit_idx;
0123     int inlined_string_idx;
0124     uint16_t aux_idx;
0125     uint16_t type_card;
0126 
0127     // For internal caching.
0128     cpp::Utf8CheckMode utf8_check_mode;
0129   };
0130   std::vector<FieldEntryInfo> field_entries;
0131 
0132   enum AuxType {
0133     kNothing = 0,
0134     kInlinedStringDonatedOffset,
0135     kSplitOffset,
0136     kSplitSizeof,
0137     kSubMessage,
0138     kSubTable,
0139     kSubMessageWeak,
0140     kMessageVerifyFunc,
0141     kSelfVerifyFunc,
0142     kEnumRange,
0143     kEnumValidator,
0144     kNumericOffset,
0145     kMapAuxInfo,
0146   };
0147   struct AuxEntry {
0148     AuxType type;
0149     struct EnumRange {
0150       int32_t first;
0151       int32_t last;
0152     };
0153     union {
0154       const FieldDescriptor* field;
0155       const Descriptor* desc;
0156       uint32_t offset;
0157       EnumRange enum_range;
0158     };
0159   };
0160   std::vector<AuxEntry> aux_entries;
0161 
0162   struct SkipEntry16 {
0163     uint16_t skipmap;
0164     uint16_t field_entry_offset;
0165   };
0166   struct SkipEntryBlock {
0167     uint32_t first_fnum;
0168     std::vector<SkipEntry16> entries;
0169   };
0170   struct NumToEntryTable {
0171     uint32_t skipmap32;  // for fields #1 - #32
0172     std::vector<SkipEntryBlock> blocks;
0173     // Compute the number of uint16_t required to represent this table.
0174     int size16() const {
0175       int size = 2;  // for the termination field#
0176       for (const auto& block : blocks) {
0177         // 2 for the field#, 1 for a count of skip entries, 2 for each entry.
0178         size += static_cast<int>(3 + block.entries.size() * 2);
0179       }
0180       return size;
0181     }
0182   };
0183   NumToEntryTable num_to_entry_table;
0184 
0185   std::vector<uint8_t> field_name_data;
0186 
0187   // Table size.
0188   int table_size_log2;
0189 };
0190 
0191 }  // namespace internal
0192 }  // namespace protobuf
0193 }  // namespace google
0194 
0195 #include "google/protobuf/port_undef.inc"
0196 
0197 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_GEN_H__