/proc/self/cwd/external/com_google_protobuf/src/google/protobuf/wire_format.cc
Line | Count | Source (jump to first uncovered line) |
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 | | // Based on original Protocol Buffers design by |
33 | | // Sanjay Ghemawat, Jeff Dean, and others. |
34 | | |
35 | | #include "google/protobuf/wire_format.h" |
36 | | |
37 | | #include <stack> |
38 | | #include <string> |
39 | | #include <vector> |
40 | | |
41 | | #include "absl/log/absl_check.h" |
42 | | #include "absl/log/absl_log.h" |
43 | | #include "absl/strings/cord.h" |
44 | | #include "google/protobuf/descriptor.h" |
45 | | #include "google/protobuf/descriptor.pb.h" |
46 | | #include "google/protobuf/dynamic_message.h" |
47 | | #include "google/protobuf/io/coded_stream.h" |
48 | | #include "google/protobuf/io/zero_copy_stream.h" |
49 | | #include "google/protobuf/io/zero_copy_stream_impl.h" |
50 | | #include "google/protobuf/map_field.h" |
51 | | #include "google/protobuf/map_field_inl.h" |
52 | | #include "google/protobuf/message.h" |
53 | | #include "google/protobuf/message_lite.h" |
54 | | #include "google/protobuf/parse_context.h" |
55 | | #include "google/protobuf/unknown_field_set.h" |
56 | | |
57 | | |
58 | | // Must be included last. |
59 | | #include "google/protobuf/port_def.inc" |
60 | | |
61 | | const size_t kMapEntryTagByteSize = 2; |
62 | | |
63 | | namespace google { |
64 | | namespace protobuf { |
65 | | namespace internal { |
66 | | |
67 | | // Forward declare static functions |
68 | | static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, |
69 | | const MapValueConstRef& value); |
70 | | |
71 | | // =================================================================== |
72 | | |
73 | | bool UnknownFieldSetFieldSkipper::SkipField(io::CodedInputStream* input, |
74 | 0 | uint32_t tag) { |
75 | 0 | return WireFormat::SkipField(input, tag, unknown_fields_); |
76 | 0 | } |
77 | | |
78 | 0 | bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) { |
79 | 0 | return WireFormat::SkipMessage(input, unknown_fields_); |
80 | 0 | } |
81 | | |
82 | 0 | void UnknownFieldSetFieldSkipper::SkipUnknownEnum(int field_number, int value) { |
83 | 0 | unknown_fields_->AddVarint(field_number, value); |
84 | 0 | } |
85 | | |
86 | | bool WireFormat::SkipField(io::CodedInputStream* input, uint32_t tag, |
87 | 7.07k | UnknownFieldSet* unknown_fields) { |
88 | 7.07k | int number = WireFormatLite::GetTagFieldNumber(tag); |
89 | | // Field number 0 is illegal. |
90 | 7.07k | if (number == 0) return false; |
91 | | |
92 | 6.96k | switch (WireFormatLite::GetTagWireType(tag)) { |
93 | 798 | case WireFormatLite::WIRETYPE_VARINT: { |
94 | 798 | uint64_t value; |
95 | 798 | if (!input->ReadVarint64(&value)) return false; |
96 | 606 | if (unknown_fields != nullptr) unknown_fields->AddVarint(number, value); |
97 | 606 | return true; |
98 | 798 | } |
99 | 196 | case WireFormatLite::WIRETYPE_FIXED64: { |
100 | 196 | uint64_t value; |
101 | 196 | if (!input->ReadLittleEndian64(&value)) return false; |
102 | 77 | if (unknown_fields != nullptr) unknown_fields->AddFixed64(number, value); |
103 | 77 | return true; |
104 | 196 | } |
105 | 4.69k | case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: { |
106 | 4.69k | uint32_t length; |
107 | 4.69k | if (!input->ReadVarint32(&length)) return false; |
108 | 4.69k | if (unknown_fields == nullptr) { |
109 | 0 | if (!input->Skip(length)) return false; |
110 | 4.69k | } else { |
111 | 4.69k | if (!input->ReadString(unknown_fields->AddLengthDelimited(number), |
112 | 4.69k | length)) { |
113 | 640 | return false; |
114 | 640 | } |
115 | 4.69k | } |
116 | 4.05k | return true; |
117 | 4.69k | } |
118 | 64 | case WireFormatLite::WIRETYPE_START_GROUP: { |
119 | 64 | if (!input->IncrementRecursionDepth()) return false; |
120 | 64 | if (!SkipMessage(input, (unknown_fields == nullptr) |
121 | 64 | ? nullptr |
122 | 64 | : unknown_fields->AddGroup(number))) { |
123 | 2 | return false; |
124 | 2 | } |
125 | 62 | input->DecrementRecursionDepth(); |
126 | | // Check that the ending tag matched the starting tag. |
127 | 62 | if (!input->LastTagWas( |
128 | 62 | WireFormatLite::MakeTag(WireFormatLite::GetTagFieldNumber(tag), |
129 | 62 | WireFormatLite::WIRETYPE_END_GROUP))) { |
130 | 57 | return false; |
131 | 57 | } |
132 | 5 | return true; |
133 | 62 | } |
134 | 0 | case WireFormatLite::WIRETYPE_END_GROUP: { |
135 | 0 | return false; |
136 | 62 | } |
137 | 775 | case WireFormatLite::WIRETYPE_FIXED32: { |
138 | 775 | uint32_t value; |
139 | 775 | if (!input->ReadLittleEndian32(&value)) return false; |
140 | 704 | if (unknown_fields != nullptr) unknown_fields->AddFixed32(number, value); |
141 | 704 | return true; |
142 | 775 | } |
143 | 439 | default: { |
144 | 439 | return false; |
145 | 775 | } |
146 | 6.96k | } |
147 | 6.96k | } |
148 | | |
149 | | bool WireFormat::SkipMessage(io::CodedInputStream* input, |
150 | 3.75k | UnknownFieldSet* unknown_fields) { |
151 | 9.19k | while (true) { |
152 | 9.19k | uint32_t tag = input->ReadTag(); |
153 | 9.19k | if (tag == 0) { |
154 | | // End of input. This is a valid place to end, so return true. |
155 | 1.99k | return true; |
156 | 1.99k | } |
157 | | |
158 | 7.19k | WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag); |
159 | | |
160 | 7.19k | if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { |
161 | | // Must be the end of the message. |
162 | 117 | return true; |
163 | 117 | } |
164 | | |
165 | 7.07k | if (!SkipField(input, tag, unknown_fields)) return false; |
166 | 7.07k | } |
167 | 3.75k | } |
168 | | |
169 | | bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input, |
170 | | uint32_t field_number, |
171 | | bool (*is_valid)(int), |
172 | | UnknownFieldSet* unknown_fields, |
173 | 0 | RepeatedField<int>* values) { |
174 | 0 | uint32_t length; |
175 | 0 | if (!input->ReadVarint32(&length)) return false; |
176 | 0 | io::CodedInputStream::Limit limit = input->PushLimit(length); |
177 | 0 | while (input->BytesUntilLimit() > 0) { |
178 | 0 | int value; |
179 | 0 | if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
180 | 0 | input, &value)) { |
181 | 0 | return false; |
182 | 0 | } |
183 | 0 | if (is_valid == nullptr || is_valid(value)) { |
184 | 0 | values->Add(value); |
185 | 0 | } else { |
186 | 0 | unknown_fields->AddVarint(field_number, value); |
187 | 0 | } |
188 | 0 | } |
189 | 0 | input->PopLimit(limit); |
190 | 0 | return true; |
191 | 0 | } |
192 | | |
193 | | uint8_t* WireFormat::InternalSerializeUnknownFieldsToArray( |
194 | | const UnknownFieldSet& unknown_fields, uint8_t* target, |
195 | 776k | io::EpsCopyOutputStream* stream) { |
196 | 797k | for (int i = 0; i < unknown_fields.field_count(); i++) { |
197 | 20.7k | const UnknownField& field = unknown_fields.field(i); |
198 | | |
199 | 20.7k | target = stream->EnsureSpace(target); |
200 | 20.7k | switch (field.type()) { |
201 | 11.0k | case UnknownField::TYPE_VARINT: |
202 | 11.0k | target = WireFormatLite::WriteUInt64ToArray(field.number(), |
203 | 11.0k | field.varint(), target); |
204 | 11.0k | break; |
205 | 4.44k | case UnknownField::TYPE_FIXED32: |
206 | 4.44k | target = WireFormatLite::WriteFixed32ToArray(field.number(), |
207 | 4.44k | field.fixed32(), target); |
208 | 4.44k | break; |
209 | 2.38k | case UnknownField::TYPE_FIXED64: |
210 | 2.38k | target = WireFormatLite::WriteFixed64ToArray(field.number(), |
211 | 2.38k | field.fixed64(), target); |
212 | 2.38k | break; |
213 | 2.29k | case UnknownField::TYPE_LENGTH_DELIMITED: |
214 | 2.29k | target = stream->WriteString(field.number(), field.length_delimited(), |
215 | 2.29k | target); |
216 | 2.29k | break; |
217 | 619 | case UnknownField::TYPE_GROUP: |
218 | 619 | target = WireFormatLite::WriteTagToArray( |
219 | 619 | field.number(), WireFormatLite::WIRETYPE_START_GROUP, target); |
220 | 619 | target = InternalSerializeUnknownFieldsToArray(field.group(), target, |
221 | 619 | stream); |
222 | 619 | target = stream->EnsureSpace(target); |
223 | 619 | target = WireFormatLite::WriteTagToArray( |
224 | 619 | field.number(), WireFormatLite::WIRETYPE_END_GROUP, target); |
225 | 619 | break; |
226 | 20.7k | } |
227 | 20.7k | } |
228 | 776k | return target; |
229 | 776k | } |
230 | | |
231 | | uint8_t* WireFormat::InternalSerializeUnknownMessageSetItemsToArray( |
232 | | const UnknownFieldSet& unknown_fields, uint8_t* target, |
233 | 0 | io::EpsCopyOutputStream* stream) { |
234 | 0 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
235 | 0 | const UnknownField& field = unknown_fields.field(i); |
236 | | |
237 | | // The only unknown fields that are allowed to exist in a MessageSet are |
238 | | // messages, which are length-delimited. |
239 | 0 | if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { |
240 | 0 | target = stream->EnsureSpace(target); |
241 | | // Start group. |
242 | 0 | target = io::CodedOutputStream::WriteTagToArray( |
243 | 0 | WireFormatLite::kMessageSetItemStartTag, target); |
244 | | |
245 | | // Write type ID. |
246 | 0 | target = io::CodedOutputStream::WriteTagToArray( |
247 | 0 | WireFormatLite::kMessageSetTypeIdTag, target); |
248 | 0 | target = |
249 | 0 | io::CodedOutputStream::WriteVarint32ToArray(field.number(), target); |
250 | | |
251 | | // Write message. |
252 | 0 | target = io::CodedOutputStream::WriteTagToArray( |
253 | 0 | WireFormatLite::kMessageSetMessageTag, target); |
254 | |
|
255 | 0 | target = field.InternalSerializeLengthDelimitedNoTag(target, stream); |
256 | |
|
257 | 0 | target = stream->EnsureSpace(target); |
258 | | // End group. |
259 | 0 | target = io::CodedOutputStream::WriteTagToArray( |
260 | 0 | WireFormatLite::kMessageSetItemEndTag, target); |
261 | 0 | } |
262 | 0 | } |
263 | |
|
264 | 0 | return target; |
265 | 0 | } |
266 | | |
267 | | size_t WireFormat::ComputeUnknownFieldsSize( |
268 | 776k | const UnknownFieldSet& unknown_fields) { |
269 | 776k | size_t size = 0; |
270 | 797k | for (int i = 0; i < unknown_fields.field_count(); i++) { |
271 | 20.7k | const UnknownField& field = unknown_fields.field(i); |
272 | | |
273 | 20.7k | switch (field.type()) { |
274 | 11.0k | case UnknownField::TYPE_VARINT: |
275 | 11.0k | size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( |
276 | 11.0k | field.number(), WireFormatLite::WIRETYPE_VARINT)); |
277 | 11.0k | size += io::CodedOutputStream::VarintSize64(field.varint()); |
278 | 11.0k | break; |
279 | 4.44k | case UnknownField::TYPE_FIXED32: |
280 | 4.44k | size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( |
281 | 4.44k | field.number(), WireFormatLite::WIRETYPE_FIXED32)); |
282 | 4.44k | size += sizeof(int32_t); |
283 | 4.44k | break; |
284 | 2.38k | case UnknownField::TYPE_FIXED64: |
285 | 2.38k | size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( |
286 | 2.38k | field.number(), WireFormatLite::WIRETYPE_FIXED64)); |
287 | 2.38k | size += sizeof(int64_t); |
288 | 2.38k | break; |
289 | 2.29k | case UnknownField::TYPE_LENGTH_DELIMITED: |
290 | 2.29k | size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( |
291 | 2.29k | field.number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); |
292 | 2.29k | size += io::CodedOutputStream::VarintSize32( |
293 | 2.29k | field.length_delimited().size()); |
294 | 2.29k | size += field.length_delimited().size(); |
295 | 2.29k | break; |
296 | 619 | case UnknownField::TYPE_GROUP: |
297 | 619 | size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( |
298 | 619 | field.number(), WireFormatLite::WIRETYPE_START_GROUP)); |
299 | 619 | size += ComputeUnknownFieldsSize(field.group()); |
300 | 619 | size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag( |
301 | 619 | field.number(), WireFormatLite::WIRETYPE_END_GROUP)); |
302 | 619 | break; |
303 | 20.7k | } |
304 | 20.7k | } |
305 | | |
306 | 776k | return size; |
307 | 776k | } |
308 | | |
309 | | size_t WireFormat::ComputeUnknownMessageSetItemsSize( |
310 | 0 | const UnknownFieldSet& unknown_fields) { |
311 | 0 | size_t size = 0; |
312 | 0 | for (int i = 0; i < unknown_fields.field_count(); i++) { |
313 | 0 | const UnknownField& field = unknown_fields.field(i); |
314 | | |
315 | | // The only unknown fields that are allowed to exist in a MessageSet are |
316 | | // messages, which are length-delimited. |
317 | 0 | if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) { |
318 | 0 | size += WireFormatLite::kMessageSetItemTagsSize; |
319 | 0 | size += io::CodedOutputStream::VarintSize32(field.number()); |
320 | |
|
321 | 0 | int field_size = field.GetLengthDelimitedSize(); |
322 | 0 | size += io::CodedOutputStream::VarintSize32(field_size); |
323 | 0 | size += field_size; |
324 | 0 | } |
325 | 0 | } |
326 | |
|
327 | 0 | return size; |
328 | 0 | } |
329 | | |
330 | | // =================================================================== |
331 | | |
332 | | bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input, |
333 | 0 | Message* message) { |
334 | 0 | const Descriptor* descriptor = message->GetDescriptor(); |
335 | 0 | const Reflection* message_reflection = message->GetReflection(); |
336 | |
|
337 | 0 | while (true) { |
338 | 0 | uint32_t tag = input->ReadTag(); |
339 | 0 | if (tag == 0) { |
340 | | // End of input. This is a valid place to end, so return true. |
341 | 0 | return true; |
342 | 0 | } |
343 | | |
344 | 0 | if (WireFormatLite::GetTagWireType(tag) == |
345 | 0 | WireFormatLite::WIRETYPE_END_GROUP) { |
346 | | // Must be the end of the message. |
347 | 0 | return true; |
348 | 0 | } |
349 | | |
350 | 0 | const FieldDescriptor* field = nullptr; |
351 | |
|
352 | 0 | if (descriptor != nullptr) { |
353 | 0 | int field_number = WireFormatLite::GetTagFieldNumber(tag); |
354 | 0 | field = descriptor->FindFieldByNumber(field_number); |
355 | | |
356 | | // If that failed, check if the field is an extension. |
357 | 0 | if (field == nullptr && descriptor->IsExtensionNumber(field_number)) { |
358 | 0 | if (input->GetExtensionPool() == nullptr) { |
359 | 0 | field = message_reflection->FindKnownExtensionByNumber(field_number); |
360 | 0 | } else { |
361 | 0 | field = input->GetExtensionPool()->FindExtensionByNumber( |
362 | 0 | descriptor, field_number); |
363 | 0 | } |
364 | 0 | } |
365 | | |
366 | | // If that failed, but we're a MessageSet, and this is the tag for a |
367 | | // MessageSet item, then parse that. |
368 | 0 | if (field == nullptr && descriptor->options().message_set_wire_format() && |
369 | 0 | tag == WireFormatLite::kMessageSetItemStartTag) { |
370 | 0 | if (!ParseAndMergeMessageSetItem(input, message)) { |
371 | 0 | return false; |
372 | 0 | } |
373 | 0 | continue; // Skip ParseAndMergeField(); already taken care of. |
374 | 0 | } |
375 | 0 | } |
376 | | |
377 | 0 | if (!ParseAndMergeField(tag, field, message, input)) { |
378 | 0 | return false; |
379 | 0 | } |
380 | 0 | } |
381 | 0 | } |
382 | | |
383 | | bool WireFormat::SkipMessageSetField(io::CodedInputStream* input, |
384 | | uint32_t field_number, |
385 | 0 | UnknownFieldSet* unknown_fields) { |
386 | 0 | uint32_t length; |
387 | 0 | if (!input->ReadVarint32(&length)) return false; |
388 | 0 | return input->ReadString(unknown_fields->AddLengthDelimited(field_number), |
389 | 0 | length); |
390 | 0 | } |
391 | | |
392 | | bool WireFormat::ParseAndMergeMessageSetField(uint32_t field_number, |
393 | | const FieldDescriptor* field, |
394 | | Message* message, |
395 | 0 | io::CodedInputStream* input) { |
396 | 0 | const Reflection* message_reflection = message->GetReflection(); |
397 | 0 | if (field == nullptr) { |
398 | | // We store unknown MessageSet extensions as groups. |
399 | 0 | return SkipMessageSetField( |
400 | 0 | input, field_number, message_reflection->MutableUnknownFields(message)); |
401 | 0 | } else if (field->is_repeated() || |
402 | 0 | field->type() != FieldDescriptor::TYPE_MESSAGE) { |
403 | | // This shouldn't happen as we only allow optional message extensions to |
404 | | // MessageSet. |
405 | 0 | ABSL_LOG(ERROR) << "Extensions of MessageSets must be optional messages."; |
406 | 0 | return false; |
407 | 0 | } else { |
408 | 0 | Message* sub_message = message_reflection->MutableMessage( |
409 | 0 | message, field, input->GetExtensionFactory()); |
410 | 0 | return WireFormatLite::ReadMessage(input, sub_message); |
411 | 0 | } |
412 | 0 | } |
413 | | |
414 | | bool WireFormat::ParseAndMergeField( |
415 | | uint32_t tag, |
416 | | const FieldDescriptor* field, // May be nullptr for unknown |
417 | 0 | Message* message, io::CodedInputStream* input) { |
418 | 0 | const Reflection* message_reflection = message->GetReflection(); |
419 | |
|
420 | 0 | enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format; |
421 | |
|
422 | 0 | if (field == nullptr) { |
423 | 0 | value_format = UNKNOWN; |
424 | 0 | } else if (WireFormatLite::GetTagWireType(tag) == |
425 | 0 | WireTypeForFieldType(field->type())) { |
426 | 0 | value_format = NORMAL_FORMAT; |
427 | 0 | } else if (field->is_packable() && |
428 | 0 | WireFormatLite::GetTagWireType(tag) == |
429 | 0 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { |
430 | 0 | value_format = PACKED_FORMAT; |
431 | 0 | } else { |
432 | | // We don't recognize this field. Either the field number is unknown |
433 | | // or the wire type doesn't match. Put it in our unknown field set. |
434 | 0 | value_format = UNKNOWN; |
435 | 0 | } |
436 | |
|
437 | 0 | if (value_format == UNKNOWN) { |
438 | 0 | return SkipField(input, tag, |
439 | 0 | message_reflection->MutableUnknownFields(message)); |
440 | 0 | } else if (value_format == PACKED_FORMAT) { |
441 | 0 | uint32_t length; |
442 | 0 | if (!input->ReadVarint32(&length)) return false; |
443 | 0 | io::CodedInputStream::Limit limit = input->PushLimit(length); |
444 | |
|
445 | 0 | switch (field->type()) { |
446 | 0 | #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
447 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
448 | 0 | while (input->BytesUntilLimit() > 0) { \ |
449 | 0 | CPPTYPE value; \ |
450 | 0 | if (!WireFormatLite::ReadPrimitive<CPPTYPE, \ |
451 | 0 | WireFormatLite::TYPE_##TYPE>(input, \ |
452 | 0 | &value)) \ |
453 | 0 | return false; \ |
454 | 0 | message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ |
455 | 0 | } \ |
456 | 0 | break; \ |
457 | 0 | } |
458 | | |
459 | 0 | HANDLE_PACKED_TYPE(INT32, int32_t, Int32) |
460 | 0 | HANDLE_PACKED_TYPE(INT64, int64_t, Int64) |
461 | 0 | HANDLE_PACKED_TYPE(SINT32, int32_t, Int32) |
462 | 0 | HANDLE_PACKED_TYPE(SINT64, int64_t, Int64) |
463 | 0 | HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) |
464 | 0 | HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) |
465 | | |
466 | 0 | HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32) |
467 | 0 | HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64) |
468 | 0 | HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32) |
469 | 0 | HANDLE_PACKED_TYPE(SFIXED64, int64_t, Int64) |
470 | | |
471 | 0 | HANDLE_PACKED_TYPE(FLOAT, float, Float) |
472 | 0 | HANDLE_PACKED_TYPE(DOUBLE, double, Double) |
473 | | |
474 | 0 | HANDLE_PACKED_TYPE(BOOL, bool, Bool) |
475 | 0 | #undef HANDLE_PACKED_TYPE |
476 | | |
477 | 0 | case FieldDescriptor::TYPE_ENUM: { |
478 | 0 | while (input->BytesUntilLimit() > 0) { |
479 | 0 | int value; |
480 | 0 | if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
481 | 0 | input, &value)) |
482 | 0 | return false; |
483 | 0 | if (!field->legacy_enum_field_treated_as_closed()) { |
484 | 0 | message_reflection->AddEnumValue(message, field, value); |
485 | 0 | } else { |
486 | 0 | const EnumValueDescriptor* enum_value = |
487 | 0 | field->enum_type()->FindValueByNumber(value); |
488 | 0 | if (enum_value != nullptr) { |
489 | 0 | message_reflection->AddEnum(message, field, enum_value); |
490 | 0 | } else { |
491 | | // The enum value is not one of the known values. Add it to the |
492 | | // UnknownFieldSet. |
493 | 0 | int64_t sign_extended_value = static_cast<int64_t>(value); |
494 | 0 | message_reflection->MutableUnknownFields(message)->AddVarint( |
495 | 0 | WireFormatLite::GetTagFieldNumber(tag), sign_extended_value); |
496 | 0 | } |
497 | 0 | } |
498 | 0 | } |
499 | | |
500 | 0 | break; |
501 | 0 | } |
502 | | |
503 | 0 | case FieldDescriptor::TYPE_STRING: |
504 | 0 | case FieldDescriptor::TYPE_GROUP: |
505 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
506 | 0 | case FieldDescriptor::TYPE_BYTES: |
507 | | // Can't have packed fields of these types: these should be caught by |
508 | | // the protocol compiler. |
509 | 0 | return false; |
510 | 0 | break; |
511 | 0 | } |
512 | | |
513 | 0 | input->PopLimit(limit); |
514 | 0 | } else { |
515 | | // Non-packed value (value_format == NORMAL_FORMAT) |
516 | 0 | switch (field->type()) { |
517 | 0 | #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
518 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
519 | 0 | CPPTYPE value; \ |
520 | 0 | if (!WireFormatLite::ReadPrimitive<CPPTYPE, WireFormatLite::TYPE_##TYPE>( \ |
521 | 0 | input, &value)) \ |
522 | 0 | return false; \ |
523 | 0 | if (field->is_repeated()) { \ |
524 | 0 | message_reflection->Add##CPPTYPE_METHOD(message, field, value); \ |
525 | 0 | } else { \ |
526 | 0 | message_reflection->Set##CPPTYPE_METHOD(message, field, value); \ |
527 | 0 | } \ |
528 | 0 | break; \ |
529 | 0 | } |
530 | | |
531 | 0 | HANDLE_TYPE(INT32, int32_t, Int32) |
532 | 0 | HANDLE_TYPE(INT64, int64_t, Int64) |
533 | 0 | HANDLE_TYPE(SINT32, int32_t, Int32) |
534 | 0 | HANDLE_TYPE(SINT64, int64_t, Int64) |
535 | 0 | HANDLE_TYPE(UINT32, uint32_t, UInt32) |
536 | 0 | HANDLE_TYPE(UINT64, uint64_t, UInt64) |
537 | | |
538 | 0 | HANDLE_TYPE(FIXED32, uint32_t, UInt32) |
539 | 0 | HANDLE_TYPE(FIXED64, uint64_t, UInt64) |
540 | 0 | HANDLE_TYPE(SFIXED32, int32_t, Int32) |
541 | 0 | HANDLE_TYPE(SFIXED64, int64_t, Int64) |
542 | | |
543 | 0 | HANDLE_TYPE(FLOAT, float, Float) |
544 | 0 | HANDLE_TYPE(DOUBLE, double, Double) |
545 | | |
546 | 0 | HANDLE_TYPE(BOOL, bool, Bool) |
547 | 0 | #undef HANDLE_TYPE |
548 | | |
549 | 0 | case FieldDescriptor::TYPE_ENUM: { |
550 | 0 | int value; |
551 | 0 | if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>( |
552 | 0 | input, &value)) |
553 | 0 | return false; |
554 | 0 | if (field->is_repeated()) { |
555 | 0 | message_reflection->AddEnumValue(message, field, value); |
556 | 0 | } else { |
557 | 0 | message_reflection->SetEnumValue(message, field, value); |
558 | 0 | } |
559 | 0 | break; |
560 | 0 | } |
561 | | |
562 | | // Handle strings separately so that we can optimize the ctype=CORD case. |
563 | 0 | case FieldDescriptor::TYPE_STRING: { |
564 | 0 | bool strict_utf8_check = field->requires_utf8_validation(); |
565 | 0 | std::string value; |
566 | 0 | if (!WireFormatLite::ReadString(input, &value)) return false; |
567 | 0 | if (strict_utf8_check) { |
568 | 0 | if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(), |
569 | 0 | WireFormatLite::PARSE, |
570 | 0 | field->full_name().c_str())) { |
571 | 0 | return false; |
572 | 0 | } |
573 | 0 | } else { |
574 | 0 | VerifyUTF8StringNamedField(value.data(), value.length(), PARSE, |
575 | 0 | field->full_name().c_str()); |
576 | 0 | } |
577 | 0 | if (field->is_repeated()) { |
578 | 0 | message_reflection->AddString(message, field, value); |
579 | 0 | } else { |
580 | 0 | message_reflection->SetString(message, field, value); |
581 | 0 | } |
582 | 0 | break; |
583 | 0 | } |
584 | | |
585 | 0 | case FieldDescriptor::TYPE_BYTES: { |
586 | 0 | if (internal::cpp::EffectiveStringCType(field) == FieldOptions::CORD) { |
587 | 0 | absl::Cord value; |
588 | 0 | if (!WireFormatLite::ReadBytes(input, &value)) return false; |
589 | 0 | message_reflection->SetString(message, field, value); |
590 | 0 | break; |
591 | 0 | } |
592 | 0 | std::string value; |
593 | 0 | if (!WireFormatLite::ReadBytes(input, &value)) return false; |
594 | 0 | if (field->is_repeated()) { |
595 | 0 | message_reflection->AddString(message, field, value); |
596 | 0 | } else { |
597 | 0 | message_reflection->SetString(message, field, value); |
598 | 0 | } |
599 | 0 | break; |
600 | 0 | } |
601 | | |
602 | 0 | case FieldDescriptor::TYPE_GROUP: { |
603 | 0 | Message* sub_message; |
604 | 0 | if (field->is_repeated()) { |
605 | 0 | sub_message = message_reflection->AddMessage( |
606 | 0 | message, field, input->GetExtensionFactory()); |
607 | 0 | } else { |
608 | 0 | sub_message = message_reflection->MutableMessage( |
609 | 0 | message, field, input->GetExtensionFactory()); |
610 | 0 | } |
611 | |
|
612 | 0 | if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag), |
613 | 0 | input, sub_message)) |
614 | 0 | return false; |
615 | 0 | break; |
616 | 0 | } |
617 | | |
618 | 0 | case FieldDescriptor::TYPE_MESSAGE: { |
619 | 0 | Message* sub_message; |
620 | 0 | if (field->is_repeated()) { |
621 | 0 | sub_message = message_reflection->AddMessage( |
622 | 0 | message, field, input->GetExtensionFactory()); |
623 | 0 | } else { |
624 | 0 | sub_message = message_reflection->MutableMessage( |
625 | 0 | message, field, input->GetExtensionFactory()); |
626 | 0 | } |
627 | |
|
628 | 0 | if (!WireFormatLite::ReadMessage(input, sub_message)) return false; |
629 | 0 | break; |
630 | 0 | } |
631 | 0 | } |
632 | 0 | } |
633 | | |
634 | 0 | return true; |
635 | 0 | } |
636 | | |
637 | | bool WireFormat::ParseAndMergeMessageSetItem(io::CodedInputStream* input, |
638 | 0 | Message* message) { |
639 | 0 | struct MSReflective { |
640 | 0 | bool ParseField(int type_id, io::CodedInputStream* input) { |
641 | 0 | const FieldDescriptor* field = |
642 | 0 | message_reflection->FindKnownExtensionByNumber(type_id); |
643 | 0 | return ParseAndMergeMessageSetField(type_id, field, message, input); |
644 | 0 | } |
645 | |
|
646 | 0 | bool SkipField(uint32_t tag, io::CodedInputStream* input) { |
647 | 0 | return WireFormat::SkipField(input, tag, nullptr); |
648 | 0 | } |
649 | |
|
650 | 0 | const Reflection* message_reflection; |
651 | 0 | Message* message; |
652 | 0 | }; |
653 | |
|
654 | 0 | return ParseMessageSetItemImpl( |
655 | 0 | input, MSReflective{message->GetReflection(), message}); |
656 | 0 | } |
657 | | |
658 | | struct WireFormat::MessageSetParser { |
659 | 0 | const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) { |
660 | | // Parse a MessageSetItem |
661 | 0 | auto metadata = reflection->MutableInternalMetadata(msg); |
662 | 0 | enum class State { kNoTag, kHasType, kHasPayload, kDone }; |
663 | 0 | State state = State::kNoTag; |
664 | |
|
665 | 0 | std::string payload; |
666 | 0 | uint32_t type_id = 0; |
667 | 0 | while (!ctx->Done(&ptr)) { |
668 | | // We use 64 bit tags in order to allow typeid's that span the whole |
669 | | // range of 32 bit numbers. |
670 | 0 | uint32_t tag = static_cast<uint8_t>(*ptr++); |
671 | 0 | if (tag == WireFormatLite::kMessageSetTypeIdTag) { |
672 | 0 | uint64_t tmp; |
673 | 0 | ptr = ParseBigVarint(ptr, &tmp); |
674 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
675 | 0 | if (state == State::kNoTag) { |
676 | 0 | type_id = tmp; |
677 | 0 | state = State::kHasType; |
678 | 0 | } else if (state == State::kHasPayload) { |
679 | 0 | type_id = tmp; |
680 | 0 | const FieldDescriptor* field; |
681 | 0 | if (ctx->data().pool == nullptr) { |
682 | 0 | field = reflection->FindKnownExtensionByNumber(type_id); |
683 | 0 | } else { |
684 | 0 | field = |
685 | 0 | ctx->data().pool->FindExtensionByNumber(descriptor, type_id); |
686 | 0 | } |
687 | 0 | if (field == nullptr || field->message_type() == nullptr) { |
688 | 0 | WriteLengthDelimited( |
689 | 0 | type_id, payload, |
690 | 0 | metadata->mutable_unknown_fields<UnknownFieldSet>()); |
691 | 0 | } else { |
692 | 0 | Message* value = |
693 | 0 | field->is_repeated() |
694 | 0 | ? reflection->AddMessage(msg, field, ctx->data().factory) |
695 | 0 | : reflection->MutableMessage(msg, field, |
696 | 0 | ctx->data().factory); |
697 | 0 | const char* p; |
698 | | // We can't use regular parse from string as we have to track |
699 | | // proper recursion depth and descriptor pools. |
700 | 0 | ParseContext tmp_ctx(ctx->depth(), false, &p, payload); |
701 | 0 | tmp_ctx.data().pool = ctx->data().pool; |
702 | 0 | tmp_ctx.data().factory = ctx->data().factory; |
703 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && |
704 | 0 | tmp_ctx.EndedAtLimit()); |
705 | 0 | } |
706 | 0 | state = State::kDone; |
707 | 0 | } |
708 | 0 | continue; |
709 | 0 | } else if (tag == WireFormatLite::kMessageSetMessageTag) { |
710 | 0 | if (state == State::kNoTag) { |
711 | 0 | int32_t size = ReadSize(&ptr); |
712 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
713 | 0 | ptr = ctx->ReadString(ptr, size, &payload); |
714 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
715 | 0 | state = State::kHasPayload; |
716 | 0 | } else if (state == State::kHasType) { |
717 | | // We're now parsing the payload |
718 | 0 | const FieldDescriptor* field = nullptr; |
719 | 0 | if (descriptor->IsExtensionNumber(type_id)) { |
720 | 0 | if (ctx->data().pool == nullptr) { |
721 | 0 | field = reflection->FindKnownExtensionByNumber(type_id); |
722 | 0 | } else { |
723 | 0 | field = |
724 | 0 | ctx->data().pool->FindExtensionByNumber(descriptor, type_id); |
725 | 0 | } |
726 | 0 | } |
727 | 0 | ptr = WireFormat::_InternalParseAndMergeField( |
728 | 0 | msg, ptr, ctx, static_cast<uint64_t>(type_id) * 8 + 2, reflection, |
729 | 0 | field); |
730 | 0 | state = State::kDone; |
731 | 0 | } else { |
732 | 0 | int32_t size = ReadSize(&ptr); |
733 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
734 | 0 | ptr = ctx->Skip(ptr, size); |
735 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
736 | 0 | } |
737 | 0 | } else { |
738 | | // An unknown field in MessageSetItem. |
739 | 0 | ptr = ReadTag(ptr - 1, &tag); |
740 | 0 | if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { |
741 | 0 | ctx->SetLastTag(tag); |
742 | 0 | return ptr; |
743 | 0 | } |
744 | | // Skip field. |
745 | 0 | ptr = internal::UnknownFieldParse( |
746 | 0 | tag, static_cast<std::string*>(nullptr), ptr, ctx); |
747 | 0 | } |
748 | 0 | GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); |
749 | 0 | } |
750 | 0 | return ptr; |
751 | 0 | } |
752 | | |
753 | 0 | const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) { |
754 | 0 | while (!ctx->Done(&ptr)) { |
755 | 0 | uint32_t tag; |
756 | 0 | ptr = ReadTag(ptr, &tag); |
757 | 0 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
758 | 0 | if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { |
759 | 0 | ctx->SetLastTag(tag); |
760 | 0 | break; |
761 | 0 | } |
762 | 0 | if (tag == WireFormatLite::kMessageSetItemStartTag) { |
763 | | // A message set item starts |
764 | 0 | ptr = ctx->ParseGroup(this, ptr, tag); |
765 | 0 | } else { |
766 | | // Parse other fields as normal extensions. |
767 | 0 | int field_number = WireFormatLite::GetTagFieldNumber(tag); |
768 | 0 | const FieldDescriptor* field = nullptr; |
769 | 0 | if (descriptor->IsExtensionNumber(field_number)) { |
770 | 0 | if (ctx->data().pool == nullptr) { |
771 | 0 | field = reflection->FindKnownExtensionByNumber(field_number); |
772 | 0 | } else { |
773 | 0 | field = ctx->data().pool->FindExtensionByNumber(descriptor, |
774 | 0 | field_number); |
775 | 0 | } |
776 | 0 | } |
777 | 0 | ptr = WireFormat::_InternalParseAndMergeField(msg, ptr, ctx, tag, |
778 | 0 | reflection, field); |
779 | 0 | } |
780 | 0 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
781 | 0 | } |
782 | 0 | return ptr; |
783 | 0 | } |
784 | | |
785 | | Message* msg; |
786 | | const Descriptor* descriptor; |
787 | | const Reflection* reflection; |
788 | | }; |
789 | | |
790 | | const char* WireFormat::_InternalParse(Message* msg, const char* ptr, |
791 | 0 | internal::ParseContext* ctx) { |
792 | 0 | const Descriptor* descriptor = msg->GetDescriptor(); |
793 | 0 | const Reflection* reflection = msg->GetReflection(); |
794 | 0 | ABSL_DCHECK(descriptor); |
795 | 0 | ABSL_DCHECK(reflection); |
796 | 0 | if (descriptor->options().message_set_wire_format()) { |
797 | 0 | MessageSetParser message_set{msg, descriptor, reflection}; |
798 | 0 | return message_set.ParseMessageSet(ptr, ctx); |
799 | 0 | } |
800 | 0 | while (!ctx->Done(&ptr)) { |
801 | 0 | uint32_t tag; |
802 | 0 | ptr = ReadTag(ptr, &tag); |
803 | 0 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
804 | 0 | if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) { |
805 | 0 | ctx->SetLastTag(tag); |
806 | 0 | break; |
807 | 0 | } |
808 | 0 | const FieldDescriptor* field = nullptr; |
809 | |
|
810 | 0 | int field_number = WireFormatLite::GetTagFieldNumber(tag); |
811 | 0 | field = descriptor->FindFieldByNumber(field_number); |
812 | | |
813 | | // If that failed, check if the field is an extension. |
814 | 0 | if (field == nullptr && descriptor->IsExtensionNumber(field_number)) { |
815 | 0 | if (ctx->data().pool == nullptr) { |
816 | 0 | field = reflection->FindKnownExtensionByNumber(field_number); |
817 | 0 | } else { |
818 | 0 | field = |
819 | 0 | ctx->data().pool->FindExtensionByNumber(descriptor, field_number); |
820 | 0 | } |
821 | 0 | } |
822 | |
|
823 | 0 | ptr = _InternalParseAndMergeField(msg, ptr, ctx, tag, reflection, field); |
824 | 0 | if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr; |
825 | 0 | } |
826 | 0 | return ptr; |
827 | 0 | } |
828 | | |
829 | | const char* WireFormat::_InternalParseAndMergeField( |
830 | | Message* msg, const char* ptr, internal::ParseContext* ctx, uint64_t tag, |
831 | 117k | const Reflection* reflection, const FieldDescriptor* field) { |
832 | 117k | if (field == nullptr) { |
833 | | // unknown field set parser takes 64bit tags, because message set type ids |
834 | | // span the full 32 bit range making the tag span [0, 2^35) range. |
835 | 14.3k | return internal::UnknownFieldParse( |
836 | 14.3k | tag, reflection->MutableUnknownFields(msg), ptr, ctx); |
837 | 14.3k | } |
838 | 103k | if (WireFormatLite::GetTagWireType(tag) != |
839 | 103k | WireTypeForFieldType(field->type())) { |
840 | 3.75k | if (field->is_packable() && WireFormatLite::GetTagWireType(tag) == |
841 | 1 | WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { |
842 | 0 | switch (field->type()) { |
843 | 0 | #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
844 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
845 | 0 | ptr = internal::Packed##CPPTYPE_METHOD##Parser( \ |
846 | 0 | reflection->MutableRepeatedFieldInternal<CPPTYPE>(msg, field), ptr, \ |
847 | 0 | ctx); \ |
848 | 0 | return ptr; \ |
849 | 0 | } |
850 | | |
851 | 0 | HANDLE_PACKED_TYPE(INT32, int32_t, Int32) |
852 | 0 | HANDLE_PACKED_TYPE(INT64, int64_t, Int64) |
853 | 0 | HANDLE_PACKED_TYPE(SINT32, int32_t, SInt32) |
854 | 0 | HANDLE_PACKED_TYPE(SINT64, int64_t, SInt64) |
855 | 0 | HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32) |
856 | 0 | HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64) |
857 | | |
858 | 0 | HANDLE_PACKED_TYPE(FIXED32, uint32_t, Fixed32) |
859 | 0 | HANDLE_PACKED_TYPE(FIXED64, uint64_t, Fixed64) |
860 | 0 | HANDLE_PACKED_TYPE(SFIXED32, int32_t, SFixed32) |
861 | 0 | HANDLE_PACKED_TYPE(SFIXED64, int64_t, SFixed64) |
862 | | |
863 | 0 | HANDLE_PACKED_TYPE(FLOAT, float, Float) |
864 | 0 | HANDLE_PACKED_TYPE(DOUBLE, double, Double) |
865 | | |
866 | 0 | HANDLE_PACKED_TYPE(BOOL, bool, Bool) |
867 | 0 | #undef HANDLE_PACKED_TYPE |
868 | | |
869 | 0 | case FieldDescriptor::TYPE_ENUM: { |
870 | 0 | auto rep_enum = |
871 | 0 | reflection->MutableRepeatedFieldInternal<int>(msg, field); |
872 | 0 | if (!field->legacy_enum_field_treated_as_closed()) { |
873 | 0 | ptr = internal::PackedEnumParser(rep_enum, ptr, ctx); |
874 | 0 | } else { |
875 | 0 | return ctx->ReadPackedVarint( |
876 | 0 | ptr, [rep_enum, field, reflection, msg](int32_t val) { |
877 | 0 | if (field->enum_type()->FindValueByNumber(val) != nullptr) { |
878 | 0 | rep_enum->Add(val); |
879 | 0 | } else { |
880 | 0 | WriteVarint(field->number(), val, |
881 | 0 | reflection->MutableUnknownFields(msg)); |
882 | 0 | } |
883 | 0 | }); |
884 | 0 | } |
885 | 0 | return ptr; |
886 | 0 | } |
887 | | |
888 | 0 | case FieldDescriptor::TYPE_STRING: |
889 | 0 | case FieldDescriptor::TYPE_GROUP: |
890 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
891 | 0 | case FieldDescriptor::TYPE_BYTES: |
892 | 0 | ABSL_LOG(FATAL) << "Can't reach"; |
893 | 0 | return nullptr; |
894 | 0 | } |
895 | 3.75k | } else { |
896 | | // mismatched wiretype; |
897 | 3.75k | return internal::UnknownFieldParse( |
898 | 3.75k | tag, reflection->MutableUnknownFields(msg), ptr, ctx); |
899 | 3.75k | } |
900 | 3.75k | } |
901 | | |
902 | | // Non-packed value |
903 | 99.7k | bool utf8_check = false; |
904 | 99.7k | bool strict_utf8_check = false; |
905 | 99.7k | switch (field->type()) { |
906 | 0 | #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
907 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
908 | 0 | CPPTYPE value; \ |
909 | 0 | ptr = VarintParse(ptr, &value); \ |
910 | 0 | if (ptr == nullptr) return nullptr; \ |
911 | 0 | if (field->is_repeated()) { \ |
912 | 0 | reflection->Add##CPPTYPE_METHOD(msg, field, value); \ |
913 | 0 | } else { \ |
914 | 0 | reflection->Set##CPPTYPE_METHOD(msg, field, value); \ |
915 | 0 | } \ |
916 | 0 | return ptr; \ |
917 | 0 | } |
918 | | |
919 | 0 | HANDLE_TYPE(BOOL, uint64_t, Bool) |
920 | 0 | HANDLE_TYPE(INT32, uint32_t, Int32) |
921 | 0 | HANDLE_TYPE(INT64, uint64_t, Int64) |
922 | 0 | HANDLE_TYPE(UINT32, uint32_t, UInt32) |
923 | 0 | HANDLE_TYPE(UINT64, uint64_t, UInt64) |
924 | | |
925 | 0 | case FieldDescriptor::TYPE_SINT32: { |
926 | 0 | int32_t value = ReadVarintZigZag32(&ptr); |
927 | 0 | if (ptr == nullptr) return nullptr; |
928 | 0 | if (field->is_repeated()) { |
929 | 0 | reflection->AddInt32(msg, field, value); |
930 | 0 | } else { |
931 | 0 | reflection->SetInt32(msg, field, value); |
932 | 0 | } |
933 | 0 | return ptr; |
934 | 0 | } |
935 | 0 | case FieldDescriptor::TYPE_SINT64: { |
936 | 0 | int64_t value = ReadVarintZigZag64(&ptr); |
937 | 0 | if (ptr == nullptr) return nullptr; |
938 | 0 | if (field->is_repeated()) { |
939 | 0 | reflection->AddInt64(msg, field, value); |
940 | 0 | } else { |
941 | 0 | reflection->SetInt64(msg, field, value); |
942 | 0 | } |
943 | 0 | return ptr; |
944 | 0 | } |
945 | 0 | #undef HANDLE_TYPE |
946 | 0 | #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ |
947 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
948 | 0 | CPPTYPE value; \ |
949 | 0 | value = UnalignedLoad<CPPTYPE>(ptr); \ |
950 | 0 | ptr += sizeof(CPPTYPE); \ |
951 | 0 | if (field->is_repeated()) { \ |
952 | 0 | reflection->Add##CPPTYPE_METHOD(msg, field, value); \ |
953 | 0 | } else { \ |
954 | 0 | reflection->Set##CPPTYPE_METHOD(msg, field, value); \ |
955 | 0 | } \ |
956 | 0 | return ptr; \ |
957 | 0 | } |
958 | | |
959 | 0 | HANDLE_TYPE(FIXED32, uint32_t, UInt32) |
960 | 0 | HANDLE_TYPE(FIXED64, uint64_t, UInt64) |
961 | 0 | HANDLE_TYPE(SFIXED32, int32_t, Int32) |
962 | 0 | HANDLE_TYPE(SFIXED64, int64_t, Int64) |
963 | | |
964 | 0 | HANDLE_TYPE(FLOAT, float, Float) |
965 | 0 | HANDLE_TYPE(DOUBLE, double, Double) |
966 | | |
967 | 0 | #undef HANDLE_TYPE |
968 | | |
969 | 0 | case FieldDescriptor::TYPE_ENUM: { |
970 | 0 | uint32_t value; |
971 | 0 | ptr = VarintParse(ptr, &value); |
972 | 0 | if (ptr == nullptr) return nullptr; |
973 | 0 | if (field->is_repeated()) { |
974 | 0 | reflection->AddEnumValue(msg, field, value); |
975 | 0 | } else { |
976 | 0 | reflection->SetEnumValue(msg, field, value); |
977 | 0 | } |
978 | 0 | return ptr; |
979 | 0 | } |
980 | | |
981 | | // Handle strings separately so that we can optimize the ctype=CORD case. |
982 | 0 | case FieldDescriptor::TYPE_STRING: |
983 | 0 | utf8_check = true; |
984 | 0 | strict_utf8_check = field->requires_utf8_validation(); |
985 | 0 | PROTOBUF_FALLTHROUGH_INTENDED; |
986 | 0 | case FieldDescriptor::TYPE_BYTES: { |
987 | 0 | int size = ReadSize(&ptr); |
988 | 0 | if (ptr == nullptr) return nullptr; |
989 | 0 | if (internal::cpp::EffectiveStringCType(field) == FieldOptions::CORD) { |
990 | 0 | absl::Cord value; |
991 | 0 | ptr = ctx->ReadCord(ptr, size, &value); |
992 | 0 | if (ptr == nullptr) return nullptr; |
993 | 0 | reflection->SetString(msg, field, value); |
994 | 0 | return ptr; |
995 | 0 | } |
996 | 0 | std::string value; |
997 | 0 | ptr = ctx->ReadString(ptr, size, &value); |
998 | 0 | if (ptr == nullptr) return nullptr; |
999 | 0 | if (utf8_check) { |
1000 | 0 | if (strict_utf8_check) { |
1001 | 0 | if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(), |
1002 | 0 | WireFormatLite::PARSE, |
1003 | 0 | field->full_name().c_str())) { |
1004 | 0 | return nullptr; |
1005 | 0 | } |
1006 | 0 | } else { |
1007 | 0 | VerifyUTF8StringNamedField(value.data(), value.length(), PARSE, |
1008 | 0 | field->full_name().c_str()); |
1009 | 0 | } |
1010 | 0 | } |
1011 | 0 | if (field->is_repeated()) { |
1012 | 0 | reflection->AddString(msg, field, std::move(value)); |
1013 | 0 | } else { |
1014 | 0 | reflection->SetString(msg, field, std::move(value)); |
1015 | 0 | } |
1016 | 0 | return ptr; |
1017 | 0 | } |
1018 | | |
1019 | 0 | case FieldDescriptor::TYPE_GROUP: { |
1020 | 0 | Message* sub_message; |
1021 | 0 | if (field->is_repeated()) { |
1022 | 0 | sub_message = reflection->AddMessage(msg, field, ctx->data().factory); |
1023 | 0 | } else { |
1024 | 0 | sub_message = |
1025 | 0 | reflection->MutableMessage(msg, field, ctx->data().factory); |
1026 | 0 | } |
1027 | |
|
1028 | 0 | return ctx->ParseGroup(sub_message, ptr, tag); |
1029 | 0 | } |
1030 | | |
1031 | 99.7k | case FieldDescriptor::TYPE_MESSAGE: { |
1032 | 99.7k | Message* sub_message; |
1033 | 99.7k | if (field->is_repeated()) { |
1034 | 99.7k | sub_message = reflection->AddMessage(msg, field, ctx->data().factory); |
1035 | 99.7k | } else { |
1036 | 0 | sub_message = |
1037 | 0 | reflection->MutableMessage(msg, field, ctx->data().factory); |
1038 | 0 | } |
1039 | 99.7k | ptr = ctx->ParseMessage(sub_message, ptr); |
1040 | | |
1041 | | // For map entries, if the value is an unknown enum we have to push it |
1042 | | // into the unknown field set and remove it from the list. |
1043 | 99.7k | if (ptr != nullptr && field->is_map()) { |
1044 | 99.7k | auto* value_field = field->message_type()->map_value(); |
1045 | 99.7k | auto* enum_type = value_field->enum_type(); |
1046 | 99.7k | if (enum_type != nullptr && |
1047 | 99.7k | !internal::cpp::HasPreservingUnknownEnumSemantics(value_field) && |
1048 | 99.7k | enum_type->FindValueByNumber( |
1049 | 0 | sub_message->GetReflection()->GetEnumValue( |
1050 | 0 | *sub_message, value_field)) == nullptr) { |
1051 | 0 | reflection->MutableUnknownFields(msg)->AddLengthDelimited( |
1052 | 0 | field->number(), sub_message->SerializeAsString()); |
1053 | 0 | reflection->RemoveLast(msg, field); |
1054 | 0 | } |
1055 | 99.7k | } |
1056 | | |
1057 | 99.7k | return ptr; |
1058 | 0 | } |
1059 | 99.7k | } |
1060 | | |
1061 | | // GCC 8 complains about control reaching end of non-void function here. |
1062 | | // Let's keep it happy by returning a nullptr. |
1063 | 0 | return nullptr; |
1064 | 99.7k | } |
1065 | | |
1066 | | // =================================================================== |
1067 | | |
1068 | | uint8_t* WireFormat::_InternalSerialize(const Message& message, uint8_t* target, |
1069 | 773k | io::EpsCopyOutputStream* stream) { |
1070 | 773k | const Descriptor* descriptor = message.GetDescriptor(); |
1071 | 773k | const Reflection* message_reflection = message.GetReflection(); |
1072 | | |
1073 | 773k | std::vector<const FieldDescriptor*> fields; |
1074 | | |
1075 | | // Fields of map entry should always be serialized. |
1076 | 773k | if (descriptor->options().map_entry()) { |
1077 | 131k | for (int i = 0; i < descriptor->field_count(); i++) { |
1078 | 87.9k | fields.push_back(descriptor->field(i)); |
1079 | 87.9k | } |
1080 | 729k | } else { |
1081 | 729k | message_reflection->ListFields(message, &fields); |
1082 | 729k | } |
1083 | | |
1084 | 1.47M | for (auto field : fields) { |
1085 | 1.47M | target = InternalSerializeField(field, message, target, stream); |
1086 | 1.47M | } |
1087 | | |
1088 | 773k | if (descriptor->options().message_set_wire_format()) { |
1089 | 0 | return InternalSerializeUnknownMessageSetItemsToArray( |
1090 | 0 | message_reflection->GetUnknownFields(message), target, stream); |
1091 | 773k | } else { |
1092 | 773k | return InternalSerializeUnknownFieldsToArray( |
1093 | 773k | message_reflection->GetUnknownFields(message), target, stream); |
1094 | 773k | } |
1095 | 773k | } |
1096 | | |
1097 | | uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, |
1098 | | const MapKey& value, uint8_t* target, |
1099 | 0 | io::EpsCopyOutputStream* stream) { |
1100 | 0 | target = stream->EnsureSpace(target); |
1101 | 0 | switch (field->type()) { |
1102 | 0 | case FieldDescriptor::TYPE_DOUBLE: |
1103 | 0 | case FieldDescriptor::TYPE_FLOAT: |
1104 | 0 | case FieldDescriptor::TYPE_GROUP: |
1105 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
1106 | 0 | case FieldDescriptor::TYPE_BYTES: |
1107 | 0 | case FieldDescriptor::TYPE_ENUM: |
1108 | 0 | ABSL_LOG(FATAL) << "Unsupported"; |
1109 | 0 | break; |
1110 | 0 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1111 | 0 | case FieldDescriptor::TYPE_##FieldType: \ |
1112 | 0 | target = WireFormatLite::Write##CamelFieldType##ToArray( \ |
1113 | 0 | 1, value.Get##CamelCppType##Value(), target); \ |
1114 | 0 | break; |
1115 | 0 | CASE_TYPE(INT64, Int64, Int64) |
1116 | 0 | CASE_TYPE(UINT64, UInt64, UInt64) |
1117 | 0 | CASE_TYPE(INT32, Int32, Int32) |
1118 | 0 | CASE_TYPE(FIXED64, Fixed64, UInt64) |
1119 | 0 | CASE_TYPE(FIXED32, Fixed32, UInt32) |
1120 | 0 | CASE_TYPE(BOOL, Bool, Bool) |
1121 | 0 | CASE_TYPE(UINT32, UInt32, UInt32) |
1122 | 0 | CASE_TYPE(SFIXED32, SFixed32, Int32) |
1123 | 0 | CASE_TYPE(SFIXED64, SFixed64, Int64) |
1124 | 0 | CASE_TYPE(SINT32, SInt32, Int32) |
1125 | 0 | CASE_TYPE(SINT64, SInt64, Int64) |
1126 | 0 | #undef CASE_TYPE |
1127 | 0 | case FieldDescriptor::TYPE_STRING: |
1128 | 0 | target = stream->WriteString(1, value.GetStringValue(), target); |
1129 | 0 | break; |
1130 | 0 | } |
1131 | 0 | return target; |
1132 | 0 | } |
1133 | | |
1134 | | static uint8_t* SerializeMapValueRefWithCachedSizes( |
1135 | | const FieldDescriptor* field, const MapValueConstRef& value, |
1136 | 0 | uint8_t* target, io::EpsCopyOutputStream* stream) { |
1137 | 0 | target = stream->EnsureSpace(target); |
1138 | 0 | switch (field->type()) { |
1139 | 0 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1140 | 0 | case FieldDescriptor::TYPE_##FieldType: \ |
1141 | 0 | target = WireFormatLite::Write##CamelFieldType##ToArray( \ |
1142 | 0 | 2, value.Get##CamelCppType##Value(), target); \ |
1143 | 0 | break; |
1144 | 0 | CASE_TYPE(INT64, Int64, Int64) |
1145 | 0 | CASE_TYPE(UINT64, UInt64, UInt64) |
1146 | 0 | CASE_TYPE(INT32, Int32, Int32) |
1147 | 0 | CASE_TYPE(FIXED64, Fixed64, UInt64) |
1148 | 0 | CASE_TYPE(FIXED32, Fixed32, UInt32) |
1149 | 0 | CASE_TYPE(BOOL, Bool, Bool) |
1150 | 0 | CASE_TYPE(UINT32, UInt32, UInt32) |
1151 | 0 | CASE_TYPE(SFIXED32, SFixed32, Int32) |
1152 | 0 | CASE_TYPE(SFIXED64, SFixed64, Int64) |
1153 | 0 | CASE_TYPE(SINT32, SInt32, Int32) |
1154 | 0 | CASE_TYPE(SINT64, SInt64, Int64) |
1155 | 0 | CASE_TYPE(ENUM, Enum, Enum) |
1156 | 0 | CASE_TYPE(DOUBLE, Double, Double) |
1157 | 0 | CASE_TYPE(FLOAT, Float, Float) |
1158 | 0 | #undef CASE_TYPE |
1159 | 0 | case FieldDescriptor::TYPE_STRING: |
1160 | 0 | case FieldDescriptor::TYPE_BYTES: |
1161 | 0 | target = stream->WriteString(2, value.GetStringValue(), target); |
1162 | 0 | break; |
1163 | 0 | case FieldDescriptor::TYPE_MESSAGE: { |
1164 | 0 | auto& msg = value.GetMessageValue(); |
1165 | 0 | target = WireFormatLite::InternalWriteMessage(2, msg, msg.GetCachedSize(), |
1166 | 0 | target, stream); |
1167 | 0 | } break; |
1168 | 0 | case FieldDescriptor::TYPE_GROUP: |
1169 | 0 | target = WireFormatLite::InternalWriteGroup(2, value.GetMessageValue(), |
1170 | 0 | target, stream); |
1171 | 0 | break; |
1172 | 0 | } |
1173 | 0 | return target; |
1174 | 0 | } |
1175 | | |
1176 | | class MapKeySorter { |
1177 | | public: |
1178 | | static std::vector<MapKey> SortKey(const Message& message, |
1179 | | const Reflection* reflection, |
1180 | 0 | const FieldDescriptor* field) { |
1181 | 0 | std::vector<MapKey> sorted_key_list; |
1182 | 0 | for (MapIterator it = |
1183 | 0 | reflection->MapBegin(const_cast<Message*>(&message), field); |
1184 | 0 | it != reflection->MapEnd(const_cast<Message*>(&message), field); |
1185 | 0 | ++it) { |
1186 | 0 | sorted_key_list.push_back(it.GetKey()); |
1187 | 0 | } |
1188 | 0 | MapKeyComparator comparator; |
1189 | 0 | std::sort(sorted_key_list.begin(), sorted_key_list.end(), comparator); |
1190 | 0 | return sorted_key_list; |
1191 | 0 | } |
1192 | | |
1193 | | private: |
1194 | | class MapKeyComparator { |
1195 | | public: |
1196 | 0 | bool operator()(const MapKey& a, const MapKey& b) const { |
1197 | 0 | ABSL_DCHECK(a.type() == b.type()); |
1198 | 0 | switch (a.type()) { |
1199 | 0 | #define CASE_TYPE(CppType, CamelCppType) \ |
1200 | 0 | case FieldDescriptor::CPPTYPE_##CppType: { \ |
1201 | 0 | return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \ |
1202 | 0 | } |
1203 | 0 | CASE_TYPE(STRING, String) |
1204 | 0 | CASE_TYPE(INT64, Int64) |
1205 | 0 | CASE_TYPE(INT32, Int32) |
1206 | 0 | CASE_TYPE(UINT64, UInt64) |
1207 | 0 | CASE_TYPE(UINT32, UInt32) |
1208 | 0 | CASE_TYPE(BOOL, Bool) |
1209 | 0 | #undef CASE_TYPE |
1210 | | |
1211 | 0 | default: |
1212 | 0 | ABSL_DLOG(FATAL) << "Invalid key for map field."; |
1213 | 0 | return true; |
1214 | 0 | } |
1215 | 0 | } |
1216 | | }; |
1217 | | }; |
1218 | | |
1219 | | static uint8_t* InternalSerializeMapEntry(const FieldDescriptor* field, |
1220 | | const MapKey& key, |
1221 | | const MapValueConstRef& value, |
1222 | | uint8_t* target, |
1223 | 0 | io::EpsCopyOutputStream* stream) { |
1224 | 0 | const FieldDescriptor* key_field = field->message_type()->field(0); |
1225 | 0 | const FieldDescriptor* value_field = field->message_type()->field(1); |
1226 | |
|
1227 | 0 | size_t size = kMapEntryTagByteSize; |
1228 | 0 | size += MapKeyDataOnlyByteSize(key_field, key); |
1229 | 0 | size += MapValueRefDataOnlyByteSize(value_field, value); |
1230 | 0 | target = stream->EnsureSpace(target); |
1231 | 0 | target = WireFormatLite::WriteTagToArray( |
1232 | 0 | field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target); |
1233 | 0 | target = io::CodedOutputStream::WriteVarint32ToArray(size, target); |
1234 | 0 | target = SerializeMapKeyWithCachedSizes(key_field, key, target, stream); |
1235 | 0 | target = |
1236 | 0 | SerializeMapValueRefWithCachedSizes(value_field, value, target, stream); |
1237 | 0 | return target; |
1238 | 0 | } |
1239 | | |
1240 | | uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field, |
1241 | | const Message& message, |
1242 | | uint8_t* target, |
1243 | 1.47M | io::EpsCopyOutputStream* stream) { |
1244 | 1.47M | const Reflection* message_reflection = message.GetReflection(); |
1245 | | |
1246 | 1.47M | if (field->is_extension() && |
1247 | 1.47M | field->containing_type()->options().message_set_wire_format() && |
1248 | 1.47M | field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
1249 | 1.47M | !field->is_repeated()) { |
1250 | 0 | return InternalSerializeMessageSetItem(field, message, target, stream); |
1251 | 0 | } |
1252 | | |
1253 | | // For map fields, we can use either repeated field reflection or map |
1254 | | // reflection. Our choice has some subtle effects. If we use repeated field |
1255 | | // reflection here, then the repeated field representation becomes |
1256 | | // authoritative for this field: any existing references that came from map |
1257 | | // reflection remain valid for reading, but mutations to them are lost and |
1258 | | // will be overwritten next time we call map reflection! |
1259 | | // |
1260 | | // So far this mainly affects Python, which keeps long-term references to map |
1261 | | // values around, and always uses map reflection. See: b/35918691 |
1262 | | // |
1263 | | // Here we choose to use map reflection API as long as the internal |
1264 | | // map is valid. In this way, the serialization doesn't change map field's |
1265 | | // internal state and existing references that came from map reflection remain |
1266 | | // valid for both reading and writing. |
1267 | 1.47M | if (field->is_map()) { |
1268 | 15.8k | const MapFieldBase* map_field = |
1269 | 15.8k | message_reflection->GetMapData(message, field); |
1270 | 15.8k | if (map_field->IsMapValid()) { |
1271 | 0 | if (stream->IsSerializationDeterministic()) { |
1272 | 0 | std::vector<MapKey> sorted_key_list = |
1273 | 0 | MapKeySorter::SortKey(message, message_reflection, field); |
1274 | 0 | for (std::vector<MapKey>::iterator it = sorted_key_list.begin(); |
1275 | 0 | it != sorted_key_list.end(); ++it) { |
1276 | 0 | MapValueConstRef map_value; |
1277 | 0 | message_reflection->LookupMapValue(message, field, *it, &map_value); |
1278 | 0 | target = |
1279 | 0 | InternalSerializeMapEntry(field, *it, map_value, target, stream); |
1280 | 0 | } |
1281 | 0 | } else { |
1282 | 0 | for (MapIterator it = message_reflection->MapBegin( |
1283 | 0 | const_cast<Message*>(&message), field); |
1284 | 0 | it != |
1285 | 0 | message_reflection->MapEnd(const_cast<Message*>(&message), field); |
1286 | 0 | ++it) { |
1287 | 0 | target = InternalSerializeMapEntry(field, it.GetKey(), |
1288 | 0 | it.GetValueRef(), target, stream); |
1289 | 0 | } |
1290 | 0 | } |
1291 | |
|
1292 | 0 | return target; |
1293 | 0 | } |
1294 | 15.8k | } |
1295 | 1.47M | int count = 0; |
1296 | | |
1297 | 1.47M | if (field->is_repeated()) { |
1298 | 262k | count = message_reflection->FieldSize(message, field); |
1299 | 1.21M | } else if (field->containing_type()->options().map_entry()) { |
1300 | | // Map entry fields always need to be serialized. |
1301 | 87.9k | count = 1; |
1302 | 1.12M | } else if (message_reflection->HasField(message, field)) { |
1303 | 1.12M | count = 1; |
1304 | 1.12M | } |
1305 | | |
1306 | | // map_entries is for maps that'll be deterministically serialized. |
1307 | 1.47M | std::vector<const Message*> map_entries; |
1308 | 1.47M | if (count > 1 && field->is_map() && stream->IsSerializationDeterministic()) { |
1309 | 0 | map_entries = |
1310 | 0 | DynamicMapSorter::Sort(message, count, message_reflection, field); |
1311 | 0 | } |
1312 | | |
1313 | 1.47M | if (field->is_packed()) { |
1314 | 0 | if (count == 0) return target; |
1315 | 0 | target = stream->EnsureSpace(target); |
1316 | 0 | switch (field->type()) { |
1317 | 0 | #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1318 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
1319 | 0 | auto r = \ |
1320 | 0 | message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \ |
1321 | 0 | target = stream->Write##TYPE_METHOD##Packed( \ |
1322 | 0 | field->number(), r, FieldDataOnlyByteSize(field, message), target); \ |
1323 | 0 | break; \ |
1324 | 0 | } |
1325 | | |
1326 | 0 | HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32) |
1327 | 0 | HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64) |
1328 | 0 | HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32) |
1329 | 0 | HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64) |
1330 | 0 | HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32) |
1331 | 0 | HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64) |
1332 | 0 | HANDLE_PRIMITIVE_TYPE(ENUM, int, Enum, Enum) |
1333 | | |
1334 | 0 | #undef HANDLE_PRIMITIVE_TYPE |
1335 | 0 | #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1336 | 0 | case FieldDescriptor::TYPE_##TYPE: { \ |
1337 | 0 | auto r = \ |
1338 | 0 | message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \ |
1339 | 0 | target = stream->WriteFixedPacked(field->number(), r, target); \ |
1340 | 0 | break; \ |
1341 | 0 | } |
1342 | | |
1343 | 0 | HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32) |
1344 | 0 | HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64) |
1345 | 0 | HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32) |
1346 | 0 | HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64) |
1347 | | |
1348 | 0 | HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) |
1349 | 0 | HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) |
1350 | | |
1351 | 0 | HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) |
1352 | 0 | #undef HANDLE_PRIMITIVE_TYPE |
1353 | 0 | default: |
1354 | 0 | ABSL_LOG(FATAL) << "Invalid descriptor"; |
1355 | 0 | } |
1356 | 0 | return target; |
1357 | 0 | } |
1358 | | |
1359 | 1.47M | auto get_message_from_field = [&message, &map_entries, message_reflection]( |
1360 | 1.47M | const FieldDescriptor* field, int j) { |
1361 | 712k | if (!field->is_repeated()) { |
1362 | 297k | return &message_reflection->GetMessage(message, field); |
1363 | 297k | } |
1364 | 414k | if (!map_entries.empty()) { |
1365 | 0 | return map_entries[j]; |
1366 | 0 | } |
1367 | 414k | return &message_reflection->GetRepeatedMessage(message, field, j); |
1368 | 414k | }; |
1369 | 3.25M | for (int j = 0; j < count; j++) { |
1370 | 1.77M | target = stream->EnsureSpace(target); |
1371 | 1.77M | switch (field->type()) { |
1372 | 0 | #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1373 | 74.9k | case FieldDescriptor::TYPE_##TYPE: { \ |
1374 | 74.9k | const CPPTYPE value = \ |
1375 | 74.9k | field->is_repeated() \ |
1376 | 74.9k | ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ |
1377 | 0 | j) \ |
1378 | 74.9k | : message_reflection->Get##CPPTYPE_METHOD(message, field); \ |
1379 | 74.9k | target = WireFormatLite::Write##TYPE_METHOD##ToArray(field->number(), \ |
1380 | 74.9k | value, target); \ |
1381 | 74.9k | break; \ |
1382 | 74.9k | } |
1383 | | |
1384 | 19.0k | HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32) |
1385 | 19.4k | HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64) |
1386 | 0 | HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32) |
1387 | 0 | HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64) |
1388 | 26.2k | HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32) |
1389 | 0 | HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64) |
1390 | | |
1391 | 0 | HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32) |
1392 | 0 | HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64) |
1393 | 0 | HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32) |
1394 | 0 | HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64) |
1395 | | |
1396 | 0 | HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float) |
1397 | 1.42k | HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double) |
1398 | | |
1399 | 8.70k | HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool) |
1400 | 0 | #undef HANDLE_PRIMITIVE_TYPE |
1401 | | |
1402 | 0 | case FieldDescriptor::TYPE_GROUP: { |
1403 | 0 | auto* msg = get_message_from_field(field, j); |
1404 | 0 | target = WireFormatLite::InternalWriteGroup(field->number(), *msg, |
1405 | 0 | target, stream); |
1406 | 0 | } break; |
1407 | | |
1408 | 712k | case FieldDescriptor::TYPE_MESSAGE: { |
1409 | 712k | auto* msg = get_message_from_field(field, j); |
1410 | 712k | target = WireFormatLite::InternalWriteMessage( |
1411 | 712k | field->number(), *msg, msg->GetCachedSize(), target, stream); |
1412 | 712k | } break; |
1413 | | |
1414 | 12.2k | case FieldDescriptor::TYPE_ENUM: { |
1415 | 12.2k | const EnumValueDescriptor* value = |
1416 | 12.2k | field->is_repeated() |
1417 | 12.2k | ? message_reflection->GetRepeatedEnum(message, field, j) |
1418 | 12.2k | : message_reflection->GetEnum(message, field); |
1419 | 12.2k | target = WireFormatLite::WriteEnumToArray(field->number(), |
1420 | 12.2k | value->number(), target); |
1421 | 12.2k | break; |
1422 | 0 | } |
1423 | | |
1424 | | // Handle strings separately so that we can get string references |
1425 | | // instead of copying. |
1426 | 943k | case FieldDescriptor::TYPE_STRING: { |
1427 | 943k | bool strict_utf8_check = field->requires_utf8_validation(); |
1428 | 943k | std::string scratch; |
1429 | 943k | const std::string& value = |
1430 | 943k | field->is_repeated() |
1431 | 943k | ? message_reflection->GetRepeatedStringReference(message, field, |
1432 | 149k | j, &scratch) |
1433 | 943k | : message_reflection->GetStringReference(message, field, |
1434 | 794k | &scratch); |
1435 | 943k | if (strict_utf8_check) { |
1436 | 943k | WireFormatLite::VerifyUtf8String(value.data(), value.length(), |
1437 | 943k | WireFormatLite::SERIALIZE, |
1438 | 943k | field->full_name().c_str()); |
1439 | 943k | } else { |
1440 | 0 | VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE, |
1441 | 0 | field->full_name().c_str()); |
1442 | 0 | } |
1443 | 943k | target = stream->WriteString(field->number(), value, target); |
1444 | 943k | break; |
1445 | 0 | } |
1446 | | |
1447 | 35.6k | case FieldDescriptor::TYPE_BYTES: { |
1448 | 35.6k | if (internal::cpp::EffectiveStringCType(field) == FieldOptions::CORD) { |
1449 | 0 | absl::Cord value = message_reflection->GetCord(message, field); |
1450 | 0 | target = stream->WriteString(field->number(), value, target); |
1451 | 0 | break; |
1452 | 0 | } |
1453 | 35.6k | std::string scratch; |
1454 | 35.6k | const std::string& value = |
1455 | 35.6k | field->is_repeated() |
1456 | 35.6k | ? message_reflection->GetRepeatedStringReference(message, field, |
1457 | 0 | j, &scratch) |
1458 | 35.6k | : message_reflection->GetStringReference(message, field, |
1459 | 35.6k | &scratch); |
1460 | 35.6k | target = stream->WriteString(field->number(), value, target); |
1461 | 35.6k | break; |
1462 | 35.6k | } |
1463 | 1.77M | } |
1464 | 1.77M | } |
1465 | 1.47M | return target; |
1466 | 1.47M | } |
1467 | | |
1468 | | uint8_t* WireFormat::InternalSerializeMessageSetItem( |
1469 | | const FieldDescriptor* field, const Message& message, uint8_t* target, |
1470 | 0 | io::EpsCopyOutputStream* stream) { |
1471 | 0 | const Reflection* message_reflection = message.GetReflection(); |
1472 | |
|
1473 | 0 | target = stream->EnsureSpace(target); |
1474 | | // Start group. |
1475 | 0 | target = io::CodedOutputStream::WriteTagToArray( |
1476 | 0 | WireFormatLite::kMessageSetItemStartTag, target); |
1477 | | // Write type ID. |
1478 | 0 | target = WireFormatLite::WriteUInt32ToArray( |
1479 | 0 | WireFormatLite::kMessageSetTypeIdNumber, field->number(), target); |
1480 | | // Write message. |
1481 | 0 | auto& msg = message_reflection->GetMessage(message, field); |
1482 | 0 | target = WireFormatLite::InternalWriteMessage( |
1483 | 0 | WireFormatLite::kMessageSetMessageNumber, msg, msg.GetCachedSize(), |
1484 | 0 | target, stream); |
1485 | | // End group. |
1486 | 0 | target = stream->EnsureSpace(target); |
1487 | 0 | target = io::CodedOutputStream::WriteTagToArray( |
1488 | 0 | WireFormatLite::kMessageSetItemEndTag, target); |
1489 | 0 | return target; |
1490 | 0 | } |
1491 | | |
1492 | | // =================================================================== |
1493 | | |
1494 | 773k | size_t WireFormat::ByteSize(const Message& message) { |
1495 | 773k | const Descriptor* descriptor = message.GetDescriptor(); |
1496 | 773k | const Reflection* message_reflection = message.GetReflection(); |
1497 | | |
1498 | 773k | size_t our_size = 0; |
1499 | | |
1500 | 773k | std::vector<const FieldDescriptor*> fields; |
1501 | | |
1502 | | // Fields of map entry should always be serialized. |
1503 | 773k | if (descriptor->options().map_entry()) { |
1504 | 131k | for (int i = 0; i < descriptor->field_count(); i++) { |
1505 | 87.9k | fields.push_back(descriptor->field(i)); |
1506 | 87.9k | } |
1507 | 729k | } else { |
1508 | 729k | message_reflection->ListFields(message, &fields); |
1509 | 729k | } |
1510 | | |
1511 | 1.47M | for (const FieldDescriptor* field : fields) { |
1512 | 1.47M | our_size += FieldByteSize(field, message); |
1513 | 1.47M | } |
1514 | | |
1515 | 773k | if (descriptor->options().message_set_wire_format()) { |
1516 | 0 | our_size += ComputeUnknownMessageSetItemsSize( |
1517 | 0 | message_reflection->GetUnknownFields(message)); |
1518 | 773k | } else { |
1519 | 773k | our_size += |
1520 | 773k | ComputeUnknownFieldsSize(message_reflection->GetUnknownFields(message)); |
1521 | 773k | } |
1522 | | |
1523 | 773k | return our_size; |
1524 | 773k | } |
1525 | | |
1526 | | size_t WireFormat::FieldByteSize(const FieldDescriptor* field, |
1527 | 1.47M | const Message& message) { |
1528 | 1.47M | const Reflection* message_reflection = message.GetReflection(); |
1529 | | |
1530 | 1.47M | if (field->is_extension() && |
1531 | 1.47M | field->containing_type()->options().message_set_wire_format() && |
1532 | 1.47M | field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && |
1533 | 1.47M | !field->is_repeated()) { |
1534 | 0 | return MessageSetItemByteSize(field, message); |
1535 | 0 | } |
1536 | | |
1537 | 1.47M | size_t count = 0; |
1538 | 1.47M | if (field->is_repeated()) { |
1539 | 262k | if (field->is_map()) { |
1540 | 15.8k | const MapFieldBase* map_field = |
1541 | 15.8k | message_reflection->GetMapData(message, field); |
1542 | 15.8k | if (map_field->IsMapValid()) { |
1543 | 0 | count = FromIntSize(map_field->size()); |
1544 | 15.8k | } else { |
1545 | 15.8k | count = FromIntSize(message_reflection->FieldSize(message, field)); |
1546 | 15.8k | } |
1547 | 246k | } else { |
1548 | 246k | count = FromIntSize(message_reflection->FieldSize(message, field)); |
1549 | 246k | } |
1550 | 1.21M | } else if (field->containing_type()->options().map_entry()) { |
1551 | | // Map entry fields always need to be serialized. |
1552 | 87.9k | count = 1; |
1553 | 1.12M | } else if (message_reflection->HasField(message, field)) { |
1554 | 1.12M | count = 1; |
1555 | 1.12M | } |
1556 | | |
1557 | 1.47M | const size_t data_size = FieldDataOnlyByteSize(field, message); |
1558 | 1.47M | size_t our_size = data_size; |
1559 | 1.47M | if (field->is_packed()) { |
1560 | 0 | if (data_size > 0) { |
1561 | | // Packed fields get serialized like a string, not their native type. |
1562 | | // Technically this doesn't really matter; the size only changes if it's |
1563 | | // a GROUP |
1564 | 0 | our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING); |
1565 | 0 | our_size += io::CodedOutputStream::VarintSize32(data_size); |
1566 | 0 | } |
1567 | 1.47M | } else { |
1568 | 1.47M | our_size += count * TagSize(field->number(), field->type()); |
1569 | 1.47M | } |
1570 | 1.47M | return our_size; |
1571 | 1.47M | } |
1572 | | |
1573 | | size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, |
1574 | 0 | const MapKey& value) { |
1575 | 0 | ABSL_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type()); |
1576 | 0 | switch (field->type()) { |
1577 | 0 | case FieldDescriptor::TYPE_DOUBLE: |
1578 | 0 | case FieldDescriptor::TYPE_FLOAT: |
1579 | 0 | case FieldDescriptor::TYPE_GROUP: |
1580 | 0 | case FieldDescriptor::TYPE_MESSAGE: |
1581 | 0 | case FieldDescriptor::TYPE_BYTES: |
1582 | 0 | case FieldDescriptor::TYPE_ENUM: |
1583 | 0 | ABSL_LOG(FATAL) << "Unsupported"; |
1584 | 0 | return 0; |
1585 | 0 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1586 | 0 | case FieldDescriptor::TYPE_##FieldType: \ |
1587 | 0 | return WireFormatLite::CamelFieldType##Size( \ |
1588 | 0 | value.Get##CamelCppType##Value()); |
1589 | | |
1590 | 0 | #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ |
1591 | 0 | case FieldDescriptor::TYPE_##FieldType: \ |
1592 | 0 | return WireFormatLite::k##CamelFieldType##Size; |
1593 | | |
1594 | 0 | CASE_TYPE(INT32, Int32, Int32); |
1595 | 0 | CASE_TYPE(INT64, Int64, Int64); |
1596 | 0 | CASE_TYPE(UINT32, UInt32, UInt32); |
1597 | 0 | CASE_TYPE(UINT64, UInt64, UInt64); |
1598 | 0 | CASE_TYPE(SINT32, SInt32, Int32); |
1599 | 0 | CASE_TYPE(SINT64, SInt64, Int64); |
1600 | 0 | CASE_TYPE(STRING, String, String); |
1601 | 0 | FIXED_CASE_TYPE(FIXED32, Fixed32); |
1602 | 0 | FIXED_CASE_TYPE(FIXED64, Fixed64); |
1603 | 0 | FIXED_CASE_TYPE(SFIXED32, SFixed32); |
1604 | 0 | FIXED_CASE_TYPE(SFIXED64, SFixed64); |
1605 | 0 | FIXED_CASE_TYPE(BOOL, Bool); |
1606 | |
|
1607 | 0 | #undef CASE_TYPE |
1608 | 0 | #undef FIXED_CASE_TYPE |
1609 | 0 | } |
1610 | 0 | ABSL_LOG(FATAL) << "Cannot get here"; |
1611 | 0 | return 0; |
1612 | 0 | } |
1613 | | |
1614 | | static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, |
1615 | 0 | const MapValueConstRef& value) { |
1616 | 0 | switch (field->type()) { |
1617 | 0 | case FieldDescriptor::TYPE_GROUP: |
1618 | 0 | ABSL_LOG(FATAL) << "Unsupported"; |
1619 | 0 | return 0; |
1620 | 0 | #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ |
1621 | 0 | case FieldDescriptor::TYPE_##FieldType: \ |
1622 | 0 | return WireFormatLite::CamelFieldType##Size( \ |
1623 | 0 | value.Get##CamelCppType##Value()); |
1624 | | |
1625 | 0 | #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ |
1626 | 0 | case FieldDescriptor::TYPE_##FieldType: \ |
1627 | 0 | return WireFormatLite::k##CamelFieldType##Size; |
1628 | | |
1629 | 0 | CASE_TYPE(INT32, Int32, Int32); |
1630 | 0 | CASE_TYPE(INT64, Int64, Int64); |
1631 | 0 | CASE_TYPE(UINT32, UInt32, UInt32); |
1632 | 0 | CASE_TYPE(UINT64, UInt64, UInt64); |
1633 | 0 | CASE_TYPE(SINT32, SInt32, Int32); |
1634 | 0 | CASE_TYPE(SINT64, SInt64, Int64); |
1635 | 0 | CASE_TYPE(STRING, String, String); |
1636 | 0 | CASE_TYPE(BYTES, Bytes, String); |
1637 | 0 | CASE_TYPE(ENUM, Enum, Enum); |
1638 | 0 | CASE_TYPE(MESSAGE, Message, Message); |
1639 | 0 | FIXED_CASE_TYPE(FIXED32, Fixed32); |
1640 | 0 | FIXED_CASE_TYPE(FIXED64, Fixed64); |
1641 | 0 | FIXED_CASE_TYPE(SFIXED32, SFixed32); |
1642 | 0 | FIXED_CASE_TYPE(SFIXED64, SFixed64); |
1643 | 0 | FIXED_CASE_TYPE(DOUBLE, Double); |
1644 | 0 | FIXED_CASE_TYPE(FLOAT, Float); |
1645 | 0 | FIXED_CASE_TYPE(BOOL, Bool); |
1646 | |
|
1647 | 0 | #undef CASE_TYPE |
1648 | 0 | #undef FIXED_CASE_TYPE |
1649 | 0 | } |
1650 | 0 | ABSL_LOG(FATAL) << "Cannot get here"; |
1651 | 0 | return 0; |
1652 | 0 | } |
1653 | | |
1654 | | size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field, |
1655 | 1.47M | const Message& message) { |
1656 | 1.47M | const Reflection* message_reflection = message.GetReflection(); |
1657 | | |
1658 | 1.47M | size_t data_size = 0; |
1659 | | |
1660 | 1.47M | if (field->is_map()) { |
1661 | 15.8k | const MapFieldBase* map_field = |
1662 | 15.8k | message_reflection->GetMapData(message, field); |
1663 | 15.8k | if (map_field->IsMapValid()) { |
1664 | 0 | MapIterator iter(const_cast<Message*>(&message), field); |
1665 | 0 | MapIterator end(const_cast<Message*>(&message), field); |
1666 | 0 | const FieldDescriptor* key_field = field->message_type()->field(0); |
1667 | 0 | const FieldDescriptor* value_field = field->message_type()->field(1); |
1668 | 0 | for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end; |
1669 | 0 | ++iter) { |
1670 | 0 | size_t size = kMapEntryTagByteSize; |
1671 | 0 | size += MapKeyDataOnlyByteSize(key_field, iter.GetKey()); |
1672 | 0 | size += MapValueRefDataOnlyByteSize(value_field, iter.GetValueRef()); |
1673 | 0 | data_size += WireFormatLite::LengthDelimitedSize(size); |
1674 | 0 | } |
1675 | 0 | return data_size; |
1676 | 0 | } |
1677 | 15.8k | } |
1678 | | |
1679 | 1.47M | size_t count = 0; |
1680 | 1.47M | if (field->is_repeated()) { |
1681 | 262k | count = |
1682 | 262k | internal::FromIntSize(message_reflection->FieldSize(message, field)); |
1683 | 1.21M | } else if (field->containing_type()->options().map_entry()) { |
1684 | | // Map entry fields always need to be serialized. |
1685 | 87.9k | count = 1; |
1686 | 1.12M | } else if (message_reflection->HasField(message, field)) { |
1687 | 1.12M | count = 1; |
1688 | 1.12M | } |
1689 | | |
1690 | 1.47M | switch (field->type()) { |
1691 | 0 | #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ |
1692 | 479k | case FieldDescriptor::TYPE_##TYPE: \ |
1693 | 479k | if (field->is_repeated()) { \ |
1694 | 531k | for (size_t j = 0; j < count; j++) { \ |
1695 | 414k | data_size += WireFormatLite::TYPE_METHOD##Size( \ |
1696 | 414k | message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \ |
1697 | 414k | j)); \ |
1698 | 414k | } \ |
1699 | 362k | } else { \ |
1700 | 362k | data_size += WireFormatLite::TYPE_METHOD##Size( \ |
1701 | 362k | message_reflection->Get##CPPTYPE_METHOD(message, field)); \ |
1702 | 362k | } \ |
1703 | 479k | break; |
1704 | | |
1705 | 0 | #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD) \ |
1706 | 10.1k | case FieldDescriptor::TYPE_##TYPE: \ |
1707 | 10.1k | data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \ |
1708 | 10.1k | break; |
1709 | | |
1710 | 19.0k | HANDLE_TYPE(INT32, Int32, Int32) |
1711 | 19.4k | HANDLE_TYPE(INT64, Int64, Int64) |
1712 | 0 | HANDLE_TYPE(SINT32, SInt32, Int32) |
1713 | 0 | HANDLE_TYPE(SINT64, SInt64, Int64) |
1714 | 26.2k | HANDLE_TYPE(UINT32, UInt32, UInt32) |
1715 | 0 | HANDLE_TYPE(UINT64, UInt64, UInt64) |
1716 | | |
1717 | 0 | HANDLE_FIXED_TYPE(FIXED32, Fixed32) |
1718 | 0 | HANDLE_FIXED_TYPE(FIXED64, Fixed64) |
1719 | 0 | HANDLE_FIXED_TYPE(SFIXED32, SFixed32) |
1720 | 0 | HANDLE_FIXED_TYPE(SFIXED64, SFixed64) |
1721 | | |
1722 | 0 | HANDLE_FIXED_TYPE(FLOAT, Float) |
1723 | 1.42k | HANDLE_FIXED_TYPE(DOUBLE, Double) |
1724 | | |
1725 | 8.70k | HANDLE_FIXED_TYPE(BOOL, Bool) |
1726 | | |
1727 | 0 | HANDLE_TYPE(GROUP, Group, Message) |
1728 | 414k | HANDLE_TYPE(MESSAGE, Message, Message) |
1729 | 0 | #undef HANDLE_TYPE |
1730 | 0 | #undef HANDLE_FIXED_TYPE |
1731 | | |
1732 | 12.2k | case FieldDescriptor::TYPE_ENUM: { |
1733 | 12.2k | if (field->is_repeated()) { |
1734 | 0 | for (size_t j = 0; j < count; j++) { |
1735 | 0 | data_size += WireFormatLite::EnumSize( |
1736 | 0 | message_reflection->GetRepeatedEnum(message, field, j)->number()); |
1737 | 0 | } |
1738 | 12.2k | } else { |
1739 | 12.2k | data_size += WireFormatLite::EnumSize( |
1740 | 12.2k | message_reflection->GetEnum(message, field)->number()); |
1741 | 12.2k | } |
1742 | 12.2k | break; |
1743 | 0 | } |
1744 | | |
1745 | | // Handle strings separately so that we can get string references |
1746 | | // instead of copying. |
1747 | 940k | case FieldDescriptor::TYPE_STRING: |
1748 | 975k | case FieldDescriptor::TYPE_BYTES: { |
1749 | 975k | if (internal::cpp::EffectiveStringCType(field) == FieldOptions::CORD) { |
1750 | 0 | for (size_t j = 0; j < count; j++) { |
1751 | 0 | absl::Cord value = message_reflection->GetCord(message, field); |
1752 | 0 | data_size += WireFormatLite::StringSize(value); |
1753 | 0 | } |
1754 | 0 | break; |
1755 | 0 | } |
1756 | 1.95M | for (size_t j = 0; j < count; j++) { |
1757 | 979k | std::string scratch; |
1758 | 979k | const std::string& value = |
1759 | 979k | field->is_repeated() |
1760 | 979k | ? message_reflection->GetRepeatedStringReference(message, field, |
1761 | 149k | j, &scratch) |
1762 | 979k | : message_reflection->GetStringReference(message, field, |
1763 | 829k | &scratch); |
1764 | 979k | data_size += WireFormatLite::StringSize(value); |
1765 | 979k | } |
1766 | 975k | break; |
1767 | 975k | } |
1768 | 1.47M | } |
1769 | 1.47M | return data_size; |
1770 | 1.47M | } |
1771 | | |
1772 | | size_t WireFormat::MessageSetItemByteSize(const FieldDescriptor* field, |
1773 | 0 | const Message& message) { |
1774 | 0 | const Reflection* message_reflection = message.GetReflection(); |
1775 | |
|
1776 | 0 | size_t our_size = WireFormatLite::kMessageSetItemTagsSize; |
1777 | | |
1778 | | // type_id |
1779 | 0 | our_size += io::CodedOutputStream::VarintSize32(field->number()); |
1780 | | |
1781 | | // message |
1782 | 0 | const Message& sub_message = message_reflection->GetMessage(message, field); |
1783 | 0 | size_t message_size = sub_message.ByteSizeLong(); |
1784 | |
|
1785 | 0 | our_size += io::CodedOutputStream::VarintSize32(message_size); |
1786 | 0 | our_size += message_size; |
1787 | |
|
1788 | 0 | return our_size; |
1789 | 0 | } |
1790 | | |
1791 | | // Compute the size of the UnknownFieldSet on the wire. |
1792 | | size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata, |
1793 | 0 | size_t total_size, CachedSize* cached_size) { |
1794 | 0 | total_size += WireFormat::ComputeUnknownFieldsSize( |
1795 | 0 | metadata.unknown_fields<UnknownFieldSet>( |
1796 | 0 | UnknownFieldSet::default_instance)); |
1797 | 0 | cached_size->Set(ToCachedSize(total_size)); |
1798 | 0 | return total_size; |
1799 | 0 | } |
1800 | | |
1801 | | } // namespace internal |
1802 | | } // namespace protobuf |
1803 | | } // namespace google |
1804 | | |
1805 | | #include "google/protobuf/port_undef.inc" |