1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
32#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
33
34#include <cstdint>
35#include <type_traits>
36
37#include <google/protobuf/port.h>
38#include <google/protobuf/extension_set.h>
39#include <google/protobuf/generated_message_tctable_decl.h>
40#include <google/protobuf/message_lite.h>
41#include <google/protobuf/metadata_lite.h>
42#include <google/protobuf/parse_context.h>
43#include <google/protobuf/wire_format_lite.h>
44
45// Must come last:
46#include <google/protobuf/port_def.inc>
47
48namespace google {
49namespace protobuf {
50
51class Message;
52class UnknownFieldSet;
53
54namespace internal {
55
56// Field layout enums.
57//
58// Structural information about fields is packed into a 16-bit value. The enum
59// types below represent bitwise fields, along with their respective widths,
60// shifts, and masks.
61//
62// Bit:
63// +-----------------------+-----------------------+
64// |15 .. 8|7 .. 0|
65// +-----------------------+-----------------------+
66// : . : . : . : . : . : . : 3|========| [3] FieldType
67// : : : : : : 5|=====| : : [2] FieldCardinality
68// : . : . : . : . 8|========| : . : . : [3] FieldRep
69// : : : 10|=====| : : : : [2] TransformValidation
70// : . : .12|=====| . : . : . : . : . : [2] FormatDiscriminator
71// +-----------------------+-----------------------+
72// |15 .. 8|7 .. 0|
73// +-----------------------+-----------------------+
74//
75namespace field_layout {
76// clang-format off
77
78// Field kind (3 bits):
79// These values broadly represent a wire type and an in-memory storage class.
80enum FieldKind : uint16_t {
81 kFkShift = 0,
82 kFkBits = 3,
83 kFkMask = ((1 << kFkBits) - 1) << kFkShift,
84
85 kFkNone = 0,
86 kFkVarint, // WT=0 rep=8,32,64 bits
87 kFkPackedVarint, // WT=2 rep=8,32,64 bits
88 kFkFixed, // WT=1,5 rep=32,64 bits
89 kFkPackedFixed, // WT=2 rep=32,64 bits
90 kFkString, // WT=2 rep=various
91 kFkMessage, // WT=2,3,4 rep=MessageLite*
92 // Maps are a special case of Message, but use different parsing logic.
93 kFkMap, // WT=2 rep=Map(Lite)<various, various>
94};
95
96static_assert(kFkMap < (1 << kFkBits), "too many types");
97
98// Cardinality (2 bits):
99// These values determine how many values a field can have and its presence.
100// Packed fields are represented in FieldType.
101enum Cardinality : uint16_t {
102 kFcShift = kFkShift + kFkBits,
103 kFcBits = 2,
104 kFcMask = ((1 << kFcBits) - 1) << kFcShift,
105
106 kFcSingular = 0,
107 kFcOptional = 1 << kFcShift,
108 kFcRepeated = 2 << kFcShift,
109 kFcOneof = 3 << kFcShift,
110};
111
112// Field representation (3 bits):
113// These values are the specific refinements of storage classes in FieldType.
114enum FieldRep : uint16_t {
115 kRepShift = kFcShift + kFcBits,
116 kRepBits = 3,
117 kRepMask = ((1 << kRepBits) - 1) << kRepShift,
118
119 // Numeric types (used for optional and repeated fields):
120 kRep8Bits = 0,
121 kRep32Bits = 2 << kRepShift,
122 kRep64Bits = 3 << kRepShift,
123 // String types:
124 kRepAString = 0, // ArenaStringPtr
125 kRepIString = 1 << kRepShift, // InlinedString
126 kRepCord = 2 << kRepShift, // absl::Cord
127 kRepSPiece = 3 << kRepShift, // StringPieceField
128 kRepSString = 4 << kRepShift, // std::string*
129 // Message types (WT=2 unless otherwise noted):
130 kRepMessage = 0, // MessageLite*
131 kRepGroup = 1 << kRepShift, // MessageLite* (WT=3,4)
132 kRepLazy = 2 << kRepShift, // LazyField*
133 kRepIWeak = 3 << kRepShift, // ImplicitWeak
134};
135
136// Transform/validation (2 bits):
137// These values determine transforms or validation to/from wire format.
138enum TransformValidation : uint16_t {
139 kTvShift = kRepShift + kRepBits,
140 kTvBits = 2,
141 kTvMask = ((1 << kTvBits) - 1) << kTvShift,
142
143 // Varint fields:
144 kTvZigZag = 1 << kTvShift,
145 kTvEnum = 2 << kTvShift, // validate using generated _IsValid()
146 kTvRange = 3 << kTvShift, // validate using FieldAux::enum_range
147 // String fields:
148 kTvUtf8Debug = 1 << kTvShift, // proto2
149 kTvUtf8 = 2 << kTvShift, // proto3
150};
151
152static_assert((kTvEnum & kTvRange) != 0,
153 "enum validation types must share a bit");
154static_assert((kTvEnum & kTvRange & kTvZigZag) == 0,
155 "zigzag encoding is not enum validation");
156
157// Format discriminators (2 bits):
158enum FormatDiscriminator : uint16_t {
159 kFmtShift = kTvShift + kTvBits,
160 kFmtBits = 2,
161 kFmtMask = ((1 << kFmtBits) - 1) << kFmtShift,
162
163 // Numeric:
164 kFmtUnsigned = 1 << kFmtShift, // fixed, varint
165 kFmtSigned = 2 << kFmtShift, // fixed, varint
166 kFmtFloating = 3 << kFmtShift, // fixed
167 kFmtEnum = 3 << kFmtShift, // varint
168 // Strings:
169 kFmtUtf8 = 1 << kFmtShift, // string (proto3, enforce_utf8=true)
170 kFmtUtf8Escape = 2 << kFmtShift, // string (proto2, enforce_utf8=false)
171 // Bytes:
172 kFmtArray = 1 << kFmtShift, // bytes
173 // Messages:
174 kFmtShow = 1 << kFmtShift, // message, map
175};
176
177// Update this assertion (and comments above) when adding or removing bits:
178static_assert(kFmtShift + kFmtBits == 12, "number of bits changed");
179
180// This assertion should not change unless the storage width changes:
181static_assert(kFmtShift + kFmtBits <= 16, "too many bits");
182
183// Convenience aliases (16 bits, with format):
184enum FieldType : uint16_t {
185 // Numeric types:
186 kBool = kFkVarint | kRep8Bits,
187
188 kFixed32 = kFkFixed | kRep32Bits | kFmtUnsigned,
189 kUInt32 = kFkVarint | kRep32Bits | kFmtUnsigned,
190 kSFixed32 = kFkFixed | kRep32Bits | kFmtSigned,
191 kInt32 = kFkVarint | kRep32Bits | kFmtSigned,
192 kSInt32 = kFkVarint | kRep32Bits | kFmtSigned | kTvZigZag,
193 kFloat = kFkFixed | kRep32Bits | kFmtFloating,
194 kEnum = kFkVarint | kRep32Bits | kFmtEnum | kTvEnum,
195 kEnumRange = kFkVarint | kRep32Bits | kFmtEnum | kTvRange,
196 kOpenEnum = kFkVarint | kRep32Bits | kFmtEnum,
197
198 kFixed64 = kFkFixed | kRep64Bits | kFmtUnsigned,
199 kUInt64 = kFkVarint | kRep64Bits | kFmtUnsigned,
200 kSFixed64 = kFkFixed | kRep64Bits | kFmtSigned,
201 kInt64 = kFkVarint | kRep64Bits | kFmtSigned,
202 kSInt64 = kFkVarint | kRep64Bits | kFmtSigned | kTvZigZag,
203 kDouble = kFkFixed | kRep64Bits | kFmtFloating,
204
205 kPackedBool = kFkPackedVarint | kRep8Bits,
206
207 kPackedFixed32 = kFkPackedFixed | kRep32Bits | kFmtUnsigned,
208 kPackedUInt32 = kFkPackedVarint | kRep32Bits | kFmtUnsigned,
209 kPackedSFixed32 = kFkPackedFixed | kRep32Bits | kFmtSigned,
210 kPackedInt32 = kFkPackedVarint | kRep32Bits | kFmtSigned,
211 kPackedSInt32 = kFkPackedVarint | kRep32Bits | kFmtSigned | kTvZigZag,
212 kPackedFloat = kFkPackedFixed | kRep32Bits | kFmtFloating,
213 kPackedEnum = kFkPackedVarint | kRep32Bits | kFmtEnum | kTvEnum,
214 kPackedEnumRange = kFkPackedVarint | kRep32Bits | kFmtEnum | kTvRange,
215 kPackedOpenEnum = kFkPackedVarint | kRep32Bits | kFmtEnum,
216
217 kPackedFixed64 = kFkPackedFixed | kRep64Bits | kFmtUnsigned,
218 kPackedUInt64 = kFkPackedVarint | kRep64Bits | kFmtUnsigned,
219 kPackedSFixed64 = kFkPackedFixed | kRep64Bits | kFmtSigned,
220 kPackedInt64 = kFkPackedVarint | kRep64Bits | kFmtSigned,
221 kPackedSInt64 = kFkPackedVarint | kRep64Bits | kFmtSigned | kTvZigZag,
222 kPackedDouble = kFkPackedFixed | kRep64Bits | kFmtFloating,
223
224 // String types:
225 kBytes = kFkString | kFmtArray,
226 kRawString = kFkString | kFmtUtf8 | kTvUtf8Debug,
227 kUtf8String = kFkString | kFmtUtf8 | kTvUtf8,
228
229 // Message types:
230 kMessage = kFkMessage,
231
232 // Map types:
233 kMap = kFkMap,
234};
235
236// clang-format on
237} // namespace field_layout
238
239// PROTOBUF_TC_PARAM_DECL are the parameters for tailcall functions, it is
240// defined in port_def.inc.
241//
242// Note that this is performance sensitive: changing the parameters will change
243// the registers used by the ABI calling convention, which subsequently affects
244// register selection logic inside the function.
245
246// PROTOBUF_TC_PARAM_PASS passes values to match PROTOBUF_TC_PARAM_DECL.
247#define PROTOBUF_TC_PARAM_PASS msg, ptr, ctx, table, hasbits, data
248
249#ifndef NDEBUG
250template <size_t align>
251#ifndef _MSC_VER
252[[noreturn]]
253#endif
254void AlignFail(uintptr_t address) {
255 GOOGLE_LOG(FATAL) << "Unaligned (" << align << ") access at " << address;
256}
257
258extern template void AlignFail<4>(uintptr_t);
259extern template void AlignFail<8>(uintptr_t);
260#endif
261
262// TcParser implements most of the parsing logic for tailcall tables.
263class PROTOBUF_EXPORT TcParser final {
264 public:
265 static const char* GenericFallback(PROTOBUF_TC_PARAM_DECL);
266 static const char* GenericFallbackLite(PROTOBUF_TC_PARAM_DECL);
267
268 static const char* ParseLoop(MessageLite* msg, const char* ptr,
269 ParseContext* ctx,
270 const TcParseTableBase* table);
271
272 // Functions referenced by generated fast tables (numeric types):
273 // F: fixed V: varint Z: zigzag
274 // 8/32/64: storage type width (bits)
275 // S: singular R: repeated P: packed
276 // 1/2: tag length (bytes)
277
278 // Fixed:
279 static const char* FastF32S1(PROTOBUF_TC_PARAM_DECL);
280 static const char* FastF32S2(PROTOBUF_TC_PARAM_DECL);
281 static const char* FastF32R1(PROTOBUF_TC_PARAM_DECL);
282 static const char* FastF32R2(PROTOBUF_TC_PARAM_DECL);
283 static const char* FastF32P1(PROTOBUF_TC_PARAM_DECL);
284 static const char* FastF32P2(PROTOBUF_TC_PARAM_DECL);
285 static const char* FastF64S1(PROTOBUF_TC_PARAM_DECL);
286 static const char* FastF64S2(PROTOBUF_TC_PARAM_DECL);
287 static const char* FastF64R1(PROTOBUF_TC_PARAM_DECL);
288 static const char* FastF64R2(PROTOBUF_TC_PARAM_DECL);
289 static const char* FastF64P1(PROTOBUF_TC_PARAM_DECL);
290 static const char* FastF64P2(PROTOBUF_TC_PARAM_DECL);
291
292 // Varint:
293 static const char* FastV8S1(PROTOBUF_TC_PARAM_DECL);
294 static const char* FastV8S2(PROTOBUF_TC_PARAM_DECL);
295 static const char* FastV8R1(PROTOBUF_TC_PARAM_DECL);
296 static const char* FastV8R2(PROTOBUF_TC_PARAM_DECL);
297 static const char* FastV8P1(PROTOBUF_TC_PARAM_DECL);
298 static const char* FastV8P2(PROTOBUF_TC_PARAM_DECL);
299 static const char* FastV32S1(PROTOBUF_TC_PARAM_DECL);
300 static const char* FastV32S2(PROTOBUF_TC_PARAM_DECL);
301 static const char* FastV32R1(PROTOBUF_TC_PARAM_DECL);
302 static const char* FastV32R2(PROTOBUF_TC_PARAM_DECL);
303 static const char* FastV32P1(PROTOBUF_TC_PARAM_DECL);
304 static const char* FastV32P2(PROTOBUF_TC_PARAM_DECL);
305 static const char* FastV64S1(PROTOBUF_TC_PARAM_DECL);
306 static const char* FastV64S2(PROTOBUF_TC_PARAM_DECL);
307 static const char* FastV64R1(PROTOBUF_TC_PARAM_DECL);
308 static const char* FastV64R2(PROTOBUF_TC_PARAM_DECL);
309 static const char* FastV64P1(PROTOBUF_TC_PARAM_DECL);
310 static const char* FastV64P2(PROTOBUF_TC_PARAM_DECL);
311
312 // Varint (with zigzag):
313 static const char* FastZ32S1(PROTOBUF_TC_PARAM_DECL);
314 static const char* FastZ32S2(PROTOBUF_TC_PARAM_DECL);
315 static const char* FastZ32R1(PROTOBUF_TC_PARAM_DECL);
316 static const char* FastZ32R2(PROTOBUF_TC_PARAM_DECL);
317 static const char* FastZ32P1(PROTOBUF_TC_PARAM_DECL);
318 static const char* FastZ32P2(PROTOBUF_TC_PARAM_DECL);
319 static const char* FastZ64S1(PROTOBUF_TC_PARAM_DECL);
320 static const char* FastZ64S2(PROTOBUF_TC_PARAM_DECL);
321 static const char* FastZ64R1(PROTOBUF_TC_PARAM_DECL);
322 static const char* FastZ64R2(PROTOBUF_TC_PARAM_DECL);
323 static const char* FastZ64P1(PROTOBUF_TC_PARAM_DECL);
324 static const char* FastZ64P2(PROTOBUF_TC_PARAM_DECL);
325
326 // Functions referenced by generated fast tables (closed enum):
327 // E: closed enum (N.B.: open enums use V32, above)
328 // r: enum range v: enum validator (_IsValid function)
329 // S: singular R: repeated
330 // 1/2: tag length (bytes)
331 static const char* FastErS1(PROTOBUF_TC_PARAM_DECL);
332 static const char* FastErS2(PROTOBUF_TC_PARAM_DECL);
333 static const char* FastErR1(PROTOBUF_TC_PARAM_DECL);
334 static const char* FastErR2(PROTOBUF_TC_PARAM_DECL);
335 static const char* FastEvS1(PROTOBUF_TC_PARAM_DECL);
336 static const char* FastEvS2(PROTOBUF_TC_PARAM_DECL);
337 static const char* FastEvR1(PROTOBUF_TC_PARAM_DECL);
338 static const char* FastEvR2(PROTOBUF_TC_PARAM_DECL);
339
340 // Functions referenced by generated fast tables (string types):
341 // B: bytes S: string U: UTF-8 string
342 // (empty): ArenaStringPtr i: InlinedString
343 // S: singular R: repeated
344 // 1/2: tag length (bytes)
345 static const char* FastBS1(PROTOBUF_TC_PARAM_DECL);
346 static const char* FastBS2(PROTOBUF_TC_PARAM_DECL);
347 static const char* FastBR1(PROTOBUF_TC_PARAM_DECL);
348 static const char* FastBR2(PROTOBUF_TC_PARAM_DECL);
349 static const char* FastSS1(PROTOBUF_TC_PARAM_DECL);
350 static const char* FastSS2(PROTOBUF_TC_PARAM_DECL);
351 static const char* FastSR1(PROTOBUF_TC_PARAM_DECL);
352 static const char* FastSR2(PROTOBUF_TC_PARAM_DECL);
353 static const char* FastUS1(PROTOBUF_TC_PARAM_DECL);
354 static const char* FastUS2(PROTOBUF_TC_PARAM_DECL);
355 static const char* FastUR1(PROTOBUF_TC_PARAM_DECL);
356 static const char* FastUR2(PROTOBUF_TC_PARAM_DECL);
357
358 static const char* FastBiS1(PROTOBUF_TC_PARAM_DECL);
359 static const char* FastBiS2(PROTOBUF_TC_PARAM_DECL);
360 static const char* FastSiS1(PROTOBUF_TC_PARAM_DECL);
361 static const char* FastSiS2(PROTOBUF_TC_PARAM_DECL);
362 static const char* FastUiS1(PROTOBUF_TC_PARAM_DECL);
363 static const char* FastUiS2(PROTOBUF_TC_PARAM_DECL);
364
365 // Functions referenced by generated fast tables (message types):
366 // M: message G: group
367 // S: singular R: repeated
368 // 1/2: tag length (bytes)
369 static const char* FastMS1(PROTOBUF_TC_PARAM_DECL);
370 static const char* FastMS2(PROTOBUF_TC_PARAM_DECL);
371 static const char* FastMR1(PROTOBUF_TC_PARAM_DECL);
372 static const char* FastMR2(PROTOBUF_TC_PARAM_DECL);
373 static const char* FastGS1(PROTOBUF_TC_PARAM_DECL);
374 static const char* FastGS2(PROTOBUF_TC_PARAM_DECL);
375 static const char* FastGR1(PROTOBUF_TC_PARAM_DECL);
376 static const char* FastGR2(PROTOBUF_TC_PARAM_DECL);
377
378 template <typename T>
379 static inline T& RefAt(void* x, size_t offset) {
380 T* target = reinterpret_cast<T*>(static_cast<char*>(x) + offset);
381#ifndef NDEBUG
382 if (PROTOBUF_PREDICT_FALSE(
383 reinterpret_cast<uintptr_t>(target) % alignof(T) != 0)) {
384 AlignFail<alignof(T)>(reinterpret_cast<uintptr_t>(target));
385 }
386#endif
387 return *target;
388 }
389
390 template <typename T>
391 static inline const T& RefAt(const void* x, size_t offset) {
392 const T* target =
393 reinterpret_cast<const T*>(static_cast<const char*>(x) + offset);
394#ifndef NDEBUG
395 if (PROTOBUF_PREDICT_FALSE(
396 reinterpret_cast<uintptr_t>(target) % alignof(T) != 0)) {
397 AlignFail<alignof(T)>(reinterpret_cast<uintptr_t>(target));
398 }
399#endif
400 return *target;
401 }
402
403 template <typename T>
404 static inline T ReadAt(const void* x, size_t offset) {
405 T out;
406 memcpy(&out, static_cast<const char*>(x) + offset, sizeof(T));
407 return out;
408 }
409
410 // Mini parsing:
411 //
412 // This function parses a field from incoming data based on metadata stored in
413 // the message definition. If the field is not defined in the message, it is
414 // stored in either the ExtensionSet (if applicable) or the UnknownFieldSet.
415 //
416 // NOTE: Currently, this function only calls the table-level fallback
417 // function, so it should only be called as the fallback from fast table
418 // parsing.
419 static const char* MiniParse(PROTOBUF_TC_PARAM_DECL);
420
421 private:
422 friend class GeneratedTcTableLiteTest;
423
424 template <typename TagType, bool group_coding>
425 static inline const char* SingularParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL);
426 template <typename TagType, bool group_coding>
427 static inline const char* RepeatedParseMessageAuxImpl(PROTOBUF_TC_PARAM_DECL);
428
429 static inline PROTOBUF_ALWAYS_INLINE void SyncHasbits(
430 MessageLite* msg, uint64_t hasbits, const TcParseTableBase* table) {
431 const uint32_t has_bits_offset = table->has_bits_offset;
432 if (has_bits_offset) {
433 // Only the first 32 has-bits are updated. Nothing above those is stored,
434 // but e.g. messages without has-bits update the upper bits.
435 RefAt<uint32_t>(x: msg, offset: has_bits_offset) = static_cast<uint32_t>(hasbits);
436 }
437 }
438
439 static const char* TagDispatch(PROTOBUF_TC_PARAM_DECL);
440 static const char* ToTagDispatch(PROTOBUF_TC_PARAM_DECL);
441 static const char* ToParseLoop(PROTOBUF_TC_PARAM_DECL);
442 static const char* Error(PROTOBUF_TC_PARAM_DECL);
443
444 static const char* FastUnknownEnumFallback(PROTOBUF_TC_PARAM_DECL);
445
446 class ScopedArenaSwap;
447
448 template <class MessageBaseT, class UnknownFieldsT>
449 static const char* GenericFallbackImpl(PROTOBUF_TC_PARAM_DECL) {
450#define CHK_(x) \
451 if (PROTOBUF_PREDICT_FALSE(!(x))) return nullptr /* NOLINT */
452
453 SyncHasbits(msg, hasbits, table);
454 CHK_(ptr);
455 uint32_t tag = data.tag();
456 if ((tag & 7) == WireFormatLite::WIRETYPE_END_GROUP || tag == 0) {
457 ctx->SetLastTag(tag);
458 return ptr;
459 }
460 uint32_t num = tag >> 3;
461 if (table->extension_range_low <= num &&
462 num <= table->extension_range_high) {
463 return RefAt<ExtensionSet>(x: msg, offset: table->extension_offset)
464 .ParseField(tag, ptr,
465 static_cast<const MessageBaseT*>(table->default_instance),
466 &msg->_internal_metadata_, ctx);
467 }
468 return UnknownFieldParse(
469 tag, msg->_internal_metadata_.mutable_unknown_fields<UnknownFieldsT>(),
470 ptr, ctx);
471#undef CHK_
472 }
473
474 // Note: `inline` is needed on template function declarations below to avoid
475 // -Wattributes diagnostic in GCC.
476
477 // Implementations for fast fixed field parsing functions:
478 template <typename LayoutType, typename TagType>
479 static inline const char* SingularFixed(PROTOBUF_TC_PARAM_DECL);
480 template <typename LayoutType, typename TagType>
481 static inline const char* RepeatedFixed(PROTOBUF_TC_PARAM_DECL);
482 template <typename LayoutType, typename TagType>
483 static inline const char* PackedFixed(PROTOBUF_TC_PARAM_DECL);
484
485 // Implementations for fast varint field parsing functions:
486 template <typename FieldType, typename TagType, bool zigzag = false>
487 static inline const char* SingularVarint(PROTOBUF_TC_PARAM_DECL);
488 template <typename FieldType, typename TagType, bool zigzag = false>
489 static inline const char* RepeatedVarint(PROTOBUF_TC_PARAM_DECL);
490 template <typename FieldType, typename TagType, bool zigzag = false>
491 static inline const char* PackedVarint(PROTOBUF_TC_PARAM_DECL);
492
493 // Helper for ints > 127:
494 template <typename FieldType, typename TagType, bool zigzag = false>
495 static const char* SingularVarBigint(PROTOBUF_TC_PARAM_DECL);
496
497 // Implementations for fast enum field parsing functions:
498 template <typename TagType, uint16_t xform_val>
499 static inline const char* SingularEnum(PROTOBUF_TC_PARAM_DECL);
500 template <typename TagType, uint16_t xform_val>
501 static inline const char* RepeatedEnum(PROTOBUF_TC_PARAM_DECL);
502
503 // Implementations for fast string field parsing functions:
504 enum Utf8Type { kNoUtf8 = 0, kUtf8 = 1, kUtf8ValidateOnly = 2 };
505 template <typename TagType, Utf8Type utf8>
506 static inline const char* SingularString(PROTOBUF_TC_PARAM_DECL);
507 template <typename TagType, Utf8Type utf8>
508 static inline const char* RepeatedString(PROTOBUF_TC_PARAM_DECL);
509
510 // Mini field lookup:
511 static const TcParseTableBase::FieldEntry* FindFieldEntry(
512 const TcParseTableBase* table, uint32_t field_num);
513 static StringPiece MessageName(const TcParseTableBase* table);
514 static StringPiece FieldName(const TcParseTableBase* table,
515 const TcParseTableBase::FieldEntry*);
516 static bool ChangeOneof(const TcParseTableBase* table,
517 const TcParseTableBase::FieldEntry& entry,
518 uint32_t field_num, ParseContext* ctx,
519 MessageLite* msg);
520
521 // UTF-8 validation:
522 static void ReportFastUtf8Error(uint32_t decoded_tag,
523 const TcParseTableBase* table);
524 static bool MpVerifyUtf8(StringPiece wire_bytes,
525 const TcParseTableBase* table,
526 const TcParseTableBase::FieldEntry& entry,
527 uint16_t xform_val);
528
529 // For FindFieldEntry tests:
530 friend class FindFieldEntryTest;
531 static constexpr const uint32_t kMtSmallScanSize = 4;
532
533 // Mini parsing:
534 static const char* MpVarint(PROTOBUF_TC_PARAM_DECL);
535 static const char* MpRepeatedVarint(PROTOBUF_TC_PARAM_DECL);
536 static const char* MpPackedVarint(PROTOBUF_TC_PARAM_DECL);
537 static const char* MpFixed(PROTOBUF_TC_PARAM_DECL);
538 static const char* MpRepeatedFixed(PROTOBUF_TC_PARAM_DECL);
539 static const char* MpPackedFixed(PROTOBUF_TC_PARAM_DECL);
540 static const char* MpString(PROTOBUF_TC_PARAM_DECL);
541 static const char* MpRepeatedString(PROTOBUF_TC_PARAM_DECL);
542 static const char* MpMessage(PROTOBUF_TC_PARAM_DECL);
543 static const char* MpRepeatedMessage(PROTOBUF_TC_PARAM_DECL);
544 static const char* MpMap(PROTOBUF_TC_PARAM_DECL);
545};
546
547} // namespace internal
548} // namespace protobuf
549} // namespace google
550
551#include <google/protobuf/port_undef.inc>
552
553#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TCTABLE_IMPL_H__
554