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: jschorr@google.com (Joseph Schorr)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/text_format.h>
36
37 #include <float.h>
38 #include <stdio.h>
39
40 #include <algorithm>
41 #include <climits>
42 #include <cmath>
43 #include <limits>
44 #include <vector>
45
46 #include <google/protobuf/stubs/stringprintf.h>
47 #include <google/protobuf/any.h>
48 #include <google/protobuf/descriptor.pb.h>
49 #include <google/protobuf/io/coded_stream.h>
50 #include <google/protobuf/io/tokenizer.h>
51 #include <google/protobuf/io/zero_copy_stream.h>
52 #include <google/protobuf/io/zero_copy_stream_impl.h>
53 #include <google/protobuf/descriptor.h>
54 #include <google/protobuf/dynamic_message.h>
55 #include <google/protobuf/map_field.h>
56 #include <google/protobuf/message.h>
57 #include <google/protobuf/port_def.inc>
58 #include <google/protobuf/repeated_field.h>
59 #include <google/protobuf/unknown_field_set.h>
60 #include <google/protobuf/wire_format_lite.h>
61 #include <google/protobuf/stubs/strutil.h>
62 #include <google/protobuf/io/strtod.h>
63 #include <google/protobuf/stubs/map_util.h>
64 #include <google/protobuf/stubs/stl_util.h>
65
66
67 namespace google {
68 namespace protobuf {
69
70 namespace {
71
IsHexNumber(const std::string & str)72 inline bool IsHexNumber(const std::string& str) {
73 return (str.length() >= 2 && str[0] == '0' &&
74 (str[1] == 'x' || str[1] == 'X'));
75 }
76
IsOctNumber(const std::string & str)77 inline bool IsOctNumber(const std::string& str) {
78 return (str.length() >= 2 && str[0] == '0' &&
79 (str[1] >= '0' && str[1] < '8'));
80 }
81
82 } // namespace
83
DebugString() const84 std::string Message::DebugString() const {
85 std::string debug_string;
86
87 TextFormat::Printer printer;
88 printer.SetExpandAny(true);
89
90 printer.PrintToString(*this, &debug_string);
91
92 return debug_string;
93 }
94
ShortDebugString() const95 std::string Message::ShortDebugString() const {
96 std::string debug_string;
97
98 TextFormat::Printer printer;
99 printer.SetSingleLineMode(true);
100 printer.SetExpandAny(true);
101
102 printer.PrintToString(*this, &debug_string);
103 // Single line mode currently might have an extra space at the end.
104 if (debug_string.size() > 0 && debug_string[debug_string.size() - 1] == ' ') {
105 debug_string.resize(debug_string.size() - 1);
106 }
107
108 return debug_string;
109 }
110
Utf8DebugString() const111 std::string Message::Utf8DebugString() const {
112 std::string debug_string;
113
114 TextFormat::Printer printer;
115 printer.SetUseUtf8StringEscaping(true);
116 printer.SetExpandAny(true);
117
118 printer.PrintToString(*this, &debug_string);
119
120 return debug_string;
121 }
122
PrintDebugString() const123 void Message::PrintDebugString() const { printf("%s", DebugString().c_str()); }
124
125
126 // ===========================================================================
127 // Implementation of the parse information tree class.
RecordLocation(const FieldDescriptor * field,TextFormat::ParseLocation location)128 void TextFormat::ParseInfoTree::RecordLocation(
129 const FieldDescriptor* field, TextFormat::ParseLocation location) {
130 locations_[field].push_back(location);
131 }
132
CreateNested(const FieldDescriptor * field)133 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
134 const FieldDescriptor* field) {
135 // Owned by us in the map.
136 auto& vec = nested_[field];
137 vec.emplace_back(new TextFormat::ParseInfoTree());
138 return vec.back().get();
139 }
140
CheckFieldIndex(const FieldDescriptor * field,int index)141 void CheckFieldIndex(const FieldDescriptor* field, int index) {
142 if (field == nullptr) {
143 return;
144 }
145
146 if (field->is_repeated() && index == -1) {
147 GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
148 << "Field: " << field->name();
149 } else if (!field->is_repeated() && index != -1) {
150 GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
151 << "Field: " << field->name();
152 }
153 }
154
GetLocation(const FieldDescriptor * field,int index) const155 TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
156 const FieldDescriptor* field, int index) const {
157 CheckFieldIndex(field, index);
158 if (index == -1) {
159 index = 0;
160 }
161
162 const std::vector<TextFormat::ParseLocation>* locations =
163 FindOrNull(locations_, field);
164 if (locations == nullptr || index >= locations->size()) {
165 return TextFormat::ParseLocation();
166 }
167
168 return (*locations)[index];
169 }
170
GetTreeForNested(const FieldDescriptor * field,int index) const171 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
172 const FieldDescriptor* field, int index) const {
173 CheckFieldIndex(field, index);
174 if (index == -1) {
175 index = 0;
176 }
177
178 auto it = nested_.find(field);
179 if (it == nested_.end() || index >= it->second.size()) {
180 return nullptr;
181 }
182
183 return it->second[index].get();
184 }
185
186 namespace {
187 // These functions implement the behavior of the "default" TextFormat::Finder,
188 // they are defined as standalone to be called when finder_ is nullptr.
DefaultFinderFindExtension(Message * message,const std::string & name)189 const FieldDescriptor* DefaultFinderFindExtension(Message* message,
190 const std::string& name) {
191 const Descriptor* descriptor = message->GetDescriptor();
192 return descriptor->file()->pool()->FindExtensionByPrintableName(descriptor,
193 name);
194 }
195
DefaultFinderFindExtensionByNumber(const Descriptor * descriptor,int number)196 const FieldDescriptor* DefaultFinderFindExtensionByNumber(
197 const Descriptor* descriptor, int number) {
198 return descriptor->file()->pool()->FindExtensionByNumber(descriptor, number);
199 }
200
DefaultFinderFindAnyType(const Message & message,const std::string & prefix,const std::string & name)201 const Descriptor* DefaultFinderFindAnyType(const Message& message,
202 const std::string& prefix,
203 const std::string& name) {
204 if (prefix != internal::kTypeGoogleApisComPrefix &&
205 prefix != internal::kTypeGoogleProdComPrefix) {
206 return nullptr;
207 }
208 return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name);
209 }
210 } // namespace
211
212 // ===========================================================================
213 // Internal class for parsing an ASCII representation of a Protocol Message.
214 // This class makes use of the Protocol Message compiler's tokenizer found
215 // in //net/proto2/io/public/tokenizer.h. Note that class's Parse
216 // method is *not* thread-safe and should only be used in a single thread at
217 // a time.
218
219 // Makes code slightly more readable. The meaning of "DO(foo)" is
220 // "Execute foo and fail if it fails.", where failure is indicated by
221 // returning false. Borrowed from parser.cc (Thanks Kenton!).
222 #define DO(STATEMENT) \
223 if (STATEMENT) { \
224 } else { \
225 return false; \
226 }
227
228 class TextFormat::Parser::ParserImpl {
229 public:
230 // Determines if repeated values for non-repeated fields and
231 // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
232 // required/optional field named "foo", or "baz: 1 qux: 2"
233 // where "baz" and "qux" are members of the same oneof.
234 enum SingularOverwritePolicy {
235 ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained
236 FORBID_SINGULAR_OVERWRITES = 1, // an error is issued
237 };
238
ParserImpl(const Descriptor * root_message_type,io::ZeroCopyInputStream * input_stream,io::ErrorCollector * error_collector,const TextFormat::Finder * finder,ParseInfoTree * parse_info_tree,SingularOverwritePolicy singular_overwrite_policy,bool allow_case_insensitive_field,bool allow_unknown_field,bool allow_unknown_extension,bool allow_unknown_enum,bool allow_field_number,bool allow_relaxed_whitespace,bool allow_partial,int recursion_limit)239 ParserImpl(const Descriptor* root_message_type,
240 io::ZeroCopyInputStream* input_stream,
241 io::ErrorCollector* error_collector,
242 const TextFormat::Finder* finder, ParseInfoTree* parse_info_tree,
243 SingularOverwritePolicy singular_overwrite_policy,
244 bool allow_case_insensitive_field, bool allow_unknown_field,
245 bool allow_unknown_extension, bool allow_unknown_enum,
246 bool allow_field_number, bool allow_relaxed_whitespace,
247 bool allow_partial, int recursion_limit)
248 : error_collector_(error_collector),
249 finder_(finder),
250 parse_info_tree_(parse_info_tree),
251 tokenizer_error_collector_(this),
252 tokenizer_(input_stream, &tokenizer_error_collector_),
253 root_message_type_(root_message_type),
254 singular_overwrite_policy_(singular_overwrite_policy),
255 allow_case_insensitive_field_(allow_case_insensitive_field),
256 allow_unknown_field_(allow_unknown_field),
257 allow_unknown_extension_(allow_unknown_extension),
258 allow_unknown_enum_(allow_unknown_enum),
259 allow_field_number_(allow_field_number),
260 allow_partial_(allow_partial),
261 recursion_limit_(recursion_limit),
262 had_errors_(false) {
263 // For backwards-compatibility with proto1, we need to allow the 'f' suffix
264 // for floats.
265 tokenizer_.set_allow_f_after_float(true);
266
267 // '#' starts a comment.
268 tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
269
270 if (allow_relaxed_whitespace) {
271 tokenizer_.set_require_space_after_number(false);
272 tokenizer_.set_allow_multiline_strings(true);
273 }
274
275 // Consume the starting token.
276 tokenizer_.Next();
277 }
~ParserImpl()278 ~ParserImpl() {}
279
280 // Parses the ASCII representation specified in input and saves the
281 // information into the output pointer (a Message). Returns
282 // false if an error occurs (an error will also be logged to
283 // GOOGLE_LOG(ERROR)).
Parse(Message * output)284 bool Parse(Message* output) {
285 // Consume fields until we cannot do so anymore.
286 while (true) {
287 if (LookingAtType(io::Tokenizer::TYPE_END)) {
288 return !had_errors_;
289 }
290
291 DO(ConsumeField(output));
292 }
293 }
294
ParseField(const FieldDescriptor * field,Message * output)295 bool ParseField(const FieldDescriptor* field, Message* output) {
296 bool suc;
297 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
298 suc = ConsumeFieldMessage(output, output->GetReflection(), field);
299 } else {
300 suc = ConsumeFieldValue(output, output->GetReflection(), field);
301 }
302 return suc && LookingAtType(io::Tokenizer::TYPE_END);
303 }
304
ReportError(int line,int col,const std::string & message)305 void ReportError(int line, int col, const std::string& message) {
306 had_errors_ = true;
307 if (error_collector_ == nullptr) {
308 if (line >= 0) {
309 GOOGLE_LOG(ERROR) << "Error parsing text-format "
310 << root_message_type_->full_name() << ": " << (line + 1)
311 << ":" << (col + 1) << ": " << message;
312 } else {
313 GOOGLE_LOG(ERROR) << "Error parsing text-format "
314 << root_message_type_->full_name() << ": " << message;
315 }
316 } else {
317 error_collector_->AddError(line, col, message);
318 }
319 }
320
ReportWarning(int line,int col,const std::string & message)321 void ReportWarning(int line, int col, const std::string& message) {
322 if (error_collector_ == nullptr) {
323 if (line >= 0) {
324 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
325 << root_message_type_->full_name() << ": " << (line + 1)
326 << ":" << (col + 1) << ": " << message;
327 } else {
328 GOOGLE_LOG(WARNING) << "Warning parsing text-format "
329 << root_message_type_->full_name() << ": " << message;
330 }
331 } else {
332 error_collector_->AddWarning(line, col, message);
333 }
334 }
335
336 private:
337 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
338
339 // Reports an error with the given message with information indicating
340 // the position (as derived from the current token).
ReportError(const std::string & message)341 void ReportError(const std::string& message) {
342 ReportError(tokenizer_.current().line, tokenizer_.current().column,
343 message);
344 }
345
346 // Reports a warning with the given message with information indicating
347 // the position (as derived from the current token).
ReportWarning(const std::string & message)348 void ReportWarning(const std::string& message) {
349 ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
350 message);
351 }
352
353 // Consumes the specified message with the given starting delimiter.
354 // This method checks to see that the end delimiter at the conclusion of
355 // the consumption matches the starting delimiter passed in here.
ConsumeMessage(Message * message,const std::string delimiter)356 bool ConsumeMessage(Message* message, const std::string delimiter) {
357 while (!LookingAt(">") && !LookingAt("}")) {
358 DO(ConsumeField(message));
359 }
360
361 // Confirm that we have a valid ending delimiter.
362 DO(Consume(delimiter));
363 return true;
364 }
365
366 // Consume either "<" or "{".
ConsumeMessageDelimiter(std::string * delimiter)367 bool ConsumeMessageDelimiter(std::string* delimiter) {
368 if (TryConsume("<")) {
369 *delimiter = ">";
370 } else {
371 DO(Consume("{"));
372 *delimiter = "}";
373 }
374 return true;
375 }
376
377
378 // Consumes the current field (as returned by the tokenizer) on the
379 // passed in message.
ConsumeField(Message * message)380 bool ConsumeField(Message* message) {
381 const Reflection* reflection = message->GetReflection();
382 const Descriptor* descriptor = message->GetDescriptor();
383
384 std::string field_name;
385 bool reserved_field = false;
386 const FieldDescriptor* field = nullptr;
387 int start_line = tokenizer_.current().line;
388 int start_column = tokenizer_.current().column;
389
390 const FieldDescriptor* any_type_url_field;
391 const FieldDescriptor* any_value_field;
392 if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field,
393 &any_value_field) &&
394 TryConsume("[")) {
395 std::string full_type_name, prefix;
396 DO(ConsumeAnyTypeUrl(&full_type_name, &prefix));
397 DO(Consume("]"));
398 TryConsume(":"); // ':' is optional between message labels and values.
399 std::string serialized_value;
400 const Descriptor* value_descriptor =
401 finder_ ? finder_->FindAnyType(*message, prefix, full_type_name)
402 : DefaultFinderFindAnyType(*message, prefix, full_type_name);
403 if (value_descriptor == nullptr) {
404 ReportError("Could not find type \"" + prefix + full_type_name +
405 "\" stored in google.protobuf.Any.");
406 return false;
407 }
408 DO(ConsumeAnyValue(value_descriptor, &serialized_value));
409 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
410 // Fail if any_type_url_field has already been specified.
411 if ((!any_type_url_field->is_repeated() &&
412 reflection->HasField(*message, any_type_url_field)) ||
413 (!any_value_field->is_repeated() &&
414 reflection->HasField(*message, any_value_field))) {
415 ReportError("Non-repeated Any specified multiple times.");
416 return false;
417 }
418 }
419 reflection->SetString(message, any_type_url_field,
420 std::string(prefix + full_type_name));
421 reflection->SetString(message, any_value_field, serialized_value);
422 return true;
423 }
424 if (TryConsume("[")) {
425 // Extension.
426 DO(ConsumeFullTypeName(&field_name));
427 DO(Consume("]"));
428
429 field = finder_ ? finder_->FindExtension(message, field_name)
430 : DefaultFinderFindExtension(message, field_name);
431
432 if (field == nullptr) {
433 if (!allow_unknown_field_ && !allow_unknown_extension_) {
434 ReportError("Extension \"" + field_name +
435 "\" is not defined or "
436 "is not an extension of \"" +
437 descriptor->full_name() + "\".");
438 return false;
439 } else {
440 ReportWarning("Ignoring extension \"" + field_name +
441 "\" which is not defined or is not an extension of \"" +
442 descriptor->full_name() + "\".");
443 }
444 }
445 } else {
446 DO(ConsumeIdentifier(&field_name));
447
448 int32 field_number;
449 if (allow_field_number_ &&
450 safe_strto32(field_name, &field_number)) {
451 if (descriptor->IsExtensionNumber(field_number)) {
452 field = finder_
453 ? finder_->FindExtensionByNumber(descriptor, field_number)
454 : DefaultFinderFindExtensionByNumber(descriptor,
455 field_number);
456 } else if (descriptor->IsReservedNumber(field_number)) {
457 reserved_field = true;
458 } else {
459 field = descriptor->FindFieldByNumber(field_number);
460 }
461 } else {
462 field = descriptor->FindFieldByName(field_name);
463 // Group names are expected to be capitalized as they appear in the
464 // .proto file, which actually matches their type names, not their
465 // field names.
466 if (field == nullptr) {
467 std::string lower_field_name = field_name;
468 LowerString(&lower_field_name);
469 field = descriptor->FindFieldByName(lower_field_name);
470 // If the case-insensitive match worked but the field is NOT a group,
471 if (field != nullptr &&
472 field->type() != FieldDescriptor::TYPE_GROUP) {
473 field = nullptr;
474 }
475 }
476 // Again, special-case group names as described above.
477 if (field != nullptr && field->type() == FieldDescriptor::TYPE_GROUP &&
478 field->message_type()->name() != field_name) {
479 field = nullptr;
480 }
481
482 if (field == nullptr && allow_case_insensitive_field_) {
483 std::string lower_field_name = field_name;
484 LowerString(&lower_field_name);
485 field = descriptor->FindFieldByLowercaseName(lower_field_name);
486 }
487
488 if (field == nullptr) {
489 reserved_field = descriptor->IsReservedName(field_name);
490 }
491 }
492
493 if (field == nullptr && !reserved_field) {
494 if (!allow_unknown_field_) {
495 ReportError("Message type \"" + descriptor->full_name() +
496 "\" has no field named \"" + field_name + "\".");
497 return false;
498 } else {
499 ReportWarning("Message type \"" + descriptor->full_name() +
500 "\" has no field named \"" + field_name + "\".");
501 }
502 }
503 }
504
505 // Skips unknown or reserved fields.
506 if (field == nullptr) {
507 GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field);
508
509 // Try to guess the type of this field.
510 // If this field is not a message, there should be a ":" between the
511 // field name and the field value and also the field value should not
512 // start with "{" or "<" which indicates the beginning of a message body.
513 // If there is no ":" or there is a "{" or "<" after ":", this field has
514 // to be a message or the input is ill-formed.
515 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
516 return SkipFieldValue();
517 } else {
518 return SkipFieldMessage();
519 }
520 }
521
522 if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
523 // Fail if the field is not repeated and it has already been specified.
524 if (!field->is_repeated() && reflection->HasField(*message, field)) {
525 ReportError("Non-repeated field \"" + field_name +
526 "\" is specified multiple times.");
527 return false;
528 }
529 // Fail if the field is a member of a oneof and another member has already
530 // been specified.
531 const OneofDescriptor* oneof = field->containing_oneof();
532 if (oneof != nullptr && reflection->HasOneof(*message, oneof)) {
533 const FieldDescriptor* other_field =
534 reflection->GetOneofFieldDescriptor(*message, oneof);
535 ReportError("Field \"" + field_name +
536 "\" is specified along with "
537 "field \"" +
538 other_field->name() +
539 "\", another member "
540 "of oneof \"" +
541 oneof->name() + "\".");
542 return false;
543 }
544 }
545
546 // Perform special handling for embedded message types.
547 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
548 // ':' is optional here.
549 bool consumed_semicolon = TryConsume(":");
550 if (consumed_semicolon && field->options().weak() &&
551 LookingAtType(io::Tokenizer::TYPE_STRING)) {
552 // we are getting a bytes string for a weak field.
553 std::string tmp;
554 DO(ConsumeString(&tmp));
555 MessageFactory* factory =
556 finder_ ? finder_->FindExtensionFactory(field) : nullptr;
557 reflection->MutableMessage(message, field, factory)
558 ->ParseFromString(tmp);
559 goto label_skip_parsing;
560 }
561 } else {
562 // ':' is required here.
563 DO(Consume(":"));
564 }
565
566 if (field->is_repeated() && TryConsume("[")) {
567 // Short repeated format, e.g. "foo: [1, 2, 3]".
568 if (!TryConsume("]")) {
569 // "foo: []" is treated as empty.
570 while (true) {
571 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
572 // Perform special handling for embedded message types.
573 DO(ConsumeFieldMessage(message, reflection, field));
574 } else {
575 DO(ConsumeFieldValue(message, reflection, field));
576 }
577 if (TryConsume("]")) {
578 break;
579 }
580 DO(Consume(","));
581 }
582 }
583 } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
584 DO(ConsumeFieldMessage(message, reflection, field));
585 } else {
586 DO(ConsumeFieldValue(message, reflection, field));
587 }
588 label_skip_parsing:
589 // For historical reasons, fields may optionally be separated by commas or
590 // semicolons.
591 TryConsume(";") || TryConsume(",");
592
593 if (field->options().deprecated()) {
594 ReportWarning("text format contains deprecated field \"" + field_name +
595 "\"");
596 }
597
598 // If a parse info tree exists, add the location for the parsed
599 // field.
600 if (parse_info_tree_ != nullptr) {
601 RecordLocation(parse_info_tree_, field,
602 ParseLocation(start_line, start_column));
603 }
604
605 return true;
606 }
607
608 // Skips the next field including the field's name and value.
SkipField()609 bool SkipField() {
610 if (TryConsume("[")) {
611 // Extension name or type URL.
612 DO(ConsumeTypeUrlOrFullTypeName());
613 DO(Consume("]"));
614 } else {
615 std::string field_name;
616 DO(ConsumeIdentifier(&field_name));
617 }
618
619 // Try to guess the type of this field.
620 // If this field is not a message, there should be a ":" between the
621 // field name and the field value and also the field value should not
622 // start with "{" or "<" which indicates the beginning of a message body.
623 // If there is no ":" or there is a "{" or "<" after ":", this field has
624 // to be a message or the input is ill-formed.
625 if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
626 DO(SkipFieldValue());
627 } else {
628 DO(SkipFieldMessage());
629 }
630 // For historical reasons, fields may optionally be separated by commas or
631 // semicolons.
632 TryConsume(";") || TryConsume(",");
633 return true;
634 }
635
ConsumeFieldMessage(Message * message,const Reflection * reflection,const FieldDescriptor * field)636 bool ConsumeFieldMessage(Message* message, const Reflection* reflection,
637 const FieldDescriptor* field) {
638 if (--recursion_limit_ < 0) {
639 ReportError("Message is too deep");
640 return false;
641 }
642 // If the parse information tree is not nullptr, create a nested one
643 // for the nested message.
644 ParseInfoTree* parent = parse_info_tree_;
645 if (parent != nullptr) {
646 parse_info_tree_ = CreateNested(parent, field);
647 }
648
649 std::string delimiter;
650 DO(ConsumeMessageDelimiter(&delimiter));
651 MessageFactory* factory =
652 finder_ ? finder_->FindExtensionFactory(field) : nullptr;
653 if (field->is_repeated()) {
654 DO(ConsumeMessage(reflection->AddMessage(message, field, factory),
655 delimiter));
656 } else {
657 DO(ConsumeMessage(reflection->MutableMessage(message, field, factory),
658 delimiter));
659 }
660
661 ++recursion_limit_;
662
663 // Reset the parse information tree.
664 parse_info_tree_ = parent;
665 return true;
666 }
667
668 // Skips the whole body of a message including the beginning delimiter and
669 // the ending delimiter.
SkipFieldMessage()670 bool SkipFieldMessage() {
671 std::string delimiter;
672 DO(ConsumeMessageDelimiter(&delimiter));
673 while (!LookingAt(">") && !LookingAt("}")) {
674 DO(SkipField());
675 }
676 DO(Consume(delimiter));
677 return true;
678 }
679
ConsumeFieldValue(Message * message,const Reflection * reflection,const FieldDescriptor * field)680 bool ConsumeFieldValue(Message* message, const Reflection* reflection,
681 const FieldDescriptor* field) {
682 // Define an easy to use macro for setting fields. This macro checks
683 // to see if the field is repeated (in which case we need to use the Add
684 // methods or not (in which case we need to use the Set methods).
685 #define SET_FIELD(CPPTYPE, VALUE) \
686 if (field->is_repeated()) { \
687 reflection->Add##CPPTYPE(message, field, VALUE); \
688 } else { \
689 reflection->Set##CPPTYPE(message, field, VALUE); \
690 }
691
692 switch (field->cpp_type()) {
693 case FieldDescriptor::CPPTYPE_INT32: {
694 int64 value;
695 DO(ConsumeSignedInteger(&value, kint32max));
696 SET_FIELD(Int32, static_cast<int32>(value));
697 break;
698 }
699
700 case FieldDescriptor::CPPTYPE_UINT32: {
701 uint64 value;
702 DO(ConsumeUnsignedInteger(&value, kuint32max));
703 SET_FIELD(UInt32, static_cast<uint32>(value));
704 break;
705 }
706
707 case FieldDescriptor::CPPTYPE_INT64: {
708 int64 value;
709 DO(ConsumeSignedInteger(&value, kint64max));
710 SET_FIELD(Int64, value);
711 break;
712 }
713
714 case FieldDescriptor::CPPTYPE_UINT64: {
715 uint64 value;
716 DO(ConsumeUnsignedInteger(&value, kuint64max));
717 SET_FIELD(UInt64, value);
718 break;
719 }
720
721 case FieldDescriptor::CPPTYPE_FLOAT: {
722 double value;
723 DO(ConsumeDouble(&value));
724 SET_FIELD(Float, io::SafeDoubleToFloat(value));
725 break;
726 }
727
728 case FieldDescriptor::CPPTYPE_DOUBLE: {
729 double value;
730 DO(ConsumeDouble(&value));
731 SET_FIELD(Double, value);
732 break;
733 }
734
735 case FieldDescriptor::CPPTYPE_STRING: {
736 std::string value;
737 DO(ConsumeString(&value));
738 SET_FIELD(String, value);
739 break;
740 }
741
742 case FieldDescriptor::CPPTYPE_BOOL: {
743 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
744 uint64 value;
745 DO(ConsumeUnsignedInteger(&value, 1));
746 SET_FIELD(Bool, value);
747 } else {
748 std::string value;
749 DO(ConsumeIdentifier(&value));
750 if (value == "true" || value == "True" || value == "t") {
751 SET_FIELD(Bool, true);
752 } else if (value == "false" || value == "False" || value == "f") {
753 SET_FIELD(Bool, false);
754 } else {
755 ReportError("Invalid value for boolean field \"" + field->name() +
756 "\". Value: \"" + value + "\".");
757 return false;
758 }
759 }
760 break;
761 }
762
763 case FieldDescriptor::CPPTYPE_ENUM: {
764 std::string value;
765 int64 int_value = kint64max;
766 const EnumDescriptor* enum_type = field->enum_type();
767 const EnumValueDescriptor* enum_value = nullptr;
768
769 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
770 DO(ConsumeIdentifier(&value));
771 // Find the enumeration value.
772 enum_value = enum_type->FindValueByName(value);
773
774 } else if (LookingAt("-") ||
775 LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
776 DO(ConsumeSignedInteger(&int_value, kint32max));
777 value = StrCat(int_value); // for error reporting
778 enum_value = enum_type->FindValueByNumber(int_value);
779 } else {
780 ReportError("Expected integer or identifier, got: " +
781 tokenizer_.current().text);
782 return false;
783 }
784
785 if (enum_value == nullptr) {
786 if (int_value != kint64max &&
787 reflection->SupportsUnknownEnumValues()) {
788 SET_FIELD(EnumValue, int_value);
789 return true;
790 } else if (!allow_unknown_enum_) {
791 ReportError("Unknown enumeration value of \"" + value +
792 "\" for "
793 "field \"" +
794 field->name() + "\".");
795 return false;
796 } else {
797 ReportWarning("Unknown enumeration value of \"" + value +
798 "\" for "
799 "field \"" +
800 field->name() + "\".");
801 return true;
802 }
803 }
804
805 SET_FIELD(Enum, enum_value);
806 break;
807 }
808
809 case FieldDescriptor::CPPTYPE_MESSAGE: {
810 // We should never get here. Put here instead of a default
811 // so that if new types are added, we get a nice compiler warning.
812 GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
813 break;
814 }
815 }
816 #undef SET_FIELD
817 return true;
818 }
819
SkipFieldValue()820 bool SkipFieldValue() {
821 if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
822 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
823 tokenizer_.Next();
824 }
825 return true;
826 }
827 if (TryConsume("[")) {
828 while (true) {
829 if (!LookingAt("{") && !LookingAt("<")) {
830 DO(SkipFieldValue());
831 } else {
832 DO(SkipFieldMessage());
833 }
834 if (TryConsume("]")) {
835 break;
836 }
837 DO(Consume(","));
838 }
839 return true;
840 }
841 // Possible field values other than string:
842 // 12345 => TYPE_INTEGER
843 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
844 // 1.2345 => TYPE_FLOAT
845 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
846 // inf => TYPE_IDENTIFIER
847 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
848 // TYPE_INTEGER => TYPE_IDENTIFIER
849 // Divides them into two group, one with TYPE_SYMBOL
850 // and the other without:
851 // Group one:
852 // 12345 => TYPE_INTEGER
853 // 1.2345 => TYPE_FLOAT
854 // inf => TYPE_IDENTIFIER
855 // TYPE_INTEGER => TYPE_IDENTIFIER
856 // Group two:
857 // -12345 => TYPE_SYMBOL + TYPE_INTEGER
858 // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT
859 // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER
860 // As we can see, the field value consists of an optional '-' and one of
861 // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
862 bool has_minus = TryConsume("-");
863 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
864 !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
865 !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
866 std::string text = tokenizer_.current().text;
867 ReportError("Cannot skip field value, unexpected token: " + text);
868 return false;
869 }
870 // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
871 // value while other combinations all generate valid values.
872 // We check if the value of this combination is valid here.
873 // TYPE_IDENTIFIER after a '-' should be one of the float values listed
874 // below:
875 // inf, inff, infinity, nan
876 if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
877 std::string text = tokenizer_.current().text;
878 LowerString(&text);
879 if (text != "inf" &&
880 text != "infinity" && text != "nan") {
881 ReportError("Invalid float number: " + text);
882 return false;
883 }
884 }
885 tokenizer_.Next();
886 return true;
887 }
888
889 // Returns true if the current token's text is equal to that specified.
LookingAt(const std::string & text)890 bool LookingAt(const std::string& text) {
891 return tokenizer_.current().text == text;
892 }
893
894 // Returns true if the current token's type is equal to that specified.
LookingAtType(io::Tokenizer::TokenType token_type)895 bool LookingAtType(io::Tokenizer::TokenType token_type) {
896 return tokenizer_.current().type == token_type;
897 }
898
899 // Consumes an identifier and saves its value in the identifier parameter.
900 // Returns false if the token is not of type IDENTFIER.
ConsumeIdentifier(std::string * identifier)901 bool ConsumeIdentifier(std::string* identifier) {
902 if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
903 *identifier = tokenizer_.current().text;
904 tokenizer_.Next();
905 return true;
906 }
907
908 // If allow_field_numer_ or allow_unknown_field_ is true, we should able
909 // to parse integer identifiers.
910 if ((allow_field_number_ || allow_unknown_field_ ||
911 allow_unknown_extension_) &&
912 LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
913 *identifier = tokenizer_.current().text;
914 tokenizer_.Next();
915 return true;
916 }
917
918 ReportError("Expected identifier, got: " + tokenizer_.current().text);
919 return false;
920 }
921
922 // Consume a string of form "<id1>.<id2>....<idN>".
ConsumeFullTypeName(std::string * name)923 bool ConsumeFullTypeName(std::string* name) {
924 DO(ConsumeIdentifier(name));
925 while (TryConsume(".")) {
926 std::string part;
927 DO(ConsumeIdentifier(&part));
928 *name += ".";
929 *name += part;
930 }
931 return true;
932 }
933
ConsumeTypeUrlOrFullTypeName()934 bool ConsumeTypeUrlOrFullTypeName() {
935 std::string discarded;
936 DO(ConsumeIdentifier(&discarded));
937 while (TryConsume(".") || TryConsume("/")) {
938 DO(ConsumeIdentifier(&discarded));
939 }
940 return true;
941 }
942
943 // Consumes a string and saves its value in the text parameter.
944 // Returns false if the token is not of type STRING.
ConsumeString(std::string * text)945 bool ConsumeString(std::string* text) {
946 if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
947 ReportError("Expected string, got: " + tokenizer_.current().text);
948 return false;
949 }
950
951 text->clear();
952 while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
953 io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
954
955 tokenizer_.Next();
956 }
957
958 return true;
959 }
960
961 // Consumes a uint64 and saves its value in the value parameter.
962 // Returns false if the token is not of type INTEGER.
ConsumeUnsignedInteger(uint64 * value,uint64 max_value)963 bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
964 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
965 ReportError("Expected integer, got: " + tokenizer_.current().text);
966 return false;
967 }
968
969 if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value,
970 value)) {
971 ReportError("Integer out of range (" + tokenizer_.current().text + ")");
972 return false;
973 }
974
975 tokenizer_.Next();
976 return true;
977 }
978
979 // Consumes an int64 and saves its value in the value parameter.
980 // Note that since the tokenizer does not support negative numbers,
981 // we actually may consume an additional token (for the minus sign) in this
982 // method. Returns false if the token is not an integer
983 // (signed or otherwise).
ConsumeSignedInteger(int64 * value,uint64 max_value)984 bool ConsumeSignedInteger(int64* value, uint64 max_value) {
985 bool negative = false;
986
987 if (TryConsume("-")) {
988 negative = true;
989 // Two's complement always allows one more negative integer than
990 // positive.
991 ++max_value;
992 }
993
994 uint64 unsigned_value;
995
996 DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
997
998 if (negative) {
999 if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) {
1000 *value = kint64min;
1001 } else {
1002 *value = -static_cast<int64>(unsigned_value);
1003 }
1004 } else {
1005 *value = static_cast<int64>(unsigned_value);
1006 }
1007
1008 return true;
1009 }
1010
1011 // Consumes a double and saves its value in the value parameter.
1012 // Accepts decimal numbers only, rejects hex or oct numbers.
ConsumeUnsignedDecimalAsDouble(double * value,uint64 max_value)1013 bool ConsumeUnsignedDecimalAsDouble(double* value, uint64 max_value) {
1014 if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1015 ReportError("Expected integer, got: " + tokenizer_.current().text);
1016 return false;
1017 }
1018
1019 const std::string& text = tokenizer_.current().text;
1020 if (IsHexNumber(text) || IsOctNumber(text)) {
1021 ReportError("Expect a decimal number, got: " + text);
1022 return false;
1023 }
1024
1025 uint64 uint64_value;
1026 if (io::Tokenizer::ParseInteger(text, max_value, &uint64_value)) {
1027 *value = static_cast<double>(uint64_value);
1028 } else {
1029 // Uint64 overflow, attempt to parse as a double instead.
1030 *value = io::Tokenizer::ParseFloat(text);
1031 }
1032
1033 tokenizer_.Next();
1034 return true;
1035 }
1036
1037 // Consumes a double and saves its value in the value parameter.
1038 // Note that since the tokenizer does not support negative numbers,
1039 // we actually may consume an additional token (for the minus sign) in this
1040 // method. Returns false if the token is not a double
1041 // (signed or otherwise).
ConsumeDouble(double * value)1042 bool ConsumeDouble(double* value) {
1043 bool negative = false;
1044
1045 if (TryConsume("-")) {
1046 negative = true;
1047 }
1048
1049 // A double can actually be an integer, according to the tokenizer.
1050 // Therefore, we must check both cases here.
1051 if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1052 // We have found an integer value for the double.
1053 DO(ConsumeUnsignedDecimalAsDouble(value, kuint64max));
1054 } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
1055 // We have found a float value for the double.
1056 *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
1057
1058 // Mark the current token as consumed.
1059 tokenizer_.Next();
1060 } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
1061 std::string text = tokenizer_.current().text;
1062 LowerString(&text);
1063 if (text == "inf" ||
1064 text == "infinity") {
1065 *value = std::numeric_limits<double>::infinity();
1066 tokenizer_.Next();
1067 } else if (text == "nan") {
1068 *value = std::numeric_limits<double>::quiet_NaN();
1069 tokenizer_.Next();
1070 } else {
1071 ReportError("Expected double, got: " + text);
1072 return false;
1073 }
1074 } else {
1075 ReportError("Expected double, got: " + tokenizer_.current().text);
1076 return false;
1077 }
1078
1079 if (negative) {
1080 *value = -*value;
1081 }
1082
1083 return true;
1084 }
1085
1086 // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name"
1087 // or "type.googleprod.com/full.type.Name"
ConsumeAnyTypeUrl(std::string * full_type_name,std::string * prefix)1088 bool ConsumeAnyTypeUrl(std::string* full_type_name, std::string* prefix) {
1089 // TODO(saito) Extend Consume() to consume multiple tokens at once, so that
1090 // this code can be written as just DO(Consume(kGoogleApisTypePrefix)).
1091 DO(ConsumeIdentifier(prefix));
1092 while (TryConsume(".")) {
1093 std::string url;
1094 DO(ConsumeIdentifier(&url));
1095 *prefix += "." + url;
1096 }
1097 DO(Consume("/"));
1098 *prefix += "/";
1099 DO(ConsumeFullTypeName(full_type_name));
1100
1101 return true;
1102 }
1103
1104 // A helper function for reconstructing Any::value. Consumes a text of
1105 // full_type_name, then serializes it into serialized_value.
ConsumeAnyValue(const Descriptor * value_descriptor,std::string * serialized_value)1106 bool ConsumeAnyValue(const Descriptor* value_descriptor,
1107 std::string* serialized_value) {
1108 DynamicMessageFactory factory;
1109 const Message* value_prototype = factory.GetPrototype(value_descriptor);
1110 if (value_prototype == nullptr) {
1111 return false;
1112 }
1113 std::unique_ptr<Message> value(value_prototype->New());
1114 std::string sub_delimiter;
1115 DO(ConsumeMessageDelimiter(&sub_delimiter));
1116 DO(ConsumeMessage(value.get(), sub_delimiter));
1117
1118 if (allow_partial_) {
1119 value->AppendPartialToString(serialized_value);
1120 } else {
1121 if (!value->IsInitialized()) {
1122 ReportError(
1123 "Value of type \"" + value_descriptor->full_name() +
1124 "\" stored in google.protobuf.Any has missing required fields");
1125 return false;
1126 }
1127 value->AppendToString(serialized_value);
1128 }
1129 return true;
1130 }
1131
1132 // Consumes a token and confirms that it matches that specified in the
1133 // value parameter. Returns false if the token found does not match that
1134 // which was specified.
Consume(const std::string & value)1135 bool Consume(const std::string& value) {
1136 const std::string& current_value = tokenizer_.current().text;
1137
1138 if (current_value != value) {
1139 ReportError("Expected \"" + value + "\", found \"" + current_value +
1140 "\".");
1141 return false;
1142 }
1143
1144 tokenizer_.Next();
1145
1146 return true;
1147 }
1148
1149 // Attempts to consume the supplied value. Returns false if a the
1150 // token found does not match the value specified.
TryConsume(const std::string & value)1151 bool TryConsume(const std::string& value) {
1152 if (tokenizer_.current().text == value) {
1153 tokenizer_.Next();
1154 return true;
1155 } else {
1156 return false;
1157 }
1158 }
1159
1160 // An internal instance of the Tokenizer's error collector, used to
1161 // collect any base-level parse errors and feed them to the ParserImpl.
1162 class ParserErrorCollector : public io::ErrorCollector {
1163 public:
ParserErrorCollector(TextFormat::Parser::ParserImpl * parser)1164 explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser)
1165 : parser_(parser) {}
1166
~ParserErrorCollector()1167 ~ParserErrorCollector() override {}
1168
AddError(int line,int column,const std::string & message)1169 void AddError(int line, int column, const std::string& message) override {
1170 parser_->ReportError(line, column, message);
1171 }
1172
AddWarning(int line,int column,const std::string & message)1173 void AddWarning(int line, int column, const std::string& message) override {
1174 parser_->ReportWarning(line, column, message);
1175 }
1176
1177 private:
1178 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
1179 TextFormat::Parser::ParserImpl* parser_;
1180 };
1181
1182 io::ErrorCollector* error_collector_;
1183 const TextFormat::Finder* finder_;
1184 ParseInfoTree* parse_info_tree_;
1185 ParserErrorCollector tokenizer_error_collector_;
1186 io::Tokenizer tokenizer_;
1187 const Descriptor* root_message_type_;
1188 SingularOverwritePolicy singular_overwrite_policy_;
1189 const bool allow_case_insensitive_field_;
1190 const bool allow_unknown_field_;
1191 const bool allow_unknown_extension_;
1192 const bool allow_unknown_enum_;
1193 const bool allow_field_number_;
1194 const bool allow_partial_;
1195 int recursion_limit_;
1196 bool had_errors_;
1197 };
1198
1199 // ===========================================================================
1200 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
1201 // from the Printer found in //net/proto2/io/public/printer.h
1202 class TextFormat::Printer::TextGenerator
1203 : public TextFormat::BaseTextGenerator {
1204 public:
TextGenerator(io::ZeroCopyOutputStream * output,int initial_indent_level)1205 explicit TextGenerator(io::ZeroCopyOutputStream* output,
1206 int initial_indent_level)
1207 : output_(output),
1208 buffer_(nullptr),
1209 buffer_size_(0),
1210 at_start_of_line_(true),
1211 failed_(false),
1212 indent_level_(initial_indent_level),
1213 initial_indent_level_(initial_indent_level) {}
1214
~TextGenerator()1215 ~TextGenerator() {
1216 // Only BackUp() if we're sure we've successfully called Next() at least
1217 // once.
1218 if (!failed_ && buffer_size_ > 0) {
1219 output_->BackUp(buffer_size_);
1220 }
1221 }
1222
1223 // Indent text by two spaces. After calling Indent(), two spaces will be
1224 // inserted at the beginning of each line of text. Indent() may be called
1225 // multiple times to produce deeper indents.
Indent()1226 void Indent() override { ++indent_level_; }
1227
1228 // Reduces the current indent level by two spaces, or crashes if the indent
1229 // level is zero.
Outdent()1230 void Outdent() override {
1231 if (indent_level_ == 0 || indent_level_ < initial_indent_level_) {
1232 GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
1233 return;
1234 }
1235
1236 --indent_level_;
1237 }
1238
GetCurrentIndentationSize() const1239 size_t GetCurrentIndentationSize() const override {
1240 return 2 * indent_level_;
1241 }
1242
1243 // Print text to the output stream.
Print(const char * text,size_t size)1244 void Print(const char* text, size_t size) override {
1245 if (indent_level_ > 0) {
1246 size_t pos = 0; // The number of bytes we've written so far.
1247 for (size_t i = 0; i < size; i++) {
1248 if (text[i] == '\n') {
1249 // Saw newline. If there is more text, we may need to insert an
1250 // indent here. So, write what we have so far, including the '\n'.
1251 Write(text + pos, i - pos + 1);
1252 pos = i + 1;
1253
1254 // Setting this true will cause the next Write() to insert an indent
1255 // first.
1256 at_start_of_line_ = true;
1257 }
1258 }
1259 // Write the rest.
1260 Write(text + pos, size - pos);
1261 } else {
1262 Write(text, size);
1263 if (size > 0 && text[size - 1] == '\n') {
1264 at_start_of_line_ = true;
1265 }
1266 }
1267 }
1268
1269 // True if any write to the underlying stream failed. (We don't just
1270 // crash in this case because this is an I/O failure, not a programming
1271 // error.)
failed() const1272 bool failed() const { return failed_; }
1273
1274 private:
1275 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
1276
Write(const char * data,size_t size)1277 void Write(const char* data, size_t size) {
1278 if (failed_) return;
1279 if (size == 0) return;
1280
1281 if (at_start_of_line_) {
1282 // Insert an indent.
1283 at_start_of_line_ = false;
1284 WriteIndent();
1285 if (failed_) return;
1286 }
1287
1288 while (size > buffer_size_) {
1289 // Data exceeds space in the buffer. Copy what we can and request a
1290 // new buffer.
1291 if (buffer_size_ > 0) {
1292 memcpy(buffer_, data, buffer_size_);
1293 data += buffer_size_;
1294 size -= buffer_size_;
1295 }
1296 void* void_buffer = nullptr;
1297 failed_ = !output_->Next(&void_buffer, &buffer_size_);
1298 if (failed_) return;
1299 buffer_ = reinterpret_cast<char*>(void_buffer);
1300 }
1301
1302 // Buffer is big enough to receive the data; copy it.
1303 memcpy(buffer_, data, size);
1304 buffer_ += size;
1305 buffer_size_ -= size;
1306 }
1307
WriteIndent()1308 void WriteIndent() {
1309 if (indent_level_ == 0) {
1310 return;
1311 }
1312 GOOGLE_DCHECK(!failed_);
1313 int size = GetCurrentIndentationSize();
1314
1315 while (size > buffer_size_) {
1316 // Data exceeds space in the buffer. Write what we can and request a new
1317 // buffer.
1318 if (buffer_size_ > 0) {
1319 memset(buffer_, ' ', buffer_size_);
1320 }
1321 size -= buffer_size_;
1322 void* void_buffer;
1323 failed_ = !output_->Next(&void_buffer, &buffer_size_);
1324 if (failed_) return;
1325 buffer_ = reinterpret_cast<char*>(void_buffer);
1326 }
1327
1328 // Buffer is big enough to receive the data; copy it.
1329 memset(buffer_, ' ', size);
1330 buffer_ += size;
1331 buffer_size_ -= size;
1332 }
1333
1334 io::ZeroCopyOutputStream* const output_;
1335 char* buffer_;
1336 int buffer_size_;
1337 bool at_start_of_line_;
1338 bool failed_;
1339
1340 int indent_level_;
1341 int initial_indent_level_;
1342 };
1343
1344 // ===========================================================================
1345 // Implementation of the default Finder for extensions.
~Finder()1346 TextFormat::Finder::~Finder() {}
1347
FindExtension(Message * message,const std::string & name) const1348 const FieldDescriptor* TextFormat::Finder::FindExtension(
1349 Message* message, const std::string& name) const {
1350 return DefaultFinderFindExtension(message, name);
1351 }
1352
FindExtensionByNumber(const Descriptor * descriptor,int number) const1353 const FieldDescriptor* TextFormat::Finder::FindExtensionByNumber(
1354 const Descriptor* descriptor, int number) const {
1355 return DefaultFinderFindExtensionByNumber(descriptor, number);
1356 }
1357
FindAnyType(const Message & message,const std::string & prefix,const std::string & name) const1358 const Descriptor* TextFormat::Finder::FindAnyType(
1359 const Message& message, const std::string& prefix,
1360 const std::string& name) const {
1361 return DefaultFinderFindAnyType(message, prefix, name);
1362 }
1363
FindExtensionFactory(const FieldDescriptor * field) const1364 MessageFactory* TextFormat::Finder::FindExtensionFactory(
1365 const FieldDescriptor* field) const {
1366 return nullptr;
1367 }
1368
1369 // ===========================================================================
1370
Parser()1371 TextFormat::Parser::Parser()
1372 : error_collector_(nullptr),
1373 finder_(nullptr),
1374 parse_info_tree_(nullptr),
1375 allow_partial_(false),
1376 allow_case_insensitive_field_(false),
1377 allow_unknown_field_(false),
1378 allow_unknown_extension_(false),
1379 allow_unknown_enum_(false),
1380 allow_field_number_(false),
1381 allow_relaxed_whitespace_(false),
1382 allow_singular_overwrites_(false),
1383 recursion_limit_(std::numeric_limits<int>::max()) {}
1384
~Parser()1385 TextFormat::Parser::~Parser() {}
1386
1387 namespace {
1388
CheckParseInputSize(StringPiece input,io::ErrorCollector * error_collector)1389 bool CheckParseInputSize(StringPiece input,
1390 io::ErrorCollector* error_collector) {
1391 if (input.size() > INT_MAX) {
1392 error_collector->AddError(
1393 -1, 0,
1394 StrCat("Input size too large: ", static_cast<int64>(input.size()),
1395 " bytes", " > ", INT_MAX, " bytes."));
1396 return false;
1397 }
1398 return true;
1399 }
1400
1401 } // namespace
1402
Parse(io::ZeroCopyInputStream * input,Message * output)1403 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
1404 Message* output) {
1405 output->Clear();
1406
1407 ParserImpl::SingularOverwritePolicy overwrites_policy =
1408 allow_singular_overwrites_ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
1409 : ParserImpl::FORBID_SINGULAR_OVERWRITES;
1410
1411 ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
1412 parse_info_tree_, overwrites_policy,
1413 allow_case_insensitive_field_, allow_unknown_field_,
1414 allow_unknown_extension_, allow_unknown_enum_,
1415 allow_field_number_, allow_relaxed_whitespace_,
1416 allow_partial_, recursion_limit_);
1417 return MergeUsingImpl(input, output, &parser);
1418 }
1419
ParseFromString(const std::string & input,Message * output)1420 bool TextFormat::Parser::ParseFromString(const std::string& input,
1421 Message* output) {
1422 DO(CheckParseInputSize(input, error_collector_));
1423 io::ArrayInputStream input_stream(input.data(), input.size());
1424 return Parse(&input_stream, output);
1425 }
1426
1427
Merge(io::ZeroCopyInputStream * input,Message * output)1428 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
1429 Message* output) {
1430 ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
1431 parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1432 allow_case_insensitive_field_, allow_unknown_field_,
1433 allow_unknown_extension_, allow_unknown_enum_,
1434 allow_field_number_, allow_relaxed_whitespace_,
1435 allow_partial_, recursion_limit_);
1436 return MergeUsingImpl(input, output, &parser);
1437 }
1438
MergeFromString(const std::string & input,Message * output)1439 bool TextFormat::Parser::MergeFromString(const std::string& input,
1440 Message* output) {
1441 DO(CheckParseInputSize(input, error_collector_));
1442 io::ArrayInputStream input_stream(input.data(), input.size());
1443 return Merge(&input_stream, output);
1444 }
1445
1446
MergeUsingImpl(io::ZeroCopyInputStream *,Message * output,ParserImpl * parser_impl)1447 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
1448 Message* output,
1449 ParserImpl* parser_impl) {
1450 if (!parser_impl->Parse(output)) return false;
1451 if (!allow_partial_ && !output->IsInitialized()) {
1452 std::vector<std::string> missing_fields;
1453 output->FindInitializationErrors(&missing_fields);
1454 parser_impl->ReportError(-1, 0,
1455 "Message missing required fields: " +
1456 Join(missing_fields, ", "));
1457 return false;
1458 }
1459 return true;
1460 }
1461
ParseFieldValueFromString(const std::string & input,const FieldDescriptor * field,Message * output)1462 bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input,
1463 const FieldDescriptor* field,
1464 Message* output) {
1465 io::ArrayInputStream input_stream(input.data(), input.size());
1466 ParserImpl parser(
1467 output->GetDescriptor(), &input_stream, error_collector_, finder_,
1468 parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1469 allow_case_insensitive_field_, allow_unknown_field_,
1470 allow_unknown_extension_, allow_unknown_enum_, allow_field_number_,
1471 allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
1472 return parser.ParseField(field, output);
1473 }
1474
Parse(io::ZeroCopyInputStream * input,Message * output)1475 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1476 Message* output) {
1477 return Parser().Parse(input, output);
1478 }
1479
Merge(io::ZeroCopyInputStream * input,Message * output)1480 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1481 Message* output) {
1482 return Parser().Merge(input, output);
1483 }
1484
ParseFromString(const std::string & input,Message * output)1485 /* static */ bool TextFormat::ParseFromString(const std::string& input,
1486 Message* output) {
1487 return Parser().ParseFromString(input, output);
1488 }
1489
MergeFromString(const std::string & input,Message * output)1490 /* static */ bool TextFormat::MergeFromString(const std::string& input,
1491 Message* output) {
1492 return Parser().MergeFromString(input, output);
1493 }
1494
1495
1496 #undef DO
1497
1498 // ===========================================================================
1499
~BaseTextGenerator()1500 TextFormat::BaseTextGenerator::~BaseTextGenerator() {}
1501
1502 namespace {
1503
1504 // A BaseTextGenerator that writes to a string.
1505 class StringBaseTextGenerator : public TextFormat::BaseTextGenerator {
1506 public:
Print(const char * text,size_t size)1507 void Print(const char* text, size_t size) override {
1508 output_.append(text, size);
1509 }
1510
1511 // Some compilers do not support ref-qualifiers even in C++11 mode.
1512 // Disable the optimization for now and revisit it later.
1513 #if 0 // LANG_CXX11
1514 std::string Consume() && { return std::move(output_); }
1515 #else // !LANG_CXX11
Get()1516 const std::string& Get() { return output_; }
1517 #endif // LANG_CXX11
1518
1519 private:
1520 std::string output_;
1521 };
1522
1523 } // namespace
1524
1525 // The default implementation for FieldValuePrinter. We just delegate the
1526 // implementation to the default FastFieldValuePrinter to avoid duplicating the
1527 // logic.
FieldValuePrinter()1528 TextFormat::FieldValuePrinter::FieldValuePrinter() {}
~FieldValuePrinter()1529 TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
1530
1531 #if 0 // LANG_CXX11
1532 #define FORWARD_IMPL(fn, ...) \
1533 StringBaseTextGenerator generator; \
1534 delegate_.fn(__VA_ARGS__, &generator); \
1535 return std::move(generator).Consume()
1536 #else // !LANG_CXX11
1537 #define FORWARD_IMPL(fn, ...) \
1538 StringBaseTextGenerator generator; \
1539 delegate_.fn(__VA_ARGS__, &generator); \
1540 return generator.Get()
1541 #endif // LANG_CXX11
1542
PrintBool(bool val) const1543 std::string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
1544 FORWARD_IMPL(PrintBool, val);
1545 }
PrintInt32(int32 val) const1546 std::string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const {
1547 FORWARD_IMPL(PrintInt32, val);
1548 }
PrintUInt32(uint32 val) const1549 std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const {
1550 FORWARD_IMPL(PrintUInt32, val);
1551 }
PrintInt64(int64 val) const1552 std::string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const {
1553 FORWARD_IMPL(PrintInt64, val);
1554 }
PrintUInt64(uint64 val) const1555 std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const {
1556 FORWARD_IMPL(PrintUInt64, val);
1557 }
PrintFloat(float val) const1558 std::string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
1559 FORWARD_IMPL(PrintFloat, val);
1560 }
PrintDouble(double val) const1561 std::string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
1562 FORWARD_IMPL(PrintDouble, val);
1563 }
PrintString(const std::string & val) const1564 std::string TextFormat::FieldValuePrinter::PrintString(
1565 const std::string& val) const {
1566 FORWARD_IMPL(PrintString, val);
1567 }
PrintBytes(const std::string & val) const1568 std::string TextFormat::FieldValuePrinter::PrintBytes(
1569 const std::string& val) const {
1570 return PrintString(val);
1571 }
PrintEnum(int32 val,const std::string & name) const1572 std::string TextFormat::FieldValuePrinter::PrintEnum(
1573 int32 val, const std::string& name) const {
1574 FORWARD_IMPL(PrintEnum, val, name);
1575 }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field) const1576 std::string TextFormat::FieldValuePrinter::PrintFieldName(
1577 const Message& message, const Reflection* reflection,
1578 const FieldDescriptor* field) const {
1579 FORWARD_IMPL(PrintFieldName, message, reflection, field);
1580 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode) const1581 std::string TextFormat::FieldValuePrinter::PrintMessageStart(
1582 const Message& message, int field_index, int field_count,
1583 bool single_line_mode) const {
1584 FORWARD_IMPL(PrintMessageStart, message, field_index, field_count,
1585 single_line_mode);
1586 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode) const1587 std::string TextFormat::FieldValuePrinter::PrintMessageEnd(
1588 const Message& message, int field_index, int field_count,
1589 bool single_line_mode) const {
1590 FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count,
1591 single_line_mode);
1592 }
1593 #undef FORWARD_IMPL
1594
FastFieldValuePrinter()1595 TextFormat::FastFieldValuePrinter::FastFieldValuePrinter() {}
~FastFieldValuePrinter()1596 TextFormat::FastFieldValuePrinter::~FastFieldValuePrinter() {}
PrintBool(bool val,BaseTextGenerator * generator) const1597 void TextFormat::FastFieldValuePrinter::PrintBool(
1598 bool val, BaseTextGenerator* generator) const {
1599 if (val) {
1600 generator->PrintLiteral("true");
1601 } else {
1602 generator->PrintLiteral("false");
1603 }
1604 }
PrintInt32(int32 val,BaseTextGenerator * generator) const1605 void TextFormat::FastFieldValuePrinter::PrintInt32(
1606 int32 val, BaseTextGenerator* generator) const {
1607 generator->PrintString(StrCat(val));
1608 }
PrintUInt32(uint32 val,BaseTextGenerator * generator) const1609 void TextFormat::FastFieldValuePrinter::PrintUInt32(
1610 uint32 val, BaseTextGenerator* generator) const {
1611 generator->PrintString(StrCat(val));
1612 }
PrintInt64(int64 val,BaseTextGenerator * generator) const1613 void TextFormat::FastFieldValuePrinter::PrintInt64(
1614 int64 val, BaseTextGenerator* generator) const {
1615 generator->PrintString(StrCat(val));
1616 }
PrintUInt64(uint64 val,BaseTextGenerator * generator) const1617 void TextFormat::FastFieldValuePrinter::PrintUInt64(
1618 uint64 val, BaseTextGenerator* generator) const {
1619 generator->PrintString(StrCat(val));
1620 }
PrintFloat(float val,BaseTextGenerator * generator) const1621 void TextFormat::FastFieldValuePrinter::PrintFloat(
1622 float val, BaseTextGenerator* generator) const {
1623 generator->PrintString(!std::isnan(val) ? SimpleFtoa(val) : "nan");
1624 }
PrintDouble(double val,BaseTextGenerator * generator) const1625 void TextFormat::FastFieldValuePrinter::PrintDouble(
1626 double val, BaseTextGenerator* generator) const {
1627 generator->PrintString(!std::isnan(val) ? SimpleDtoa(val) : "nan");
1628 }
PrintEnum(int32 val,const std::string & name,BaseTextGenerator * generator) const1629 void TextFormat::FastFieldValuePrinter::PrintEnum(
1630 int32 val, const std::string& name, BaseTextGenerator* generator) const {
1631 generator->PrintString(name);
1632 }
1633
PrintString(const std::string & val,BaseTextGenerator * generator) const1634 void TextFormat::FastFieldValuePrinter::PrintString(
1635 const std::string& val, BaseTextGenerator* generator) const {
1636 generator->PrintLiteral("\"");
1637 generator->PrintString(CEscape(val));
1638 generator->PrintLiteral("\"");
1639 }
PrintBytes(const std::string & val,BaseTextGenerator * generator) const1640 void TextFormat::FastFieldValuePrinter::PrintBytes(
1641 const std::string& val, BaseTextGenerator* generator) const {
1642 PrintString(val, generator);
1643 }
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,BaseTextGenerator * generator) const1644 void TextFormat::FastFieldValuePrinter::PrintFieldName(
1645 const Message& message, int field_index, int field_count,
1646 const Reflection* reflection, const FieldDescriptor* field,
1647 BaseTextGenerator* generator) const {
1648 PrintFieldName(message, reflection, field, generator);
1649 }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,BaseTextGenerator * generator) const1650 void TextFormat::FastFieldValuePrinter::PrintFieldName(
1651 const Message& message, const Reflection* reflection,
1652 const FieldDescriptor* field, BaseTextGenerator* generator) const {
1653 if (field->is_extension()) {
1654 generator->PrintLiteral("[");
1655 generator->PrintString(field->PrintableNameForExtension());
1656 generator->PrintLiteral("]");
1657 } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
1658 // Groups must be serialized with their original capitalization.
1659 generator->PrintString(field->message_type()->name());
1660 } else {
1661 generator->PrintString(field->name());
1662 }
1663 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode,BaseTextGenerator * generator) const1664 void TextFormat::FastFieldValuePrinter::PrintMessageStart(
1665 const Message& message, int field_index, int field_count,
1666 bool single_line_mode, BaseTextGenerator* generator) const {
1667 if (single_line_mode) {
1668 generator->PrintLiteral(" { ");
1669 } else {
1670 generator->PrintLiteral(" {\n");
1671 }
1672 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode,BaseTextGenerator * generator) const1673 void TextFormat::FastFieldValuePrinter::PrintMessageEnd(
1674 const Message& message, int field_index, int field_count,
1675 bool single_line_mode, BaseTextGenerator* generator) const {
1676 if (single_line_mode) {
1677 generator->PrintLiteral("} ");
1678 } else {
1679 generator->PrintLiteral("}\n");
1680 }
1681 }
1682
1683 namespace {
1684
1685 // A legacy compatibility wrapper. Takes ownership of the delegate.
1686 class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter {
1687 public:
FieldValuePrinterWrapper(const TextFormat::FieldValuePrinter * delegate)1688 explicit FieldValuePrinterWrapper(
1689 const TextFormat::FieldValuePrinter* delegate)
1690 : delegate_(delegate) {}
1691
SetDelegate(const TextFormat::FieldValuePrinter * delegate)1692 void SetDelegate(const TextFormat::FieldValuePrinter* delegate) {
1693 delegate_.reset(delegate);
1694 }
1695
PrintBool(bool val,TextFormat::BaseTextGenerator * generator) const1696 void PrintBool(bool val,
1697 TextFormat::BaseTextGenerator* generator) const override {
1698 generator->PrintString(delegate_->PrintBool(val));
1699 }
PrintInt32(int32 val,TextFormat::BaseTextGenerator * generator) const1700 void PrintInt32(int32 val,
1701 TextFormat::BaseTextGenerator* generator) const override {
1702 generator->PrintString(delegate_->PrintInt32(val));
1703 }
PrintUInt32(uint32 val,TextFormat::BaseTextGenerator * generator) const1704 void PrintUInt32(uint32 val,
1705 TextFormat::BaseTextGenerator* generator) const override {
1706 generator->PrintString(delegate_->PrintUInt32(val));
1707 }
PrintInt64(int64 val,TextFormat::BaseTextGenerator * generator) const1708 void PrintInt64(int64 val,
1709 TextFormat::BaseTextGenerator* generator) const override {
1710 generator->PrintString(delegate_->PrintInt64(val));
1711 }
PrintUInt64(uint64 val,TextFormat::BaseTextGenerator * generator) const1712 void PrintUInt64(uint64 val,
1713 TextFormat::BaseTextGenerator* generator) const override {
1714 generator->PrintString(delegate_->PrintUInt64(val));
1715 }
PrintFloat(float val,TextFormat::BaseTextGenerator * generator) const1716 void PrintFloat(float val,
1717 TextFormat::BaseTextGenerator* generator) const override {
1718 generator->PrintString(delegate_->PrintFloat(val));
1719 }
PrintDouble(double val,TextFormat::BaseTextGenerator * generator) const1720 void PrintDouble(double val,
1721 TextFormat::BaseTextGenerator* generator) const override {
1722 generator->PrintString(delegate_->PrintDouble(val));
1723 }
PrintString(const std::string & val,TextFormat::BaseTextGenerator * generator) const1724 void PrintString(const std::string& val,
1725 TextFormat::BaseTextGenerator* generator) const override {
1726 generator->PrintString(delegate_->PrintString(val));
1727 }
PrintBytes(const std::string & val,TextFormat::BaseTextGenerator * generator) const1728 void PrintBytes(const std::string& val,
1729 TextFormat::BaseTextGenerator* generator) const override {
1730 generator->PrintString(delegate_->PrintBytes(val));
1731 }
PrintEnum(int32 val,const std::string & name,TextFormat::BaseTextGenerator * generator) const1732 void PrintEnum(int32 val, const std::string& name,
1733 TextFormat::BaseTextGenerator* generator) const override {
1734 generator->PrintString(delegate_->PrintEnum(val, name));
1735 }
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,TextFormat::BaseTextGenerator * generator) const1736 void PrintFieldName(const Message& message, int field_index, int field_count,
1737 const Reflection* reflection,
1738 const FieldDescriptor* field,
1739 TextFormat::BaseTextGenerator* generator) const override {
1740 generator->PrintString(
1741 delegate_->PrintFieldName(message, reflection, field));
1742 }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextFormat::BaseTextGenerator * generator) const1743 void PrintFieldName(const Message& message, const Reflection* reflection,
1744 const FieldDescriptor* field,
1745 TextFormat::BaseTextGenerator* generator) const override {
1746 generator->PrintString(
1747 delegate_->PrintFieldName(message, reflection, field));
1748 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const1749 void PrintMessageStart(
1750 const Message& message, int field_index, int field_count,
1751 bool single_line_mode,
1752 TextFormat::BaseTextGenerator* generator) const override {
1753 generator->PrintString(delegate_->PrintMessageStart(
1754 message, field_index, field_count, single_line_mode));
1755 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const1756 void PrintMessageEnd(
1757 const Message& message, int field_index, int field_count,
1758 bool single_line_mode,
1759 TextFormat::BaseTextGenerator* generator) const override {
1760 generator->PrintString(delegate_->PrintMessageEnd(
1761 message, field_index, field_count, single_line_mode));
1762 }
1763
1764 private:
1765 std::unique_ptr<const TextFormat::FieldValuePrinter> delegate_;
1766 };
1767
1768 // Our own specialization: for UTF8 escaped strings.
1769 class FastFieldValuePrinterUtf8Escaping
1770 : public TextFormat::FastFieldValuePrinter {
1771 public:
PrintString(const std::string & val,TextFormat::BaseTextGenerator * generator) const1772 void PrintString(const std::string& val,
1773 TextFormat::BaseTextGenerator* generator) const override {
1774 generator->PrintLiteral("\"");
1775 generator->PrintString(strings::Utf8SafeCEscape(val));
1776 generator->PrintLiteral("\"");
1777 }
PrintBytes(const std::string & val,TextFormat::BaseTextGenerator * generator) const1778 void PrintBytes(const std::string& val,
1779 TextFormat::BaseTextGenerator* generator) const override {
1780 return FastFieldValuePrinter::PrintString(val, generator);
1781 }
1782 };
1783
1784 } // namespace
1785
Printer()1786 TextFormat::Printer::Printer()
1787 : initial_indent_level_(0),
1788 single_line_mode_(false),
1789 use_field_number_(false),
1790 use_short_repeated_primitives_(false),
1791 hide_unknown_fields_(false),
1792 print_message_fields_in_index_order_(false),
1793 expand_any_(false),
1794 truncate_string_field_longer_than_(0LL),
1795 finder_(nullptr) {
1796 SetUseUtf8StringEscaping(false);
1797 }
1798
SetUseUtf8StringEscaping(bool as_utf8)1799 void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
1800 SetDefaultFieldValuePrinter(as_utf8 ? new FastFieldValuePrinterUtf8Escaping()
1801 : new FastFieldValuePrinter());
1802 }
1803
SetDefaultFieldValuePrinter(const FieldValuePrinter * printer)1804 void TextFormat::Printer::SetDefaultFieldValuePrinter(
1805 const FieldValuePrinter* printer) {
1806 default_field_value_printer_.reset(new FieldValuePrinterWrapper(printer));
1807 }
1808
SetDefaultFieldValuePrinter(const FastFieldValuePrinter * printer)1809 void TextFormat::Printer::SetDefaultFieldValuePrinter(
1810 const FastFieldValuePrinter* printer) {
1811 default_field_value_printer_.reset(printer);
1812 }
1813
RegisterFieldValuePrinter(const FieldDescriptor * field,const FieldValuePrinter * printer)1814 bool TextFormat::Printer::RegisterFieldValuePrinter(
1815 const FieldDescriptor* field, const FieldValuePrinter* printer) {
1816 if (field == nullptr || printer == nullptr) {
1817 return false;
1818 }
1819 std::unique_ptr<FieldValuePrinterWrapper> wrapper(
1820 new FieldValuePrinterWrapper(nullptr));
1821 auto pair = custom_printers_.insert(std::make_pair(field, nullptr));
1822 if (pair.second) {
1823 wrapper->SetDelegate(printer);
1824 pair.first->second = std::move(wrapper);
1825 return true;
1826 } else {
1827 return false;
1828 }
1829 }
1830
RegisterFieldValuePrinter(const FieldDescriptor * field,const FastFieldValuePrinter * printer)1831 bool TextFormat::Printer::RegisterFieldValuePrinter(
1832 const FieldDescriptor* field, const FastFieldValuePrinter* printer) {
1833 if (field == nullptr || printer == nullptr) {
1834 return false;
1835 }
1836 auto pair = custom_printers_.insert(std::make_pair(field, nullptr));
1837 if (pair.second) {
1838 pair.first->second.reset(printer);
1839 return true;
1840 } else {
1841 return false;
1842 }
1843 }
1844
RegisterMessagePrinter(const Descriptor * descriptor,const MessagePrinter * printer)1845 bool TextFormat::Printer::RegisterMessagePrinter(
1846 const Descriptor* descriptor, const MessagePrinter* printer) {
1847 if (descriptor == nullptr || printer == nullptr) {
1848 return false;
1849 }
1850 auto pair =
1851 custom_message_printers_.insert(std::make_pair(descriptor, nullptr));
1852 if (pair.second) {
1853 pair.first->second.reset(printer);
1854 return true;
1855 } else {
1856 return false;
1857 }
1858 }
1859
PrintToString(const Message & message,std::string * output) const1860 bool TextFormat::Printer::PrintToString(const Message& message,
1861 std::string* output) const {
1862 GOOGLE_DCHECK(output) << "output specified is nullptr";
1863
1864 output->clear();
1865 io::StringOutputStream output_stream(output);
1866
1867 return Print(message, &output_stream);
1868 }
1869
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,std::string * output) const1870 bool TextFormat::Printer::PrintUnknownFieldsToString(
1871 const UnknownFieldSet& unknown_fields, std::string* output) const {
1872 GOOGLE_DCHECK(output) << "output specified is nullptr";
1873
1874 output->clear();
1875 io::StringOutputStream output_stream(output);
1876 return PrintUnknownFields(unknown_fields, &output_stream);
1877 }
1878
Print(const Message & message,io::ZeroCopyOutputStream * output) const1879 bool TextFormat::Printer::Print(const Message& message,
1880 io::ZeroCopyOutputStream* output) const {
1881 TextGenerator generator(output, initial_indent_level_);
1882
1883 Print(message, &generator);
1884
1885 // Output false if the generator failed internally.
1886 return !generator.failed();
1887 }
1888
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output) const1889 bool TextFormat::Printer::PrintUnknownFields(
1890 const UnknownFieldSet& unknown_fields,
1891 io::ZeroCopyOutputStream* output) const {
1892 TextGenerator generator(output, initial_indent_level_);
1893
1894 PrintUnknownFields(unknown_fields, &generator);
1895
1896 // Output false if the generator failed internally.
1897 return !generator.failed();
1898 }
1899
1900 namespace {
1901 // Comparison functor for sorting FieldDescriptors by field index.
1902 // Normal fields have higher precedence than extensions.
1903 struct FieldIndexSorter {
operator ()google::protobuf::__anond8f1862d0611::FieldIndexSorter1904 bool operator()(const FieldDescriptor* left,
1905 const FieldDescriptor* right) const {
1906 if (left->is_extension() && right->is_extension()) {
1907 return left->number() < right->number();
1908 } else if (left->is_extension()) {
1909 return false;
1910 } else if (right->is_extension()) {
1911 return true;
1912 } else {
1913 return left->index() < right->index();
1914 }
1915 }
1916 };
1917
1918 } // namespace
1919
PrintAny(const Message & message,TextGenerator * generator) const1920 bool TextFormat::Printer::PrintAny(const Message& message,
1921 TextGenerator* generator) const {
1922 const FieldDescriptor* type_url_field;
1923 const FieldDescriptor* value_field;
1924 if (!internal::GetAnyFieldDescriptors(message, &type_url_field,
1925 &value_field)) {
1926 return false;
1927 }
1928
1929 const Reflection* reflection = message.GetReflection();
1930
1931 // Extract the full type name from the type_url field.
1932 const std::string& type_url = reflection->GetString(message, type_url_field);
1933 std::string url_prefix;
1934 std::string full_type_name;
1935 if (!internal::ParseAnyTypeUrl(type_url, &url_prefix, &full_type_name)) {
1936 return false;
1937 }
1938
1939 // Print the "value" in text.
1940 const Descriptor* value_descriptor =
1941 finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name)
1942 : DefaultFinderFindAnyType(message, url_prefix, full_type_name);
1943 if (value_descriptor == nullptr) {
1944 GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found";
1945 return false;
1946 }
1947 DynamicMessageFactory factory;
1948 std::unique_ptr<Message> value_message(
1949 factory.GetPrototype(value_descriptor)->New());
1950 std::string serialized_value = reflection->GetString(message, value_field);
1951 if (!value_message->ParseFromString(serialized_value)) {
1952 GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents";
1953 return false;
1954 }
1955 generator->PrintLiteral("[");
1956 generator->PrintString(type_url);
1957 generator->PrintLiteral("]");
1958 const FastFieldValuePrinter* printer = GetFieldPrinter(value_field);
1959 printer->PrintMessageStart(message, -1, 0, single_line_mode_, generator);
1960 generator->Indent();
1961 Print(*value_message, generator);
1962 generator->Outdent();
1963 printer->PrintMessageEnd(message, -1, 0, single_line_mode_, generator);
1964 return true;
1965 }
1966
Print(const Message & message,TextGenerator * generator) const1967 void TextFormat::Printer::Print(const Message& message,
1968 TextGenerator* generator) const {
1969 const Reflection* reflection = message.GetReflection();
1970 if (!reflection) {
1971 // This message does not provide any way to describe its structure.
1972 // Parse it again in an UnknownFieldSet, and display this instead.
1973 UnknownFieldSet unknown_fields;
1974 {
1975 std::string serialized = message.SerializeAsString();
1976 io::ArrayInputStream input(serialized.data(), serialized.size());
1977 unknown_fields.ParseFromZeroCopyStream(&input);
1978 }
1979 PrintUnknownFields(unknown_fields, generator);
1980 return;
1981 }
1982 const Descriptor* descriptor = message.GetDescriptor();
1983 auto itr = custom_message_printers_.find(descriptor);
1984 if (itr != custom_message_printers_.end()) {
1985 itr->second->Print(message, single_line_mode_, generator);
1986 return;
1987 }
1988 if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ &&
1989 PrintAny(message, generator)) {
1990 return;
1991 }
1992 std::vector<const FieldDescriptor*> fields;
1993 if (descriptor->options().map_entry()) {
1994 fields.push_back(descriptor->field(0));
1995 fields.push_back(descriptor->field(1));
1996 } else {
1997 reflection->ListFields(message, &fields);
1998 }
1999
2000 if (print_message_fields_in_index_order_) {
2001 std::sort(fields.begin(), fields.end(), FieldIndexSorter());
2002 }
2003 for (int i = 0; i < fields.size(); i++) {
2004 PrintField(message, reflection, fields[i], generator);
2005 }
2006 if (!hide_unknown_fields_) {
2007 PrintUnknownFields(reflection->GetUnknownFields(message), generator);
2008 }
2009 }
2010
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,std::string * output) const2011 void TextFormat::Printer::PrintFieldValueToString(const Message& message,
2012 const FieldDescriptor* field,
2013 int index,
2014 std::string* output) const {
2015 GOOGLE_DCHECK(output) << "output specified is nullptr";
2016
2017 output->clear();
2018 io::StringOutputStream output_stream(output);
2019 TextGenerator generator(&output_stream, initial_indent_level_);
2020
2021 PrintFieldValue(message, message.GetReflection(), field, index, &generator);
2022 }
2023
2024 class MapEntryMessageComparator {
2025 public:
MapEntryMessageComparator(const Descriptor * descriptor)2026 explicit MapEntryMessageComparator(const Descriptor* descriptor)
2027 : field_(descriptor->field(0)) {}
2028
operator ()(const Message * a,const Message * b)2029 bool operator()(const Message* a, const Message* b) {
2030 const Reflection* reflection = a->GetReflection();
2031 switch (field_->cpp_type()) {
2032 case FieldDescriptor::CPPTYPE_BOOL: {
2033 bool first = reflection->GetBool(*a, field_);
2034 bool second = reflection->GetBool(*b, field_);
2035 return first < second;
2036 }
2037 case FieldDescriptor::CPPTYPE_INT32: {
2038 int32 first = reflection->GetInt32(*a, field_);
2039 int32 second = reflection->GetInt32(*b, field_);
2040 return first < second;
2041 }
2042 case FieldDescriptor::CPPTYPE_INT64: {
2043 int64 first = reflection->GetInt64(*a, field_);
2044 int64 second = reflection->GetInt64(*b, field_);
2045 return first < second;
2046 }
2047 case FieldDescriptor::CPPTYPE_UINT32: {
2048 uint32 first = reflection->GetUInt32(*a, field_);
2049 uint32 second = reflection->GetUInt32(*b, field_);
2050 return first < second;
2051 }
2052 case FieldDescriptor::CPPTYPE_UINT64: {
2053 uint64 first = reflection->GetUInt64(*a, field_);
2054 uint64 second = reflection->GetUInt64(*b, field_);
2055 return first < second;
2056 }
2057 case FieldDescriptor::CPPTYPE_STRING: {
2058 std::string first = reflection->GetString(*a, field_);
2059 std::string second = reflection->GetString(*b, field_);
2060 return first < second;
2061 }
2062 default:
2063 GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
2064 return true;
2065 }
2066 }
2067
2068 private:
2069 const FieldDescriptor* field_;
2070 };
2071
2072 namespace internal {
2073 class MapFieldPrinterHelper {
2074 public:
2075 // DynamicMapSorter::Sort cannot be used because it enfores syncing with
2076 // repeated field.
2077 static bool SortMap(const Message& message, const Reflection* reflection,
2078 const FieldDescriptor* field, MessageFactory* factory,
2079 std::vector<const Message*>* sorted_map_field);
2080 static void CopyKey(const MapKey& key, Message* message,
2081 const FieldDescriptor* field_desc);
2082 static void CopyValue(const MapValueRef& value, Message* message,
2083 const FieldDescriptor* field_desc);
2084 };
2085
2086 // Returns true if elements contained in sorted_map_field need to be released.
SortMap(const Message & message,const Reflection * reflection,const FieldDescriptor * field,MessageFactory * factory,std::vector<const Message * > * sorted_map_field)2087 bool MapFieldPrinterHelper::SortMap(
2088 const Message& message, const Reflection* reflection,
2089 const FieldDescriptor* field, MessageFactory* factory,
2090 std::vector<const Message*>* sorted_map_field) {
2091 bool need_release = false;
2092 const MapFieldBase& base = *reflection->GetMapData(message, field);
2093
2094 if (base.IsRepeatedFieldValid()) {
2095 const RepeatedPtrField<Message>& map_field =
2096 reflection->GetRepeatedPtrFieldInternal<Message>(message, field);
2097 for (int i = 0; i < map_field.size(); ++i) {
2098 sorted_map_field->push_back(
2099 const_cast<RepeatedPtrField<Message>*>(&map_field)->Mutable(i));
2100 }
2101 } else {
2102 // TODO(teboring): For performance, instead of creating map entry message
2103 // for each element, just store map keys and sort them.
2104 const Descriptor* map_entry_desc = field->message_type();
2105 const Message* prototype = factory->GetPrototype(map_entry_desc);
2106 for (MapIterator iter =
2107 reflection->MapBegin(const_cast<Message*>(&message), field);
2108 iter != reflection->MapEnd(const_cast<Message*>(&message), field);
2109 ++iter) {
2110 Message* map_entry_message = prototype->New();
2111 CopyKey(iter.GetKey(), map_entry_message, map_entry_desc->field(0));
2112 CopyValue(iter.GetValueRef(), map_entry_message,
2113 map_entry_desc->field(1));
2114 sorted_map_field->push_back(map_entry_message);
2115 }
2116 need_release = true;
2117 }
2118
2119 MapEntryMessageComparator comparator(field->message_type());
2120 std::stable_sort(sorted_map_field->begin(), sorted_map_field->end(),
2121 comparator);
2122 return need_release;
2123 }
2124
CopyKey(const MapKey & key,Message * message,const FieldDescriptor * field_desc)2125 void MapFieldPrinterHelper::CopyKey(const MapKey& key, Message* message,
2126 const FieldDescriptor* field_desc) {
2127 const Reflection* reflection = message->GetReflection();
2128 switch (field_desc->cpp_type()) {
2129 case FieldDescriptor::CPPTYPE_DOUBLE:
2130 case FieldDescriptor::CPPTYPE_FLOAT:
2131 case FieldDescriptor::CPPTYPE_ENUM:
2132 case FieldDescriptor::CPPTYPE_MESSAGE:
2133 GOOGLE_LOG(ERROR) << "Not supported.";
2134 break;
2135 case FieldDescriptor::CPPTYPE_STRING:
2136 reflection->SetString(message, field_desc, key.GetStringValue());
2137 return;
2138 case FieldDescriptor::CPPTYPE_INT64:
2139 reflection->SetInt64(message, field_desc, key.GetInt64Value());
2140 return;
2141 case FieldDescriptor::CPPTYPE_INT32:
2142 reflection->SetInt32(message, field_desc, key.GetInt32Value());
2143 return;
2144 case FieldDescriptor::CPPTYPE_UINT64:
2145 reflection->SetUInt64(message, field_desc, key.GetUInt64Value());
2146 return;
2147 case FieldDescriptor::CPPTYPE_UINT32:
2148 reflection->SetUInt32(message, field_desc, key.GetUInt32Value());
2149 return;
2150 case FieldDescriptor::CPPTYPE_BOOL:
2151 reflection->SetBool(message, field_desc, key.GetBoolValue());
2152 return;
2153 }
2154 }
2155
CopyValue(const MapValueRef & value,Message * message,const FieldDescriptor * field_desc)2156 void MapFieldPrinterHelper::CopyValue(const MapValueRef& value,
2157 Message* message,
2158 const FieldDescriptor* field_desc) {
2159 const Reflection* reflection = message->GetReflection();
2160 switch (field_desc->cpp_type()) {
2161 case FieldDescriptor::CPPTYPE_DOUBLE:
2162 reflection->SetDouble(message, field_desc, value.GetDoubleValue());
2163 return;
2164 case FieldDescriptor::CPPTYPE_FLOAT:
2165 reflection->SetFloat(message, field_desc, value.GetFloatValue());
2166 return;
2167 case FieldDescriptor::CPPTYPE_ENUM:
2168 reflection->SetEnumValue(message, field_desc, value.GetEnumValue());
2169 return;
2170 case FieldDescriptor::CPPTYPE_MESSAGE: {
2171 Message* sub_message = value.GetMessageValue().New();
2172 sub_message->CopyFrom(value.GetMessageValue());
2173 reflection->SetAllocatedMessage(message, sub_message, field_desc);
2174 return;
2175 }
2176 case FieldDescriptor::CPPTYPE_STRING:
2177 reflection->SetString(message, field_desc, value.GetStringValue());
2178 return;
2179 case FieldDescriptor::CPPTYPE_INT64:
2180 reflection->SetInt64(message, field_desc, value.GetInt64Value());
2181 return;
2182 case FieldDescriptor::CPPTYPE_INT32:
2183 reflection->SetInt32(message, field_desc, value.GetInt32Value());
2184 return;
2185 case FieldDescriptor::CPPTYPE_UINT64:
2186 reflection->SetUInt64(message, field_desc, value.GetUInt64Value());
2187 return;
2188 case FieldDescriptor::CPPTYPE_UINT32:
2189 reflection->SetUInt32(message, field_desc, value.GetUInt32Value());
2190 return;
2191 case FieldDescriptor::CPPTYPE_BOOL:
2192 reflection->SetBool(message, field_desc, value.GetBoolValue());
2193 return;
2194 }
2195 }
2196 } // namespace internal
2197
PrintField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator * generator) const2198 void TextFormat::Printer::PrintField(const Message& message,
2199 const Reflection* reflection,
2200 const FieldDescriptor* field,
2201 TextGenerator* generator) const {
2202 if (use_short_repeated_primitives_ && field->is_repeated() &&
2203 field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
2204 field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
2205 PrintShortRepeatedField(message, reflection, field, generator);
2206 return;
2207 }
2208
2209 int count = 0;
2210
2211 if (field->is_repeated()) {
2212 count = reflection->FieldSize(message, field);
2213 } else if (reflection->HasField(message, field) ||
2214 field->containing_type()->options().map_entry()) {
2215 count = 1;
2216 }
2217
2218 DynamicMessageFactory factory;
2219 std::vector<const Message*> sorted_map_field;
2220 bool need_release = false;
2221 bool is_map = field->is_map();
2222 if (is_map) {
2223 need_release = internal::MapFieldPrinterHelper::SortMap(
2224 message, reflection, field, &factory, &sorted_map_field);
2225 }
2226
2227 for (int j = 0; j < count; ++j) {
2228 const int field_index = field->is_repeated() ? j : -1;
2229
2230 PrintFieldName(message, field_index, count, reflection, field, generator);
2231
2232 if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2233 const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2234 const Message& sub_message =
2235 field->is_repeated()
2236 ? (is_map ? *sorted_map_field[j]
2237 : reflection->GetRepeatedMessage(message, field, j))
2238 : reflection->GetMessage(message, field);
2239 printer->PrintMessageStart(sub_message, field_index, count,
2240 single_line_mode_, generator);
2241 generator->Indent();
2242 Print(sub_message, generator);
2243 generator->Outdent();
2244 printer->PrintMessageEnd(sub_message, field_index, count,
2245 single_line_mode_, generator);
2246 } else {
2247 generator->PrintLiteral(": ");
2248 // Write the field value.
2249 PrintFieldValue(message, reflection, field, field_index, generator);
2250 if (single_line_mode_) {
2251 generator->PrintLiteral(" ");
2252 } else {
2253 generator->PrintLiteral("\n");
2254 }
2255 }
2256 }
2257
2258 if (need_release) {
2259 for (int j = 0; j < sorted_map_field.size(); ++j) {
2260 delete sorted_map_field[j];
2261 }
2262 }
2263 }
2264
PrintShortRepeatedField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator * generator) const2265 void TextFormat::Printer::PrintShortRepeatedField(
2266 const Message& message, const Reflection* reflection,
2267 const FieldDescriptor* field, TextGenerator* generator) const {
2268 // Print primitive repeated field in short form.
2269 int size = reflection->FieldSize(message, field);
2270 PrintFieldName(message, /*field_index=*/-1, /*field_count=*/size, reflection,
2271 field, generator);
2272 generator->PrintLiteral(": [");
2273 for (int i = 0; i < size; i++) {
2274 if (i > 0) generator->PrintLiteral(", ");
2275 PrintFieldValue(message, reflection, field, i, generator);
2276 }
2277 if (single_line_mode_) {
2278 generator->PrintLiteral("] ");
2279 } else {
2280 generator->PrintLiteral("]\n");
2281 }
2282 }
2283
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,TextGenerator * generator) const2284 void TextFormat::Printer::PrintFieldName(const Message& message,
2285 int field_index, int field_count,
2286 const Reflection* reflection,
2287 const FieldDescriptor* field,
2288 TextGenerator* generator) const {
2289 // if use_field_number_ is true, prints field number instead
2290 // of field name.
2291 if (use_field_number_) {
2292 generator->PrintString(StrCat(field->number()));
2293 return;
2294 }
2295
2296 const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2297 printer->PrintFieldName(message, field_index, field_count, reflection, field,
2298 generator);
2299 }
2300
PrintFieldValue(const Message & message,const Reflection * reflection,const FieldDescriptor * field,int index,TextGenerator * generator) const2301 void TextFormat::Printer::PrintFieldValue(const Message& message,
2302 const Reflection* reflection,
2303 const FieldDescriptor* field,
2304 int index,
2305 TextGenerator* generator) const {
2306 GOOGLE_DCHECK(field->is_repeated() || (index == -1))
2307 << "Index must be -1 for non-repeated fields";
2308
2309 const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2310
2311 switch (field->cpp_type()) {
2312 #define OUTPUT_FIELD(CPPTYPE, METHOD) \
2313 case FieldDescriptor::CPPTYPE_##CPPTYPE: \
2314 printer->Print##METHOD( \
2315 field->is_repeated() \
2316 ? reflection->GetRepeated##METHOD(message, field, index) \
2317 : reflection->Get##METHOD(message, field), \
2318 generator); \
2319 break
2320
2321 OUTPUT_FIELD(INT32, Int32);
2322 OUTPUT_FIELD(INT64, Int64);
2323 OUTPUT_FIELD(UINT32, UInt32);
2324 OUTPUT_FIELD(UINT64, UInt64);
2325 OUTPUT_FIELD(FLOAT, Float);
2326 OUTPUT_FIELD(DOUBLE, Double);
2327 OUTPUT_FIELD(BOOL, Bool);
2328 #undef OUTPUT_FIELD
2329
2330 case FieldDescriptor::CPPTYPE_STRING: {
2331 std::string scratch;
2332 const std::string& value =
2333 field->is_repeated()
2334 ? reflection->GetRepeatedStringReference(message, field, index,
2335 &scratch)
2336 : reflection->GetStringReference(message, field, &scratch);
2337 const std::string* value_to_print = &value;
2338 std::string truncated_value;
2339 if (truncate_string_field_longer_than_ > 0 &&
2340 truncate_string_field_longer_than_ < value.size()) {
2341 truncated_value = value.substr(0, truncate_string_field_longer_than_) +
2342 "...<truncated>...";
2343 value_to_print = &truncated_value;
2344 }
2345 if (field->type() == FieldDescriptor::TYPE_STRING) {
2346 printer->PrintString(*value_to_print, generator);
2347 } else {
2348 GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
2349 printer->PrintBytes(*value_to_print, generator);
2350 }
2351 break;
2352 }
2353
2354 case FieldDescriptor::CPPTYPE_ENUM: {
2355 int enum_value =
2356 field->is_repeated()
2357 ? reflection->GetRepeatedEnumValue(message, field, index)
2358 : reflection->GetEnumValue(message, field);
2359 const EnumValueDescriptor* enum_desc =
2360 field->enum_type()->FindValueByNumber(enum_value);
2361 if (enum_desc != nullptr) {
2362 printer->PrintEnum(enum_value, enum_desc->name(), generator);
2363 } else {
2364 // Ordinarily, enum_desc should not be null, because proto2 has the
2365 // invariant that set enum field values must be in-range, but with the
2366 // new integer-based API for enums (or the RepeatedField<int> loophole),
2367 // it is possible for the user to force an unknown integer value. So we
2368 // simply use the integer value itself as the enum value name in this
2369 // case.
2370 printer->PrintEnum(enum_value, StrCat(enum_value), generator);
2371 }
2372 break;
2373 }
2374
2375 case FieldDescriptor::CPPTYPE_MESSAGE:
2376 Print(field->is_repeated()
2377 ? reflection->GetRepeatedMessage(message, field, index)
2378 : reflection->GetMessage(message, field),
2379 generator);
2380 break;
2381 }
2382 }
2383
Print(const Message & message,io::ZeroCopyOutputStream * output)2384 /* static */ bool TextFormat::Print(const Message& message,
2385 io::ZeroCopyOutputStream* output) {
2386 return Printer().Print(message, output);
2387 }
2388
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output)2389 /* static */ bool TextFormat::PrintUnknownFields(
2390 const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) {
2391 return Printer().PrintUnknownFields(unknown_fields, output);
2392 }
2393
PrintToString(const Message & message,std::string * output)2394 /* static */ bool TextFormat::PrintToString(const Message& message,
2395 std::string* output) {
2396 return Printer().PrintToString(message, output);
2397 }
2398
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,std::string * output)2399 /* static */ bool TextFormat::PrintUnknownFieldsToString(
2400 const UnknownFieldSet& unknown_fields, std::string* output) {
2401 return Printer().PrintUnknownFieldsToString(unknown_fields, output);
2402 }
2403
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,std::string * output)2404 /* static */ void TextFormat::PrintFieldValueToString(
2405 const Message& message, const FieldDescriptor* field, int index,
2406 std::string* output) {
2407 return Printer().PrintFieldValueToString(message, field, index, output);
2408 }
2409
ParseFieldValueFromString(const std::string & input,const FieldDescriptor * field,Message * message)2410 /* static */ bool TextFormat::ParseFieldValueFromString(
2411 const std::string& input, const FieldDescriptor* field, Message* message) {
2412 return Parser().ParseFieldValueFromString(input, field, message);
2413 }
2414
PrintUnknownFields(const UnknownFieldSet & unknown_fields,TextGenerator * generator) const2415 void TextFormat::Printer::PrintUnknownFields(
2416 const UnknownFieldSet& unknown_fields, TextGenerator* generator) const {
2417 for (int i = 0; i < unknown_fields.field_count(); i++) {
2418 const UnknownField& field = unknown_fields.field(i);
2419 std::string field_number = StrCat(field.number());
2420
2421 switch (field.type()) {
2422 case UnknownField::TYPE_VARINT:
2423 generator->PrintString(field_number);
2424 generator->PrintLiteral(": ");
2425 generator->PrintString(StrCat(field.varint()));
2426 if (single_line_mode_) {
2427 generator->PrintLiteral(" ");
2428 } else {
2429 generator->PrintLiteral("\n");
2430 }
2431 break;
2432 case UnknownField::TYPE_FIXED32: {
2433 generator->PrintString(field_number);
2434 generator->PrintLiteral(": 0x");
2435 generator->PrintString(
2436 StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8)));
2437 if (single_line_mode_) {
2438 generator->PrintLiteral(" ");
2439 } else {
2440 generator->PrintLiteral("\n");
2441 }
2442 break;
2443 }
2444 case UnknownField::TYPE_FIXED64: {
2445 generator->PrintString(field_number);
2446 generator->PrintLiteral(": 0x");
2447 generator->PrintString(
2448 StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16)));
2449 if (single_line_mode_) {
2450 generator->PrintLiteral(" ");
2451 } else {
2452 generator->PrintLiteral("\n");
2453 }
2454 break;
2455 }
2456 case UnknownField::TYPE_LENGTH_DELIMITED: {
2457 generator->PrintString(field_number);
2458 const std::string& value = field.length_delimited();
2459 UnknownFieldSet embedded_unknown_fields;
2460 if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
2461 // This field is parseable as a Message.
2462 // So it is probably an embedded message.
2463 if (single_line_mode_) {
2464 generator->PrintLiteral(" { ");
2465 } else {
2466 generator->PrintLiteral(" {\n");
2467 generator->Indent();
2468 }
2469 PrintUnknownFields(embedded_unknown_fields, generator);
2470 if (single_line_mode_) {
2471 generator->PrintLiteral("} ");
2472 } else {
2473 generator->Outdent();
2474 generator->PrintLiteral("}\n");
2475 }
2476 } else {
2477 // This field is not parseable as a Message.
2478 // So it is probably just a plain string.
2479 generator->PrintLiteral(": \"");
2480 generator->PrintString(CEscape(value));
2481 if (single_line_mode_) {
2482 generator->PrintLiteral("\" ");
2483 } else {
2484 generator->PrintLiteral("\"\n");
2485 }
2486 }
2487 break;
2488 }
2489 case UnknownField::TYPE_GROUP:
2490 generator->PrintString(field_number);
2491 if (single_line_mode_) {
2492 generator->PrintLiteral(" { ");
2493 } else {
2494 generator->PrintLiteral(" {\n");
2495 generator->Indent();
2496 }
2497 PrintUnknownFields(field.group(), generator);
2498 if (single_line_mode_) {
2499 generator->PrintLiteral("} ");
2500 } else {
2501 generator->Outdent();
2502 generator->PrintLiteral("}\n");
2503 }
2504 break;
2505 }
2506 }
2507 }
2508
2509 } // namespace protobuf
2510 } // namespace google
2511