Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-03 09:11:32

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 // Author: kenton@google.com (Kenton Varda)
0009 //         atenasio@google.com (Chris Atenasio) (ZigZag transform)
0010 //         wink@google.com (Wink Saville) (refactored from wire_format.h)
0011 //  Based on original Protocol Buffers design by
0012 //  Sanjay Ghemawat, Jeff Dean, and others.
0013 //
0014 // This header is logically internal, but is made public because it is used
0015 // from protocol-compiler-generated code, which may reside in other components.
0016 
0017 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
0018 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
0019 
0020 #include <algorithm>
0021 #include <cstddef>
0022 #include <cstdint>
0023 #include <limits>
0024 #include <string>
0025 #include <utility>
0026 
0027 #include "absl/base/casts.h"
0028 #include "absl/base/optimization.h"
0029 #include "absl/log/absl_check.h"
0030 #include "absl/strings/string_view.h"
0031 #include "google/protobuf/arenastring.h"
0032 #include "google/protobuf/io/coded_stream.h"
0033 #include "google/protobuf/message_lite.h"
0034 #include "google/protobuf/port.h"
0035 #include "google/protobuf/repeated_field.h"
0036 
0037 
0038 #ifndef NDEBUG
0039 #define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
0040 #endif
0041 
0042 // Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL.
0043 //
0044 // If some one needs the macro TYPE_BOOL in a file that includes this header,
0045 // it's possible to bring it back using push/pop_macro as follows.
0046 //
0047 // #pragma push_macro("TYPE_BOOL")
0048 // #include this header and/or all headers that need the macro to be undefined.
0049 // #pragma pop_macro("TYPE_BOOL")
0050 #undef TYPE_BOOL
0051 
0052 
0053 // Must be included last.
0054 #include "google/protobuf/port_def.inc"
0055 
0056 namespace google {
0057 namespace protobuf {
0058 namespace internal {
0059 
0060 // This class is for internal use by the protocol buffer library and by
0061 // protocol-compiler-generated message classes.  It must not be called
0062 // directly by clients.
0063 //
0064 // This class contains helpers for implementing the binary protocol buffer
0065 // wire format without the need for reflection. Use WireFormat when using
0066 // reflection.
0067 //
0068 // This class is really a namespace that contains only static methods.
0069 class PROTOBUF_EXPORT WireFormatLite {
0070  public:
0071   WireFormatLite() = delete;
0072   // -----------------------------------------------------------------
0073   // Helper constants and functions related to the format.  These are
0074   // mostly meant for internal and generated code to use.
0075 
0076   // The wire format is composed of a sequence of tag/value pairs, each
0077   // of which contains the value of one field (or one element of a repeated
0078   // field).  Each tag is encoded as a varint.  The lower bits of the tag
0079   // identify its wire type, which specifies the format of the data to follow.
0080   // The rest of the bits contain the field number.  Each type of field (as
0081   // declared by FieldDescriptor::Type, in descriptor.h) maps to one of
0082   // these wire types.  Immediately following each tag is the field's value,
0083   // encoded in the format specified by the wire type.  Because the tag
0084   // identifies the encoding of this data, it is possible to skip
0085   // unrecognized fields for forwards compatibility.
0086 
0087   enum WireType
0088 #ifndef SWIG
0089       : int
0090 #endif  // !SWIG
0091   {
0092     WIRETYPE_VARINT = 0,
0093     WIRETYPE_FIXED64 = 1,
0094     WIRETYPE_LENGTH_DELIMITED = 2,
0095     WIRETYPE_START_GROUP = 3,
0096     WIRETYPE_END_GROUP = 4,
0097     WIRETYPE_FIXED32 = 5,
0098   };
0099 
0100   // Lite alternative to FieldDescriptor::Type.  Must be kept in sync.
0101   enum FieldType {
0102     TYPE_DOUBLE = 1,
0103     TYPE_FLOAT = 2,
0104     TYPE_INT64 = 3,
0105     TYPE_UINT64 = 4,
0106     TYPE_INT32 = 5,
0107     TYPE_FIXED64 = 6,
0108     TYPE_FIXED32 = 7,
0109     TYPE_BOOL = 8,
0110     TYPE_STRING = 9,
0111     TYPE_GROUP = 10,
0112     TYPE_MESSAGE = 11,
0113     TYPE_BYTES = 12,
0114     TYPE_UINT32 = 13,
0115     TYPE_ENUM = 14,
0116     TYPE_SFIXED32 = 15,
0117     TYPE_SFIXED64 = 16,
0118     TYPE_SINT32 = 17,
0119     TYPE_SINT64 = 18,
0120     MAX_FIELD_TYPE = 18,
0121   };
0122 
0123   // Lite alternative to FieldDescriptor::CppType.  Must be kept in sync.
0124   enum CppType {
0125     CPPTYPE_INT32 = 1,
0126     CPPTYPE_INT64 = 2,
0127     CPPTYPE_UINT32 = 3,
0128     CPPTYPE_UINT64 = 4,
0129     CPPTYPE_DOUBLE = 5,
0130     CPPTYPE_FLOAT = 6,
0131     CPPTYPE_BOOL = 7,
0132     CPPTYPE_ENUM = 8,
0133     CPPTYPE_STRING = 9,
0134     CPPTYPE_MESSAGE = 10,
0135     MAX_CPPTYPE = 10,
0136   };
0137 
0138   template <typename T>
0139   static constexpr CppType CppTypeFor() {
0140     if constexpr (std::is_same_v<int32_t, T>) {
0141       return CPPTYPE_INT32;
0142     } else if constexpr (std::is_same_v<int64_t, T>) {
0143       return CPPTYPE_INT64;
0144     } else if constexpr (std::is_same_v<uint32_t, T>) {
0145       return CPPTYPE_UINT32;
0146     } else if constexpr (std::is_same_v<uint64_t, T>) {
0147       return CPPTYPE_UINT64;
0148     } else if constexpr (std::is_same_v<double, T>) {
0149       return CPPTYPE_DOUBLE;
0150     } else if constexpr (std::is_same_v<float, T>) {
0151       return CPPTYPE_FLOAT;
0152     } else if constexpr (std::is_same_v<bool, T>) {
0153       return CPPTYPE_BOOL;
0154     } else if constexpr (std::is_enum_v<T>) {
0155       return CPPTYPE_ENUM;
0156     } else if constexpr (std::is_base_of_v<MessageLite, T>) {
0157       return CPPTYPE_MESSAGE;
0158     } else if constexpr (std::is_same_v<std::string, T> ||
0159                          std::is_same_v<absl::string_view, T> ||
0160                          std::is_same_v<absl::Cord, T>) {
0161       return CPPTYPE_STRING;
0162     } else {
0163       // For repeated fields.
0164       return CppTypeFor<typename T::value_type>();
0165     }
0166   }
0167 
0168   // Helper method to get the CppType for a particular Type.
0169   static CppType FieldTypeToCppType(FieldType type);
0170 
0171   // Given a FieldDescriptor::Type return its WireType
0172   static inline WireFormatLite::WireType WireTypeForFieldType(
0173       WireFormatLite::FieldType type) {
0174     return kWireTypeForFieldType[type];
0175   }
0176 
0177   // Number of bits in a tag which identify the wire type.
0178   static constexpr int kTagTypeBits = 3;
0179   // Mask for those bits.
0180   static constexpr uint32_t kTagTypeMask = (1 << kTagTypeBits) - 1;
0181 
0182   // Helper functions for encoding and decoding tags.  (Inlined below and in
0183   // _inl.h)
0184   //
0185   // This is different from MakeTag(field->number(), field->type()) in the
0186   // case of packed repeated fields.
0187   constexpr static uint32_t MakeTag(int field_number, WireType type);
0188   static WireType GetTagWireType(uint32_t tag);
0189   static int GetTagFieldNumber(uint32_t tag);
0190 
0191   // Compute the byte size of a tag.  For groups, this includes both the start
0192   // and end tags.
0193   static inline size_t TagSize(int field_number,
0194                                WireFormatLite::FieldType type);
0195 
0196   // Skips a field value with the given tag.  The input should start
0197   // positioned immediately after the tag.  Skipped values are simply
0198   // discarded, not recorded anywhere.  See WireFormat::SkipField() for a
0199   // version that records to an UnknownFieldSet.
0200   static bool SkipField(io::CodedInputStream* input, uint32_t tag);
0201 
0202   // Skips a field value with the given tag.  The input should start
0203   // positioned immediately after the tag. Skipped values are recorded to a
0204   // CodedOutputStream.
0205   static bool SkipField(io::CodedInputStream* input, uint32_t tag,
0206                         io::CodedOutputStream* output);
0207 
0208   // Reads and ignores a message from the input.  Skipped values are simply
0209   // discarded, not recorded anywhere.  See WireFormat::SkipMessage() for a
0210   // version that records to an UnknownFieldSet.
0211   static bool SkipMessage(io::CodedInputStream* input);
0212 
0213   // Reads and ignores a message from the input.  Skipped values are recorded
0214   // to a CodedOutputStream.
0215   static bool SkipMessage(io::CodedInputStream* input,
0216                           io::CodedOutputStream* output);
0217 
0218   // This macro does the same thing as WireFormatLite::MakeTag(), but the
0219   // result is usable as a compile-time constant, which makes it usable
0220   // as a switch case or a template input.  WireFormatLite::MakeTag() is more
0221   // type-safe, though, so prefer it if possible.
0222 #define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
0223   static_cast<uint32_t>((static_cast<uint32_t>(FIELD_NUMBER) << 3) | (TYPE))
0224 
0225   // These are the tags for the old MessageSet format, which was defined as:
0226   //   message MessageSet {
0227   //     repeated group Item = 1 {
0228   //       required int32 type_id = 2;
0229   //       required string message = 3;
0230   //     }
0231   //   }
0232   static constexpr int kMessageSetItemNumber = 1;
0233   static constexpr int kMessageSetTypeIdNumber = 2;
0234   static constexpr int kMessageSetMessageNumber = 3;
0235   static const int kMessageSetItemStartTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
0236       kMessageSetItemNumber, WireFormatLite::WIRETYPE_START_GROUP);
0237   static const int kMessageSetItemEndTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
0238       kMessageSetItemNumber, WireFormatLite::WIRETYPE_END_GROUP);
0239   static const int kMessageSetTypeIdTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
0240       kMessageSetTypeIdNumber, WireFormatLite::WIRETYPE_VARINT);
0241   static const int kMessageSetMessageTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
0242       kMessageSetMessageNumber, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
0243 
0244   // Byte size of all tags of a MessageSet::Item combined.
0245   static const size_t kMessageSetItemTagsSize;
0246 
0247   // Helper functions for converting between floats/doubles and IEEE-754
0248   // uint32s/uint64s so that they can be written.  (Assumes your platform
0249   // uses IEEE-754 floats.)
0250   static uint32_t EncodeFloat(float value);
0251   static float DecodeFloat(uint32_t value);
0252   static uint64_t EncodeDouble(double value);
0253   static double DecodeDouble(uint64_t value);
0254 
0255   // Helper functions for mapping signed integers to unsigned integers in
0256   // such a way that numbers with small magnitudes will encode to smaller
0257   // varints.  If you simply static_cast a negative number to an unsigned
0258   // number and varint-encode it, it will always take 10 bytes, defeating
0259   // the purpose of varint.  So, for the "sint32" and "sint64" field types,
0260   // we ZigZag-encode the values.
0261   static uint32_t ZigZagEncode32(int32_t n);
0262   static int32_t ZigZagDecode32(uint32_t n);
0263   static uint64_t ZigZagEncode64(int64_t n);
0264   static int64_t ZigZagDecode64(uint64_t n);
0265 
0266   // =================================================================
0267   // Methods for reading/writing individual field.
0268 
0269   // Read fields, not including tags.  The assumption is that you already
0270   // read the tag to determine what field to read.
0271 
0272   // For primitive fields, we just use a templatized routine parameterized by
0273   // the represented type and the FieldType. These are specialized with the
0274   // appropriate definition for each declared type.
0275   template <typename CType, enum FieldType DeclaredType>
0276   PROTOBUF_NDEBUG_INLINE static bool ReadPrimitive(io::CodedInputStream* input,
0277                                                    CType* value);
0278 
0279   // Reads repeated primitive values, with optimizations for repeats.
0280   // tag_size and tag should both be compile-time constants provided by the
0281   // protocol compiler.
0282   template <typename CType, enum FieldType DeclaredType>
0283   PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedPrimitive(
0284       int tag_size, uint32_t tag, io::CodedInputStream* input,
0285       RepeatedField<CType>* value);
0286 
0287   // Reads a primitive value directly from the provided buffer. It returns a
0288   // pointer past the segment of data that was read.
0289   //
0290   // This is only implemented for the types with fixed wire size, e.g.
0291   // float, double, and the (s)fixed* types.
0292   template <typename CType, enum FieldType DeclaredType>
0293   PROTOBUF_NDEBUG_INLINE static const uint8_t* ReadPrimitiveFromArray(
0294       const uint8_t* buffer, CType* value);
0295 
0296   // Reads a primitive packed field.
0297   //
0298   // This is only implemented for packable types.
0299   template <typename CType, enum FieldType DeclaredType>
0300   PROTOBUF_NDEBUG_INLINE static bool ReadPackedPrimitive(
0301       io::CodedInputStream* input, RepeatedField<CType>* value);
0302 
0303   // Read a string.  ReadString(..., std::string* value) requires an
0304   // existing std::string.
0305   static inline bool ReadString(io::CodedInputStream* input,
0306                                 std::string* value);
0307   // Analogous to ReadString().
0308   static bool ReadBytes(io::CodedInputStream* input, std::string* value);
0309 
0310   static inline bool ReadBytes(io::CodedInputStream* input, absl::Cord* value);
0311 
0312   enum Operation {
0313     PARSE = 0,
0314     SERIALIZE = 1,
0315   };
0316 
0317   // Returns true if the data is valid UTF-8.
0318   static bool VerifyUtf8String(const char* data, int size, Operation op,
0319                                absl::string_view field_name);
0320 
0321   template <typename MessageType>
0322   static inline bool ReadGroup(int field_number, io::CodedInputStream* input,
0323                                MessageType* value);
0324 
0325   template <typename MessageType>
0326   static inline bool ReadMessage(io::CodedInputStream* input,
0327                                  MessageType* value);
0328 
0329   template <typename MessageType>
0330   static inline bool ReadMessageNoVirtual(io::CodedInputStream* input,
0331                                           MessageType* value) {
0332     return ReadMessage(input, value);
0333   }
0334 
0335   // Write a tag.  The Write*() functions typically include the tag, so
0336   // normally there's no need to call this unless using the Write*NoTag()
0337   // variants.
0338   PROTOBUF_NDEBUG_INLINE static void WriteTag(int field_number, WireType type,
0339                                               io::CodedOutputStream* output);
0340 
0341   // Write fields, without tags.
0342   PROTOBUF_NDEBUG_INLINE static void WriteInt32NoTag(
0343       int32_t value, io::CodedOutputStream* output);
0344   PROTOBUF_NDEBUG_INLINE static void WriteInt64NoTag(
0345       int64_t value, io::CodedOutputStream* output);
0346   PROTOBUF_NDEBUG_INLINE static void WriteUInt32NoTag(
0347       uint32_t value, io::CodedOutputStream* output);
0348   PROTOBUF_NDEBUG_INLINE static void WriteUInt64NoTag(
0349       uint64_t value, io::CodedOutputStream* output);
0350   PROTOBUF_NDEBUG_INLINE static void WriteSInt32NoTag(
0351       int32_t value, io::CodedOutputStream* output);
0352   PROTOBUF_NDEBUG_INLINE static void WriteSInt64NoTag(
0353       int64_t value, io::CodedOutputStream* output);
0354   PROTOBUF_NDEBUG_INLINE static void WriteFixed32NoTag(
0355       uint32_t value, io::CodedOutputStream* output);
0356   PROTOBUF_NDEBUG_INLINE static void WriteFixed64NoTag(
0357       uint64_t value, io::CodedOutputStream* output);
0358   PROTOBUF_NDEBUG_INLINE static void WriteSFixed32NoTag(
0359       int32_t value, io::CodedOutputStream* output);
0360   PROTOBUF_NDEBUG_INLINE static void WriteSFixed64NoTag(
0361       int64_t value, io::CodedOutputStream* output);
0362   PROTOBUF_NDEBUG_INLINE static void WriteFloatNoTag(
0363       float value, io::CodedOutputStream* output);
0364   PROTOBUF_NDEBUG_INLINE static void WriteDoubleNoTag(
0365       double value, io::CodedOutputStream* output);
0366   PROTOBUF_NDEBUG_INLINE static void WriteBoolNoTag(
0367       bool value, io::CodedOutputStream* output);
0368   PROTOBUF_NDEBUG_INLINE static void WriteEnumNoTag(
0369       int value, io::CodedOutputStream* output);
0370 
0371   // Write array of primitive fields, without tags
0372   static void WriteFloatArray(const float* a, int n,
0373                               io::CodedOutputStream* output);
0374   static void WriteDoubleArray(const double* a, int n,
0375                                io::CodedOutputStream* output);
0376   static void WriteFixed32Array(const uint32_t* a, int n,
0377                                 io::CodedOutputStream* output);
0378   static void WriteFixed64Array(const uint64_t* a, int n,
0379                                 io::CodedOutputStream* output);
0380   static void WriteSFixed32Array(const int32_t* a, int n,
0381                                  io::CodedOutputStream* output);
0382   static void WriteSFixed64Array(const int64_t* a, int n,
0383                                  io::CodedOutputStream* output);
0384   static void WriteBoolArray(const bool* a, int n,
0385                              io::CodedOutputStream* output);
0386 
0387   // Write fields, including tags.
0388   static void WriteInt32(int field_number, int32_t value,
0389                          io::CodedOutputStream* output);
0390   static void WriteInt64(int field_number, int64_t value,
0391                          io::CodedOutputStream* output);
0392   static void WriteUInt32(int field_number, uint32_t value,
0393                           io::CodedOutputStream* output);
0394   static void WriteUInt64(int field_number, uint64_t value,
0395                           io::CodedOutputStream* output);
0396   static void WriteSInt32(int field_number, int32_t value,
0397                           io::CodedOutputStream* output);
0398   static void WriteSInt64(int field_number, int64_t value,
0399                           io::CodedOutputStream* output);
0400   static void WriteFixed32(int field_number, uint32_t value,
0401                            io::CodedOutputStream* output);
0402   static void WriteFixed64(int field_number, uint64_t value,
0403                            io::CodedOutputStream* output);
0404   static void WriteSFixed32(int field_number, int32_t value,
0405                             io::CodedOutputStream* output);
0406   static void WriteSFixed64(int field_number, int64_t value,
0407                             io::CodedOutputStream* output);
0408   static void WriteFloat(int field_number, float value,
0409                          io::CodedOutputStream* output);
0410   static void WriteDouble(int field_number, double value,
0411                           io::CodedOutputStream* output);
0412   static void WriteBool(int field_number, bool value,
0413                         io::CodedOutputStream* output);
0414   static void WriteEnum(int field_number, int value,
0415                         io::CodedOutputStream* output);
0416 
0417   static void WriteString(int field_number, const std::string& value,
0418                           io::CodedOutputStream* output);
0419   static void WriteBytes(int field_number, const std::string& value,
0420                          io::CodedOutputStream* output);
0421   static void WriteStringMaybeAliased(int field_number,
0422                                       const std::string& value,
0423                                       io::CodedOutputStream* output);
0424   static void WriteBytesMaybeAliased(int field_number, const std::string& value,
0425                                      io::CodedOutputStream* output);
0426 
0427   static void WriteGroup(int field_number, const MessageLite& value,
0428                          io::CodedOutputStream* output);
0429   static void WriteMessage(int field_number, const MessageLite& value,
0430                            io::CodedOutputStream* output);
0431   // Like above, but these will check if the output stream has enough
0432   // space to write directly to a flat array.
0433   static void WriteGroupMaybeToArray(int field_number, const MessageLite& value,
0434                                      io::CodedOutputStream* output);
0435   static void WriteMessageMaybeToArray(int field_number,
0436                                        const MessageLite& value,
0437                                        io::CodedOutputStream* output);
0438 
0439   // Like above, but use only *ToArray methods of CodedOutputStream.
0440   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteTagToArray(int field_number,
0441                                                          WireType type,
0442                                                          uint8_t* target);
0443 
0444   // Write fields, without tags.
0445   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32NoTagToArray(
0446       int32_t value, uint8_t* target);
0447   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64NoTagToArray(
0448       int64_t value, uint8_t* target);
0449   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32NoTagToArray(
0450       uint32_t value, uint8_t* target);
0451   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64NoTagToArray(
0452       uint64_t value, uint8_t* target);
0453   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32NoTagToArray(
0454       int32_t value, uint8_t* target);
0455   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64NoTagToArray(
0456       int64_t value, uint8_t* target);
0457   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32NoTagToArray(
0458       uint32_t value, uint8_t* target);
0459   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64NoTagToArray(
0460       uint64_t value, uint8_t* target);
0461   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32NoTagToArray(
0462       int32_t value, uint8_t* target);
0463   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64NoTagToArray(
0464       int64_t value, uint8_t* target);
0465   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatNoTagToArray(
0466       float value, uint8_t* target);
0467   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleNoTagToArray(
0468       double value, uint8_t* target);
0469   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolNoTagToArray(bool value,
0470                                                                uint8_t* target);
0471   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumNoTagToArray(int value,
0472                                                                uint8_t* target);
0473 
0474   // Write fields, without tags.  These require that value.size() > 0.
0475   template <typename T>
0476   PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveNoTagToArray(
0477       const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
0478       uint8_t* target);
0479   template <typename T>
0480   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixedNoTagToArray(
0481       const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
0482       uint8_t* target);
0483 
0484   // Write fields, including tags.
0485   template <int field_number>
0486   PROTOBUF_NOINLINE static uint8_t* WriteInt32ToArrayWithField(
0487       ::google::protobuf::io::EpsCopyOutputStream* stream, int32_t value,
0488       uint8_t* target) {
0489     target = stream->EnsureSpace(target);
0490     return WriteInt32ToArray(field_number, value, target);
0491   }
0492 
0493   template <int field_number>
0494   PROTOBUF_NOINLINE static uint8_t* WriteInt64ToArrayWithField(
0495       ::google::protobuf::io::EpsCopyOutputStream* stream, int64_t value,
0496       uint8_t* target) {
0497     target = stream->EnsureSpace(target);
0498     return WriteInt64ToArray(field_number, value, target);
0499   }
0500 
0501   template <int field_number>
0502   PROTOBUF_NOINLINE static uint8_t* WriteEnumToArrayWithField(
0503       ::google::protobuf::io::EpsCopyOutputStream* stream, int value, uint8_t* target) {
0504     target = stream->EnsureSpace(target);
0505     return WriteEnumToArray(field_number, value, target);
0506   }
0507 
0508   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt32ToArray(int field_number,
0509                                                            int32_t value,
0510                                                            uint8_t* target);
0511   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteInt64ToArray(int field_number,
0512                                                            int64_t value,
0513                                                            uint8_t* target);
0514   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt32ToArray(int field_number,
0515                                                             uint32_t value,
0516                                                             uint8_t* target);
0517   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteUInt64ToArray(int field_number,
0518                                                             uint64_t value,
0519                                                             uint8_t* target);
0520   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt32ToArray(int field_number,
0521                                                             int32_t value,
0522                                                             uint8_t* target);
0523   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSInt64ToArray(int field_number,
0524                                                             int64_t value,
0525                                                             uint8_t* target);
0526   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed32ToArray(int field_number,
0527                                                              uint32_t value,
0528                                                              uint8_t* target);
0529   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFixed64ToArray(int field_number,
0530                                                              uint64_t value,
0531                                                              uint8_t* target);
0532   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed32ToArray(int field_number,
0533                                                               int32_t value,
0534                                                               uint8_t* target);
0535   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteSFixed64ToArray(int field_number,
0536                                                               int64_t value,
0537                                                               uint8_t* target);
0538   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteFloatToArray(int field_number,
0539                                                            float value,
0540                                                            uint8_t* target);
0541   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteDoubleToArray(int field_number,
0542                                                             double value,
0543                                                             uint8_t* target);
0544   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBoolToArray(int field_number,
0545                                                           bool value,
0546                                                           uint8_t* target);
0547   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteEnumToArray(int field_number,
0548                                                           int value,
0549                                                           uint8_t* target);
0550 
0551   template <typename T>
0552   PROTOBUF_NDEBUG_INLINE static uint8_t* WritePrimitiveToArray(
0553       int field_number, const RepeatedField<T>& value,
0554       uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target);
0555 
0556   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteStringToArray(
0557       int field_number, const std::string& value, uint8_t* target);
0558   PROTOBUF_NDEBUG_INLINE static uint8_t* WriteBytesToArray(
0559       int field_number, const std::string& value, uint8_t* target);
0560 
0561   // Whether to serialize deterministically (e.g., map keys are
0562   // sorted) is a property of a CodedOutputStream, and in the process
0563   // of serialization, the "ToArray" variants may be invoked.  But they don't
0564   // have a CodedOutputStream available, so they get an additional parameter
0565   // telling them whether to serialize deterministically.
0566   static uint8_t* InternalWriteGroup(int field_number, const MessageLite& value,
0567                                      uint8_t* target,
0568                                      io::EpsCopyOutputStream* stream);
0569   static uint8_t* InternalWriteMessage(int field_number,
0570                                        const MessageLite& value,
0571                                        int cached_size, uint8_t* target,
0572                                        io::EpsCopyOutputStream* stream);
0573 
0574   // Like above, but de-virtualize the call to SerializeWithCachedSizes().
0575   template <typename MessageType>
0576   PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteGroupNoVirtualToArray(
0577       int field_number, const MessageType& value, uint8_t* target);
0578   template <typename MessageType>
0579   PROTOBUF_NDEBUG_INLINE static uint8_t* InternalWriteMessageNoVirtualToArray(
0580       int field_number, const MessageType& value, uint8_t* target);
0581 
0582   // Compute the byte size of a field.  The XxSize() functions do NOT include
0583   // the tag, so you must also call TagSize().  (This is because, for repeated
0584   // fields, you should only call TagSize() once and multiply it by the element
0585   // count, but you may have to call XxSize() for each individual element.)
0586   static inline size_t Int32Size(int32_t value);
0587   static inline size_t Int64Size(int64_t value);
0588   static inline size_t UInt32Size(uint32_t value);
0589   static inline size_t UInt64Size(uint64_t value);
0590   static inline size_t SInt32Size(int32_t value);
0591   static inline size_t SInt64Size(int64_t value);
0592   static inline size_t EnumSize(int value);
0593   static inline size_t Int32SizePlusOne(int32_t value);
0594   static inline size_t Int64SizePlusOne(int64_t value);
0595   static inline size_t UInt32SizePlusOne(uint32_t value);
0596   static inline size_t UInt64SizePlusOne(uint64_t value);
0597   static inline size_t SInt32SizePlusOne(int32_t value);
0598   static inline size_t SInt64SizePlusOne(int64_t value);
0599   static inline size_t EnumSizePlusOne(int value);
0600 
0601   static size_t Int32Size(const RepeatedField<int32_t>& value);
0602   static size_t Int64Size(const RepeatedField<int64_t>& value);
0603   static size_t UInt32Size(const RepeatedField<uint32_t>& value);
0604   static size_t UInt64Size(const RepeatedField<uint64_t>& value);
0605   static size_t SInt32Size(const RepeatedField<int32_t>& value);
0606   static size_t SInt64Size(const RepeatedField<int64_t>& value);
0607   static size_t EnumSize(const RepeatedField<int>& value);
0608 
0609   static size_t Int32SizeWithPackedTagSize(
0610       const RepeatedField<int32_t>& value, size_t tag_size,
0611       const internal::CachedSize& cached_size);
0612   static size_t Int64SizeWithPackedTagSize(
0613       const RepeatedField<int64_t>& value, size_t tag_size,
0614       const internal::CachedSize& cached_size);
0615   static size_t UInt32SizeWithPackedTagSize(
0616       const RepeatedField<uint32_t>& value, size_t tag_size,
0617       const internal::CachedSize& cached_size);
0618   static size_t UInt64SizeWithPackedTagSize(
0619       const RepeatedField<uint64_t>& value, size_t tag_size,
0620       const internal::CachedSize& cached_size);
0621   static size_t SInt32SizeWithPackedTagSize(
0622       const RepeatedField<int32_t>& value, size_t tag_size,
0623       const internal::CachedSize& cached_size);
0624   static size_t SInt64SizeWithPackedTagSize(
0625       const RepeatedField<int64_t>& value, size_t tag_size,
0626       const internal::CachedSize& cached_size);
0627   static size_t EnumSizeWithPackedTagSize(
0628       const RepeatedField<int>& value, size_t tag_size,
0629       const internal::CachedSize& cached_size);
0630 
0631   // These types always have the same size.
0632   static constexpr size_t kFixed32Size = 4;
0633   static constexpr size_t kFixed64Size = 8;
0634   static constexpr size_t kSFixed32Size = 4;
0635   static constexpr size_t kSFixed64Size = 8;
0636   static constexpr size_t kFloatSize = 4;
0637   static constexpr size_t kDoubleSize = 8;
0638   static constexpr size_t kBoolSize = 1;
0639 
0640   static inline size_t StringSize(const std::string& value);
0641   static inline size_t StringSize(const absl::Cord& value);
0642   static inline size_t BytesSize(const std::string& value);
0643   static inline size_t BytesSize(const absl::Cord& value);
0644   static inline size_t StringSize(absl::string_view value);
0645   static inline size_t BytesSize(absl::string_view value);
0646 
0647   template <typename MessageType>
0648   static inline size_t GroupSize(const MessageType& value);
0649   template <typename MessageType>
0650   static inline size_t MessageSize(const MessageType& value);
0651 
0652   // Given the length of data, calculate the byte size of the data on the
0653   // wire if we encode the data as a length delimited field.
0654   static inline size_t LengthDelimitedSize(size_t length);
0655 
0656 
0657  private:
0658   // A helper method for the repeated primitive reader. This method has
0659   // optimizations for primitive types that have fixed size on the wire, and
0660   // can be read using potentially faster paths.
0661   template <typename CType, enum FieldType DeclaredType>
0662   PROTOBUF_NDEBUG_INLINE static bool ReadRepeatedFixedSizePrimitive(
0663       int tag_size, uint32_t tag, io::CodedInputStream* input,
0664       RepeatedField<CType>* value);
0665 
0666   // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
0667   template <typename CType, enum FieldType DeclaredType>
0668   PROTOBUF_NDEBUG_INLINE static bool ReadPackedFixedSizePrimitive(
0669       io::CodedInputStream* input, RepeatedField<CType>* value);
0670 
0671   static const CppType kFieldTypeToCppTypeMap[];
0672   static const WireFormatLite::WireType kWireTypeForFieldType[];
0673   static void WriteSubMessageMaybeToArray(int size, const MessageLite& value,
0674                                           io::CodedOutputStream* output);
0675 };
0676 
0677 // A class which deals with unknown values.  The default implementation just
0678 // discards them.  WireFormat defines a subclass which writes to an
0679 // UnknownFieldSet.  This class is used by ExtensionSet::ParseField(), since
0680 // ExtensionSet is part of the lite library but UnknownFieldSet is not.
0681 class PROTOBUF_EXPORT FieldSkipper {
0682  public:
0683   FieldSkipper() = default;
0684   virtual ~FieldSkipper() = default;
0685 
0686   // Skip a field whose tag has already been consumed.
0687   virtual bool SkipField(io::CodedInputStream* input, uint32_t tag);
0688 
0689   // Skip an entire message or group, up to an end-group tag (which is consumed)
0690   // or end-of-stream.
0691   virtual bool SkipMessage(io::CodedInputStream* input);
0692 
0693   // Deal with an already-parsed unrecognized enum value.  The default
0694   // implementation does nothing, but the UnknownFieldSet-based implementation
0695   // saves it as an unknown varint.
0696   virtual void SkipUnknownEnum(int field_number, int value);
0697 };
0698 
0699 // Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
0700 
0701 class PROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
0702  public:
0703   explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
0704       : unknown_fields_(unknown_fields) {}
0705   ~CodedOutputStreamFieldSkipper() override = default;
0706 
0707   // implements FieldSkipper -----------------------------------------
0708   bool SkipField(io::CodedInputStream* input, uint32_t tag) override;
0709   bool SkipMessage(io::CodedInputStream* input) override;
0710   void SkipUnknownEnum(int field_number, int value) override;
0711 
0712  protected:
0713   io::CodedOutputStream* unknown_fields_;
0714 };
0715 
0716 // inline methods ====================================================
0717 
0718 inline WireFormatLite::CppType WireFormatLite::FieldTypeToCppType(
0719     FieldType type) {
0720   return kFieldTypeToCppTypeMap[type];
0721 }
0722 
0723 constexpr inline uint32_t WireFormatLite::MakeTag(int field_number,
0724                                                   WireType type) {
0725   return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
0726 }
0727 
0728 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32_t tag) {
0729   return static_cast<WireType>(tag & kTagTypeMask);
0730 }
0731 
0732 inline int WireFormatLite::GetTagFieldNumber(uint32_t tag) {
0733   return static_cast<int>(tag >> kTagTypeBits);
0734 }
0735 
0736 inline size_t WireFormatLite::TagSize(int field_number,
0737                                       WireFormatLite::FieldType type) {
0738   size_t result = io::CodedOutputStream::VarintSize32(
0739       static_cast<uint32_t>(field_number << kTagTypeBits));
0740   if (type == TYPE_GROUP) {
0741     // Groups have both a start and an end tag.
0742     return result * 2;
0743   } else {
0744     return result;
0745   }
0746 }
0747 
0748 inline uint32_t WireFormatLite::EncodeFloat(float value) {
0749   return absl::bit_cast<uint32_t>(value);
0750 }
0751 
0752 inline float WireFormatLite::DecodeFloat(uint32_t value) {
0753   return absl::bit_cast<float>(value);
0754 }
0755 
0756 inline uint64_t WireFormatLite::EncodeDouble(double value) {
0757   return absl::bit_cast<uint64_t>(value);
0758 }
0759 
0760 inline double WireFormatLite::DecodeDouble(uint64_t value) {
0761   return absl::bit_cast<double>(value);
0762 }
0763 
0764 // ZigZag Transform:  Encodes signed integers so that they can be
0765 // effectively used with varint encoding.
0766 //
0767 // varint operates on unsigned integers, encoding smaller numbers into
0768 // fewer bytes.  If you try to use it on a signed integer, it will treat
0769 // this number as a very large unsigned integer, which means that even
0770 // small signed numbers like -1 will take the maximum number of bytes
0771 // (10) to encode.  ZigZagEncode() maps signed integers to unsigned
0772 // in such a way that those with a small absolute value will have smaller
0773 // encoded values, making them appropriate for encoding using varint.
0774 //
0775 //       int32_t ->     uint32_t
0776 // -------------------------
0777 //           0 ->          0
0778 //          -1 ->          1
0779 //           1 ->          2
0780 //          -2 ->          3
0781 //         ... ->        ...
0782 //  2147483647 -> 4294967294
0783 // -2147483648 -> 4294967295
0784 //
0785 //        >> encode >>
0786 //        << decode <<
0787 
0788 inline uint32_t WireFormatLite::ZigZagEncode32(int32_t n) {
0789   // Note:  the right-shift must be arithmetic
0790   // Note:  left shift must be unsigned because of overflow
0791   return (static_cast<uint32_t>(n) << 1) ^ static_cast<uint32_t>(n >> 31);
0792 }
0793 
0794 inline int32_t WireFormatLite::ZigZagDecode32(uint32_t n) {
0795   // Note:  Using unsigned types prevent undefined behavior
0796   return static_cast<int32_t>((n >> 1) ^ (~(n & 1) + 1));
0797 }
0798 
0799 inline uint64_t WireFormatLite::ZigZagEncode64(int64_t n) {
0800   // Note:  the right-shift must be arithmetic
0801   // Note:  left shift must be unsigned because of overflow
0802   return (static_cast<uint64_t>(n) << 1) ^ static_cast<uint64_t>(n >> 63);
0803 }
0804 
0805 inline int64_t WireFormatLite::ZigZagDecode64(uint64_t n) {
0806   // Note:  Using unsigned types prevent undefined behavior
0807   return static_cast<int64_t>((n >> 1) ^ (~(n & 1) + 1));
0808 }
0809 
0810 // String is for UTF-8 text only, but, even so, ReadString() can simply
0811 // call ReadBytes().
0812 
0813 inline bool WireFormatLite::ReadString(io::CodedInputStream* input,
0814                                        std::string* value) {
0815   return ReadBytes(input, value);
0816 }
0817 
0818 inline uint8_t* InternalSerializeUnknownMessageSetItemsToArray(
0819     const std::string& unknown_fields, uint8_t* target,
0820     io::EpsCopyOutputStream* stream) {
0821   return stream->WriteRaw(unknown_fields.data(),
0822                           static_cast<int>(unknown_fields.size()), target);
0823 }
0824 
0825 inline size_t ComputeUnknownMessageSetItemsSize(
0826     const std::string& unknown_fields) {
0827   return unknown_fields.size();
0828 }
0829 
0830 // Implementation details of ReadPrimitive.
0831 
0832 template <>
0833 inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>(
0834     io::CodedInputStream* input, int32_t* value) {
0835   uint32_t temp;
0836   if (!input->ReadVarint32(&temp)) return false;
0837   *value = static_cast<int32_t>(temp);
0838   return true;
0839 }
0840 template <>
0841 inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_INT64>(
0842     io::CodedInputStream* input, int64_t* value) {
0843   uint64_t temp;
0844   if (!input->ReadVarint64(&temp)) return false;
0845   *value = static_cast<int64_t>(temp);
0846   return true;
0847 }
0848 template <>
0849 inline bool
0850 WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_UINT32>(
0851     io::CodedInputStream* input, uint32_t* value) {
0852   return input->ReadVarint32(value);
0853 }
0854 template <>
0855 inline bool
0856 WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_UINT64>(
0857     io::CodedInputStream* input, uint64_t* value) {
0858   return input->ReadVarint64(value);
0859 }
0860 template <>
0861 inline bool WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SINT32>(
0862     io::CodedInputStream* input, int32_t* value) {
0863   uint32_t temp;
0864   if (!input->ReadVarint32(&temp)) return false;
0865   *value = ZigZagDecode32(temp);
0866   return true;
0867 }
0868 template <>
0869 inline bool WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SINT64>(
0870     io::CodedInputStream* input, int64_t* value) {
0871   uint64_t temp;
0872   if (!input->ReadVarint64(&temp)) return false;
0873   *value = ZigZagDecode64(temp);
0874   return true;
0875 }
0876 template <>
0877 inline bool
0878 WireFormatLite::ReadPrimitive<uint32_t, WireFormatLite::TYPE_FIXED32>(
0879     io::CodedInputStream* input, uint32_t* value) {
0880   return input->ReadLittleEndian32(value);
0881 }
0882 template <>
0883 inline bool
0884 WireFormatLite::ReadPrimitive<uint64_t, WireFormatLite::TYPE_FIXED64>(
0885     io::CodedInputStream* input, uint64_t* value) {
0886   return input->ReadLittleEndian64(value);
0887 }
0888 template <>
0889 inline bool
0890 WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_SFIXED32>(
0891     io::CodedInputStream* input, int32_t* value) {
0892   uint32_t temp;
0893   if (!input->ReadLittleEndian32(&temp)) return false;
0894   *value = static_cast<int32_t>(temp);
0895   return true;
0896 }
0897 template <>
0898 inline bool
0899 WireFormatLite::ReadPrimitive<int64_t, WireFormatLite::TYPE_SFIXED64>(
0900     io::CodedInputStream* input, int64_t* value) {
0901   uint64_t temp;
0902   if (!input->ReadLittleEndian64(&temp)) return false;
0903   *value = static_cast<int64_t>(temp);
0904   return true;
0905 }
0906 template <>
0907 inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
0908     io::CodedInputStream* input, float* value) {
0909   uint32_t temp;
0910   if (!input->ReadLittleEndian32(&temp)) return false;
0911   *value = DecodeFloat(temp);
0912   return true;
0913 }
0914 template <>
0915 inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
0916     io::CodedInputStream* input, double* value) {
0917   uint64_t temp;
0918   if (!input->ReadLittleEndian64(&temp)) return false;
0919   *value = DecodeDouble(temp);
0920   return true;
0921 }
0922 template <>
0923 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
0924     io::CodedInputStream* input, bool* value) {
0925   uint64_t temp;
0926   if (!input->ReadVarint64(&temp)) return false;
0927   *value = temp != 0;
0928   return true;
0929 }
0930 template <>
0931 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
0932     io::CodedInputStream* input, int* value) {
0933   uint32_t temp;
0934   if (!input->ReadVarint32(&temp)) return false;
0935   *value = static_cast<int>(temp);
0936   return true;
0937 }
0938 
0939 template <>
0940 inline const uint8_t*
0941 WireFormatLite::ReadPrimitiveFromArray<uint32_t, WireFormatLite::TYPE_FIXED32>(
0942     const uint8_t* buffer, uint32_t* value) {
0943   return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
0944 }
0945 template <>
0946 inline const uint8_t*
0947 WireFormatLite::ReadPrimitiveFromArray<uint64_t, WireFormatLite::TYPE_FIXED64>(
0948     const uint8_t* buffer, uint64_t* value) {
0949   return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
0950 }
0951 template <>
0952 inline const uint8_t*
0953 WireFormatLite::ReadPrimitiveFromArray<int32_t, WireFormatLite::TYPE_SFIXED32>(
0954     const uint8_t* buffer, int32_t* value) {
0955   uint32_t temp;
0956   buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
0957   *value = static_cast<int32_t>(temp);
0958   return buffer;
0959 }
0960 template <>
0961 inline const uint8_t*
0962 WireFormatLite::ReadPrimitiveFromArray<int64_t, WireFormatLite::TYPE_SFIXED64>(
0963     const uint8_t* buffer, int64_t* value) {
0964   uint64_t temp;
0965   buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
0966   *value = static_cast<int64_t>(temp);
0967   return buffer;
0968 }
0969 template <>
0970 inline const uint8_t*
0971 WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>(
0972     const uint8_t* buffer, float* value) {
0973   uint32_t temp;
0974   buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
0975   *value = DecodeFloat(temp);
0976   return buffer;
0977 }
0978 template <>
0979 inline const uint8_t*
0980 WireFormatLite::ReadPrimitiveFromArray<double, WireFormatLite::TYPE_DOUBLE>(
0981     const uint8_t* buffer, double* value) {
0982   uint64_t temp;
0983   buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
0984   *value = DecodeDouble(temp);
0985   return buffer;
0986 }
0987 
0988 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
0989 inline bool WireFormatLite::ReadRepeatedPrimitive(
0990     int,  // tag_size, unused.
0991     uint32_t tag, io::CodedInputStream* input, RepeatedField<CType>* values) {
0992   CType value;
0993   if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
0994   values->Add(value);
0995   int elements_already_reserved = values->Capacity() - values->size();
0996   while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
0997     if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
0998     values->AddAlreadyReserved(value);
0999     elements_already_reserved--;
1000   }
1001   return true;
1002 }
1003 
1004 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1005 inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
1006     int tag_size, uint32_t tag, io::CodedInputStream* input,
1007     RepeatedField<CType>* values) {
1008   ABSL_DCHECK_EQ(UInt32Size(tag), static_cast<size_t>(tag_size));
1009   CType value;
1010   if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1011   values->Add(value);
1012 
1013   // For fixed size values, repeated values can be read more quickly by
1014   // reading directly from a raw array.
1015   //
1016   // We can get a tight loop by only reading as many elements as can be
1017   // added to the RepeatedField without having to do any resizing. Additionally,
1018   // we only try to read as many elements as are available from the current
1019   // buffer space. Doing so avoids having to perform boundary checks when
1020   // reading the value: the maximum number of elements that can be read is
1021   // known outside of the loop.
1022   const void* void_pointer;
1023   int size;
1024   input->GetDirectBufferPointerInline(&void_pointer, &size);
1025   if (size > 0) {
1026     const uint8_t* buffer = reinterpret_cast<const uint8_t*>(void_pointer);
1027     // The number of bytes each type occupies on the wire.
1028     const int per_value_size = tag_size + static_cast<int>(sizeof(value));
1029 
1030     // parentheses around (std::min) prevents macro expansion of min(...)
1031     int elements_available =
1032         (std::min)(values->Capacity() - values->size(), size / per_value_size);
1033     int num_read = 0;
1034     while (num_read < elements_available &&
1035            (buffer = io::CodedInputStream::ExpectTagFromArray(buffer, tag)) !=
1036                nullptr) {
1037       buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
1038       values->AddAlreadyReserved(value);
1039       ++num_read;
1040     }
1041     const int read_bytes = num_read * per_value_size;
1042     if (read_bytes > 0) {
1043       input->Skip(read_bytes);
1044     }
1045   }
1046   return true;
1047 }
1048 
1049 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use
1050 // the optimized code path.
1051 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)        \
1052   template <>                                                             \
1053   inline bool WireFormatLite::ReadRepeatedPrimitive<                      \
1054       CPPTYPE, WireFormatLite::DECLARED_TYPE>(                            \
1055       int tag_size, uint32_t tag, io::CodedInputStream* input,            \
1056       RepeatedField<CPPTYPE>* values) {                                   \
1057     return ReadRepeatedFixedSizePrimitive<CPPTYPE,                        \
1058                                           WireFormatLite::DECLARED_TYPE>( \
1059         tag_size, tag, input, values);                                    \
1060   }
1061 
1062 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32)
1063 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64)
1064 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32)
1065 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64_t, TYPE_SFIXED64)
1066 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
1067 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
1068 
1069 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
1070 
1071 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1072 inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
1073                                                 RepeatedField<CType>* values) {
1074   int length;
1075   if (!input->ReadVarintSizeAsInt(&length)) return false;
1076   io::CodedInputStream::Limit limit = input->PushLimit(length);
1077   while (input->BytesUntilLimit() > 0) {
1078     CType value;
1079     if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1080     values->Add(value);
1081   }
1082   input->PopLimit(limit);
1083   return true;
1084 }
1085 
1086 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1087 inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
1088     io::CodedInputStream* input, RepeatedField<CType>* values) {
1089   int length;
1090   if (!input->ReadVarintSizeAsInt(&length)) return false;
1091   const int old_entries = values->size();
1092   const int new_entries = length / static_cast<int>(sizeof(CType));
1093   const int new_bytes = new_entries * static_cast<int>(sizeof(CType));
1094   if (new_bytes != length) return false;
1095   // We would *like* to pre-allocate the buffer to write into (for
1096   // speed), but *must* avoid performing a very large allocation due
1097   // to a malicious user-supplied "length" above.  So we have a fast
1098   // path that pre-allocates when the "length" is less than a bound.
1099   // We determine the bound by calling BytesUntilTotalBytesLimit() and
1100   // BytesUntilLimit().  These return -1 to mean "no limit set".
1101   // There are four cases:
1102   // TotalBytesLimit  Limit
1103   // -1               -1     Use slow path.
1104   // -1               >= 0   Use fast path if length <= Limit.
1105   // >= 0             -1     Use slow path.
1106   // >= 0             >= 0   Use fast path if length <= min(both limits).
1107   int64_t bytes_limit = input->BytesUntilTotalBytesLimit();
1108   if (bytes_limit == -1) {
1109     bytes_limit = input->BytesUntilLimit();
1110   } else {
1111     // parentheses around (std::min) prevents macro expansion of min(...)
1112     bytes_limit =
1113         (std::min)(bytes_limit, static_cast<int64_t>(input->BytesUntilLimit()));
1114   }
1115   if (bytes_limit >= new_bytes) {
1116     // Fast-path that pre-allocates *values to the final size.
1117 #if defined(ABSL_IS_LITTLE_ENDIAN)
1118     values->Resize(old_entries + new_entries, 0);
1119     // values->mutable_data() may change after Resize(), so do this after:
1120     void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
1121     if (!input->ReadRaw(dest, new_bytes)) {
1122       values->Truncate(old_entries);
1123       return false;
1124     }
1125 #else
1126     values->Reserve(old_entries + new_entries);
1127     CType value;
1128     for (int i = 0; i < new_entries; ++i) {
1129       if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1130       values->AddAlreadyReserved(value);
1131     }
1132 #endif
1133   } else {
1134     // This is the slow-path case where "length" may be too large to
1135     // safely allocate.  We read as much as we can into *values
1136     // without pre-allocating "length" bytes.
1137     CType value;
1138     for (int i = 0; i < new_entries; ++i) {
1139       if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1140       values->Add(value);
1141     }
1142   }
1143   return true;
1144 }
1145 
1146 // Specializations of ReadPackedPrimitive for the fixed size types, which use
1147 // an optimized code path.
1148 #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)      \
1149   template <>                                                                  \
1150   inline bool                                                                  \
1151   WireFormatLite::ReadPackedPrimitive<CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
1152       io::CodedInputStream * input, RepeatedField<CPPTYPE> * values) {         \
1153     return ReadPackedFixedSizePrimitive<CPPTYPE,                               \
1154                                         WireFormatLite::DECLARED_TYPE>(        \
1155         input, values);                                                        \
1156   }
1157 
1158 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32_t, TYPE_FIXED32)
1159 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64_t, TYPE_FIXED64)
1160 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32_t, TYPE_SFIXED32)
1161 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64_t, TYPE_SFIXED64)
1162 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
1163 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
1164 
1165 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
1166 
1167 inline bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
1168                                       absl::Cord* value) {
1169   int length;
1170   return input->ReadVarintSizeAsInt(&length) && input->ReadCord(value, length);
1171 }
1172 
1173 
1174 template <typename MessageType>
1175 inline bool WireFormatLite::ReadGroup(int field_number,
1176                                       io::CodedInputStream* input,
1177                                       MessageType* value) {
1178   if (!input->IncrementRecursionDepth()) return false;
1179   if (!value->MergePartialFromCodedStream(input)) return false;
1180   input->UnsafeDecrementRecursionDepth();
1181   // Make sure the last thing read was an end tag for this group.
1182   if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
1183     return false;
1184   }
1185   return true;
1186 }
1187 template <typename MessageType>
1188 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
1189                                         MessageType* value) {
1190   int length;
1191   if (!input->ReadVarintSizeAsInt(&length)) return false;
1192   std::pair<io::CodedInputStream::Limit, int> p =
1193       input->IncrementRecursionDepthAndPushLimit(length);
1194   if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
1195   // Make sure that parsing stopped when the limit was hit, not at an endgroup
1196   // tag.
1197   return input->DecrementRecursionDepthAndPopLimit(p.first);
1198 }
1199 
1200 // ===================================================================
1201 
1202 inline void WireFormatLite::WriteTag(int field_number, WireType type,
1203                                      io::CodedOutputStream* output) {
1204   output->WriteTag(MakeTag(field_number, type));
1205 }
1206 
1207 inline void WireFormatLite::WriteInt32NoTag(int32_t value,
1208                                             io::CodedOutputStream* output) {
1209   output->WriteVarint32SignExtended(value);
1210 }
1211 inline void WireFormatLite::WriteInt64NoTag(int64_t value,
1212                                             io::CodedOutputStream* output) {
1213   output->WriteVarint64(static_cast<uint64_t>(value));
1214 }
1215 inline void WireFormatLite::WriteUInt32NoTag(uint32_t value,
1216                                              io::CodedOutputStream* output) {
1217   output->WriteVarint32(value);
1218 }
1219 inline void WireFormatLite::WriteUInt64NoTag(uint64_t value,
1220                                              io::CodedOutputStream* output) {
1221   output->WriteVarint64(value);
1222 }
1223 inline void WireFormatLite::WriteSInt32NoTag(int32_t value,
1224                                              io::CodedOutputStream* output) {
1225   output->WriteVarint32(ZigZagEncode32(value));
1226 }
1227 inline void WireFormatLite::WriteSInt64NoTag(int64_t value,
1228                                              io::CodedOutputStream* output) {
1229   output->WriteVarint64(ZigZagEncode64(value));
1230 }
1231 inline void WireFormatLite::WriteFixed32NoTag(uint32_t value,
1232                                               io::CodedOutputStream* output) {
1233   output->WriteLittleEndian32(value);
1234 }
1235 inline void WireFormatLite::WriteFixed64NoTag(uint64_t value,
1236                                               io::CodedOutputStream* output) {
1237   output->WriteLittleEndian64(value);
1238 }
1239 inline void WireFormatLite::WriteSFixed32NoTag(int32_t value,
1240                                                io::CodedOutputStream* output) {
1241   output->WriteLittleEndian32(static_cast<uint32_t>(value));
1242 }
1243 inline void WireFormatLite::WriteSFixed64NoTag(int64_t value,
1244                                                io::CodedOutputStream* output) {
1245   output->WriteLittleEndian64(static_cast<uint64_t>(value));
1246 }
1247 inline void WireFormatLite::WriteFloatNoTag(float value,
1248                                             io::CodedOutputStream* output) {
1249   output->WriteLittleEndian32(EncodeFloat(value));
1250 }
1251 inline void WireFormatLite::WriteDoubleNoTag(double value,
1252                                              io::CodedOutputStream* output) {
1253   output->WriteLittleEndian64(EncodeDouble(value));
1254 }
1255 inline void WireFormatLite::WriteBoolNoTag(bool value,
1256                                            io::CodedOutputStream* output) {
1257   output->WriteVarint32(value ? 1 : 0);
1258 }
1259 inline void WireFormatLite::WriteEnumNoTag(int value,
1260                                            io::CodedOutputStream* output) {
1261   output->WriteVarint32SignExtended(value);
1262 }
1263 
1264 // ===================================================================
1265 
1266 inline uint8_t* WireFormatLite::WriteTagToArray(int field_number, WireType type,
1267                                                 uint8_t* target) {
1268   return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
1269                                                 target);
1270 }
1271 
1272 inline uint8_t* WireFormatLite::WriteInt32NoTagToArray(int32_t value,
1273                                                        uint8_t* target) {
1274   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
1275 }
1276 inline uint8_t* WireFormatLite::WriteInt64NoTagToArray(int64_t value,
1277                                                        uint8_t* target) {
1278   return io::CodedOutputStream::WriteVarint64ToArray(
1279       static_cast<uint64_t>(value), target);
1280 }
1281 inline uint8_t* WireFormatLite::WriteUInt32NoTagToArray(uint32_t value,
1282                                                         uint8_t* target) {
1283   return io::CodedOutputStream::WriteVarint32ToArray(value, target);
1284 }
1285 inline uint8_t* WireFormatLite::WriteUInt64NoTagToArray(uint64_t value,
1286                                                         uint8_t* target) {
1287   return io::CodedOutputStream::WriteVarint64ToArray(value, target);
1288 }
1289 inline uint8_t* WireFormatLite::WriteSInt32NoTagToArray(int32_t value,
1290                                                         uint8_t* target) {
1291   return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
1292                                                      target);
1293 }
1294 inline uint8_t* WireFormatLite::WriteSInt64NoTagToArray(int64_t value,
1295                                                         uint8_t* target) {
1296   return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
1297                                                      target);
1298 }
1299 inline uint8_t* WireFormatLite::WriteFixed32NoTagToArray(uint32_t value,
1300                                                          uint8_t* target) {
1301   return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
1302 }
1303 inline uint8_t* WireFormatLite::WriteFixed64NoTagToArray(uint64_t value,
1304                                                          uint8_t* target) {
1305   return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
1306 }
1307 inline uint8_t* WireFormatLite::WriteSFixed32NoTagToArray(int32_t value,
1308                                                           uint8_t* target) {
1309   return io::CodedOutputStream::WriteLittleEndian32ToArray(
1310       static_cast<uint32_t>(value), target);
1311 }
1312 inline uint8_t* WireFormatLite::WriteSFixed64NoTagToArray(int64_t value,
1313                                                           uint8_t* target) {
1314   return io::CodedOutputStream::WriteLittleEndian64ToArray(
1315       static_cast<uint64_t>(value), target);
1316 }
1317 inline uint8_t* WireFormatLite::WriteFloatNoTagToArray(float value,
1318                                                        uint8_t* target) {
1319   return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
1320                                                            target);
1321 }
1322 inline uint8_t* WireFormatLite::WriteDoubleNoTagToArray(double value,
1323                                                         uint8_t* target) {
1324   return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
1325                                                            target);
1326 }
1327 inline uint8_t* WireFormatLite::WriteBoolNoTagToArray(bool value,
1328                                                       uint8_t* target) {
1329   return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
1330 }
1331 inline uint8_t* WireFormatLite::WriteEnumNoTagToArray(int value,
1332                                                       uint8_t* target) {
1333   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
1334 }
1335 
1336 template <typename T>
1337 inline uint8_t* WireFormatLite::WritePrimitiveNoTagToArray(
1338     const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
1339     uint8_t* target) {
1340   const int n = value.size();
1341   ABSL_DCHECK_GT(n, 0);
1342 
1343   const T* ii = value.data();
1344   int i = 0;
1345   do {
1346     target = Writer(ii[i], target);
1347   } while (++i < n);
1348 
1349   return target;
1350 }
1351 
1352 template <typename T>
1353 inline uint8_t* WireFormatLite::WriteFixedNoTagToArray(
1354     const RepeatedField<T>& value, uint8_t* (*Writer)(T, uint8_t*),
1355     uint8_t* target) {
1356 #if defined(ABSL_IS_LITTLE_ENDIAN)
1357   (void)Writer;
1358 
1359   const int n = value.size();
1360   ABSL_DCHECK_GT(n, 0);
1361 
1362   const T* ii = value.data();
1363   const int bytes = n * static_cast<int>(sizeof(ii[0]));
1364   memcpy(target, ii, static_cast<size_t>(bytes));
1365   return target + bytes;
1366 #else
1367   return WritePrimitiveNoTagToArray(value, Writer, target);
1368 #endif
1369 }
1370 
1371 inline uint8_t* WireFormatLite::WriteInt32ToArray(int field_number,
1372                                                   int32_t value,
1373                                                   uint8_t* target) {
1374   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1375   return WriteInt32NoTagToArray(value, target);
1376 }
1377 inline uint8_t* WireFormatLite::WriteInt64ToArray(int field_number,
1378                                                   int64_t value,
1379                                                   uint8_t* target) {
1380   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1381   return WriteInt64NoTagToArray(value, target);
1382 }
1383 inline uint8_t* WireFormatLite::WriteUInt32ToArray(int field_number,
1384                                                    uint32_t value,
1385                                                    uint8_t* target) {
1386   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1387   return WriteUInt32NoTagToArray(value, target);
1388 }
1389 inline uint8_t* WireFormatLite::WriteUInt64ToArray(int field_number,
1390                                                    uint64_t value,
1391                                                    uint8_t* target) {
1392   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1393   return WriteUInt64NoTagToArray(value, target);
1394 }
1395 inline uint8_t* WireFormatLite::WriteSInt32ToArray(int field_number,
1396                                                    int32_t value,
1397                                                    uint8_t* target) {
1398   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1399   return WriteSInt32NoTagToArray(value, target);
1400 }
1401 inline uint8_t* WireFormatLite::WriteSInt64ToArray(int field_number,
1402                                                    int64_t value,
1403                                                    uint8_t* target) {
1404   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1405   return WriteSInt64NoTagToArray(value, target);
1406 }
1407 inline uint8_t* WireFormatLite::WriteFixed32ToArray(int field_number,
1408                                                     uint32_t value,
1409                                                     uint8_t* target) {
1410   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1411   return WriteFixed32NoTagToArray(value, target);
1412 }
1413 inline uint8_t* WireFormatLite::WriteFixed64ToArray(int field_number,
1414                                                     uint64_t value,
1415                                                     uint8_t* target) {
1416   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1417   return WriteFixed64NoTagToArray(value, target);
1418 }
1419 inline uint8_t* WireFormatLite::WriteSFixed32ToArray(int field_number,
1420                                                      int32_t value,
1421                                                      uint8_t* target) {
1422   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1423   return WriteSFixed32NoTagToArray(value, target);
1424 }
1425 inline uint8_t* WireFormatLite::WriteSFixed64ToArray(int field_number,
1426                                                      int64_t value,
1427                                                      uint8_t* target) {
1428   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1429   return WriteSFixed64NoTagToArray(value, target);
1430 }
1431 inline uint8_t* WireFormatLite::WriteFloatToArray(int field_number, float value,
1432                                                   uint8_t* target) {
1433   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1434   return WriteFloatNoTagToArray(value, target);
1435 }
1436 inline uint8_t* WireFormatLite::WriteDoubleToArray(int field_number,
1437                                                    double value,
1438                                                    uint8_t* target) {
1439   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1440   return WriteDoubleNoTagToArray(value, target);
1441 }
1442 inline uint8_t* WireFormatLite::WriteBoolToArray(int field_number, bool value,
1443                                                  uint8_t* target) {
1444   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1445   return WriteBoolNoTagToArray(value, target);
1446 }
1447 inline uint8_t* WireFormatLite::WriteEnumToArray(int field_number, int value,
1448                                                  uint8_t* target) {
1449   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1450   return WriteEnumNoTagToArray(value, target);
1451 }
1452 
1453 template <typename T>
1454 inline uint8_t* WireFormatLite::WritePrimitiveToArray(
1455     int field_number, const RepeatedField<T>& value,
1456     uint8_t* (*Writer)(int, T, uint8_t*), uint8_t* target) {
1457   const int n = value.size();
1458   if (n == 0) {
1459     return target;
1460   }
1461 
1462   const T* ii = value.data();
1463   int i = 0;
1464   do {
1465     target = Writer(field_number, ii[i], target);
1466   } while (++i < n);
1467 
1468   return target;
1469 }
1470 
1471 inline uint8_t* WireFormatLite::WriteStringToArray(int field_number,
1472                                                    const std::string& value,
1473                                                    uint8_t* target) {
1474   // String is for UTF-8 text only
1475   // WARNING:  In wire_format.cc, both strings and bytes are handled by
1476   //   WriteString() to avoid code duplication.  If the implementations become
1477   //   different, you will need to update that usage.
1478   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1479   return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
1480 }
1481 inline uint8_t* WireFormatLite::WriteBytesToArray(int field_number,
1482                                                   const std::string& value,
1483                                                   uint8_t* target) {
1484   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1485   return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
1486 }
1487 
1488 
1489 // See comment on ReadGroupNoVirtual to understand the need for this template
1490 // parameter name.
1491 template <typename MessageType_WorkAroundCppLookupDefect>
1492 inline uint8_t* WireFormatLite::InternalWriteGroupNoVirtualToArray(
1493     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1494     uint8_t* target) {
1495   target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
1496   target = value.MessageType_WorkAroundCppLookupDefect::
1497                SerializeWithCachedSizesToArray(target);
1498   return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
1499 }
1500 template <typename MessageType_WorkAroundCppLookupDefect>
1501 inline uint8_t* WireFormatLite::InternalWriteMessageNoVirtualToArray(
1502     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1503     uint8_t* target) {
1504   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1505   target = io::CodedOutputStream::WriteVarint32ToArray(
1506       static_cast<uint32_t>(
1507           value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()),
1508       target);
1509   return value
1510       .MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizesToArray(
1511           target);
1512 }
1513 
1514 // ===================================================================
1515 
1516 inline size_t WireFormatLite::Int32Size(int32_t value) {
1517   return io::CodedOutputStream::VarintSize32SignExtended(value);
1518 }
1519 inline size_t WireFormatLite::Int64Size(int64_t value) {
1520   return io::CodedOutputStream::VarintSize64(static_cast<uint64_t>(value));
1521 }
1522 inline size_t WireFormatLite::UInt32Size(uint32_t value) {
1523   return io::CodedOutputStream::VarintSize32(value);
1524 }
1525 inline size_t WireFormatLite::UInt64Size(uint64_t value) {
1526   return io::CodedOutputStream::VarintSize64(value);
1527 }
1528 inline size_t WireFormatLite::SInt32Size(int32_t value) {
1529   return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
1530 }
1531 inline size_t WireFormatLite::SInt64Size(int64_t value) {
1532   return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
1533 }
1534 inline size_t WireFormatLite::EnumSize(int value) {
1535   return io::CodedOutputStream::VarintSize32SignExtended(value);
1536 }
1537 inline size_t WireFormatLite::Int32SizePlusOne(int32_t value) {
1538   return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value);
1539 }
1540 inline size_t WireFormatLite::Int64SizePlusOne(int64_t value) {
1541   return io::CodedOutputStream::VarintSize64PlusOne(
1542       static_cast<uint64_t>(value));
1543 }
1544 inline size_t WireFormatLite::UInt32SizePlusOne(uint32_t value) {
1545   return io::CodedOutputStream::VarintSize32PlusOne(value);
1546 }
1547 inline size_t WireFormatLite::UInt64SizePlusOne(uint64_t value) {
1548   return io::CodedOutputStream::VarintSize64PlusOne(value);
1549 }
1550 inline size_t WireFormatLite::SInt32SizePlusOne(int32_t value) {
1551   return io::CodedOutputStream::VarintSize32PlusOne(ZigZagEncode32(value));
1552 }
1553 inline size_t WireFormatLite::SInt64SizePlusOne(int64_t value) {
1554   return io::CodedOutputStream::VarintSize64PlusOne(ZigZagEncode64(value));
1555 }
1556 inline size_t WireFormatLite::EnumSizePlusOne(int value) {
1557   return io::CodedOutputStream::VarintSize32SignExtendedPlusOne(value);
1558 }
1559 
1560 inline size_t WireFormatLite::StringSize(const std::string& value) {
1561   return LengthDelimitedSize(value.size());
1562 }
1563 inline size_t WireFormatLite::BytesSize(const std::string& value) {
1564   return StringSize(value);
1565 }
1566 
1567 inline size_t WireFormatLite::BytesSize(const absl::Cord& value) {
1568   return LengthDelimitedSize(value.size());
1569 }
1570 
1571 inline size_t WireFormatLite::StringSize(const absl::Cord& value) {
1572   return LengthDelimitedSize(value.size());
1573 }
1574 
1575 inline size_t WireFormatLite::StringSize(const absl::string_view value) {
1576   // WARNING:  In wire_format.cc, both strings and bytes are handled by
1577   //   StringSize() to avoid code duplication.  If the implementations become
1578   //   different, you will need to update that usage.
1579   return LengthDelimitedSize(value.size());
1580 }
1581 inline size_t WireFormatLite::BytesSize(const absl::string_view value) {
1582   return LengthDelimitedSize(value.size());
1583 }
1584 
1585 template <typename MessageType>
1586 inline size_t WireFormatLite::GroupSize(const MessageType& value) {
1587   return value.ByteSizeLong();
1588 }
1589 template <typename MessageType>
1590 inline size_t WireFormatLite::MessageSize(const MessageType& value) {
1591   return LengthDelimitedSize(value.ByteSizeLong());
1592 }
1593 
1594 inline size_t WireFormatLite::LengthDelimitedSize(size_t length) {
1595   // The static_cast here prevents an error in certain compiler configurations
1596   // but is not technically correct--if length is too large to fit in a uint32_t
1597   // then it will be silently truncated. We will need to fix this if we ever
1598   // decide to start supporting serialized messages greater than 2 GiB in size.
1599   return length +
1600          io::CodedOutputStream::VarintSize32(static_cast<uint32_t>(length));
1601 }
1602 
1603 template <typename MS>
1604 bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) {
1605   // This method parses a group which should contain two fields:
1606   //   required int32 type_id = 2;
1607   //   required data message = 3;
1608 
1609   uint32_t last_type_id = 0;
1610 
1611   // If we see message data before the type_id, we'll append it to this so
1612   // we can parse it later.
1613   std::string message_data;
1614 
1615   enum class State { kNoTag, kHasType, kHasPayload, kDone };
1616   State state = State::kNoTag;
1617 
1618   while (true) {
1619     const uint32_t tag = input->ReadTagNoLastTag();
1620     if (tag == 0) return false;
1621 
1622     switch (tag) {
1623       case WireFormatLite::kMessageSetTypeIdTag: {
1624         uint32_t type_id;
1625         // We should fail parsing if type id is 0.
1626         if (!input->ReadVarint32(&type_id) || type_id == 0) return false;
1627         if (state == State::kNoTag) {
1628           last_type_id = type_id;
1629           state = State::kHasType;
1630         } else if (state == State::kHasPayload) {
1631           // We saw some message data before the type_id.  Have to parse it
1632           // now.
1633           io::CodedInputStream sub_input(
1634               reinterpret_cast<const uint8_t*>(message_data.data()),
1635               static_cast<int>(message_data.size()));
1636           sub_input.SetRecursionLimit(input->RecursionBudget());
1637           if (!ms.ParseField(type_id, &sub_input)) {
1638             return false;
1639           }
1640           message_data.clear();
1641           state = State::kDone;
1642         }
1643 
1644         break;
1645       }
1646 
1647       case WireFormatLite::kMessageSetMessageTag: {
1648         if (state == State::kHasType) {
1649           // Already saw type_id, so we can parse this directly.
1650           if (!ms.ParseField(last_type_id, input)) {
1651             return false;
1652           }
1653           state = State::kDone;
1654         } else if (state == State::kNoTag) {
1655           // We haven't seen a type_id yet.  Append this data to message_data.
1656           uint32_t length;
1657           if (!input->ReadVarint32(&length)) return false;
1658           if (static_cast<int32_t>(length) < 0) return false;
1659           uint32_t size = static_cast<uint32_t>(
1660               length + io::CodedOutputStream::VarintSize32(length));
1661           message_data.resize(size);
1662           auto ptr = reinterpret_cast<uint8_t*>(&message_data[0]);
1663           ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr);
1664           if (!input->ReadRaw(ptr, length)) return false;
1665           state = State::kHasPayload;
1666         } else {
1667           if (!ms.SkipField(tag, input)) return false;
1668         }
1669 
1670         break;
1671       }
1672 
1673       case WireFormatLite::kMessageSetItemEndTag: {
1674         return true;
1675       }
1676 
1677       default: {
1678         if (!ms.SkipField(tag, input)) return false;
1679       }
1680     }
1681   }
1682 }
1683 
1684 }  // namespace internal
1685 }  // namespace protobuf
1686 }  // namespace google
1687 
1688 #include "google/protobuf/port_undef.inc"
1689 
1690 #endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__