33 #include <google/protobuf/parse_context.h>
34 #include <google/protobuf/extension_set.h>
37 #include <google/protobuf/message_lite.h>
38 #include <google/protobuf/wire_format_lite.h>
41 #include <google/protobuf/port_def.inc>
67 template <WireFormatLite::WireType Wt>
68 inline PROTOBUF_ALWAYS_INLINE
void InvertPacked(TcFieldData&
data) {
78 template <
typename LayoutType,
typename TagType>
80 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
83 ptr +=
sizeof(TagType);
90 template <
typename LayoutType,
typename TagType>
92 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
97 InvertPacked<fallback_wt>(
data);
98 if (
data.coded_tag<TagType>() == 0) {
104 auto&
field = RefAt<RepeatedField<LayoutType>>(
msg,
data.offset());
109 auto expected_tag = UnalignedLoad<TagType>(
ptr);
111 ptr +=
sizeof(TagType);
114 if (
idx >= space)
break;
115 if (!
ctx->DataAvailable(
ptr))
break;
116 }
while (UnalignedLoad<TagType>(
ptr) == expected_tag);
121 template <
typename LayoutType,
typename TagType>
123 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
128 InvertPacked<fallback_wt>(
data);
129 if (
data.coded_tag<TagType>() == 0) {
135 ptr +=
sizeof(TagType);
139 auto&
field = RefAt<RepeatedField<LayoutType>>(
msg,
data.offset());
152 inline PROTOBUF_ALWAYS_INLINE std::pair<const char*, uint64_t>
153 Parse64FallbackPair(
const char* p,
int64_t res1) {
154 auto ptr =
reinterpret_cast<const int8_t*
>(p);
175 #define SHLD(n) byte = ((byte << (n * 7)) | (ones >> (64 - (n * 7))))
178 #if defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(__x86_64__)
182 #define SHLD_SIGN(n) \
183 asm("shldq %3, %2, %1" \
184 : "=@ccs"(sign_bit), "+r"(byte) \
185 : "r"(ones), "i"(n * 7))
188 #define SHLD_SIGN(n) \
191 sign_bit = static_cast<int64_t>(byte) < 0; \
198 if (!sign_bit)
goto done2;
202 if (!sign_bit)
goto done3;
210 if (res1 >= 0)
goto done4;
214 if (res2 >= 0)
goto done5;
218 if (res3 >= 0)
goto done6;
222 if (res1 >= 0)
goto done7;
226 if (res2 >= 0)
goto done8;
230 if (res3 >= 0)
goto done9;
238 if (PROTOBUF_PREDICT_TRUE(
byte == 1))
goto done10;
244 res3 ^=
static_cast<uint64_t>(1) << 63;
252 #define DONE(n) done##n : return {p + n, res1 & res2 & res3};
254 return {p + 2, res1 & res2};
266 inline PROTOBUF_ALWAYS_INLINE
const char* ParseVarint(
const char* p,
269 if (PROTOBUF_PREDICT_TRUE(
byte >= 0)) {
273 auto tmp = Parse64FallbackPair(p,
byte);
274 if (PROTOBUF_PREDICT_TRUE(
tmp.first)) *
value =
tmp.second;
286 int32_t ZigZagDecodeHelper<int32_t, TcParser::VarintDecode::kZigZag>(
292 int64_t ZigZagDecodeHelper<int64_t, TcParser::VarintDecode::kZigZag>(
299 template <
typename FieldType,
typename TagType, TcParser::Var
intDecode zigzag>
301 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
304 ptr +=
sizeof(TagType);
308 if (
ptr ==
nullptr) {
311 RefAt<FieldType>(
msg,
data.offset()) =
312 ZigZagDecodeHelper<FieldType, zigzag>(
tmp);
316 template <
typename FieldType,
typename TagType, TcParser::Var
intDecode zigzag>
318 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
320 InvertPacked<WireFormatLite::WIRETYPE_VARINT>(
data);
321 if (
data.coded_tag<TagType>() == 0) {
327 auto&
field = RefAt<RepeatedField<FieldType>>(
msg,
data.offset());
328 auto expected_tag = UnalignedLoad<TagType>(
ptr);
330 ptr +=
sizeof(TagType);
333 if (
ptr ==
nullptr) {
336 field.Add(ZigZagDecodeHelper<FieldType, zigzag>(
tmp));
337 if (!
ctx->DataAvailable(
ptr)) {
340 }
while (UnalignedLoad<TagType>(
ptr) == expected_tag);
344 template <
typename FieldType,
typename TagType, TcParser::Var
intDecode zigzag>
346 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
347 InvertPacked<WireFormatLite::WIRETYPE_VARINT>(
data);
348 if (
data.coded_tag<TagType>() == 0) {
354 ptr +=
sizeof(TagType);
358 auto*
field = &RefAt<RepeatedField<FieldType>>(
msg,
data.offset());
380 bool emit_stacktrace);
388 if (!
ptr)
return nullptr;
389 return stream->ReadString(
395 template <
typename TagType, TcParser::Utf8Type utf8>
397 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
400 ptr +=
sizeof(TagType);
402 auto&
field = RefAt<ArenaStringPtr>(
msg,
data.offset());
426 template <
typename TagType, TcParser::Utf8Type utf8>
428 if (PROTOBUF_PREDICT_FALSE(
data.coded_tag<TagType>() != 0)) {
431 auto expected_tag = UnalignedLoad<TagType>(
ptr);
432 auto&
field = RefAt<RepeatedPtrField<std::string>>(
msg,
data.offset());
434 ptr +=
sizeof(TagType);
437 if (
ptr ==
nullptr) {
446 if (!
ctx->DataAvailable(
ptr))
break;
447 }
while (UnalignedLoad<TagType>(
ptr) == expected_tag);
451 #define PROTOBUF_TCT_SOURCE
452 #include <google/protobuf/generated_message_tctable_impl.inc>