• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 // This file contains routines to generate tail-call table parsing tables.
9 // Everything in this file is for internal use only.
10 
11 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_GEN_H__
12 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_GEN_H__
13 
14 #include <cstdint>
15 #include <vector>
16 
17 #include "absl/types/span.h"
18 #include "absl/types/variant.h"
19 #include "google/protobuf/descriptor.h"
20 #include "google/protobuf/descriptor.pb.h"
21 
22 // Must come last:
23 #include "google/protobuf/port_def.inc"
24 
25 namespace google {
26 namespace protobuf {
27 namespace internal {
28 enum class TcParseFunction : uint8_t;
29 
30 namespace field_layout {
31 enum TransformValidation : uint16_t;
32 }  // namespace field_layout
33 
34 // Helper class for generating tailcall parsing functions.
35 struct PROTOBUF_EXPORT TailCallTableInfo {
36   struct MessageOptions {
37     bool is_lite;
38     bool uses_codegen;
39     // TODO: remove this after A/B test is done.
40     bool should_profile_driven_cluster_aux_subtable;
41   };
42   struct FieldOptions {
43     const FieldDescriptor* field;
44     int has_bit_index;
45     // For presence awareness (e.g. PDProto).
46     float presence_probability;
47     // kTvEager, kTvLazy, or 0
48     field_layout::TransformValidation lazy_opt;
49     bool is_string_inlined;
50     bool is_implicitly_weak;
51     bool use_direct_tcparser_table;
52     bool should_split;
53     int inlined_string_index;
54   };
55 
56   TailCallTableInfo(const Descriptor* descriptor,
57                     const MessageOptions& message_options,
58                     absl::Span<const FieldOptions> ordered_fields);
59 
60   TcParseFunction fallback_function;
61 
62   // Fields parsed by the table fast-path.
63   struct FastFieldInfo {
64     struct Empty {};
65     struct Field {
66       TcParseFunction func;
67       const FieldDescriptor* field;
68       uint16_t coded_tag;
69       uint8_t hasbit_idx;
70       uint8_t aux_idx;
71 
72       // For internal caching.
73       float presence_probability;
74     };
75     struct NonField {
76       TcParseFunction func;
77       uint16_t coded_tag;
78       uint16_t nonfield_info;
79     };
80     absl::variant<Empty, Field, NonField> data;
81 
is_emptyTailCallTableInfo::FastFieldInfo82     bool is_empty() const { return absl::holds_alternative<Empty>(data); }
AsFieldTailCallTableInfo::FastFieldInfo83     const Field* AsField() const { return absl::get_if<Field>(&data); }
AsNonFieldTailCallTableInfo::FastFieldInfo84     const NonField* AsNonField() const { return absl::get_if<NonField>(&data); }
85   };
86   std::vector<FastFieldInfo> fast_path_fields;
87 
88   // Fields parsed by mini parsing routines.
89   struct FieldEntryInfo {
90     const FieldDescriptor* field;
91     int hasbit_idx;
92     int inlined_string_idx;
93     uint16_t aux_idx;
94     uint16_t type_card;
95 
96     // For internal caching.
97     cpp::Utf8CheckMode utf8_check_mode;
98   };
99   std::vector<FieldEntryInfo> field_entries;
100 
101   enum AuxType {
102     kNothing = 0,
103     kInlinedStringDonatedOffset,
104     kSplitOffset,
105     kSplitSizeof,
106     kSubMessage,
107     kSubTable,
108     kSubMessageWeak,
109     kMessageVerifyFunc,
110     kSelfVerifyFunc,
111     kEnumRange,
112     kEnumValidator,
113     kNumericOffset,
114     kMapAuxInfo,
115   };
116   struct AuxEntry {
117     AuxType type;
118     struct EnumRange {
119       int16_t start;
120       uint16_t size;
121     };
122     union {
123       const FieldDescriptor* field;
124       const Descriptor* desc;
125       uint32_t offset;
126       EnumRange enum_range;
127     };
128   };
129   std::vector<AuxEntry> aux_entries;
130 
131   struct SkipEntry16 {
132     uint16_t skipmap;
133     uint16_t field_entry_offset;
134   };
135   struct SkipEntryBlock {
136     uint32_t first_fnum;
137     std::vector<SkipEntry16> entries;
138   };
139   struct NumToEntryTable {
140     uint32_t skipmap32;  // for fields #1 - #32
141     std::vector<SkipEntryBlock> blocks;
142     // Compute the number of uint16_t required to represent this table.
size16TailCallTableInfo::NumToEntryTable143     int size16() const {
144       int size = 2;  // for the termination field#
145       for (const auto& block : blocks) {
146         // 2 for the field#, 1 for a count of skip entries, 2 for each entry.
147         size += static_cast<int>(3 + block.entries.size() * 2);
148       }
149       return size;
150     }
151   };
152   NumToEntryTable num_to_entry_table;
153 
154   std::vector<uint8_t> field_name_data;
155 
156   // Table size.
157   int table_size_log2;
158 };
159 
160 }  // namespace internal
161 }  // namespace protobuf
162 }  // namespace google
163 
164 #include "google/protobuf/port_undef.inc"
165 
166 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_GEN_H__
167