Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-08 09:12:13

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 #ifndef GOOGLE_PROTOBUF_PARSE_CONTEXT_H__
0009 #define GOOGLE_PROTOBUF_PARSE_CONTEXT_H__
0010 
0011 #include <algorithm>
0012 #include <climits>
0013 #include <cstddef>
0014 #include <cstdint>
0015 #include <cstring>
0016 #include <limits>
0017 #include <string>
0018 #include <type_traits>
0019 #include <utility>
0020 
0021 #include "absl/base/config.h"
0022 #include "absl/base/prefetch.h"
0023 #include "absl/log/absl_check.h"
0024 #include "absl/log/absl_log.h"
0025 #include "absl/strings/cord.h"
0026 #include "absl/strings/internal/resize_uninitialized.h"
0027 #include "absl/strings/string_view.h"
0028 #include "absl/types/span.h"
0029 #include "google/protobuf/arena.h"
0030 #include "google/protobuf/arenastring.h"
0031 #include "google/protobuf/endian.h"
0032 #include "google/protobuf/inlined_string_field.h"
0033 #include "google/protobuf/io/coded_stream.h"
0034 #include "google/protobuf/io/zero_copy_stream.h"
0035 #include "google/protobuf/message_lite.h"
0036 #include "google/protobuf/metadata_lite.h"
0037 #include "google/protobuf/micro_string.h"
0038 #include "google/protobuf/port.h"
0039 #include "google/protobuf/repeated_field.h"
0040 #include "google/protobuf/repeated_ptr_field.h"
0041 #include "google/protobuf/wire_format_lite.h"
0042 
0043 
0044 // Must be included last.
0045 #include "google/protobuf/port_def.inc"
0046 
0047 
0048 namespace google {
0049 namespace protobuf {
0050 
0051 class UnknownFieldSet;
0052 class DescriptorPool;
0053 class MessageFactory;
0054 
0055 namespace internal {
0056 
0057 // Template code below needs to know about the existence of these functions.
0058 PROTOBUF_EXPORT void WriteVarint(uint32_t num, uint64_t val, std::string* s);
0059 PROTOBUF_EXPORT void WriteLengthDelimited(uint32_t num, absl::string_view val,
0060                                           std::string* s);
0061 // Inline because it is just forwarding to s->WriteVarint
0062 inline void WriteVarint(uint32_t num, uint64_t val, UnknownFieldSet* unknown);
0063 inline void WriteLengthDelimited(uint32_t num, absl::string_view val,
0064                                  UnknownFieldSet* unknown);
0065 
0066 
0067 // The basic abstraction the parser is designed for is a slight modification
0068 // of the ZeroCopyInputStream (ZCIS) abstraction. A ZCIS presents a serialized
0069 // stream as a series of buffers that concatenate to the full stream.
0070 // Pictorially a ZCIS presents a stream in chunks like so
0071 // [---------------------------------------------------------------]
0072 // [---------------------] chunk 1
0073 //                      [----------------------------] chunk 2
0074 //                                          chunk 3 [--------------]
0075 //
0076 // Where the '-' represent the bytes which are vertically lined up with the
0077 // bytes of the stream. The proto parser requires its input to be presented
0078 // similarly with the extra
0079 // property that each chunk has kSlopBytes past its end that overlaps with the
0080 // first kSlopBytes of the next chunk, or if there is no next chunk at least its
0081 // still valid to read those bytes. Again, pictorially, we now have
0082 //
0083 // [---------------------------------------------------------------]
0084 // [-------------------....] chunk 1
0085 //                    [------------------------....] chunk 2
0086 //                                    chunk 3 [------------------..**]
0087 //                                                      chunk 4 [--****]
0088 // Here '-' mean the bytes of the stream or chunk and '.' means bytes past the
0089 // chunk that match up with the start of the next chunk. Above each chunk has
0090 // 4 '.' after the chunk. In the case these 'overflow' bytes represents bytes
0091 // past the stream, indicated by '*' above, their values are unspecified. It is
0092 // still legal to read them (ie. should not segfault). Reading past the
0093 // end should be detected by the user and indicated as an error.
0094 //
0095 // The reason for this, admittedly, unconventional invariant is to ruthlessly
0096 // optimize the protobuf parser. Having an overlap helps in two important ways.
0097 // Firstly it alleviates having to performing bounds checks if a piece of code
0098 // is guaranteed to not read more than kSlopBytes. Secondly, and more
0099 // importantly, the protobuf wireformat is such that reading a key/value pair is
0100 // always less than 16 bytes. This removes the need to change to next buffer in
0101 // the middle of reading primitive values. Hence there is no need to store and
0102 // load the current position.
0103 
0104 class PROTOBUF_EXPORT EpsCopyInputStream {
0105  public:
0106   enum { kMaxCordBytesToCopy = 512 };
0107   explicit EpsCopyInputStream(bool enable_aliasing)
0108       : aliasing_(enable_aliasing ? kOnPatch : kNoAliasing) {}
0109 
0110   void BackUp(const char* ptr) {
0111     ABSL_DCHECK(ptr <= buffer_end_ + kSlopBytes);
0112     int count;
0113     if (next_chunk_ == patch_buffer_) {
0114       count = BytesAvailable(ptr);
0115     } else {
0116       count = size_ + static_cast<int>(buffer_end_ - ptr);
0117     }
0118     if (count > 0) StreamBackUp(count);
0119   }
0120 
0121   // In sanitizer mode we use memory poisoning to guarantee that:
0122   //  - We do not read an uninitialized token.
0123   //  - We would like to verify that this token was consumed, but unfortunately
0124   //    __asan_address_is_poisoned is allowed to have false negatives.
0125   class LimitToken {
0126    public:
0127     LimitToken() { internal::PoisonMemoryRegion(&token_, sizeof(token_)); }
0128 
0129     explicit LimitToken(int token) : token_(token) {
0130       internal::UnpoisonMemoryRegion(&token_, sizeof(token_));
0131     }
0132 
0133     LimitToken(const LimitToken&) = delete;
0134     LimitToken& operator=(const LimitToken&) = delete;
0135 
0136     LimitToken(LimitToken&& other) { *this = std::move(other); }
0137 
0138     LimitToken& operator=(LimitToken&& other) {
0139       internal::UnpoisonMemoryRegion(&token_, sizeof(token_));
0140       token_ = other.token_;
0141       internal::PoisonMemoryRegion(&other.token_, sizeof(token_));
0142       return *this;
0143     }
0144 
0145     ~LimitToken() { internal::UnpoisonMemoryRegion(&token_, sizeof(token_)); }
0146 
0147     int token() && {
0148       int t = token_;
0149       internal::PoisonMemoryRegion(&token_, sizeof(token_));
0150       return t;
0151     }
0152 
0153    private:
0154     int token_;
0155   };
0156 
0157   // If return value is negative it's an error
0158   [[nodiscard]] LimitToken PushLimit(const char* ptr, int limit) {
0159     ABSL_DCHECK(limit >= 0 && limit <= INT_MAX - kSlopBytes);
0160     // This add is safe due to the invariant above, because
0161     // ptr - buffer_end_ <= kSlopBytes.
0162     limit += static_cast<int>(ptr - buffer_end_);
0163     limit_end_ = buffer_end_ + (std::min)(0, limit);
0164     auto old_limit = limit_;
0165     limit_ = limit;
0166     return LimitToken(old_limit - limit);
0167   }
0168 
0169   [[nodiscard]] bool PopLimit(LimitToken delta) {
0170     // We must update the limit first before the early return. Otherwise, we can
0171     // end up with an invalid limit and it can lead to integer overflows.
0172     limit_ = limit_ + std::move(delta).token();
0173     if (ABSL_PREDICT_FALSE(!EndedAtLimit())) return false;
0174     // TODO We could remove this line and hoist the code to
0175     // DoneFallback. Study the perf/bin-size effects.
0176     limit_end_ = buffer_end_ + (std::min)(0, limit_);
0177     return true;
0178   }
0179 
0180   [[nodiscard]] const char* Skip(const char* ptr, int size) {
0181     if (CanReadFromPtr(size, ptr)) {
0182       return ptr + size;
0183     }
0184     return SkipFallback(ptr, size);
0185   }
0186   [[nodiscard]] const char* ReadString(const char* ptr, int size,
0187                                        std::string* s) {
0188     if (CanReadFromPtr(size, ptr)) {
0189       // Fundamentally we just want to do assign to the string.
0190       // However micro-benchmarks regress on string reading cases. So we copy
0191       // the same logic from the old CodedInputStream ReadString. Note: as of
0192       // Apr 2021, this is still a significant win over `assign()`.
0193       absl::strings_internal::STLStringResizeUninitialized(s, size);
0194       char* z = &(*s)[0];
0195       memcpy(z, ptr, size);
0196       return ptr + size;
0197     }
0198     return ReadStringFallback(ptr, size, s);
0199   }
0200   [[nodiscard]] const char* AppendString(const char* ptr, int size,
0201                                          std::string* s) {
0202     if (CanReadFromPtr(size, ptr)) {
0203       s->append(ptr, size);
0204       return ptr + size;
0205     }
0206     return AppendStringFallback(ptr, size, s);
0207   }
0208 
0209   [[nodiscard]] const char* ReadArray(const char* ptr, absl::Span<char> out);
0210   [[nodiscard]] const char* VerifyUTF8(const char* ptr, size_t size);
0211 
0212   [[nodiscard]] const char* ReadMicroString(const char* ptr, MicroString& str,
0213                                             Arena* arena);
0214   [[nodiscard]] const char* ReadMicroStringFallback(const char* ptr, int size,
0215                                                     MicroString& str,
0216                                                     Arena* arena);
0217 
0218   // Implemented in arenastring.cc
0219   [[nodiscard]] const char* ReadArenaString(const char* ptr, ArenaStringPtr* s,
0220                                             Arena* arena);
0221 
0222   [[nodiscard]] const char* ReadCord(const char* ptr, int size,
0223                                      ::absl::Cord* cord) {
0224     if (IsRequestedLessThanOrEqualTo(
0225             size, std::min<int>(BytesAvailable(ptr), kMaxCordBytesToCopy))) {
0226       *cord = absl::string_view(ptr, size);
0227       return ptr + size;
0228     }
0229     return ReadCordFallback(ptr, size, cord);
0230   }
0231 
0232 
0233   template <typename FuncT>
0234   [[nodiscard]] const char* ReadChunkAndCallback(const char* ptr, int size,
0235                                                  FuncT&& callback) {
0236     if (CanReadFromPtr(size, ptr)) {
0237       callback(ptr, size);
0238       return ptr + size;
0239     }
0240     return AppendSize(ptr, size, callback);
0241   }
0242 
0243   template <typename Tag, typename T>
0244   [[nodiscard]] const char* ReadRepeatedFixed(const char* ptr, Tag expected_tag,
0245                                               RepeatedField<T>* out);
0246 
0247   template <typename T>
0248   [[nodiscard]] const char* ReadPackedFixed(const char* ptr, int size,
0249                                             RepeatedField<T>* out);
0250   template <typename Add>
0251   [[nodiscard]] const char* ReadPackedVarint(const char* ptr, Add add) {
0252     return ReadPackedVarint(ptr, add, [](int) {});
0253   }
0254   template <typename Add, typename SizeCb>
0255   [[nodiscard]] const char* ReadPackedVarint(const char* ptr, Add add,
0256                                              SizeCb size_callback);
0257 
0258   uint32_t LastTag() const { return last_tag_minus_1_ + 1; }
0259   bool ConsumeEndGroup(uint32_t start_tag) {
0260     bool res = last_tag_minus_1_ == start_tag;
0261     last_tag_minus_1_ = 0;
0262     return res;
0263   }
0264   bool EndedAtLimit() const { return last_tag_minus_1_ == 0; }
0265   bool EndedAtEndOfStream() const { return last_tag_minus_1_ == 1; }
0266   void SetLastTag(uint32_t tag) { last_tag_minus_1_ = tag - 1; }
0267   void SetEndOfStream() { last_tag_minus_1_ = 1; }
0268   bool IsExceedingLimit(const char* ptr) {
0269     return ptr > limit_end_ &&
0270            (next_chunk_ == nullptr || ptr - buffer_end_ > limit_);
0271   }
0272   bool AliasingEnabled() const { return aliasing_ != kNoAliasing; }
0273   int BytesUntilLimit(const char* ptr) const {
0274     return limit_ + static_cast<int>(buffer_end_ - ptr);
0275   }
0276   // Maximum number of sequential bytes that can be read starting from `ptr`.
0277   int MaximumReadSize(const char* ptr) const {
0278     return static_cast<int>(limit_end_ - ptr) + kSlopBytes;
0279   }
0280   // Returns true if more data is available, if false is returned one has to
0281   // call Done for further checks.
0282   bool DataAvailable(const char* ptr) { return ptr < limit_end_; }
0283 
0284   int BytesAvailable(const char* ptr) const {
0285     ABSL_DCHECK_NE(ptr, nullptr);
0286     ptrdiff_t available = buffer_end_ + kSlopBytes - ptr;
0287     ABSL_DCHECK_GE(available, 0);
0288     ABSL_DCHECK_LE(available, INT_MAX);
0289     return static_cast<int>(available);
0290   }
0291 
0292 
0293  protected:
0294   // Returns true if limit (either an explicit limit or end of stream) is
0295   // reached. It aligns *ptr across buffer seams.
0296   // If limit is exceeded, it returns true and ptr is set to null.
0297   template <bool kExperimentalV2>
0298   bool DoneWithCheck(const char** ptr, int d) {
0299     ABSL_DCHECK(*ptr);
0300     if (ABSL_PREDICT_TRUE(*ptr < limit_end_)) return false;
0301     int overrun = static_cast<int>(*ptr - buffer_end_);
0302     ABSL_DCHECK_LE(overrun, kSlopBytes);  // Guaranteed by parse loop.
0303     if (overrun ==
0304         limit_) {  //  No need to flip buffers if we ended on a limit.
0305       // If we actually overrun the buffer and next_chunk_ is null, it means
0306       // the stream ended and we passed the stream end.
0307       if (overrun > 0 && next_chunk_ == nullptr) *ptr = nullptr;
0308       return true;
0309     }
0310     auto res = DoneFallback<kExperimentalV2>(overrun, d);
0311     *ptr = res.first;
0312     return res.second;
0313   }
0314 
0315 
0316   const char* InitFrom(absl::string_view flat) {
0317     overall_limit_ = 0;
0318     if (flat.size() > kSlopBytes) {
0319       limit_ = kSlopBytes;
0320       limit_end_ = buffer_end_ = flat.data() + flat.size() - kSlopBytes;
0321       next_chunk_ = patch_buffer_;
0322       if (aliasing_ == kOnPatch) aliasing_ = kNoDelta;
0323       return flat.data();
0324     } else {
0325       if (!flat.empty()) {
0326         std::memcpy(patch_buffer_, flat.data(), flat.size());
0327       }
0328       limit_ = 0;
0329       limit_end_ = buffer_end_ = patch_buffer_ + flat.size();
0330       next_chunk_ = nullptr;
0331       if (aliasing_ == kOnPatch) {
0332         aliasing_ = reinterpret_cast<std::uintptr_t>(flat.data()) -
0333                     reinterpret_cast<std::uintptr_t>(patch_buffer_);
0334       }
0335       return patch_buffer_;
0336     }
0337   }
0338 
0339   const char* InitFrom(io::ZeroCopyInputStream* zcis);
0340 
0341   const char* InitFrom(io::ZeroCopyInputStream* zcis, int limit) {
0342     if (limit == -1) return InitFrom(zcis);
0343     overall_limit_ = limit;
0344     auto res = InitFrom(zcis);
0345     limit_ = limit - static_cast<int>(buffer_end_ - res);
0346     limit_end_ = buffer_end_ + (std::min)(0, limit_);
0347     return res;
0348   }
0349 
0350   // TODO Can V1 enjoy a code deduplication benefit by using this?
0351   const char* InitFrom(const BoundedZCIS& bounded_zcis) {
0352     return InitFrom(bounded_zcis.zcis, bounded_zcis.limit);
0353   }
0354 
0355  protected:
0356   enum { kSlopBytes = 16, kPatchBufferSize = 32 };
0357   static_assert(kPatchBufferSize >= kSlopBytes * 2,
0358                 "Patch buffer needs to be at least large enough to hold all "
0359                 "the slop bytes from the previous buffer, plus the first "
0360                 "kSlopBytes from the next buffer.");
0361 
0362  private:
0363   const char* limit_end_;  // buffer_end_ + min(limit_, 0)
0364   const char* buffer_end_;
0365   const char* next_chunk_;
0366   int size_;
0367   int limit_;  // relative to buffer_end_;
0368   io::ZeroCopyInputStream* zcis_ = nullptr;
0369   char patch_buffer_[kPatchBufferSize] = {};
0370   enum { kNoAliasing = 0, kOnPatch = 1, kNoDelta = 2 };
0371   std::uintptr_t aliasing_ = kNoAliasing;
0372   // This variable is used to communicate how the parse ended, in order to
0373   // completely verify the parsed data. A wire-format parse can end because of
0374   // one of the following conditions:
0375   // 1) A parse can end on a pushed limit.
0376   // 2) A parse can end on End Of Stream (EOS).
0377   // 3) A parse can end on 0 tag (only valid for toplevel message).
0378   // 4) A parse can end on an end-group tag.
0379   // This variable should always be set to 0, which indicates case 1. If the
0380   // parse terminated due to EOS (case 2), it's set to 1. In case the parse
0381   // ended due to a terminating tag (case 3 and 4) it's set to (tag - 1).
0382   // This var doesn't really belong in EpsCopyInputStream and should be part of
0383   // the ParseContext, but case 2 is most easily and optimally implemented in
0384   // DoneFallback.
0385   uint32_t last_tag_minus_1_ = 0;
0386   int overall_limit_ = INT_MAX;  // Overall limit independent of pushed limits.
0387   // Pretty random large number that seems like a safe allocation on most
0388   // systems. TODO do we need to set this as build flag?
0389   enum { kSafeStringSize = 50000000 };
0390 
0391   // Returns true if it has enough available data given requested. Note that
0392   // "available" can be negative but "requested" must not. Casting is done to
0393   // preserve sign bit for the latter only.
0394   bool IsRequestedLessThanOrEqualTo(int requested, int available);
0395 
0396   // Returns true if "requested" bytes can be read contiguously from "ptr". Note
0397   // that negative "requested" is converted to uint32_t before comparison, which
0398   // will cause failure.
0399   bool CanReadFromPtr(int requested, const char* ptr);
0400 
0401   // Returns true if "requested" bytes are avilable till limit. Note that
0402   // negative "requested" is converted to uint32_t before comparison.
0403   bool HasEnoughTillLimit(int requested, const char* ptr);
0404 
0405   // Advances to next buffer chunk returns a pointer to the same logical place
0406   // in the stream as set by overrun. Overrun indicates the position in the slop
0407   // region the parse was left (0 <= overrun <= kSlopBytes). Returns true if at
0408   // limit, at which point the returned pointer maybe null if there was an
0409   // error. The invariant of this function is that it's guaranteed that
0410   // kSlopBytes bytes can be accessed from the returned ptr. This function might
0411   // advance more buffers than one in the underlying ZeroCopyInputStream.
0412   template <bool kExperimentalV2>
0413   std::pair<const char*, bool> DoneFallback(int overrun, int depth);
0414   // Advances to the next buffer, at most one call to Next() on the underlying
0415   // ZeroCopyInputStream is made. This function DOES NOT match the returned
0416   // pointer to where in the slop region the parse ends, hence no overrun
0417   // parameter. This is useful for string operations where you always copy
0418   // to the end of the buffer (including the slop region).
0419   const char* Next();
0420   // overrun is the location in the slop region the stream currently is
0421   // (0 <= overrun <= kSlopBytes). To prevent flipping to the next buffer of
0422   // the ZeroCopyInputStream in the case the parse will end in the last
0423   // kSlopBytes of the current buffer. depth is the current depth of nested
0424   // groups (or negative if the use case does not need careful tracking).
0425   template <bool kExperimentalV2>
0426   inline const char* NextBuffer(int overrun, int depth);
0427   const char* SkipFallback(const char* ptr, int size);
0428   const char* AppendStringFallback(const char* ptr, int size, std::string* str);
0429   const char* VerifyUTF8Fallback(const char* ptr, size_t size);
0430   const char* ReadStringFallback(const char* ptr, int size, std::string* str);
0431   const char* ReadArrayFallback(const char* ptr, absl::Span<char> out);
0432   const char* ReadCordFallback(const char* ptr, int size, absl::Cord* cord);
0433   template <bool kExperimentalV2>
0434   static bool ParseEndsInSlopRegion(const char* begin, int overrun, int depth);
0435   bool StreamNext(const void** data) {
0436     bool res = zcis_->Next(data, &size_);
0437     if (res) overall_limit_ -= size_;
0438     return res;
0439   }
0440   void StreamBackUp(int count) {
0441     zcis_->BackUp(count);
0442     overall_limit_ += count;
0443   }
0444 
0445   template <typename A>
0446   const char* AppendSize(const char* ptr, uint32_t size, const A& append) {
0447     // Some append functions may return false to bail out early.
0448     constexpr bool kCheckReturn =
0449         std::is_invocable_r_v<bool, decltype(append), const char*, int>;
0450 
0451     ABSL_DCHECK_GE(BytesAvailable(ptr), 0);
0452     uint32_t chunk_size = static_cast<uint32_t>(BytesAvailable(ptr));
0453     do {
0454       ABSL_DCHECK_GT(size, chunk_size);
0455       if (next_chunk_ == nullptr) return nullptr;
0456       if constexpr (kCheckReturn) {
0457         if (!append(ptr, chunk_size)) return nullptr;
0458       } else {
0459         append(ptr, chunk_size);
0460       }
0461       ptr += chunk_size;
0462       size -= chunk_size;
0463       // TODO Next calls NextBuffer which generates buffers with
0464       // overlap and thus incurs cost of copying the slop regions. This is not
0465       // necessary for reading strings. We should just call Next buffers.
0466       if (limit_ <= kSlopBytes) return nullptr;
0467       ptr = Next();
0468       if (ptr == nullptr) return nullptr;  // passed the limit
0469       ptr += kSlopBytes;
0470       chunk_size = BytesAvailable(ptr);
0471     } while (size > chunk_size);
0472 
0473     if constexpr (kCheckReturn) {
0474       if (!append(ptr, size)) return nullptr;
0475     } else {
0476       append(ptr, size);
0477     }
0478     return ptr + size;
0479   }
0480 
0481   // AppendUntilEnd appends data until a limit (either a PushLimit or end of
0482   // stream. Normal payloads are from length delimited fields which have an
0483   // explicit size. Reading until limit only comes when the string takes
0484   // the place of a protobuf, ie RawMessage, lazy fields and implicit weak
0485   // messages. We keep these methods private and friend them.
0486   template <typename A>
0487   const char* AppendUntilEnd(const char* ptr, const A& append) {
0488     if (ptr - buffer_end_ > limit_) return nullptr;
0489     while (limit_ > kSlopBytes) {
0490       size_t chunk_size = BytesAvailable(ptr);
0491       append(ptr, chunk_size);
0492       ptr = Next();
0493       if (ptr == nullptr) return limit_end_;
0494       ptr += kSlopBytes;
0495     }
0496     auto end = buffer_end_ + limit_;
0497     ABSL_DCHECK(end >= ptr);
0498     append(ptr, end - ptr);
0499     return end;
0500   }
0501 
0502   [[nodiscard]] const char* AppendString(const char* ptr, std::string* str) {
0503     return AppendUntilEnd(
0504         ptr, [str](const char* p, ptrdiff_t s) { str->append(p, s); });
0505   }
0506   friend class ImplicitWeakMessage;
0507 
0508   // Needs access to kSlopBytes.
0509   friend PROTOBUF_EXPORT std::pair<const char*, int32_t> ReadSizeFallback(
0510       const char* p, uint32_t res);
0511 };
0512 
0513 using LazyEagerVerifyFnType = const char* (*)(const char* ptr,
0514                                               ParseContext* ctx);
0515 using LazyEagerVerifyFnRef = std::remove_pointer<LazyEagerVerifyFnType>::type&;
0516 
0517 // ParseContext holds all data that is global to the entire parse. Most
0518 // importantly it contains the input stream, but also recursion depth and also
0519 // stores the end group tag, in case a parser ended on a endgroup, to verify
0520 // matching start/end group tags.
0521 class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream {
0522  public:
0523   struct Data {
0524     const DescriptorPool* pool = nullptr;
0525     MessageFactory* factory = nullptr;
0526   };
0527 
0528   template <typename... T>
0529   ParseContext(int depth, bool aliasing, const char** start, T&&... args)
0530       : EpsCopyInputStream(aliasing), depth_(depth) {
0531     *start = InitFrom(std::forward<T>(args)...);
0532   }
0533 
0534   struct Spawn {};
0535   static constexpr Spawn kSpawn = {};
0536 
0537   // Creates a new context from a given "ctx" to inherit a few attributes to
0538   // emulate continued parsing. For example, recursion depth or descriptor pools
0539   // must be passed down to a new "spawned" context to maintain the same parse
0540   // context. Note that the spawned context always disables aliasing (different
0541   // input).
0542   template <typename... T>
0543   ParseContext(Spawn, const ParseContext& ctx, const char** start, T&&... args)
0544       : EpsCopyInputStream(false),
0545         depth_(ctx.depth_),
0546         data_(ctx.data_)
0547   {
0548     *start = InitFrom(std::forward<T>(args)...);
0549   }
0550 
0551   // Move constructor and assignment operator are not supported because "ptr"
0552   // for parsing may have pointed to an inlined buffer (patch_buffer_) which can
0553   // be invalid afterwards.
0554   ParseContext(ParseContext&&) = delete;
0555   ParseContext& operator=(ParseContext&&) = delete;
0556   ParseContext& operator=(const ParseContext&) = delete;
0557 
0558   void TrackCorrectEnding() {
0559     group_depth_ = 0;
0560   }
0561 
0562   // Done should only be called when the parsing pointer is pointing to the
0563   // beginning of field data - that is, at a tag.  Or if it is NULL.
0564   bool Done(const char** ptr) {
0565     return DoneWithCheck</*kExperimentalV2=*/false>(ptr, group_depth_);
0566   }
0567 
0568 
0569   int depth() const { return depth_; }
0570 
0571   Data& data() { return data_; }
0572   const Data& data() const { return data_; }
0573 
0574   const char* ParseMessage(MessageLite* msg, const char* ptr);
0575 
0576   // Read the length prefix, push the new limit, call the func(ptr), and then
0577   // pop the limit. Useful for situations that don't have an actual message.
0578   template <typename Func>
0579   [[nodiscard]] const char* ParseLengthDelimitedInlined(const char*,
0580                                                         const Func& func);
0581 
0582   // Push the recursion depth, call the func(ptr), and then pop depth. Useful
0583   // for situations that don't have an actual message.
0584   template <typename Func>
0585   [[nodiscard]] const char* ParseGroupInlined(const char* ptr,
0586                                               uint32_t start_tag,
0587                                               const Func& func);
0588 
0589   // Use a template to avoid the strong dep into TcParser. All callers will have
0590   // the dep.
0591   template <typename Parser = TcParser>
0592   PROTOBUF_ALWAYS_INLINE const char* ParseMessage(
0593       MessageLite* msg, const TcParseTableBase* tc_table, const char* ptr) {
0594     return ParseLengthDelimitedInlined(ptr, [&](const char* ptr) {
0595       return Parser::ParseLoop(msg, ptr, this, tc_table);
0596     });
0597   }
0598   template <typename Parser = TcParser>
0599   PROTOBUF_ALWAYS_INLINE const char* ParseGroup(
0600       MessageLite* msg, const TcParseTableBase* tc_table, const char* ptr,
0601       uint32_t start_tag) {
0602     return ParseGroupInlined(ptr, start_tag, [&](const char* ptr) {
0603       return Parser::ParseLoop(msg, ptr, this, tc_table);
0604     });
0605   }
0606 
0607 
0608   [[nodiscard]] PROTOBUF_NDEBUG_INLINE const char* ParseGroup(MessageLite* msg,
0609                                                               const char* ptr,
0610                                                               uint32_t tag) {
0611     if (--depth_ < 0) return nullptr;
0612     group_depth_++;
0613     auto old_depth = depth_;
0614     auto old_group_depth = group_depth_;
0615     ptr = msg->_InternalParse(ptr, this);
0616     if (ptr != nullptr) {
0617       ABSL_DCHECK_EQ(old_depth, depth_);
0618       ABSL_DCHECK_EQ(old_group_depth, group_depth_);
0619     }
0620     group_depth_--;
0621     depth_++;
0622     if (ABSL_PREDICT_FALSE(!ConsumeEndGroup(tag))) return nullptr;
0623     return ptr;
0624   }
0625 
0626  private:
0627   // Out-of-line routine to save space in ParseContext::ParseMessage<T>
0628   //   LimitToken old;
0629   //   ptr = ReadSizeAndPushLimitAndDepth(ptr, &old)
0630   // is equivalent to:
0631   //   int size = ReadSize(&ptr);
0632   //   if (!ptr) return nullptr;
0633   //   LimitToken old = PushLimit(ptr, size);
0634   //   if (--depth_ < 0) return nullptr;
0635   [[nodiscard]] const char* ReadSizeAndPushLimitAndDepth(const char* ptr,
0636                                                          LimitToken* old_limit);
0637 
0638   // As above, but fully inlined for the cases where we care about performance
0639   // more than size. eg TcParser.
0640   [[nodiscard]] PROTOBUF_ALWAYS_INLINE const char*
0641   ReadSizeAndPushLimitAndDepthInlined(const char* ptr, LimitToken* old_limit);
0642 
0643   // The context keeps an internal stack to keep track of the recursive
0644   // part of the parse state.
0645   // Current depth of the active parser, depth counts down.
0646   // This is used to limit recursion depth (to prevent overflow on malicious
0647   // data), but is also used to index in stack_ to store the current state.
0648   int depth_;
0649   // Unfortunately necessary for the fringe case of ending on 0 or end-group tag
0650   // in the last kSlopBytes of a ZeroCopyInputStream chunk. Note that INT16_MIN
0651   // is intentionally used to avoid decrementing INT_MIN, which is UB.
0652   int group_depth_ = std::numeric_limits<int16_t>::min();
0653   Data data_;
0654 };
0655 
0656 template <int>
0657 struct EndianHelper;
0658 
0659 template <>
0660 struct EndianHelper<1> {
0661   static uint8_t Load(const void* p) { return *static_cast<const uint8_t*>(p); }
0662 };
0663 
0664 template <>
0665 struct EndianHelper<2> {
0666   static uint16_t Load(const void* p) {
0667     uint16_t tmp;
0668     std::memcpy(&tmp, p, 2);
0669     return little_endian::ToHost(tmp);
0670   }
0671 };
0672 
0673 template <>
0674 struct EndianHelper<4> {
0675   static uint32_t Load(const void* p) {
0676     uint32_t tmp;
0677     std::memcpy(&tmp, p, 4);
0678     return little_endian::ToHost(tmp);
0679   }
0680 };
0681 
0682 template <>
0683 struct EndianHelper<8> {
0684   static uint64_t Load(const void* p) {
0685     uint64_t tmp;
0686     std::memcpy(&tmp, p, 8);
0687     return little_endian::ToHost(tmp);
0688   }
0689 };
0690 
0691 template <typename T>
0692 T UnalignedLoad(const char* p) {
0693   auto tmp = EndianHelper<sizeof(T)>::Load(p);
0694   T res;
0695   memcpy(&res, &tmp, sizeof(T));
0696   return res;
0697 }
0698 template <typename T, typename Void,
0699           typename = std::enable_if_t<std::is_same<Void, void>::value>>
0700 T UnalignedLoad(const Void* p) {
0701   return UnalignedLoad<T>(reinterpret_cast<const char*>(p));
0702 }
0703 
0704 PROTOBUF_EXPORT
0705 std::pair<const char*, uint32_t> VarintParseSlow32(const char* p, uint32_t res);
0706 PROTOBUF_EXPORT
0707 std::pair<const char*, uint64_t> VarintParseSlow64(const char* p, uint32_t res);
0708 
0709 inline const char* VarintParseSlow(const char* p, uint32_t res, uint32_t* out) {
0710   auto tmp = VarintParseSlow32(p, res);
0711   *out = tmp.second;
0712   return tmp.first;
0713 }
0714 
0715 inline const char* VarintParseSlow(const char* p, uint32_t res, uint64_t* out) {
0716   auto tmp = VarintParseSlow64(p, res);
0717   *out = tmp.second;
0718   return tmp.first;
0719 }
0720 
0721 #if defined(__aarch64__) && !defined(_MSC_VER)
0722 // Generally, speaking, the ARM-optimized Varint decode algorithm is to extract
0723 // and concatenate all potentially valid data bits, compute the actual length
0724 // of the Varint, and mask off the data bits which are not actually part of the
0725 // result.  More detail on the two main parts is shown below.
0726 //
0727 // 1) Extract and concatenate all potentially valid data bits.
0728 //    Two ARM-specific features help significantly:
0729 //    a) Efficient and non-destructive bit extraction (UBFX)
0730 //    b) A single instruction can perform both an OR with a shifted
0731 //       second operand in one cycle.  E.g., the following two lines do the same
0732 //       thing
0733 //       ```result = operand_1 | (operand2 << 7);```
0734 //       ```ORR %[result], %[operand_1], %[operand_2], LSL #7```
0735 //    The figure below shows the implementation for handling four chunks.
0736 //
0737 // Bits   32    31-24    23   22-16    15    14-8      7     6-0
0738 //      +----+---------+----+---------+----+---------+----+---------+
0739 //      |CB 3| Chunk 3 |CB 2| Chunk 2 |CB 1| Chunk 1 |CB 0| Chunk 0 |
0740 //      +----+---------+----+---------+----+---------+----+---------+
0741 //                |              |              |              |
0742 //               UBFX           UBFX           UBFX           UBFX    -- cycle 1
0743 //                |              |              |              |
0744 //                V              V              V              V
0745 //               Combined LSL #7 and ORR     Combined LSL #7 and ORR  -- cycle 2
0746 //                                 |             |
0747 //                                 V             V
0748 //                            Combined LSL #14 and ORR                -- cycle 3
0749 //                                       |
0750 //                                       V
0751 //                                Parsed bits 0-27
0752 //
0753 //
0754 // 2) Calculate the index of the cleared continuation bit in order to determine
0755 //    where the encoded Varint ends and the size of the decoded value.  The
0756 //    easiest way to do this is mask off all data bits, leaving just the
0757 //    continuation bits.  We actually need to do the masking on an inverted
0758 //    copy of the data, which leaves a 1 in all continuation bits which were
0759 //    originally clear.  The number of trailing zeroes in this value indicates
0760 //    the size of the Varint.
0761 //
0762 //  AND  0x80    0x80    0x80    0x80    0x80    0x80    0x80    0x80
0763 //
0764 // Bits   63      55      47      39      31      23      15       7
0765 //      +----+--+----+--+----+--+----+--+----+--+----+--+----+--+----+--+
0766 // ~    |CB 7|  |CB 6|  |CB 5|  |CB 4|  |CB 3|  |CB 2|  |CB 1|  |CB 0|  |
0767 //      +----+--+----+--+----+--+----+--+----+--+----+--+----+--+----+--+
0768 //         |       |       |       |       |       |       |       |
0769 //         V       V       V       V       V       V       V       V
0770 // Bits   63      55      47      39      31      23      15       7
0771 //      +----+--+----+--+----+--+----+--+----+--+----+--+----+--+----+--+
0772 //      |~CB 7|0|~CB 6|0|~CB 5|0|~CB 4|0|~CB 3|0|~CB 2|0|~CB 1|0|~CB 0|0|
0773 //      +----+--+----+--+----+--+----+--+----+--+----+--+----+--+----+--+
0774 //                                      |
0775 //                                     CTZ
0776 //                                      V
0777 //                     Index of first cleared continuation bit
0778 //
0779 //
0780 // While this is implemented in C++ significant care has been taken to ensure
0781 // the compiler emits the best instruction sequence.  In some cases we use the
0782 // following two functions to manipulate the compiler's scheduling decisions.
0783 //
0784 // Controls compiler scheduling by telling it that the first value is modified
0785 // by the second value the callsite.  This is useful if non-critical path
0786 // instructions are too aggressively scheduled, resulting in a slowdown of the
0787 // actual critical path due to opportunity costs.  An example usage is shown
0788 // where a false dependence of num_bits on result is added to prevent checking
0789 // for a very unlikely error until all critical path instructions have been
0790 // fetched.
0791 //
0792 // ```
0793 // num_bits = <multiple operations to calculate new num_bits value>
0794 // result = <multiple operations to calculate result>
0795 // num_bits = ValueBarrier(num_bits, result);
0796 // if (num_bits == 63) {
0797 //   ABSL_LOG(FATAL) << "Invalid num_bits value";
0798 // }
0799 // ```
0800 // Falsely indicate that the specific value is modified at this location.  This
0801 // prevents code which depends on this value from being scheduled earlier.
0802 template <typename V1Type>
0803 PROTOBUF_ALWAYS_INLINE V1Type ValueBarrier(V1Type value1) {
0804   asm("" : "+r"(value1));
0805   return value1;
0806 }
0807 
0808 template <typename V1Type, typename V2Type>
0809 PROTOBUF_ALWAYS_INLINE V1Type ValueBarrier(V1Type value1, V2Type value2) {
0810   asm("" : "+r"(value1) : "r"(value2));
0811   return value1;
0812 }
0813 
0814 // Performs a 7 bit UBFX (Unsigned Bit Extract) starting at the indicated bit.
0815 static PROTOBUF_ALWAYS_INLINE uint64_t Ubfx7(uint64_t data, uint64_t start) {
0816   return ValueBarrier((data >> start) & 0x7f);
0817 }
0818 
0819 PROTOBUF_ALWAYS_INLINE uint64_t ExtractAndMergeTwoChunks(uint64_t data,
0820                                                          uint64_t first_byte) {
0821   ABSL_DCHECK_LE(first_byte, 6U);
0822   uint64_t first = Ubfx7(data, first_byte * 8);
0823   uint64_t second = Ubfx7(data, (first_byte + 1) * 8);
0824   return ValueBarrier(first | (second << 7));
0825 }
0826 
0827 struct SlowPathEncodedInfo {
0828   const char* p;
0829   uint64_t last8;
0830   uint64_t valid_bits;
0831   uint64_t valid_chunk_bits;
0832   uint64_t masked_cont_bits;
0833 };
0834 
0835 // Performs multiple actions which are identical between 32 and 64 bit Varints
0836 // in order to compute the length of the encoded Varint and compute the new
0837 // of p.
0838 PROTOBUF_ALWAYS_INLINE SlowPathEncodedInfo
0839 ComputeLengthAndUpdateP(const char* p) {
0840   SlowPathEncodedInfo result;
0841   // Load the last two bytes of the encoded Varint.
0842   std::memcpy(&result.last8, p + 2, sizeof(result.last8));
0843   uint64_t mask = ValueBarrier(0x8080808080808080);
0844   // Only set continuation bits remain
0845   result.masked_cont_bits = ValueBarrier(mask & ~result.last8);
0846   // The first cleared continuation bit is the most significant 1 in the
0847   // reversed value.  Result is undefined for an input of 0 and we handle that
0848   // case below.
0849   result.valid_bits = absl::countr_zero(result.masked_cont_bits);
0850   // Calculates the number of chunks in the encoded Varint.  This value is low
0851   // by three as neither the cleared continuation chunk nor the first two chunks
0852   // are counted.
0853   uint64_t set_continuation_bits = result.valid_bits >> 3;
0854   // Update p to point past the encoded Varint.
0855   result.p = p + set_continuation_bits + 3;
0856   // Calculate number of valid data bits in the decoded value so invalid bits
0857   // can be masked off.  Value is too low by 14 but we account for that when
0858   // calculating the mask.
0859   result.valid_chunk_bits = result.valid_bits - set_continuation_bits;
0860   return result;
0861 }
0862 
0863 PROTOBUF_ALWAYS_INLINE std::pair<const char*, uint64_t> VarintParseSlowArm64(
0864     const char* p, uint64_t first8) {
0865   constexpr uint64_t kResultMaskUnshifted = 0xffffffffffffc000ULL;
0866   constexpr uint64_t kFirstResultBitChunk2 = 2 * 7;
0867   constexpr uint64_t kFirstResultBitChunk4 = 4 * 7;
0868   constexpr uint64_t kFirstResultBitChunk6 = 6 * 7;
0869   constexpr uint64_t kFirstResultBitChunk8 = 8 * 7;
0870 
0871   SlowPathEncodedInfo info = ComputeLengthAndUpdateP(p);
0872   // Extract data bits from the low six chunks.  This includes chunks zero and
0873   // one which we already know are valid.
0874   uint64_t merged_01 = ExtractAndMergeTwoChunks(first8, /*first_chunk=*/0);
0875   uint64_t merged_23 = ExtractAndMergeTwoChunks(first8, /*first_chunk=*/2);
0876   uint64_t merged_45 = ExtractAndMergeTwoChunks(first8, /*first_chunk=*/4);
0877   // Low 42 bits of decoded value.
0878   uint64_t result = merged_01 | (merged_23 << kFirstResultBitChunk2) |
0879                     (merged_45 << kFirstResultBitChunk4);
0880   // This immediate ends in 14 zeroes since valid_chunk_bits is too low by 14.
0881   uint64_t result_mask = kResultMaskUnshifted << info.valid_chunk_bits;
0882   //  iff the Varint i invalid.
0883   if (ABSL_PREDICT_FALSE(info.masked_cont_bits == 0)) {
0884     return {nullptr, 0};
0885   }
0886   // Test for early exit if Varint does not exceed 6 chunks.  Branching on one
0887   // bit is faster on ARM than via a compare and branch.
0888   if (ABSL_PREDICT_FALSE((info.valid_bits & 0x20) != 0)) {
0889     // Extract data bits from high four chunks.
0890     uint64_t merged_67 = ExtractAndMergeTwoChunks(first8, /*first_chunk=*/6);
0891     // Last two chunks come from last two bytes of info.last8.
0892     uint64_t merged_89 =
0893         ExtractAndMergeTwoChunks(info.last8, /*first_chunk=*/6);
0894     result |= merged_67 << kFirstResultBitChunk6;
0895     result |= merged_89 << kFirstResultBitChunk8;
0896     // Handle an invalid Varint with all 10 continuation bits set.
0897   }
0898   // Mask off invalid data bytes.
0899   result &= ~result_mask;
0900   return {info.p, result};
0901 }
0902 
0903 // See comments in VarintParseSlowArm64 for a description of the algorithm.
0904 // Differences in the 32 bit version are noted below.
0905 PROTOBUF_ALWAYS_INLINE std::pair<const char*, uint32_t> VarintParseSlowArm32(
0906     const char* p, uint64_t first8) {
0907   constexpr uint64_t kResultMaskUnshifted = 0xffffffffffffc000ULL;
0908   constexpr uint64_t kFirstResultBitChunk1 = 1 * 7;
0909   constexpr uint64_t kFirstResultBitChunk3 = 3 * 7;
0910 
0911   // This also skips the slop bytes.
0912   SlowPathEncodedInfo info = ComputeLengthAndUpdateP(p);
0913   // Extract data bits from chunks 1-4.  Chunk zero is merged in below.
0914   uint64_t merged_12 = ExtractAndMergeTwoChunks(first8, /*first_chunk=*/1);
0915   uint64_t merged_34 = ExtractAndMergeTwoChunks(first8, /*first_chunk=*/3);
0916   first8 = ValueBarrier(first8, p);
0917   uint64_t result = Ubfx7(first8, /*start=*/0);
0918   result = ValueBarrier(result | merged_12 << kFirstResultBitChunk1);
0919   result = ValueBarrier(result | merged_34 << kFirstResultBitChunk3);
0920   uint64_t result_mask = kResultMaskUnshifted << info.valid_chunk_bits;
0921   result &= ~result_mask;
0922   // It is extremely unlikely that a Varint is invalid so checking that
0923   // condition isn't on the critical path. Here we make sure that we don't do so
0924   // until result has been computed.
0925   info.masked_cont_bits = ValueBarrier(info.masked_cont_bits, result);
0926   if (ABSL_PREDICT_FALSE(info.masked_cont_bits == 0)) {
0927     return {nullptr, 0};
0928   }
0929   return {info.p, result};
0930 }
0931 
0932 static const char* VarintParseSlowArm(const char* p, uint32_t* out,
0933                                       uint64_t first8) {
0934   auto tmp = VarintParseSlowArm32(p, first8);
0935   *out = tmp.second;
0936   return tmp.first;
0937 }
0938 
0939 static const char* VarintParseSlowArm(const char* p, uint64_t* out,
0940                                       uint64_t first8) {
0941   auto tmp = VarintParseSlowArm64(p, first8);
0942   *out = tmp.second;
0943   return tmp.first;
0944 }
0945 #endif
0946 
0947 // The caller must ensure that p points to at least 10 valid bytes.
0948 template <typename T>
0949 [[nodiscard]] const char* VarintParse(const char* p, T* out) {
0950   AssertBytesAreReadable(p, 10);
0951 #if defined(__aarch64__) && defined(ABSL_IS_LITTLE_ENDIAN) && !defined(_MSC_VER)
0952   // This optimization is not supported in big endian mode
0953   uint64_t first8;
0954   std::memcpy(&first8, p, sizeof(first8));
0955   if (ABSL_PREDICT_TRUE((first8 & 0x80) == 0)) {
0956     *out = static_cast<uint8_t>(first8);
0957     return p + 1;
0958   }
0959   if (ABSL_PREDICT_TRUE((first8 & 0x8000) == 0)) {
0960     uint64_t chunk1;
0961     uint64_t chunk2;
0962     // Extracting the two chunks this way gives a speedup for this path.
0963     chunk1 = Ubfx7(first8, 0);
0964     chunk2 = Ubfx7(first8, 8);
0965     *out = chunk1 | (chunk2 << 7);
0966     return p + 2;
0967   }
0968   return VarintParseSlowArm(p, out, first8);
0969 #else   // __aarch64__
0970   auto ptr = reinterpret_cast<const uint8_t*>(p);
0971   uint32_t res = ptr[0];
0972   if ((res & 0x80) == 0) {
0973     *out = res;
0974     return p + 1;
0975   }
0976   return VarintParseSlow(p, res, out);
0977 #endif  // __aarch64__
0978 }
0979 
0980 // Used for tags, could read up to 5 bytes which must be available.
0981 // Caller must ensure it's safe to call.
0982 
0983 PROTOBUF_EXPORT
0984 std::pair<const char*, uint32_t> ReadTagFallback(const char* p, uint32_t res);
0985 
0986 // Same as ParseVarint but only accept 5 bytes at most.
0987 inline const char* ReadTag(const char* p, uint32_t* out,
0988                            uint32_t /*max_tag*/ = 0) {
0989   uint32_t res = static_cast<uint8_t>(p[0]);
0990   if (res < 128) {
0991     *out = res;
0992     return p + 1;
0993   }
0994   uint32_t second = static_cast<uint8_t>(p[1]);
0995   res += (second - 1) << 7;
0996   if (second < 128) {
0997     *out = res;
0998     return p + 2;
0999   }
1000   auto tmp = ReadTagFallback(p, res);
1001   *out = tmp.second;
1002   return tmp.first;
1003 }
1004 
1005 // As above, but optimized to consume very few registers while still being fast,
1006 // ReadTagInlined is useful for callers that don't mind the extra code but would
1007 // like to avoid an extern function call causing spills into the stack.
1008 //
1009 // Two support routines for ReadTagInlined come first...
1010 template <class T>
1011 [[nodiscard]] PROTOBUF_ALWAYS_INLINE constexpr T RotateLeft(T x,
1012                                                             int s) noexcept {
1013   return static_cast<T>(x << (s & (std::numeric_limits<T>::digits - 1))) |
1014          static_cast<T>(x >> ((-s) & (std::numeric_limits<T>::digits - 1)));
1015 }
1016 
1017 [[nodiscard]] PROTOBUF_ALWAYS_INLINE uint64_t
1018 RotRight7AndReplaceLowByte(uint64_t res, const char byte) {
1019   // TODO: remove the inline assembly
1020 #if defined(__x86_64__) && defined(__GNUC__)
1021   // This will only use one register for `res`.
1022   // `byte` comes as a reference to allow the compiler to generate code like:
1023   //
1024   //   rorq    $7, %rcx
1025   //   movb    1(%rax), %cl
1026   //
1027   // which avoids loading the incoming bytes into a separate register first.
1028   asm("ror $7,%0\n\t"
1029       "movb %1,%b0"
1030       : "+r"(res)
1031       : "m"(byte));
1032 #else
1033   res = RotateLeft(res, -7);
1034   res = res & ~0xFF;
1035   res |= 0xFF & byte;
1036 #endif
1037   return res;
1038 }
1039 
1040 PROTOBUF_ALWAYS_INLINE const char* ReadTagInlined(const char* ptr,
1041                                                   uint32_t* out) {
1042   uint64_t res = 0xFF & ptr[0];
1043   if (ABSL_PREDICT_FALSE(res >= 128)) {
1044     res = RotRight7AndReplaceLowByte(res, ptr[1]);
1045     if (ABSL_PREDICT_FALSE(res & 0x80)) {
1046       res = RotRight7AndReplaceLowByte(res, ptr[2]);
1047       if (ABSL_PREDICT_FALSE(res & 0x80)) {
1048         res = RotRight7AndReplaceLowByte(res, ptr[3]);
1049         if (ABSL_PREDICT_FALSE(res & 0x80)) {
1050           // Note: this wouldn't work if res were 32-bit,
1051           // because then replacing the low byte would overwrite
1052           // the bottom 4 bits of the result.
1053           res = RotRight7AndReplaceLowByte(res, ptr[4]);
1054           if (ABSL_PREDICT_FALSE(res & 0x80)) {
1055             // The proto format does not permit longer than 5-byte encodings for
1056             // tags.
1057             *out = 0;
1058             return nullptr;
1059           }
1060           *out = static_cast<uint32_t>(RotateLeft(res, 28));
1061 #if defined(__GNUC__)
1062           // Note: this asm statement prevents the compiler from
1063           // trying to share the "return ptr + constant" among all
1064           // branches.
1065           asm("" : "+r"(ptr));
1066 #endif
1067           return ptr + 5;
1068         }
1069         *out = static_cast<uint32_t>(RotateLeft(res, 21));
1070         return ptr + 4;
1071       }
1072       *out = static_cast<uint32_t>(RotateLeft(res, 14));
1073       return ptr + 3;
1074     }
1075     *out = static_cast<uint32_t>(RotateLeft(res, 7));
1076     return ptr + 2;
1077   }
1078   *out = static_cast<uint32_t>(res);
1079   return ptr + 1;
1080 }
1081 
1082 // Decode 2 consecutive bytes of a varint and returns the value, shifted left
1083 // by 1. It simultaneous updates *ptr to *ptr + 1 or *ptr + 2 depending if the
1084 // first byte's continuation bit is set.
1085 // If bit 15 of return value is set (equivalent to the continuation bits of both
1086 // bytes being set) the varint continues, otherwise the parse is done. On x86
1087 // movsx eax, dil
1088 // and edi, eax
1089 // add eax, edi
1090 // adc [rsi], 1
1091 inline uint32_t DecodeTwoBytes(const char** ptr) {
1092   uint32_t value = UnalignedLoad<uint16_t>(*ptr);
1093   // Sign extend the low byte continuation bit
1094   uint32_t x = static_cast<int8_t>(value);
1095   value &= x;  // Mask out the high byte iff no continuation
1096   // This add is an amazing operation, it cancels the low byte continuation bit
1097   // from y transferring it to the carry. Simultaneously it also shifts the 7
1098   // LSB left by one tightly against high byte varint bits. Hence value now
1099   // contains the unpacked value shifted left by 1.
1100   value += x;
1101   // Use the carry to update the ptr appropriately.
1102   *ptr += value < x ? 2 : 1;
1103   return value;
1104 }
1105 
1106 // More efficient varint parsing for big varints
1107 inline const char* ParseBigVarint(const char* p, uint64_t* out) {
1108   auto pnew = p;
1109   auto tmp = DecodeTwoBytes(&pnew);
1110   uint64_t res = tmp >> 1;
1111   if (ABSL_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) {
1112     *out = res;
1113     return pnew;
1114   }
1115   for (std::uint32_t i = 1; i < 5; i++) {
1116     pnew = p + 2 * i;
1117     tmp = DecodeTwoBytes(&pnew);
1118     res += (static_cast<std::uint64_t>(tmp) - 2) << (14 * i - 1);
1119     if (ABSL_PREDICT_TRUE(static_cast<std::int16_t>(tmp) >= 0)) {
1120       *out = res;
1121       return pnew;
1122     }
1123   }
1124   return nullptr;
1125 }
1126 
1127 PROTOBUF_EXPORT
1128 std::pair<const char*, int32_t> ReadSizeFallback(const char* p, uint32_t res);
1129 
1130 // Used for length prefixes. Could read up to 5 bytes, but no more than
1131 // necessary for a single varint. The caller must ensure enough bytes are
1132 // available. Additionally it makes sure the unsigned value fits in an int32_t,
1133 // otherwise returns nullptr. Caller must ensure it is safe to call.
1134 inline uint32_t ReadSize(const char** pp) {
1135   auto p = *pp;
1136   uint32_t res = static_cast<uint8_t>(p[0]);
1137   if (res < 128) {
1138     *pp = p + 1;
1139     return res;
1140   }
1141   auto x = ReadSizeFallback(p, res);
1142   *pp = x.first;
1143   return x.second;
1144 }
1145 
1146 // Some convenience functions to simplify the generated parse loop code.
1147 // Returning the value and updating the buffer pointer allows for nicer
1148 // function composition. We rely on the compiler to inline this.
1149 // Also in debug compiles having local scoped variables tend to generated
1150 // stack frames that scale as O(num fields).
1151 inline uint64_t ReadVarint64(const char** p) {
1152   uint64_t tmp;
1153   *p = VarintParse(*p, &tmp);
1154   return tmp;
1155 }
1156 
1157 inline uint32_t ReadVarint32(const char** p) {
1158   uint32_t tmp;
1159   *p = VarintParse(*p, &tmp);
1160   return tmp;
1161 }
1162 
1163 inline int64_t ReadVarintZigZag64(const char** p) {
1164   uint64_t tmp;
1165   *p = VarintParse(*p, &tmp);
1166   return WireFormatLite::ZigZagDecode64(tmp);
1167 }
1168 
1169 inline int32_t ReadVarintZigZag32(const char** p) {
1170   uint64_t tmp;
1171   *p = VarintParse(*p, &tmp);
1172   return WireFormatLite::ZigZagDecode32(static_cast<uint32_t>(tmp));
1173 }
1174 
1175 template <typename Func>
1176 [[nodiscard]] PROTOBUF_ALWAYS_INLINE const char*
1177 ParseContext::ParseLengthDelimitedInlined(const char* ptr, const Func& func) {
1178   LimitToken old;
1179   ptr = ReadSizeAndPushLimitAndDepthInlined(ptr, &old);
1180   if (ptr == nullptr) return ptr;
1181   auto old_depth = depth_;
1182   PROTOBUF_ALWAYS_INLINE_CALL ptr = func(ptr);
1183   if (ptr != nullptr) ABSL_DCHECK_EQ(old_depth, depth_);
1184   depth_++;
1185   if (!PopLimit(std::move(old))) return nullptr;
1186   return ptr;
1187 }
1188 
1189 template <typename Func>
1190 [[nodiscard]] PROTOBUF_ALWAYS_INLINE const char*
1191 ParseContext::ParseGroupInlined(const char* ptr, uint32_t start_tag,
1192                                 const Func& func) {
1193   if (--depth_ < 0) return nullptr;
1194   group_depth_++;
1195   auto old_depth = depth_;
1196   auto old_group_depth = group_depth_;
1197   PROTOBUF_ALWAYS_INLINE_CALL ptr = func(ptr);
1198   if (ptr != nullptr) {
1199     ABSL_DCHECK_EQ(old_depth, depth_);
1200     ABSL_DCHECK_EQ(old_group_depth, group_depth_);
1201   }
1202   group_depth_--;
1203   depth_++;
1204   if (ABSL_PREDICT_FALSE(!ConsumeEndGroup(start_tag))) return nullptr;
1205   return ptr;
1206 }
1207 
1208 inline const char* ParseContext::ReadSizeAndPushLimitAndDepthInlined(
1209     const char* ptr, LimitToken* old_limit) {
1210   int size = ReadSize(&ptr);
1211   if (ABSL_PREDICT_FALSE(!ptr) || depth_ <= 0) {
1212     return nullptr;
1213   }
1214   *old_limit = PushLimit(ptr, size);
1215   --depth_;
1216   return ptr;
1217 }
1218 
1219 inline const char* EpsCopyInputStream::ReadMicroString(const char* ptr,
1220                                                        MicroString& str,
1221                                                        Arena* arena) {
1222   int size = ReadSize(&ptr);
1223   if (!ptr) return nullptr;
1224 
1225   if (size <= BytesAvailable(ptr)) {
1226     str.Set(absl::string_view(ptr, size), arena);
1227     return ptr + size;
1228   }
1229   return ReadMicroStringFallback(ptr, size, str, arena);
1230 }
1231 
1232 
1233 template <typename Tag, typename T>
1234 const char* EpsCopyInputStream::ReadRepeatedFixed(const char* ptr,
1235                                                   Tag expected_tag,
1236                                                   RepeatedField<T>* out) {
1237   do {
1238     out->Add(UnalignedLoad<T>(ptr));
1239     ptr += sizeof(T);
1240     if (ABSL_PREDICT_FALSE(ptr >= limit_end_)) return ptr;
1241   } while (UnalignedLoad<Tag>(ptr) == expected_tag && (ptr += sizeof(Tag)));
1242   return ptr;
1243 }
1244 
1245 // Add any of the following lines to debug which parse function is failing.
1246 
1247 #define GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, ret) \
1248   if (!(predicate)) {                                  \
1249     /*  ::raise(SIGINT);  */                           \
1250     /*  ABSL_LOG(ERROR) << "Parse failure";  */        \
1251     return ret;                                        \
1252   }
1253 
1254 #define GOOGLE_PROTOBUF_PARSER_ASSERT(predicate) \
1255   GOOGLE_PROTOBUF_ASSERT_RETURN(predicate, nullptr)
1256 
1257 template <typename T>
1258 const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size,
1259                                                 RepeatedField<T>* out) {
1260   GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
1261   int nbytes = BytesAvailable(ptr);
1262   while (size > nbytes) {
1263     int num = nbytes / sizeof(T);
1264     int old_entries = out->size();
1265     out->Reserve(old_entries + num);
1266     int block_size = num * sizeof(T);
1267     auto dst = out->AddNAlreadyReserved(num);
1268 #ifdef ABSL_IS_LITTLE_ENDIAN
1269     std::memcpy(dst, ptr, block_size);
1270 #else
1271     for (int i = 0; i < num; i++)
1272       dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
1273 #endif
1274     size -= block_size;
1275     if (limit_ <= kSlopBytes) return nullptr;
1276     ptr = Next();
1277     if (ptr == nullptr) return nullptr;
1278     ptr += kSlopBytes - (nbytes - block_size);
1279     nbytes = BytesAvailable(ptr);
1280   }
1281   int num = size / sizeof(T);
1282   int block_size = num * sizeof(T);
1283   if (num == 0) return size == block_size ? ptr : nullptr;
1284   int old_entries = out->size();
1285   out->Reserve(old_entries + num);
1286   auto dst = out->AddNAlreadyReserved(num);
1287 #ifdef ABSL_IS_LITTLE_ENDIAN
1288   ABSL_CHECK(dst != nullptr) << out << "," << num;
1289   std::memcpy(dst, ptr, block_size);
1290 #else
1291   for (int i = 0; i < num; i++) dst[i] = UnalignedLoad<T>(ptr + i * sizeof(T));
1292 #endif
1293   ptr += block_size;
1294   if (size != block_size) return nullptr;
1295   return ptr;
1296 }
1297 
1298 template <typename Add>
1299 const char* ReadPackedVarintArray(const char* ptr, const char* end, Add add) {
1300   while (ptr < end) {
1301     uint64_t varint;
1302     ptr = VarintParse(ptr, &varint);
1303     if (ptr == nullptr) return nullptr;
1304     add(varint);
1305   }
1306   return ptr;
1307 }
1308 
1309 template <typename Add, typename SizeCb>
1310 const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add,
1311                                                  SizeCb size_callback) {
1312   int size = ReadSize(&ptr);
1313   size_callback(size);
1314 
1315   GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
1316   int chunk_size = static_cast<int>(buffer_end_ - ptr);
1317   while (size > chunk_size) {
1318     ptr = ReadPackedVarintArray(ptr, buffer_end_, add);
1319     if (ptr == nullptr) return nullptr;
1320     int overrun = static_cast<int>(ptr - buffer_end_);
1321     ABSL_DCHECK(overrun >= 0 && overrun <= kSlopBytes);
1322     if (size - chunk_size <= kSlopBytes) {
1323       // The current buffer contains all the information needed, we don't need
1324       // to flip buffers. However we must parse from a buffer with enough space
1325       // so we are not prone to a buffer overflow.
1326       char buf[kSlopBytes + 10] = {};
1327       std::memcpy(buf, buffer_end_, kSlopBytes);
1328       ABSL_CHECK_LE(size - chunk_size, kSlopBytes);
1329       auto end = buf + (size - chunk_size);
1330       auto res = ReadPackedVarintArray(buf + overrun, end, add);
1331       if (res == nullptr || res != end) return nullptr;
1332       return buffer_end_ + (res - buf);
1333     }
1334     size -= overrun + chunk_size;
1335     ABSL_DCHECK_GT(size, 0);
1336     // We must flip buffers
1337     if (limit_ <= kSlopBytes) return nullptr;
1338     ptr = Next();
1339     if (ptr == nullptr) return nullptr;
1340     ptr += overrun;
1341     chunk_size = static_cast<int>(buffer_end_ - ptr);
1342   }
1343   auto end = ptr + size;
1344   ptr = ReadPackedVarintArray(ptr, end, add);
1345   return end == ptr ? ptr : nullptr;
1346 }
1347 
1348 // Helper for verification of utf8
1349 PROTOBUF_EXPORT
1350 bool VerifyUTF8(absl::string_view s, const char* field_name);
1351 
1352 inline bool VerifyUTF8(const std::string* s, const char* field_name) {
1353   return VerifyUTF8(*s, field_name);
1354 }
1355 
1356 // All the string parsers with or without UTF checking and for all CTypes.
1357 [[nodiscard]] PROTOBUF_EXPORT const char* InlineGreedyStringParser(
1358     std::string* s, const char* ptr, ParseContext* ctx);
1359 
1360 [[nodiscard]] inline const char* InlineCordParser(::absl::Cord* cord,
1361                                                   const char* ptr,
1362                                                   ParseContext* ctx) {
1363   int size = ReadSize(&ptr);
1364   if (!ptr) return nullptr;
1365   return ctx->ReadCord(ptr, size, cord);
1366 }
1367 
1368 
1369 template <typename T>
1370 [[nodiscard]] const char* FieldParser(uint64_t tag, T& field_parser,
1371                                       const char* ptr, ParseContext* ctx) {
1372   uint32_t number = tag >> 3;
1373   GOOGLE_PROTOBUF_PARSER_ASSERT(number != 0);
1374   using WireType = internal::WireFormatLite::WireType;
1375   switch (tag & 7) {
1376     case WireType::WIRETYPE_VARINT: {
1377       uint64_t value;
1378       ptr = VarintParse(ptr, &value);
1379       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
1380       field_parser.AddVarint(number, value);
1381       break;
1382     }
1383     case WireType::WIRETYPE_FIXED64: {
1384       uint64_t value = UnalignedLoad<uint64_t>(ptr);
1385       ptr += 8;
1386       field_parser.AddFixed64(number, value);
1387       break;
1388     }
1389     case WireType::WIRETYPE_LENGTH_DELIMITED: {
1390       ptr = field_parser.ParseLengthDelimited(number, ptr, ctx);
1391       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
1392       break;
1393     }
1394     case WireType::WIRETYPE_START_GROUP: {
1395       ptr = field_parser.ParseGroup(number, ptr, ctx);
1396       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
1397       break;
1398     }
1399     case WireType::WIRETYPE_END_GROUP: {
1400       ABSL_LOG(FATAL) << "Can't happen";
1401       break;
1402     }
1403     case WireType::WIRETYPE_FIXED32: {
1404       uint32_t value = UnalignedLoad<uint32_t>(ptr);
1405       ptr += 4;
1406       field_parser.AddFixed32(number, value);
1407       break;
1408     }
1409     default:
1410       return nullptr;
1411   }
1412   return ptr;
1413 }
1414 
1415 template <typename T>
1416 [[nodiscard]] const char* WireFormatParser(T& field_parser, const char* ptr,
1417                                            ParseContext* ctx) {
1418   while (!ctx->Done(&ptr)) {
1419     uint32_t tag;
1420     ptr = ReadTag(ptr, &tag);
1421     GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
1422     if (tag == 0 || (tag & 7) == 4) {
1423       ctx->SetLastTag(tag);
1424       return ptr;
1425     }
1426     ptr = FieldParser(tag, field_parser, ptr, ctx);
1427     GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
1428   }
1429   return ptr;
1430 }
1431 
1432 // The packed parsers parse repeated numeric primitives directly into  the
1433 // corresponding field
1434 
1435 // These are packed varints
1436 [[nodiscard]] PROTOBUF_EXPORT const char* PackedInt32Parser(void* object,
1437                                                             const char* ptr,
1438                                                             ParseContext* ctx);
1439 [[nodiscard]] PROTOBUF_EXPORT const char* PackedUInt32Parser(void* object,
1440                                                              const char* ptr,
1441                                                              ParseContext* ctx);
1442 [[nodiscard]] PROTOBUF_EXPORT const char* PackedInt64Parser(void* object,
1443                                                             const char* ptr,
1444                                                             ParseContext* ctx);
1445 [[nodiscard]] PROTOBUF_EXPORT const char* PackedUInt64Parser(void* object,
1446                                                              const char* ptr,
1447                                                              ParseContext* ctx);
1448 [[nodiscard]] PROTOBUF_EXPORT const char* PackedSInt32Parser(void* object,
1449                                                              const char* ptr,
1450                                                              ParseContext* ctx);
1451 [[nodiscard]] PROTOBUF_EXPORT const char* PackedSInt64Parser(void* object,
1452                                                              const char* ptr,
1453                                                              ParseContext* ctx);
1454 [[nodiscard]] PROTOBUF_EXPORT const char* PackedEnumParser(void* object,
1455                                                            const char* ptr,
1456                                                            ParseContext* ctx);
1457 
1458 template <typename T, typename Validator>
1459 [[nodiscard]] const char* PackedEnumParserArg(void* object, const char* ptr,
1460                                               ParseContext* ctx,
1461                                               Validator validator,
1462                                               InternalMetadata* metadata,
1463                                               int field_num) {
1464   return ctx->ReadPackedVarint(
1465       ptr, [object, validator, metadata, field_num](int32_t val) {
1466         if (validator.IsValid(val)) {
1467           static_cast<RepeatedField<int>*>(object)->Add(val);
1468         } else {
1469           WriteVarint(field_num, val, metadata->mutable_unknown_fields<T>());
1470         }
1471       });
1472 }
1473 
1474 [[nodiscard]] PROTOBUF_EXPORT const char* PackedBoolParser(void* object,
1475                                                            const char* ptr,
1476                                                            ParseContext* ctx);
1477 [[nodiscard]] PROTOBUF_EXPORT const char* PackedFixed32Parser(
1478     void* object, const char* ptr, ParseContext* ctx);
1479 [[nodiscard]] PROTOBUF_EXPORT const char* PackedSFixed32Parser(
1480     void* object, const char* ptr, ParseContext* ctx);
1481 [[nodiscard]] PROTOBUF_EXPORT const char* PackedFixed64Parser(
1482     void* object, const char* ptr, ParseContext* ctx);
1483 [[nodiscard]] PROTOBUF_EXPORT const char* PackedSFixed64Parser(
1484     void* object, const char* ptr, ParseContext* ctx);
1485 [[nodiscard]] PROTOBUF_EXPORT const char* PackedFloatParser(void* object,
1486                                                             const char* ptr,
1487                                                             ParseContext* ctx);
1488 [[nodiscard]] PROTOBUF_EXPORT const char* PackedDoubleParser(void* object,
1489                                                              const char* ptr,
1490                                                              ParseContext* ctx);
1491 
1492 // This is the only recursive parser.
1493 [[nodiscard]] PROTOBUF_EXPORT const char* UnknownGroupLiteParse(
1494     std::string* unknown, const char* ptr, ParseContext* ctx);
1495 // This is a helper to for the UnknownGroupLiteParse but is actually also
1496 // useful in the generated code. It uses overload on std::string* vs
1497 // UnknownFieldSet* to make the generated code isomorphic between full and lite.
1498 [[nodiscard]] PROTOBUF_EXPORT const char* UnknownFieldParse(
1499     uint32_t tag, std::string* unknown, const char* ptr, ParseContext* ctx);
1500 
1501 extern template std::pair<const char*, bool>
1502 EpsCopyInputStream::DoneFallback<false>(int, int);
1503 extern template std::pair<const char*, bool>
1504 EpsCopyInputStream::DoneFallback<true>(int, int);
1505 
1506 }  // namespace internal
1507 }  // namespace protobuf
1508 }  // namespace google
1509 
1510 #include "google/protobuf/port_undef.inc"
1511 
1512 #endif  // GOOGLE_PROTOBUF_PARSE_CONTEXT_H__