• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //         atenasio@google.com (Chris Atenasio) (ZigZag transform)
33 //         wink@google.com (Wink Saville) (refactored from wire_format.h)
34 //  Based on original Protocol Buffers design by
35 //  Sanjay Ghemawat, Jeff Dean, and others.
36 //
37 // This header is logically internal, but is made public because it is used
38 // from protocol-compiler-generated code, which may reside in other components.
39 
40 #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
41 #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
42 
43 #include <string>
44 
45 #include <google/protobuf/stubs/common.h>
46 #include <google/protobuf/stubs/logging.h>
47 #include <google/protobuf/io/coded_stream.h>
48 #include <google/protobuf/arenastring.h>
49 #include <google/protobuf/message_lite.h>
50 #include <google/protobuf/port.h>
51 #include <google/protobuf/repeated_field.h>
52 #include <google/protobuf/stubs/casts.h>
53 
54 // Do UTF-8 validation on string type in Debug build only
55 #ifndef NDEBUG
56 #define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
57 #endif
58 
59 // Avoid conflict with iOS where <ConditionalMacros.h> #defines TYPE_BOOL.
60 //
61 // If some one needs the macro TYPE_BOOL in a file that includes this header,
62 // it's possible to bring it back using push/pop_macro as follows.
63 //
64 // #pragma push_macro("TYPE_BOOL")
65 // #include this header and/or all headers that need the macro to be undefined.
66 // #pragma pop_macro("TYPE_BOOL")
67 #undef TYPE_BOOL
68 
69 
70 namespace google {
71 namespace protobuf {
72 namespace internal {
73 
74 #include <google/protobuf/port_def.inc>
75 
76 // This class is for internal use by the protocol buffer library and by
77 // protocol-compiler-generated message classes.  It must not be called
78 // directly by clients.
79 //
80 // This class contains helpers for implementing the binary protocol buffer
81 // wire format without the need for reflection. Use WireFormat when using
82 // reflection.
83 //
84 // This class is really a namespace that contains only static methods.
85 class PROTOBUF_EXPORT WireFormatLite {
86  public:
87   // -----------------------------------------------------------------
88   // Helper constants and functions related to the format.  These are
89   // mostly meant for internal and generated code to use.
90 
91   // The wire format is composed of a sequence of tag/value pairs, each
92   // of which contains the value of one field (or one element of a repeated
93   // field).  Each tag is encoded as a varint.  The lower bits of the tag
94   // identify its wire type, which specifies the format of the data to follow.
95   // The rest of the bits contain the field number.  Each type of field (as
96   // declared by FieldDescriptor::Type, in descriptor.h) maps to one of
97   // these wire types.  Immediately following each tag is the field's value,
98   // encoded in the format specified by the wire type.  Because the tag
99   // identifies the encoding of this data, it is possible to skip
100   // unrecognized fields for forwards compatibility.
101 
102   enum WireType {
103     WIRETYPE_VARINT = 0,
104     WIRETYPE_FIXED64 = 1,
105     WIRETYPE_LENGTH_DELIMITED = 2,
106     WIRETYPE_START_GROUP = 3,
107     WIRETYPE_END_GROUP = 4,
108     WIRETYPE_FIXED32 = 5,
109   };
110 
111   // Lite alternative to FieldDescriptor::Type.  Must be kept in sync.
112   enum FieldType {
113     TYPE_DOUBLE = 1,
114     TYPE_FLOAT = 2,
115     TYPE_INT64 = 3,
116     TYPE_UINT64 = 4,
117     TYPE_INT32 = 5,
118     TYPE_FIXED64 = 6,
119     TYPE_FIXED32 = 7,
120     TYPE_BOOL = 8,
121     TYPE_STRING = 9,
122     TYPE_GROUP = 10,
123     TYPE_MESSAGE = 11,
124     TYPE_BYTES = 12,
125     TYPE_UINT32 = 13,
126     TYPE_ENUM = 14,
127     TYPE_SFIXED32 = 15,
128     TYPE_SFIXED64 = 16,
129     TYPE_SINT32 = 17,
130     TYPE_SINT64 = 18,
131     MAX_FIELD_TYPE = 18,
132   };
133 
134   // Lite alternative to FieldDescriptor::CppType.  Must be kept in sync.
135   enum CppType {
136     CPPTYPE_INT32 = 1,
137     CPPTYPE_INT64 = 2,
138     CPPTYPE_UINT32 = 3,
139     CPPTYPE_UINT64 = 4,
140     CPPTYPE_DOUBLE = 5,
141     CPPTYPE_FLOAT = 6,
142     CPPTYPE_BOOL = 7,
143     CPPTYPE_ENUM = 8,
144     CPPTYPE_STRING = 9,
145     CPPTYPE_MESSAGE = 10,
146     MAX_CPPTYPE = 10,
147   };
148 
149   // Helper method to get the CppType for a particular Type.
150   static CppType FieldTypeToCppType(FieldType type);
151 
152   // Given a FieldDescriptor::Type return its WireType
WireTypeForFieldType(WireFormatLite::FieldType type)153   static inline WireFormatLite::WireType WireTypeForFieldType(
154       WireFormatLite::FieldType type) {
155     return kWireTypeForFieldType[type];
156   }
157 
158   // Number of bits in a tag which identify the wire type.
159   static constexpr int kTagTypeBits = 3;
160   // Mask for those bits.
161   static constexpr uint32 kTagTypeMask = (1 << kTagTypeBits) - 1;
162 
163   // Helper functions for encoding and decoding tags.  (Inlined below and in
164   // _inl.h)
165   //
166   // This is different from MakeTag(field->number(), field->type()) in the
167   // case of packed repeated fields.
168   constexpr static uint32 MakeTag(int field_number, WireType type);
169   static WireType GetTagWireType(uint32 tag);
170   static int GetTagFieldNumber(uint32 tag);
171 
172   // Compute the byte size of a tag.  For groups, this includes both the start
173   // and end tags.
174   static inline size_t TagSize(int field_number,
175                                WireFormatLite::FieldType type);
176 
177   // Skips a field value with the given tag.  The input should start
178   // positioned immediately after the tag.  Skipped values are simply
179   // discarded, not recorded anywhere.  See WireFormat::SkipField() for a
180   // version that records to an UnknownFieldSet.
181   static bool SkipField(io::CodedInputStream* input, uint32 tag);
182 
183   // Skips a field value with the given tag.  The input should start
184   // positioned immediately after the tag. Skipped values are recorded to a
185   // CodedOutputStream.
186   static bool SkipField(io::CodedInputStream* input, uint32 tag,
187                         io::CodedOutputStream* output);
188 
189   // Reads and ignores a message from the input.  Skipped values are simply
190   // discarded, not recorded anywhere.  See WireFormat::SkipMessage() for a
191   // version that records to an UnknownFieldSet.
192   static bool SkipMessage(io::CodedInputStream* input);
193 
194   // Reads and ignores a message from the input.  Skipped values are recorded
195   // to a CodedOutputStream.
196   static bool SkipMessage(io::CodedInputStream* input,
197                           io::CodedOutputStream* output);
198 
199   // This macro does the same thing as WireFormatLite::MakeTag(), but the
200   // result is usable as a compile-time constant, which makes it usable
201   // as a switch case or a template input.  WireFormatLite::MakeTag() is more
202   // type-safe, though, so prefer it if possible.
203 #define GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(FIELD_NUMBER, TYPE) \
204   static_cast<uint32>((static_cast<uint32>(FIELD_NUMBER) << 3) | (TYPE))
205 
206   // These are the tags for the old MessageSet format, which was defined as:
207   //   message MessageSet {
208   //     repeated group Item = 1 {
209   //       required int32 type_id = 2;
210   //       required string message = 3;
211   //     }
212   //   }
213   static constexpr int kMessageSetItemNumber = 1;
214   static constexpr int kMessageSetTypeIdNumber = 2;
215   static constexpr int kMessageSetMessageNumber = 3;
216   static const int kMessageSetItemStartTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
217       kMessageSetItemNumber, WireFormatLite::WIRETYPE_START_GROUP);
218   static const int kMessageSetItemEndTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
219       kMessageSetItemNumber, WireFormatLite::WIRETYPE_END_GROUP);
220   static const int kMessageSetTypeIdTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
221       kMessageSetTypeIdNumber, WireFormatLite::WIRETYPE_VARINT);
222   static const int kMessageSetMessageTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
223       kMessageSetMessageNumber, WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
224 
225   // Byte size of all tags of a MessageSet::Item combined.
226   static const size_t kMessageSetItemTagsSize;
227 
228   // Helper functions for converting between floats/doubles and IEEE-754
229   // uint32s/uint64s so that they can be written.  (Assumes your platform
230   // uses IEEE-754 floats.)
231   static uint32 EncodeFloat(float value);
232   static float DecodeFloat(uint32 value);
233   static uint64 EncodeDouble(double value);
234   static double DecodeDouble(uint64 value);
235 
236   // Helper functions for mapping signed integers to unsigned integers in
237   // such a way that numbers with small magnitudes will encode to smaller
238   // varints.  If you simply static_cast a negative number to an unsigned
239   // number and varint-encode it, it will always take 10 bytes, defeating
240   // the purpose of varint.  So, for the "sint32" and "sint64" field types,
241   // we ZigZag-encode the values.
242   static uint32 ZigZagEncode32(int32 n);
243   static int32 ZigZagDecode32(uint32 n);
244   static uint64 ZigZagEncode64(int64 n);
245   static int64 ZigZagDecode64(uint64 n);
246 
247   // =================================================================
248   // Methods for reading/writing individual field.
249 
250   // Read fields, not including tags.  The assumption is that you already
251   // read the tag to determine what field to read.
252 
253   // For primitive fields, we just use a templatized routine parameterized by
254   // the represented type and the FieldType. These are specialized with the
255   // appropriate definition for each declared type.
256   template <typename CType, enum FieldType DeclaredType>
257   PROTOBUF_ALWAYS_INLINE static bool ReadPrimitive(io::CodedInputStream* input,
258                                                    CType* value);
259 
260   // Reads repeated primitive values, with optimizations for repeats.
261   // tag_size and tag should both be compile-time constants provided by the
262   // protocol compiler.
263   template <typename CType, enum FieldType DeclaredType>
264   PROTOBUF_ALWAYS_INLINE static bool ReadRepeatedPrimitive(
265       int tag_size, uint32 tag, io::CodedInputStream* input,
266       RepeatedField<CType>* value);
267 
268   // Identical to ReadRepeatedPrimitive, except will not inline the
269   // implementation.
270   template <typename CType, enum FieldType DeclaredType>
271   static bool ReadRepeatedPrimitiveNoInline(int tag_size, uint32 tag,
272                                             io::CodedInputStream* input,
273                                             RepeatedField<CType>* value);
274 
275   // Reads a primitive value directly from the provided buffer. It returns a
276   // pointer past the segment of data that was read.
277   //
278   // This is only implemented for the types with fixed wire size, e.g.
279   // float, double, and the (s)fixed* types.
280   template <typename CType, enum FieldType DeclaredType>
281   PROTOBUF_ALWAYS_INLINE static const uint8* ReadPrimitiveFromArray(
282       const uint8* buffer, CType* value);
283 
284   // Reads a primitive packed field.
285   //
286   // This is only implemented for packable types.
287   template <typename CType, enum FieldType DeclaredType>
288   PROTOBUF_ALWAYS_INLINE static bool ReadPackedPrimitive(
289       io::CodedInputStream* input, RepeatedField<CType>* value);
290 
291   // Identical to ReadPackedPrimitive, except will not inline the
292   // implementation.
293   template <typename CType, enum FieldType DeclaredType>
294   static bool ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
295                                           RepeatedField<CType>* value);
296 
297   // Read a packed enum field. If the is_valid function is not NULL, values for
298   // which is_valid(value) returns false are silently dropped.
299   static bool ReadPackedEnumNoInline(io::CodedInputStream* input,
300                                      bool (*is_valid)(int),
301                                      RepeatedField<int>* values);
302 
303   // Read a packed enum field. If the is_valid function is not NULL, values for
304   // which is_valid(value) returns false are appended to unknown_fields_stream.
305   static bool ReadPackedEnumPreserveUnknowns(
306       io::CodedInputStream* input, int field_number, bool (*is_valid)(int),
307       io::CodedOutputStream* unknown_fields_stream, RepeatedField<int>* values);
308 
309   // Read a string.  ReadString(..., std::string* value) requires an
310   // existing std::string.
311   static inline bool ReadString(io::CodedInputStream* input,
312                                 std::string* value);
313   // ReadString(..., std::string** p) is internal-only, and should only be
314   // called from generated code. It starts by setting *p to "new std::string" if
315   // *p == &GetEmptyStringAlreadyInited().  It then invokes
316   // ReadString(io::CodedInputStream* input, *p).  This is useful for reducing
317   // code size.
318   static inline bool ReadString(io::CodedInputStream* input, std::string** p);
319   // Analogous to ReadString().
320   static bool ReadBytes(io::CodedInputStream* input, std::string* value);
321   static bool ReadBytes(io::CodedInputStream* input, std::string** p);
322 
323   enum Operation {
324     PARSE = 0,
325     SERIALIZE = 1,
326   };
327 
328   // Returns true if the data is valid UTF-8.
329   static bool VerifyUtf8String(const char* data, int size, Operation op,
330                                const char* field_name);
331 
332   template <typename MessageType>
333   static inline bool ReadGroup(int field_number, io::CodedInputStream* input,
334                                MessageType* value);
335 
336   template <typename MessageType>
337   static inline bool ReadMessage(io::CodedInputStream* input,
338                                  MessageType* value);
339 
340   template <typename MessageType>
ReadMessageNoVirtual(io::CodedInputStream * input,MessageType * value)341   static inline bool ReadMessageNoVirtual(io::CodedInputStream* input,
342                                           MessageType* value) {
343     return ReadMessage(input, value);
344   }
345 
346   // Write a tag.  The Write*() functions typically include the tag, so
347   // normally there's no need to call this unless using the Write*NoTag()
348   // variants.
349   PROTOBUF_ALWAYS_INLINE static void WriteTag(int field_number, WireType type,
350                                               io::CodedOutputStream* output);
351 
352   // Write fields, without tags.
353   PROTOBUF_ALWAYS_INLINE static void WriteInt32NoTag(
354       int32 value, io::CodedOutputStream* output);
355   PROTOBUF_ALWAYS_INLINE static void WriteInt64NoTag(
356       int64 value, io::CodedOutputStream* output);
357   PROTOBUF_ALWAYS_INLINE static void WriteUInt32NoTag(
358       uint32 value, io::CodedOutputStream* output);
359   PROTOBUF_ALWAYS_INLINE static void WriteUInt64NoTag(
360       uint64 value, io::CodedOutputStream* output);
361   PROTOBUF_ALWAYS_INLINE static void WriteSInt32NoTag(
362       int32 value, io::CodedOutputStream* output);
363   PROTOBUF_ALWAYS_INLINE static void WriteSInt64NoTag(
364       int64 value, io::CodedOutputStream* output);
365   PROTOBUF_ALWAYS_INLINE static void WriteFixed32NoTag(
366       uint32 value, io::CodedOutputStream* output);
367   PROTOBUF_ALWAYS_INLINE static void WriteFixed64NoTag(
368       uint64 value, io::CodedOutputStream* output);
369   PROTOBUF_ALWAYS_INLINE static void WriteSFixed32NoTag(
370       int32 value, io::CodedOutputStream* output);
371   PROTOBUF_ALWAYS_INLINE static void WriteSFixed64NoTag(
372       int64 value, io::CodedOutputStream* output);
373   PROTOBUF_ALWAYS_INLINE static void WriteFloatNoTag(
374       float value, io::CodedOutputStream* output);
375   PROTOBUF_ALWAYS_INLINE static void WriteDoubleNoTag(
376       double value, io::CodedOutputStream* output);
377   PROTOBUF_ALWAYS_INLINE static void WriteBoolNoTag(
378       bool value, io::CodedOutputStream* output);
379   PROTOBUF_ALWAYS_INLINE static void WriteEnumNoTag(
380       int value, io::CodedOutputStream* output);
381 
382   // Write array of primitive fields, without tags
383   static void WriteFloatArray(const float* a, int n,
384                               io::CodedOutputStream* output);
385   static void WriteDoubleArray(const double* a, int n,
386                                io::CodedOutputStream* output);
387   static void WriteFixed32Array(const uint32* a, int n,
388                                 io::CodedOutputStream* output);
389   static void WriteFixed64Array(const uint64* a, int n,
390                                 io::CodedOutputStream* output);
391   static void WriteSFixed32Array(const int32* a, int n,
392                                  io::CodedOutputStream* output);
393   static void WriteSFixed64Array(const int64* a, int n,
394                                  io::CodedOutputStream* output);
395   static void WriteBoolArray(const bool* a, int n,
396                              io::CodedOutputStream* output);
397 
398   // Write fields, including tags.
399   static void WriteInt32(int field_number, int32 value,
400                          io::CodedOutputStream* output);
401   static void WriteInt64(int field_number, int64 value,
402                          io::CodedOutputStream* output);
403   static void WriteUInt32(int field_number, uint32 value,
404                           io::CodedOutputStream* output);
405   static void WriteUInt64(int field_number, uint64 value,
406                           io::CodedOutputStream* output);
407   static void WriteSInt32(int field_number, int32 value,
408                           io::CodedOutputStream* output);
409   static void WriteSInt64(int field_number, int64 value,
410                           io::CodedOutputStream* output);
411   static void WriteFixed32(int field_number, uint32 value,
412                            io::CodedOutputStream* output);
413   static void WriteFixed64(int field_number, uint64 value,
414                            io::CodedOutputStream* output);
415   static void WriteSFixed32(int field_number, int32 value,
416                             io::CodedOutputStream* output);
417   static void WriteSFixed64(int field_number, int64 value,
418                             io::CodedOutputStream* output);
419   static void WriteFloat(int field_number, float value,
420                          io::CodedOutputStream* output);
421   static void WriteDouble(int field_number, double value,
422                           io::CodedOutputStream* output);
423   static void WriteBool(int field_number, bool value,
424                         io::CodedOutputStream* output);
425   static void WriteEnum(int field_number, int value,
426                         io::CodedOutputStream* output);
427 
428   static void WriteString(int field_number, const std::string& value,
429                           io::CodedOutputStream* output);
430   static void WriteBytes(int field_number, const std::string& value,
431                          io::CodedOutputStream* output);
432   static void WriteStringMaybeAliased(int field_number,
433                                       const std::string& value,
434                                       io::CodedOutputStream* output);
435   static void WriteBytesMaybeAliased(int field_number, const std::string& value,
436                                      io::CodedOutputStream* output);
437 
438   static void WriteGroup(int field_number, const MessageLite& value,
439                          io::CodedOutputStream* output);
440   static void WriteMessage(int field_number, const MessageLite& value,
441                            io::CodedOutputStream* output);
442   // Like above, but these will check if the output stream has enough
443   // space to write directly to a flat array.
444   static void WriteGroupMaybeToArray(int field_number, const MessageLite& value,
445                                      io::CodedOutputStream* output);
446   static void WriteMessageMaybeToArray(int field_number,
447                                        const MessageLite& value,
448                                        io::CodedOutputStream* output);
449 
450   // Like above, but de-virtualize the call to SerializeWithCachedSizes().  The
451   // pointer must point at an instance of MessageType, *not* a subclass (or
452   // the subclass must not override SerializeWithCachedSizes()).
453   template <typename MessageType>
454   static inline void WriteGroupNoVirtual(int field_number,
455                                          const MessageType& value,
456                                          io::CodedOutputStream* output);
457   template <typename MessageType>
458   static inline void WriteMessageNoVirtual(int field_number,
459                                            const MessageType& value,
460                                            io::CodedOutputStream* output);
461 
462   // Like above, but use only *ToArray methods of CodedOutputStream.
463   PROTOBUF_ALWAYS_INLINE static uint8* WriteTagToArray(int field_number,
464                                                        WireType type,
465                                                        uint8* target);
466 
467   // Write fields, without tags.
468   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32NoTagToArray(int32 value,
469                                                               uint8* target);
470   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64NoTagToArray(int64 value,
471                                                               uint8* target);
472   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32NoTagToArray(uint32 value,
473                                                                uint8* target);
474   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64NoTagToArray(uint64 value,
475                                                                uint8* target);
476   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32NoTagToArray(int32 value,
477                                                                uint8* target);
478   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64NoTagToArray(int64 value,
479                                                                uint8* target);
480   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32NoTagToArray(uint32 value,
481                                                                 uint8* target);
482   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64NoTagToArray(uint64 value,
483                                                                 uint8* target);
484   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32NoTagToArray(int32 value,
485                                                                  uint8* target);
486   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64NoTagToArray(int64 value,
487                                                                  uint8* target);
488   PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatNoTagToArray(float value,
489                                                               uint8* target);
490   PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleNoTagToArray(double value,
491                                                                uint8* target);
492   PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolNoTagToArray(bool value,
493                                                              uint8* target);
494   PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumNoTagToArray(int value,
495                                                              uint8* target);
496 
497   // Write fields, without tags.  These require that value.size() > 0.
498   template <typename T>
499   PROTOBUF_ALWAYS_INLINE static uint8* WritePrimitiveNoTagToArray(
500       const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*),
501       uint8* target);
502   template <typename T>
503   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixedNoTagToArray(
504       const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*),
505       uint8* target);
506 
507   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32NoTagToArray(
508       const RepeatedField<int32>& value, uint8* output);
509   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64NoTagToArray(
510       const RepeatedField<int64>& value, uint8* output);
511   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32NoTagToArray(
512       const RepeatedField<uint32>& value, uint8* output);
513   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64NoTagToArray(
514       const RepeatedField<uint64>& value, uint8* output);
515   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32NoTagToArray(
516       const RepeatedField<int32>& value, uint8* output);
517   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64NoTagToArray(
518       const RepeatedField<int64>& value, uint8* output);
519   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32NoTagToArray(
520       const RepeatedField<uint32>& value, uint8* output);
521   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64NoTagToArray(
522       const RepeatedField<uint64>& value, uint8* output);
523   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32NoTagToArray(
524       const RepeatedField<int32>& value, uint8* output);
525   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64NoTagToArray(
526       const RepeatedField<int64>& value, uint8* output);
527   PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatNoTagToArray(
528       const RepeatedField<float>& value, uint8* output);
529   PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleNoTagToArray(
530       const RepeatedField<double>& value, uint8* output);
531   PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolNoTagToArray(
532       const RepeatedField<bool>& value, uint8* output);
533   PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumNoTagToArray(
534       const RepeatedField<int>& value, uint8* output);
535 
536   // Write fields, including tags.
537   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32ToArray(int field_number,
538                                                          int32 value,
539                                                          uint8* target);
540   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64ToArray(int field_number,
541                                                          int64 value,
542                                                          uint8* target);
543   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32ToArray(int field_number,
544                                                           uint32 value,
545                                                           uint8* target);
546   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64ToArray(int field_number,
547                                                           uint64 value,
548                                                           uint8* target);
549   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32ToArray(int field_number,
550                                                           int32 value,
551                                                           uint8* target);
552   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64ToArray(int field_number,
553                                                           int64 value,
554                                                           uint8* target);
555   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32ToArray(int field_number,
556                                                            uint32 value,
557                                                            uint8* target);
558   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64ToArray(int field_number,
559                                                            uint64 value,
560                                                            uint8* target);
561   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32ToArray(int field_number,
562                                                             int32 value,
563                                                             uint8* target);
564   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64ToArray(int field_number,
565                                                             int64 value,
566                                                             uint8* target);
567   PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatToArray(int field_number,
568                                                          float value,
569                                                          uint8* target);
570   PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleToArray(int field_number,
571                                                           double value,
572                                                           uint8* target);
573   PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolToArray(int field_number,
574                                                         bool value,
575                                                         uint8* target);
576   PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumToArray(int field_number,
577                                                         int value,
578                                                         uint8* target);
579 
580   template <typename T>
581   PROTOBUF_ALWAYS_INLINE static uint8* WritePrimitiveToArray(
582       int field_number, const RepeatedField<T>& value,
583       uint8* (*Writer)(int, T, uint8*), uint8* target);
584 
585   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt32ToArray(
586       int field_number, const RepeatedField<int32>& value, uint8* output);
587   PROTOBUF_ALWAYS_INLINE static uint8* WriteInt64ToArray(
588       int field_number, const RepeatedField<int64>& value, uint8* output);
589   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt32ToArray(
590       int field_number, const RepeatedField<uint32>& value, uint8* output);
591   PROTOBUF_ALWAYS_INLINE static uint8* WriteUInt64ToArray(
592       int field_number, const RepeatedField<uint64>& value, uint8* output);
593   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt32ToArray(
594       int field_number, const RepeatedField<int32>& value, uint8* output);
595   PROTOBUF_ALWAYS_INLINE static uint8* WriteSInt64ToArray(
596       int field_number, const RepeatedField<int64>& value, uint8* output);
597   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed32ToArray(
598       int field_number, const RepeatedField<uint32>& value, uint8* output);
599   PROTOBUF_ALWAYS_INLINE static uint8* WriteFixed64ToArray(
600       int field_number, const RepeatedField<uint64>& value, uint8* output);
601   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed32ToArray(
602       int field_number, const RepeatedField<int32>& value, uint8* output);
603   PROTOBUF_ALWAYS_INLINE static uint8* WriteSFixed64ToArray(
604       int field_number, const RepeatedField<int64>& value, uint8* output);
605   PROTOBUF_ALWAYS_INLINE static uint8* WriteFloatToArray(
606       int field_number, const RepeatedField<float>& value, uint8* output);
607   PROTOBUF_ALWAYS_INLINE static uint8* WriteDoubleToArray(
608       int field_number, const RepeatedField<double>& value, uint8* output);
609   PROTOBUF_ALWAYS_INLINE static uint8* WriteBoolToArray(
610       int field_number, const RepeatedField<bool>& value, uint8* output);
611   PROTOBUF_ALWAYS_INLINE static uint8* WriteEnumToArray(
612       int field_number, const RepeatedField<int>& value, uint8* output);
613 
614   PROTOBUF_ALWAYS_INLINE static uint8* WriteStringToArray(
615       int field_number, const std::string& value, uint8* target);
616   PROTOBUF_ALWAYS_INLINE static uint8* WriteBytesToArray(
617       int field_number, const std::string& value, uint8* target);
618 
619   // Whether to serialize deterministically (e.g., map keys are
620   // sorted) is a property of a CodedOutputStream, and in the process
621   // of serialization, the "ToArray" variants may be invoked.  But they don't
622   // have a CodedOutputStream available, so they get an additional parameter
623   // telling them whether to serialize deterministically.
624   template <typename MessageType>
625   PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteGroup(
626       int field_number, const MessageType& value, uint8* target,
627       io::EpsCopyOutputStream* stream);
628   template <typename MessageType>
629   PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteMessage(
630       int field_number, const MessageType& value, uint8* target,
631       io::EpsCopyOutputStream* stream);
632 
633   // Like above, but de-virtualize the call to SerializeWithCachedSizes().  The
634   // pointer must point at an instance of MessageType, *not* a subclass (or
635   // the subclass must not override SerializeWithCachedSizes()).
636   template <typename MessageType>
637   PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteGroupNoVirtualToArray(
638       int field_number, const MessageType& value, uint8* target);
639   template <typename MessageType>
640   PROTOBUF_ALWAYS_INLINE static uint8* InternalWriteMessageNoVirtualToArray(
641       int field_number, const MessageType& value, uint8* target);
642 
643   // For backward-compatibility, the last four methods also have versions
644   // that are non-deterministic always.
WriteGroupToArray(int field_number,const MessageLite & value,uint8 * target)645   PROTOBUF_ALWAYS_INLINE static uint8* WriteGroupToArray(
646       int field_number, const MessageLite& value, uint8* target) {
647     io::EpsCopyOutputStream stream(
648         target,
649         value.GetCachedSize() +
650             static_cast<int>(2 * io::CodedOutputStream::VarintSize32(
651                                      static_cast<uint32>(field_number) << 3)),
652         io::CodedOutputStream::IsDefaultSerializationDeterministic());
653     return InternalWriteGroup(field_number, value, target, &stream);
654   }
WriteMessageToArray(int field_number,const MessageLite & value,uint8 * target)655   PROTOBUF_ALWAYS_INLINE static uint8* WriteMessageToArray(
656       int field_number, const MessageLite& value, uint8* target) {
657     int size = value.GetCachedSize();
658     io::EpsCopyOutputStream stream(
659         target,
660         size + static_cast<int>(io::CodedOutputStream::VarintSize32(
661                                     static_cast<uint32>(field_number) << 3) +
662                                 io::CodedOutputStream::VarintSize32(size)),
663         io::CodedOutputStream::IsDefaultSerializationDeterministic());
664     return InternalWriteMessage(field_number, value, target, &stream);
665   }
666 
667   // Compute the byte size of a field.  The XxSize() functions do NOT include
668   // the tag, so you must also call TagSize().  (This is because, for repeated
669   // fields, you should only call TagSize() once and multiply it by the element
670   // count, but you may have to call XxSize() for each individual element.)
671   static inline size_t Int32Size(int32 value);
672   static inline size_t Int64Size(int64 value);
673   static inline size_t UInt32Size(uint32 value);
674   static inline size_t UInt64Size(uint64 value);
675   static inline size_t SInt32Size(int32 value);
676   static inline size_t SInt64Size(int64 value);
677   static inline size_t EnumSize(int value);
678 
679   static size_t Int32Size(const RepeatedField<int32>& value);
680   static size_t Int64Size(const RepeatedField<int64>& value);
681   static size_t UInt32Size(const RepeatedField<uint32>& value);
682   static size_t UInt64Size(const RepeatedField<uint64>& value);
683   static size_t SInt32Size(const RepeatedField<int32>& value);
684   static size_t SInt64Size(const RepeatedField<int64>& value);
685   static size_t EnumSize(const RepeatedField<int>& value);
686 
687   // These types always have the same size.
688   static constexpr size_t kFixed32Size = 4;
689   static constexpr size_t kFixed64Size = 8;
690   static constexpr size_t kSFixed32Size = 4;
691   static constexpr size_t kSFixed64Size = 8;
692   static constexpr size_t kFloatSize = 4;
693   static constexpr size_t kDoubleSize = 8;
694   static constexpr size_t kBoolSize = 1;
695 
696   static inline size_t StringSize(const std::string& value);
697   static inline size_t BytesSize(const std::string& value);
698 
699   template <typename MessageType>
700   static inline size_t GroupSize(const MessageType& value);
701   template <typename MessageType>
702   static inline size_t MessageSize(const MessageType& value);
703 
704   // Like above, but de-virtualize the call to ByteSize().  The
705   // pointer must point at an instance of MessageType, *not* a subclass (or
706   // the subclass must not override ByteSize()).
707   template <typename MessageType>
708   static inline size_t GroupSizeNoVirtual(const MessageType& value);
709   template <typename MessageType>
710   static inline size_t MessageSizeNoVirtual(const MessageType& value);
711 
712   // Given the length of data, calculate the byte size of the data on the
713   // wire if we encode the data as a length delimited field.
714   static inline size_t LengthDelimitedSize(size_t length);
715 
716  private:
717   // A helper method for the repeated primitive reader. This method has
718   // optimizations for primitive types that have fixed size on the wire, and
719   // can be read using potentially faster paths.
720   template <typename CType, enum FieldType DeclaredType>
721   PROTOBUF_ALWAYS_INLINE static bool ReadRepeatedFixedSizePrimitive(
722       int tag_size, uint32 tag, io::CodedInputStream* input,
723       RepeatedField<CType>* value);
724 
725   // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
726   template <typename CType, enum FieldType DeclaredType>
727   PROTOBUF_ALWAYS_INLINE static bool ReadPackedFixedSizePrimitive(
728       io::CodedInputStream* input, RepeatedField<CType>* value);
729 
730   static const CppType kFieldTypeToCppTypeMap[];
731   static const WireFormatLite::WireType kWireTypeForFieldType[];
732   static void WriteSubMessageMaybeToArray(int size, const MessageLite& value,
733                                           io::CodedOutputStream* output);
734 
735   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite);
736 };
737 
738 // A class which deals with unknown values.  The default implementation just
739 // discards them.  WireFormat defines a subclass which writes to an
740 // UnknownFieldSet.  This class is used by ExtensionSet::ParseField(), since
741 // ExtensionSet is part of the lite library but UnknownFieldSet is not.
742 class PROTOBUF_EXPORT FieldSkipper {
743  public:
FieldSkipper()744   FieldSkipper() {}
~FieldSkipper()745   virtual ~FieldSkipper() {}
746 
747   // Skip a field whose tag has already been consumed.
748   virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
749 
750   // Skip an entire message or group, up to an end-group tag (which is consumed)
751   // or end-of-stream.
752   virtual bool SkipMessage(io::CodedInputStream* input);
753 
754   // Deal with an already-parsed unrecognized enum value.  The default
755   // implementation does nothing, but the UnknownFieldSet-based implementation
756   // saves it as an unknown varint.
757   virtual void SkipUnknownEnum(int field_number, int value);
758 };
759 
760 // Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
761 
762 class PROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
763  public:
CodedOutputStreamFieldSkipper(io::CodedOutputStream * unknown_fields)764   explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
765       : unknown_fields_(unknown_fields) {}
~CodedOutputStreamFieldSkipper()766   ~CodedOutputStreamFieldSkipper() override {}
767 
768   // implements FieldSkipper -----------------------------------------
769   bool SkipField(io::CodedInputStream* input, uint32 tag) override;
770   bool SkipMessage(io::CodedInputStream* input) override;
771   void SkipUnknownEnum(int field_number, int value) override;
772 
773  protected:
774   io::CodedOutputStream* unknown_fields_;
775 };
776 
777 // inline methods ====================================================
778 
FieldTypeToCppType(FieldType type)779 inline WireFormatLite::CppType WireFormatLite::FieldTypeToCppType(
780     FieldType type) {
781   return kFieldTypeToCppTypeMap[type];
782 }
783 
MakeTag(int field_number,WireType type)784 constexpr inline uint32 WireFormatLite::MakeTag(int field_number,
785                                                 WireType type) {
786   return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
787 }
788 
GetTagWireType(uint32 tag)789 inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
790   return static_cast<WireType>(tag & kTagTypeMask);
791 }
792 
GetTagFieldNumber(uint32 tag)793 inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
794   return static_cast<int>(tag >> kTagTypeBits);
795 }
796 
TagSize(int field_number,WireFormatLite::FieldType type)797 inline size_t WireFormatLite::TagSize(int field_number,
798                                       WireFormatLite::FieldType type) {
799   size_t result = io::CodedOutputStream::VarintSize32(
800       static_cast<uint32>(field_number << kTagTypeBits));
801   if (type == TYPE_GROUP) {
802     // Groups have both a start and an end tag.
803     return result * 2;
804   } else {
805     return result;
806   }
807 }
808 
EncodeFloat(float value)809 inline uint32 WireFormatLite::EncodeFloat(float value) {
810   return bit_cast<uint32>(value);
811 }
812 
DecodeFloat(uint32 value)813 inline float WireFormatLite::DecodeFloat(uint32 value) {
814   return bit_cast<float>(value);
815 }
816 
EncodeDouble(double value)817 inline uint64 WireFormatLite::EncodeDouble(double value) {
818   return bit_cast<uint64>(value);
819 }
820 
DecodeDouble(uint64 value)821 inline double WireFormatLite::DecodeDouble(uint64 value) {
822   return bit_cast<double>(value);
823 }
824 
825 // ZigZag Transform:  Encodes signed integers so that they can be
826 // effectively used with varint encoding.
827 //
828 // varint operates on unsigned integers, encoding smaller numbers into
829 // fewer bytes.  If you try to use it on a signed integer, it will treat
830 // this number as a very large unsigned integer, which means that even
831 // small signed numbers like -1 will take the maximum number of bytes
832 // (10) to encode.  ZigZagEncode() maps signed integers to unsigned
833 // in such a way that those with a small absolute value will have smaller
834 // encoded values, making them appropriate for encoding using varint.
835 //
836 //       int32 ->     uint32
837 // -------------------------
838 //           0 ->          0
839 //          -1 ->          1
840 //           1 ->          2
841 //          -2 ->          3
842 //         ... ->        ...
843 //  2147483647 -> 4294967294
844 // -2147483648 -> 4294967295
845 //
846 //        >> encode >>
847 //        << decode <<
848 
ZigZagEncode32(int32 n)849 inline uint32 WireFormatLite::ZigZagEncode32(int32 n) {
850   // Note:  the right-shift must be arithmetic
851   // Note:  left shift must be unsigned because of overflow
852   return (static_cast<uint32>(n) << 1) ^ static_cast<uint32>(n >> 31);
853 }
854 
ZigZagDecode32(uint32 n)855 inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
856   // Note:  Using unsigned types prevent undefined behavior
857   return static_cast<int32>((n >> 1) ^ (~(n & 1) + 1));
858 }
859 
ZigZagEncode64(int64 n)860 inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
861   // Note:  the right-shift must be arithmetic
862   // Note:  left shift must be unsigned because of overflow
863   return (static_cast<uint64>(n) << 1) ^ static_cast<uint64>(n >> 63);
864 }
865 
ZigZagDecode64(uint64 n)866 inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
867   // Note:  Using unsigned types prevent undefined behavior
868   return static_cast<int64>((n >> 1) ^ (~(n & 1) + 1));
869 }
870 
871 // String is for UTF-8 text only, but, even so, ReadString() can simply
872 // call ReadBytes().
873 
ReadString(io::CodedInputStream * input,std::string * value)874 inline bool WireFormatLite::ReadString(io::CodedInputStream* input,
875                                        std::string* value) {
876   return ReadBytes(input, value);
877 }
878 
ReadString(io::CodedInputStream * input,std::string ** p)879 inline bool WireFormatLite::ReadString(io::CodedInputStream* input,
880                                        std::string** p) {
881   return ReadBytes(input, p);
882 }
883 
InternalSerializeUnknownMessageSetItemsToArray(const std::string & unknown_fields,uint8 * target,io::EpsCopyOutputStream * stream)884 inline uint8* InternalSerializeUnknownMessageSetItemsToArray(
885     const std::string& unknown_fields, uint8* target,
886     io::EpsCopyOutputStream* stream) {
887   return stream->WriteRaw(unknown_fields.data(),
888                           static_cast<int>(unknown_fields.size()), target);
889 }
890 
ComputeUnknownMessageSetItemsSize(const std::string & unknown_fields)891 inline size_t ComputeUnknownMessageSetItemsSize(
892     const std::string& unknown_fields) {
893   return unknown_fields.size();
894 }
895 
896 // Implementation details of ReadPrimitive.
897 
898 template <>
899 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
900     io::CodedInputStream* input, int32* value) {
901   uint32 temp;
902   if (!input->ReadVarint32(&temp)) return false;
903   *value = static_cast<int32>(temp);
904   return true;
905 }
906 template <>
907 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
908     io::CodedInputStream* input, int64* value) {
909   uint64 temp;
910   if (!input->ReadVarint64(&temp)) return false;
911   *value = static_cast<int64>(temp);
912   return true;
913 }
914 template <>
915 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
916     io::CodedInputStream* input, uint32* value) {
917   return input->ReadVarint32(value);
918 }
919 template <>
920 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
921     io::CodedInputStream* input, uint64* value) {
922   return input->ReadVarint64(value);
923 }
924 template <>
925 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
926     io::CodedInputStream* input, int32* value) {
927   uint32 temp;
928   if (!input->ReadVarint32(&temp)) return false;
929   *value = ZigZagDecode32(temp);
930   return true;
931 }
932 template <>
933 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
934     io::CodedInputStream* input, int64* value) {
935   uint64 temp;
936   if (!input->ReadVarint64(&temp)) return false;
937   *value = ZigZagDecode64(temp);
938   return true;
939 }
940 template <>
941 inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
942     io::CodedInputStream* input, uint32* value) {
943   return input->ReadLittleEndian32(value);
944 }
945 template <>
946 inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
947     io::CodedInputStream* input, uint64* value) {
948   return input->ReadLittleEndian64(value);
949 }
950 template <>
951 inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
952     io::CodedInputStream* input, int32* value) {
953   uint32 temp;
954   if (!input->ReadLittleEndian32(&temp)) return false;
955   *value = static_cast<int32>(temp);
956   return true;
957 }
958 template <>
959 inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
960     io::CodedInputStream* input, int64* value) {
961   uint64 temp;
962   if (!input->ReadLittleEndian64(&temp)) return false;
963   *value = static_cast<int64>(temp);
964   return true;
965 }
966 template <>
967 inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
968     io::CodedInputStream* input, float* value) {
969   uint32 temp;
970   if (!input->ReadLittleEndian32(&temp)) return false;
971   *value = DecodeFloat(temp);
972   return true;
973 }
974 template <>
975 inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
976     io::CodedInputStream* input, double* value) {
977   uint64 temp;
978   if (!input->ReadLittleEndian64(&temp)) return false;
979   *value = DecodeDouble(temp);
980   return true;
981 }
982 template <>
983 inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
984     io::CodedInputStream* input, bool* value) {
985   uint64 temp;
986   if (!input->ReadVarint64(&temp)) return false;
987   *value = temp != 0;
988   return true;
989 }
990 template <>
991 inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
992     io::CodedInputStream* input, int* value) {
993   uint32 temp;
994   if (!input->ReadVarint32(&temp)) return false;
995   *value = static_cast<int>(temp);
996   return true;
997 }
998 
999 template <>
1000 inline const uint8*
1001 WireFormatLite::ReadPrimitiveFromArray<uint32, WireFormatLite::TYPE_FIXED32>(
1002     const uint8* buffer, uint32* value) {
1003   return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
1004 }
1005 template <>
1006 inline const uint8*
1007 WireFormatLite::ReadPrimitiveFromArray<uint64, WireFormatLite::TYPE_FIXED64>(
1008     const uint8* buffer, uint64* value) {
1009   return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
1010 }
1011 template <>
1012 inline const uint8*
1013 WireFormatLite::ReadPrimitiveFromArray<int32, WireFormatLite::TYPE_SFIXED32>(
1014     const uint8* buffer, int32* value) {
1015   uint32 temp;
1016   buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
1017   *value = static_cast<int32>(temp);
1018   return buffer;
1019 }
1020 template <>
1021 inline const uint8*
1022 WireFormatLite::ReadPrimitiveFromArray<int64, WireFormatLite::TYPE_SFIXED64>(
1023     const uint8* buffer, int64* value) {
1024   uint64 temp;
1025   buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
1026   *value = static_cast<int64>(temp);
1027   return buffer;
1028 }
1029 template <>
1030 inline const uint8*
1031 WireFormatLite::ReadPrimitiveFromArray<float, WireFormatLite::TYPE_FLOAT>(
1032     const uint8* buffer, float* value) {
1033   uint32 temp;
1034   buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
1035   *value = DecodeFloat(temp);
1036   return buffer;
1037 }
1038 template <>
1039 inline const uint8*
1040 WireFormatLite::ReadPrimitiveFromArray<double, WireFormatLite::TYPE_DOUBLE>(
1041     const uint8* buffer, double* value) {
1042   uint64 temp;
1043   buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
1044   *value = DecodeDouble(temp);
1045   return buffer;
1046 }
1047 
1048 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadRepeatedPrimitive(int,uint32 tag,io::CodedInputStream * input,RepeatedField<CType> * values)1049 inline bool WireFormatLite::ReadRepeatedPrimitive(
1050     int,  // tag_size, unused.
1051     uint32 tag, io::CodedInputStream* input, RepeatedField<CType>* values) {
1052   CType value;
1053   if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1054   values->Add(value);
1055   int elements_already_reserved = values->Capacity() - values->size();
1056   while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
1057     if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1058     values->AddAlreadyReserved(value);
1059     elements_already_reserved--;
1060   }
1061   return true;
1062 }
1063 
1064 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadRepeatedFixedSizePrimitive(int tag_size,uint32 tag,io::CodedInputStream * input,RepeatedField<CType> * values)1065 inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
1066     int tag_size, uint32 tag, io::CodedInputStream* input,
1067     RepeatedField<CType>* values) {
1068   GOOGLE_DCHECK_EQ(UInt32Size(tag), static_cast<size_t>(tag_size));
1069   CType value;
1070   if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1071   values->Add(value);
1072 
1073   // For fixed size values, repeated values can be read more quickly by
1074   // reading directly from a raw array.
1075   //
1076   // We can get a tight loop by only reading as many elements as can be
1077   // added to the RepeatedField without having to do any resizing. Additionally,
1078   // we only try to read as many elements as are available from the current
1079   // buffer space. Doing so avoids having to perform boundary checks when
1080   // reading the value: the maximum number of elements that can be read is
1081   // known outside of the loop.
1082   const void* void_pointer;
1083   int size;
1084   input->GetDirectBufferPointerInline(&void_pointer, &size);
1085   if (size > 0) {
1086     const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
1087     // The number of bytes each type occupies on the wire.
1088     const int per_value_size = tag_size + static_cast<int>(sizeof(value));
1089 
1090     // parentheses around (std::min) prevents macro expansion of min(...)
1091     int elements_available =
1092         (std::min)(values->Capacity() - values->size(), size / per_value_size);
1093     int num_read = 0;
1094     while (num_read < elements_available &&
1095            (buffer = io::CodedInputStream::ExpectTagFromArray(buffer, tag)) !=
1096                NULL) {
1097       buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
1098       values->AddAlreadyReserved(value);
1099       ++num_read;
1100     }
1101     const int read_bytes = num_read * per_value_size;
1102     if (read_bytes > 0) {
1103       input->Skip(read_bytes);
1104     }
1105   }
1106   return true;
1107 }
1108 
1109 // Specializations of ReadRepeatedPrimitive for the fixed size types, which use
1110 // the optimized code path.
1111 #define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)        \
1112   template <>                                                             \
1113   inline bool WireFormatLite::ReadRepeatedPrimitive<                      \
1114       CPPTYPE, WireFormatLite::DECLARED_TYPE>(                            \
1115       int tag_size, uint32 tag, io::CodedInputStream* input,              \
1116       RepeatedField<CPPTYPE>* values) {                                   \
1117     return ReadRepeatedFixedSizePrimitive<CPPTYPE,                        \
1118                                           WireFormatLite::DECLARED_TYPE>( \
1119         tag_size, tag, input, values);                                    \
1120   }
1121 
READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32,TYPE_FIXED32)1122 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
1123 READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
1124 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
1125 READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
1126 READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
1127 READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
1128 
1129 #undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
1130 
1131 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1132 bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
1133     int tag_size, uint32 tag, io::CodedInputStream* input,
1134     RepeatedField<CType>* value) {
1135   return ReadRepeatedPrimitive<CType, DeclaredType>(tag_size, tag, input,
1136                                                     value);
1137 }
1138 
1139 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedPrimitive(io::CodedInputStream * input,RepeatedField<CType> * values)1140 inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
1141                                                 RepeatedField<CType>* values) {
1142   int length;
1143   if (!input->ReadVarintSizeAsInt(&length)) return false;
1144   io::CodedInputStream::Limit limit = input->PushLimit(length);
1145   while (input->BytesUntilLimit() > 0) {
1146     CType value;
1147     if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1148     values->Add(value);
1149   }
1150   input->PopLimit(limit);
1151   return true;
1152 }
1153 
1154 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
ReadPackedFixedSizePrimitive(io::CodedInputStream * input,RepeatedField<CType> * values)1155 inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
1156     io::CodedInputStream* input, RepeatedField<CType>* values) {
1157   int length;
1158   if (!input->ReadVarintSizeAsInt(&length)) return false;
1159   const int old_entries = values->size();
1160   const int new_entries = length / static_cast<int>(sizeof(CType));
1161   const int new_bytes = new_entries * static_cast<int>(sizeof(CType));
1162   if (new_bytes != length) return false;
1163   // We would *like* to pre-allocate the buffer to write into (for
1164   // speed), but *must* avoid performing a very large allocation due
1165   // to a malicious user-supplied "length" above.  So we have a fast
1166   // path that pre-allocates when the "length" is less than a bound.
1167   // We determine the bound by calling BytesUntilTotalBytesLimit() and
1168   // BytesUntilLimit().  These return -1 to mean "no limit set".
1169   // There are four cases:
1170   // TotalBytesLimit  Limit
1171   // -1               -1     Use slow path.
1172   // -1               >= 0   Use fast path if length <= Limit.
1173   // >= 0             -1     Use slow path.
1174   // >= 0             >= 0   Use fast path if length <= min(both limits).
1175   int64 bytes_limit = input->BytesUntilTotalBytesLimit();
1176   if (bytes_limit == -1) {
1177     bytes_limit = input->BytesUntilLimit();
1178   } else {
1179     // parentheses around (std::min) prevents macro expansion of min(...)
1180     bytes_limit =
1181         (std::min)(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
1182   }
1183   if (bytes_limit >= new_bytes) {
1184     // Fast-path that pre-allocates *values to the final size.
1185 #if defined(PROTOBUF_LITTLE_ENDIAN)
1186     values->Resize(old_entries + new_entries, 0);
1187     // values->mutable_data() may change after Resize(), so do this after:
1188     void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
1189     if (!input->ReadRaw(dest, new_bytes)) {
1190       values->Truncate(old_entries);
1191       return false;
1192     }
1193 #else
1194     values->Reserve(old_entries + new_entries);
1195     CType value;
1196     for (int i = 0; i < new_entries; ++i) {
1197       if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1198       values->AddAlreadyReserved(value);
1199     }
1200 #endif
1201   } else {
1202     // This is the slow-path case where "length" may be too large to
1203     // safely allocate.  We read as much as we can into *values
1204     // without pre-allocating "length" bytes.
1205     CType value;
1206     for (int i = 0; i < new_entries; ++i) {
1207       if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
1208       values->Add(value);
1209     }
1210   }
1211   return true;
1212 }
1213 
1214 // Specializations of ReadPackedPrimitive for the fixed size types, which use
1215 // an optimized code path.
1216 #define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)      \
1217   template <>                                                                  \
1218   inline bool                                                                  \
1219   WireFormatLite::ReadPackedPrimitive<CPPTYPE, WireFormatLite::DECLARED_TYPE>( \
1220       io::CodedInputStream * input, RepeatedField<CPPTYPE> * values) {         \
1221     return ReadPackedFixedSizePrimitive<CPPTYPE,                               \
1222                                         WireFormatLite::DECLARED_TYPE>(        \
1223         input, values);                                                        \
1224   }
1225 
READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32,TYPE_FIXED32)1226 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
1227 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
1228 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
1229 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
1230 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
1231 READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
1232 
1233 #undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
1234 
1235 template <typename CType, enum WireFormatLite::FieldType DeclaredType>
1236 bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
1237                                                  RepeatedField<CType>* values) {
1238   return ReadPackedPrimitive<CType, DeclaredType>(input, values);
1239 }
1240 
1241 
1242 template <typename MessageType>
ReadGroup(int field_number,io::CodedInputStream * input,MessageType * value)1243 inline bool WireFormatLite::ReadGroup(int field_number,
1244                                       io::CodedInputStream* input,
1245                                       MessageType* value) {
1246   if (!input->IncrementRecursionDepth()) return false;
1247   if (!value->MergePartialFromCodedStream(input)) return false;
1248   input->UnsafeDecrementRecursionDepth();
1249   // Make sure the last thing read was an end tag for this group.
1250   if (!input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP))) {
1251     return false;
1252   }
1253   return true;
1254 }
1255 template <typename MessageType>
ReadMessage(io::CodedInputStream * input,MessageType * value)1256 inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input,
1257                                         MessageType* value) {
1258   int length;
1259   if (!input->ReadVarintSizeAsInt(&length)) return false;
1260   std::pair<io::CodedInputStream::Limit, int> p =
1261       input->IncrementRecursionDepthAndPushLimit(length);
1262   if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false;
1263   // Make sure that parsing stopped when the limit was hit, not at an endgroup
1264   // tag.
1265   return input->DecrementRecursionDepthAndPopLimit(p.first);
1266 }
1267 
1268 // ===================================================================
1269 
WriteTag(int field_number,WireType type,io::CodedOutputStream * output)1270 inline void WireFormatLite::WriteTag(int field_number, WireType type,
1271                                      io::CodedOutputStream* output) {
1272   output->WriteTag(MakeTag(field_number, type));
1273 }
1274 
WriteInt32NoTag(int32 value,io::CodedOutputStream * output)1275 inline void WireFormatLite::WriteInt32NoTag(int32 value,
1276                                             io::CodedOutputStream* output) {
1277   output->WriteVarint32SignExtended(value);
1278 }
WriteInt64NoTag(int64 value,io::CodedOutputStream * output)1279 inline void WireFormatLite::WriteInt64NoTag(int64 value,
1280                                             io::CodedOutputStream* output) {
1281   output->WriteVarint64(static_cast<uint64>(value));
1282 }
WriteUInt32NoTag(uint32 value,io::CodedOutputStream * output)1283 inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
1284                                              io::CodedOutputStream* output) {
1285   output->WriteVarint32(value);
1286 }
WriteUInt64NoTag(uint64 value,io::CodedOutputStream * output)1287 inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
1288                                              io::CodedOutputStream* output) {
1289   output->WriteVarint64(value);
1290 }
WriteSInt32NoTag(int32 value,io::CodedOutputStream * output)1291 inline void WireFormatLite::WriteSInt32NoTag(int32 value,
1292                                              io::CodedOutputStream* output) {
1293   output->WriteVarint32(ZigZagEncode32(value));
1294 }
WriteSInt64NoTag(int64 value,io::CodedOutputStream * output)1295 inline void WireFormatLite::WriteSInt64NoTag(int64 value,
1296                                              io::CodedOutputStream* output) {
1297   output->WriteVarint64(ZigZagEncode64(value));
1298 }
WriteFixed32NoTag(uint32 value,io::CodedOutputStream * output)1299 inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
1300                                               io::CodedOutputStream* output) {
1301   output->WriteLittleEndian32(value);
1302 }
WriteFixed64NoTag(uint64 value,io::CodedOutputStream * output)1303 inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
1304                                               io::CodedOutputStream* output) {
1305   output->WriteLittleEndian64(value);
1306 }
WriteSFixed32NoTag(int32 value,io::CodedOutputStream * output)1307 inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
1308                                                io::CodedOutputStream* output) {
1309   output->WriteLittleEndian32(static_cast<uint32>(value));
1310 }
WriteSFixed64NoTag(int64 value,io::CodedOutputStream * output)1311 inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
1312                                                io::CodedOutputStream* output) {
1313   output->WriteLittleEndian64(static_cast<uint64>(value));
1314 }
WriteFloatNoTag(float value,io::CodedOutputStream * output)1315 inline void WireFormatLite::WriteFloatNoTag(float value,
1316                                             io::CodedOutputStream* output) {
1317   output->WriteLittleEndian32(EncodeFloat(value));
1318 }
WriteDoubleNoTag(double value,io::CodedOutputStream * output)1319 inline void WireFormatLite::WriteDoubleNoTag(double value,
1320                                              io::CodedOutputStream* output) {
1321   output->WriteLittleEndian64(EncodeDouble(value));
1322 }
WriteBoolNoTag(bool value,io::CodedOutputStream * output)1323 inline void WireFormatLite::WriteBoolNoTag(bool value,
1324                                            io::CodedOutputStream* output) {
1325   output->WriteVarint32(value ? 1 : 0);
1326 }
WriteEnumNoTag(int value,io::CodedOutputStream * output)1327 inline void WireFormatLite::WriteEnumNoTag(int value,
1328                                            io::CodedOutputStream* output) {
1329   output->WriteVarint32SignExtended(value);
1330 }
1331 
1332 // See comment on ReadGroupNoVirtual to understand the need for this template
1333 // parameter name.
1334 template <typename MessageType_WorkAroundCppLookupDefect>
WriteGroupNoVirtual(int field_number,const MessageType_WorkAroundCppLookupDefect & value,io::CodedOutputStream * output)1335 inline void WireFormatLite::WriteGroupNoVirtual(
1336     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1337     io::CodedOutputStream* output) {
1338   WriteTag(field_number, WIRETYPE_START_GROUP, output);
1339   value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
1340   WriteTag(field_number, WIRETYPE_END_GROUP, output);
1341 }
1342 template <typename MessageType_WorkAroundCppLookupDefect>
WriteMessageNoVirtual(int field_number,const MessageType_WorkAroundCppLookupDefect & value,io::CodedOutputStream * output)1343 inline void WireFormatLite::WriteMessageNoVirtual(
1344     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1345     io::CodedOutputStream* output) {
1346   WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
1347   output->WriteVarint32(
1348       value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
1349   value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
1350 }
1351 
1352 // ===================================================================
1353 
WriteTagToArray(int field_number,WireType type,uint8 * target)1354 inline uint8* WireFormatLite::WriteTagToArray(int field_number, WireType type,
1355                                               uint8* target) {
1356   return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
1357                                                 target);
1358 }
1359 
WriteInt32NoTagToArray(int32 value,uint8 * target)1360 inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
1361                                                      uint8* target) {
1362   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
1363 }
WriteInt64NoTagToArray(int64 value,uint8 * target)1364 inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
1365                                                      uint8* target) {
1366   return io::CodedOutputStream::WriteVarint64ToArray(static_cast<uint64>(value),
1367                                                      target);
1368 }
WriteUInt32NoTagToArray(uint32 value,uint8 * target)1369 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
1370                                                       uint8* target) {
1371   return io::CodedOutputStream::WriteVarint32ToArray(value, target);
1372 }
WriteUInt64NoTagToArray(uint64 value,uint8 * target)1373 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
1374                                                       uint8* target) {
1375   return io::CodedOutputStream::WriteVarint64ToArray(value, target);
1376 }
WriteSInt32NoTagToArray(int32 value,uint8 * target)1377 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
1378                                                       uint8* target) {
1379   return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
1380                                                      target);
1381 }
WriteSInt64NoTagToArray(int64 value,uint8 * target)1382 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
1383                                                       uint8* target) {
1384   return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
1385                                                      target);
1386 }
WriteFixed32NoTagToArray(uint32 value,uint8 * target)1387 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
1388                                                        uint8* target) {
1389   return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
1390 }
WriteFixed64NoTagToArray(uint64 value,uint8 * target)1391 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
1392                                                        uint8* target) {
1393   return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
1394 }
WriteSFixed32NoTagToArray(int32 value,uint8 * target)1395 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
1396                                                         uint8* target) {
1397   return io::CodedOutputStream::WriteLittleEndian32ToArray(
1398       static_cast<uint32>(value), target);
1399 }
WriteSFixed64NoTagToArray(int64 value,uint8 * target)1400 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
1401                                                         uint8* target) {
1402   return io::CodedOutputStream::WriteLittleEndian64ToArray(
1403       static_cast<uint64>(value), target);
1404 }
WriteFloatNoTagToArray(float value,uint8 * target)1405 inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
1406                                                      uint8* target) {
1407   return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
1408                                                            target);
1409 }
WriteDoubleNoTagToArray(double value,uint8 * target)1410 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
1411                                                       uint8* target) {
1412   return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
1413                                                            target);
1414 }
WriteBoolNoTagToArray(bool value,uint8 * target)1415 inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value, uint8* target) {
1416   return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
1417 }
WriteEnumNoTagToArray(int value,uint8 * target)1418 inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, uint8* target) {
1419   return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
1420 }
1421 
1422 template <typename T>
WritePrimitiveNoTagToArray(const RepeatedField<T> & value,uint8 * (* Writer)(T,uint8 *),uint8 * target)1423 inline uint8* WireFormatLite::WritePrimitiveNoTagToArray(
1424     const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), uint8* target) {
1425   const int n = value.size();
1426   GOOGLE_DCHECK_GT(n, 0);
1427 
1428   const T* ii = value.data();
1429   int i = 0;
1430   do {
1431     target = Writer(ii[i], target);
1432   } while (++i < n);
1433 
1434   return target;
1435 }
1436 
1437 template <typename T>
WriteFixedNoTagToArray(const RepeatedField<T> & value,uint8 * (* Writer)(T,uint8 *),uint8 * target)1438 inline uint8* WireFormatLite::WriteFixedNoTagToArray(
1439     const RepeatedField<T>& value, uint8* (*Writer)(T, uint8*), uint8* target) {
1440 #if defined(PROTOBUF_LITTLE_ENDIAN)
1441   (void)Writer;
1442 
1443   const int n = value.size();
1444   GOOGLE_DCHECK_GT(n, 0);
1445 
1446   const T* ii = value.data();
1447   const int bytes = n * static_cast<int>(sizeof(ii[0]));
1448   memcpy(target, ii, static_cast<size_t>(bytes));
1449   return target + bytes;
1450 #else
1451   return WritePrimitiveNoTagToArray(value, Writer, target);
1452 #endif
1453 }
1454 
WriteInt32NoTagToArray(const RepeatedField<int32> & value,uint8 * target)1455 inline uint8* WireFormatLite::WriteInt32NoTagToArray(
1456     const RepeatedField<int32>& value, uint8* target) {
1457   return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target);
1458 }
WriteInt64NoTagToArray(const RepeatedField<int64> & value,uint8 * target)1459 inline uint8* WireFormatLite::WriteInt64NoTagToArray(
1460     const RepeatedField<int64>& value, uint8* target) {
1461   return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target);
1462 }
WriteUInt32NoTagToArray(const RepeatedField<uint32> & value,uint8 * target)1463 inline uint8* WireFormatLite::WriteUInt32NoTagToArray(
1464     const RepeatedField<uint32>& value, uint8* target) {
1465   return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target);
1466 }
WriteUInt64NoTagToArray(const RepeatedField<uint64> & value,uint8 * target)1467 inline uint8* WireFormatLite::WriteUInt64NoTagToArray(
1468     const RepeatedField<uint64>& value, uint8* target) {
1469   return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target);
1470 }
WriteSInt32NoTagToArray(const RepeatedField<int32> & value,uint8 * target)1471 inline uint8* WireFormatLite::WriteSInt32NoTagToArray(
1472     const RepeatedField<int32>& value, uint8* target) {
1473   return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target);
1474 }
WriteSInt64NoTagToArray(const RepeatedField<int64> & value,uint8 * target)1475 inline uint8* WireFormatLite::WriteSInt64NoTagToArray(
1476     const RepeatedField<int64>& value, uint8* target) {
1477   return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target);
1478 }
WriteFixed32NoTagToArray(const RepeatedField<uint32> & value,uint8 * target)1479 inline uint8* WireFormatLite::WriteFixed32NoTagToArray(
1480     const RepeatedField<uint32>& value, uint8* target) {
1481   return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target);
1482 }
WriteFixed64NoTagToArray(const RepeatedField<uint64> & value,uint8 * target)1483 inline uint8* WireFormatLite::WriteFixed64NoTagToArray(
1484     const RepeatedField<uint64>& value, uint8* target) {
1485   return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target);
1486 }
WriteSFixed32NoTagToArray(const RepeatedField<int32> & value,uint8 * target)1487 inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(
1488     const RepeatedField<int32>& value, uint8* target) {
1489   return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target);
1490 }
WriteSFixed64NoTagToArray(const RepeatedField<int64> & value,uint8 * target)1491 inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(
1492     const RepeatedField<int64>& value, uint8* target) {
1493   return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target);
1494 }
WriteFloatNoTagToArray(const RepeatedField<float> & value,uint8 * target)1495 inline uint8* WireFormatLite::WriteFloatNoTagToArray(
1496     const RepeatedField<float>& value, uint8* target) {
1497   return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target);
1498 }
WriteDoubleNoTagToArray(const RepeatedField<double> & value,uint8 * target)1499 inline uint8* WireFormatLite::WriteDoubleNoTagToArray(
1500     const RepeatedField<double>& value, uint8* target) {
1501   return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target);
1502 }
WriteBoolNoTagToArray(const RepeatedField<bool> & value,uint8 * target)1503 inline uint8* WireFormatLite::WriteBoolNoTagToArray(
1504     const RepeatedField<bool>& value, uint8* target) {
1505   return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target);
1506 }
WriteEnumNoTagToArray(const RepeatedField<int> & value,uint8 * target)1507 inline uint8* WireFormatLite::WriteEnumNoTagToArray(
1508     const RepeatedField<int>& value, uint8* target) {
1509   return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target);
1510 }
1511 
WriteInt32ToArray(int field_number,int32 value,uint8 * target)1512 inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, int32 value,
1513                                                 uint8* target) {
1514   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1515   return WriteInt32NoTagToArray(value, target);
1516 }
WriteInt64ToArray(int field_number,int64 value,uint8 * target)1517 inline uint8* WireFormatLite::WriteInt64ToArray(int field_number, int64 value,
1518                                                 uint8* target) {
1519   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1520   return WriteInt64NoTagToArray(value, target);
1521 }
WriteUInt32ToArray(int field_number,uint32 value,uint8 * target)1522 inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number, uint32 value,
1523                                                  uint8* target) {
1524   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1525   return WriteUInt32NoTagToArray(value, target);
1526 }
WriteUInt64ToArray(int field_number,uint64 value,uint8 * target)1527 inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number, uint64 value,
1528                                                  uint8* target) {
1529   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1530   return WriteUInt64NoTagToArray(value, target);
1531 }
WriteSInt32ToArray(int field_number,int32 value,uint8 * target)1532 inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number, int32 value,
1533                                                  uint8* target) {
1534   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1535   return WriteSInt32NoTagToArray(value, target);
1536 }
WriteSInt64ToArray(int field_number,int64 value,uint8 * target)1537 inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number, int64 value,
1538                                                  uint8* target) {
1539   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1540   return WriteSInt64NoTagToArray(value, target);
1541 }
WriteFixed32ToArray(int field_number,uint32 value,uint8 * target)1542 inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
1543                                                   uint32 value, uint8* target) {
1544   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1545   return WriteFixed32NoTagToArray(value, target);
1546 }
WriteFixed64ToArray(int field_number,uint64 value,uint8 * target)1547 inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
1548                                                   uint64 value, uint8* target) {
1549   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1550   return WriteFixed64NoTagToArray(value, target);
1551 }
WriteSFixed32ToArray(int field_number,int32 value,uint8 * target)1552 inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
1553                                                    int32 value, uint8* target) {
1554   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1555   return WriteSFixed32NoTagToArray(value, target);
1556 }
WriteSFixed64ToArray(int field_number,int64 value,uint8 * target)1557 inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
1558                                                    int64 value, uint8* target) {
1559   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1560   return WriteSFixed64NoTagToArray(value, target);
1561 }
WriteFloatToArray(int field_number,float value,uint8 * target)1562 inline uint8* WireFormatLite::WriteFloatToArray(int field_number, float value,
1563                                                 uint8* target) {
1564   target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
1565   return WriteFloatNoTagToArray(value, target);
1566 }
WriteDoubleToArray(int field_number,double value,uint8 * target)1567 inline uint8* WireFormatLite::WriteDoubleToArray(int field_number, double value,
1568                                                  uint8* target) {
1569   target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
1570   return WriteDoubleNoTagToArray(value, target);
1571 }
WriteBoolToArray(int field_number,bool value,uint8 * target)1572 inline uint8* WireFormatLite::WriteBoolToArray(int field_number, bool value,
1573                                                uint8* target) {
1574   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1575   return WriteBoolNoTagToArray(value, target);
1576 }
WriteEnumToArray(int field_number,int value,uint8 * target)1577 inline uint8* WireFormatLite::WriteEnumToArray(int field_number, int value,
1578                                                uint8* target) {
1579   target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
1580   return WriteEnumNoTagToArray(value, target);
1581 }
1582 
1583 template <typename T>
WritePrimitiveToArray(int field_number,const RepeatedField<T> & value,uint8 * (* Writer)(int,T,uint8 *),uint8 * target)1584 inline uint8* WireFormatLite::WritePrimitiveToArray(
1585     int field_number, const RepeatedField<T>& value,
1586     uint8* (*Writer)(int, T, uint8*), uint8* target) {
1587   const int n = value.size();
1588   if (n == 0) {
1589     return target;
1590   }
1591 
1592   const T* ii = value.data();
1593   int i = 0;
1594   do {
1595     target = Writer(field_number, ii[i], target);
1596   } while (++i < n);
1597 
1598   return target;
1599 }
1600 
WriteInt32ToArray(int field_number,const RepeatedField<int32> & value,uint8 * target)1601 inline uint8* WireFormatLite::WriteInt32ToArray(
1602     int field_number, const RepeatedField<int32>& value, uint8* target) {
1603   return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target);
1604 }
WriteInt64ToArray(int field_number,const RepeatedField<int64> & value,uint8 * target)1605 inline uint8* WireFormatLite::WriteInt64ToArray(
1606     int field_number, const RepeatedField<int64>& value, uint8* target) {
1607   return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target);
1608 }
WriteUInt32ToArray(int field_number,const RepeatedField<uint32> & value,uint8 * target)1609 inline uint8* WireFormatLite::WriteUInt32ToArray(
1610     int field_number, const RepeatedField<uint32>& value, uint8* target) {
1611   return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target);
1612 }
WriteUInt64ToArray(int field_number,const RepeatedField<uint64> & value,uint8 * target)1613 inline uint8* WireFormatLite::WriteUInt64ToArray(
1614     int field_number, const RepeatedField<uint64>& value, uint8* target) {
1615   return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target);
1616 }
WriteSInt32ToArray(int field_number,const RepeatedField<int32> & value,uint8 * target)1617 inline uint8* WireFormatLite::WriteSInt32ToArray(
1618     int field_number, const RepeatedField<int32>& value, uint8* target) {
1619   return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target);
1620 }
WriteSInt64ToArray(int field_number,const RepeatedField<int64> & value,uint8 * target)1621 inline uint8* WireFormatLite::WriteSInt64ToArray(
1622     int field_number, const RepeatedField<int64>& value, uint8* target) {
1623   return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target);
1624 }
WriteFixed32ToArray(int field_number,const RepeatedField<uint32> & value,uint8 * target)1625 inline uint8* WireFormatLite::WriteFixed32ToArray(
1626     int field_number, const RepeatedField<uint32>& value, uint8* target) {
1627   return WritePrimitiveToArray(field_number, value, WriteFixed32ToArray,
1628                                target);
1629 }
WriteFixed64ToArray(int field_number,const RepeatedField<uint64> & value,uint8 * target)1630 inline uint8* WireFormatLite::WriteFixed64ToArray(
1631     int field_number, const RepeatedField<uint64>& value, uint8* target) {
1632   return WritePrimitiveToArray(field_number, value, WriteFixed64ToArray,
1633                                target);
1634 }
WriteSFixed32ToArray(int field_number,const RepeatedField<int32> & value,uint8 * target)1635 inline uint8* WireFormatLite::WriteSFixed32ToArray(
1636     int field_number, const RepeatedField<int32>& value, uint8* target) {
1637   return WritePrimitiveToArray(field_number, value, WriteSFixed32ToArray,
1638                                target);
1639 }
WriteSFixed64ToArray(int field_number,const RepeatedField<int64> & value,uint8 * target)1640 inline uint8* WireFormatLite::WriteSFixed64ToArray(
1641     int field_number, const RepeatedField<int64>& value, uint8* target) {
1642   return WritePrimitiveToArray(field_number, value, WriteSFixed64ToArray,
1643                                target);
1644 }
WriteFloatToArray(int field_number,const RepeatedField<float> & value,uint8 * target)1645 inline uint8* WireFormatLite::WriteFloatToArray(
1646     int field_number, const RepeatedField<float>& value, uint8* target) {
1647   return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target);
1648 }
WriteDoubleToArray(int field_number,const RepeatedField<double> & value,uint8 * target)1649 inline uint8* WireFormatLite::WriteDoubleToArray(
1650     int field_number, const RepeatedField<double>& value, uint8* target) {
1651   return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target);
1652 }
WriteBoolToArray(int field_number,const RepeatedField<bool> & value,uint8 * target)1653 inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
1654                                                const RepeatedField<bool>& value,
1655                                                uint8* target) {
1656   return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target);
1657 }
WriteEnumToArray(int field_number,const RepeatedField<int> & value,uint8 * target)1658 inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
1659                                                const RepeatedField<int>& value,
1660                                                uint8* target) {
1661   return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target);
1662 }
WriteStringToArray(int field_number,const std::string & value,uint8 * target)1663 inline uint8* WireFormatLite::WriteStringToArray(int field_number,
1664                                                  const std::string& value,
1665                                                  uint8* target) {
1666   // String is for UTF-8 text only
1667   // WARNING:  In wire_format.cc, both strings and bytes are handled by
1668   //   WriteString() to avoid code duplication.  If the implementations become
1669   //   different, you will need to update that usage.
1670   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1671   return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
1672 }
WriteBytesToArray(int field_number,const std::string & value,uint8 * target)1673 inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
1674                                                 const std::string& value,
1675                                                 uint8* target) {
1676   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1677   return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
1678 }
1679 
1680 
1681 template <typename MessageType>
InternalWriteGroup(int field_number,const MessageType & value,uint8 * target,io::EpsCopyOutputStream * stream)1682 inline uint8* WireFormatLite::InternalWriteGroup(
1683     int field_number, const MessageType& value, uint8* target,
1684     io::EpsCopyOutputStream* stream) {
1685   target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
1686   target = value._InternalSerialize(target, stream);
1687   target = stream->EnsureSpace(target);
1688   return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
1689 }
1690 template <typename MessageType>
InternalWriteMessage(int field_number,const MessageType & value,uint8 * target,io::EpsCopyOutputStream * stream)1691 inline uint8* WireFormatLite::InternalWriteMessage(
1692     int field_number, const MessageType& value, uint8* target,
1693     io::EpsCopyOutputStream* stream) {
1694   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1695   target = io::CodedOutputStream::WriteVarint32ToArray(
1696       static_cast<uint32>(value.GetCachedSize()), target);
1697   return value._InternalSerialize(target, stream);
1698 }
1699 
1700 // See comment on ReadGroupNoVirtual to understand the need for this template
1701 // parameter name.
1702 template <typename MessageType_WorkAroundCppLookupDefect>
InternalWriteGroupNoVirtualToArray(int field_number,const MessageType_WorkAroundCppLookupDefect & value,uint8 * target)1703 inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray(
1704     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1705     uint8* target) {
1706   target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
1707   target = value.MessageType_WorkAroundCppLookupDefect::
1708                SerializeWithCachedSizesToArray(target);
1709   return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
1710 }
1711 template <typename MessageType_WorkAroundCppLookupDefect>
InternalWriteMessageNoVirtualToArray(int field_number,const MessageType_WorkAroundCppLookupDefect & value,uint8 * target)1712 inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray(
1713     int field_number, const MessageType_WorkAroundCppLookupDefect& value,
1714     uint8* target) {
1715   target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
1716   target = io::CodedOutputStream::WriteVarint32ToArray(
1717       static_cast<uint32>(
1718           value.MessageType_WorkAroundCppLookupDefect::GetCachedSize()),
1719       target);
1720   return value
1721       .MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizesToArray(
1722           target);
1723 }
1724 
1725 // ===================================================================
1726 
Int32Size(int32 value)1727 inline size_t WireFormatLite::Int32Size(int32 value) {
1728   return io::CodedOutputStream::VarintSize32SignExtended(value);
1729 }
Int64Size(int64 value)1730 inline size_t WireFormatLite::Int64Size(int64 value) {
1731   return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
1732 }
UInt32Size(uint32 value)1733 inline size_t WireFormatLite::UInt32Size(uint32 value) {
1734   return io::CodedOutputStream::VarintSize32(value);
1735 }
UInt64Size(uint64 value)1736 inline size_t WireFormatLite::UInt64Size(uint64 value) {
1737   return io::CodedOutputStream::VarintSize64(value);
1738 }
SInt32Size(int32 value)1739 inline size_t WireFormatLite::SInt32Size(int32 value) {
1740   return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
1741 }
SInt64Size(int64 value)1742 inline size_t WireFormatLite::SInt64Size(int64 value) {
1743   return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
1744 }
EnumSize(int value)1745 inline size_t WireFormatLite::EnumSize(int value) {
1746   return io::CodedOutputStream::VarintSize32SignExtended(value);
1747 }
1748 
StringSize(const std::string & value)1749 inline size_t WireFormatLite::StringSize(const std::string& value) {
1750   return LengthDelimitedSize(value.size());
1751 }
BytesSize(const std::string & value)1752 inline size_t WireFormatLite::BytesSize(const std::string& value) {
1753   return LengthDelimitedSize(value.size());
1754 }
1755 
1756 
1757 template <typename MessageType>
GroupSize(const MessageType & value)1758 inline size_t WireFormatLite::GroupSize(const MessageType& value) {
1759   return value.ByteSizeLong();
1760 }
1761 template <typename MessageType>
MessageSize(const MessageType & value)1762 inline size_t WireFormatLite::MessageSize(const MessageType& value) {
1763   return LengthDelimitedSize(value.ByteSizeLong());
1764 }
1765 
1766 // See comment on ReadGroupNoVirtual to understand the need for this template
1767 // parameter name.
1768 template <typename MessageType_WorkAroundCppLookupDefect>
GroupSizeNoVirtual(const MessageType_WorkAroundCppLookupDefect & value)1769 inline size_t WireFormatLite::GroupSizeNoVirtual(
1770     const MessageType_WorkAroundCppLookupDefect& value) {
1771   return value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong();
1772 }
1773 template <typename MessageType_WorkAroundCppLookupDefect>
MessageSizeNoVirtual(const MessageType_WorkAroundCppLookupDefect & value)1774 inline size_t WireFormatLite::MessageSizeNoVirtual(
1775     const MessageType_WorkAroundCppLookupDefect& value) {
1776   return LengthDelimitedSize(
1777       value.MessageType_WorkAroundCppLookupDefect::ByteSizeLong());
1778 }
1779 
LengthDelimitedSize(size_t length)1780 inline size_t WireFormatLite::LengthDelimitedSize(size_t length) {
1781   // The static_cast here prevents an error in certain compiler configurations
1782   // but is not technically correct--if length is too large to fit in a uint32
1783   // then it will be silently truncated. We will need to fix this if we ever
1784   // decide to start supporting serialized messages greater than 2 GiB in size.
1785   return length +
1786          io::CodedOutputStream::VarintSize32(static_cast<uint32>(length));
1787 }
1788 
1789 template <typename MS>
ParseMessageSetItemImpl(io::CodedInputStream * input,MS ms)1790 bool ParseMessageSetItemImpl(io::CodedInputStream* input, MS ms) {
1791   // This method parses a group which should contain two fields:
1792   //   required int32 type_id = 2;
1793   //   required data message = 3;
1794 
1795   uint32 last_type_id = 0;
1796 
1797   // If we see message data before the type_id, we'll append it to this so
1798   // we can parse it later.
1799   std::string message_data;
1800 
1801   while (true) {
1802     const uint32 tag = input->ReadTagNoLastTag();
1803     if (tag == 0) return false;
1804 
1805     switch (tag) {
1806       case WireFormatLite::kMessageSetTypeIdTag: {
1807         uint32 type_id;
1808         if (!input->ReadVarint32(&type_id)) return false;
1809         last_type_id = type_id;
1810 
1811         if (!message_data.empty()) {
1812           // We saw some message data before the type_id.  Have to parse it
1813           // now.
1814           io::CodedInputStream sub_input(
1815               reinterpret_cast<const uint8*>(message_data.data()),
1816               static_cast<int>(message_data.size()));
1817           sub_input.SetRecursionLimit(input->RecursionBudget());
1818           if (!ms.ParseField(last_type_id, &sub_input)) {
1819             return false;
1820           }
1821           message_data.clear();
1822         }
1823 
1824         break;
1825       }
1826 
1827       case WireFormatLite::kMessageSetMessageTag: {
1828         if (last_type_id == 0) {
1829           // We haven't seen a type_id yet.  Append this data to message_data.
1830           uint32 length;
1831           if (!input->ReadVarint32(&length)) return false;
1832           if (static_cast<int32>(length) < 0) return false;
1833           uint32 size = static_cast<uint32>(
1834               length + io::CodedOutputStream::VarintSize32(length));
1835           message_data.resize(size);
1836           auto ptr = reinterpret_cast<uint8*>(&message_data[0]);
1837           ptr = io::CodedOutputStream::WriteVarint32ToArray(length, ptr);
1838           if (!input->ReadRaw(ptr, length)) return false;
1839         } else {
1840           // Already saw type_id, so we can parse this directly.
1841           if (!ms.ParseField(last_type_id, input)) {
1842             return false;
1843           }
1844         }
1845 
1846         break;
1847       }
1848 
1849       case WireFormatLite::kMessageSetItemEndTag: {
1850         return true;
1851       }
1852 
1853       default: {
1854         if (!ms.SkipField(tag, input)) return false;
1855       }
1856     }
1857   }
1858 }
1859 
1860 }  // namespace internal
1861 }  // namespace protobuf
1862 }  // namespace google
1863 
1864 #include <google/protobuf/port_undef.inc>
1865 
1866 #endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
1867