• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: 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.empty() && 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         initial_recursion_limit_(recursion_limit),
262         recursion_limit_(recursion_limit),
263         had_errors_(false) {
264     // For backwards-compatibility with proto1, we need to allow the 'f' suffix
265     // for floats.
266     tokenizer_.set_allow_f_after_float(true);
267 
268     // '#' starts a comment.
269     tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
270 
271     if (allow_relaxed_whitespace) {
272       tokenizer_.set_require_space_after_number(false);
273       tokenizer_.set_allow_multiline_strings(true);
274     }
275 
276     // Consume the starting token.
277     tokenizer_.Next();
278   }
~ParserImpl()279   ~ParserImpl() {}
280 
281   // Parses the ASCII representation specified in input and saves the
282   // information into the output pointer (a Message). Returns
283   // false if an error occurs (an error will also be logged to
284   // GOOGLE_LOG(ERROR)).
Parse(Message * output)285   bool Parse(Message* output) {
286     // Consume fields until we cannot do so anymore.
287     while (true) {
288       if (LookingAtType(io::Tokenizer::TYPE_END)) {
289         // Ensures recursion limit properly unwinded, but only for success
290         // cases. This implicitly avoids the check when `Parse` returns false
291         // via `DO(...)`.
292         GOOGLE_DCHECK(had_errors_ || recursion_limit_ == initial_recursion_limit_)
293             << "Recursion limit at end of parse should be "
294             << initial_recursion_limit_ << ", but was " << recursion_limit_
295             << ". Difference of " << initial_recursion_limit_ - recursion_limit_
296             << " stack frames not accounted for stack unwind.";
297 
298         return !had_errors_;
299       }
300 
301       DO(ConsumeField(output));
302     }
303   }
304 
ParseField(const FieldDescriptor * field,Message * output)305   bool ParseField(const FieldDescriptor* field, Message* output) {
306     bool suc;
307     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
308       suc = ConsumeFieldMessage(output, output->GetReflection(), field);
309     } else {
310       suc = ConsumeFieldValue(output, output->GetReflection(), field);
311     }
312     return suc && LookingAtType(io::Tokenizer::TYPE_END);
313   }
314 
ReportError(int line,int col,const std::string & message)315   void ReportError(int line, int col, const std::string& message) {
316     had_errors_ = true;
317     if (error_collector_ == nullptr) {
318       if (line >= 0) {
319         GOOGLE_LOG(ERROR) << "Error parsing text-format "
320                    << root_message_type_->full_name() << ": " << (line + 1)
321                    << ":" << (col + 1) << ": " << message;
322       } else {
323         GOOGLE_LOG(ERROR) << "Error parsing text-format "
324                    << root_message_type_->full_name() << ": " << message;
325       }
326     } else {
327       error_collector_->AddError(line, col, message);
328     }
329   }
330 
ReportWarning(int line,int col,const std::string & message)331   void ReportWarning(int line, int col, const std::string& message) {
332     if (error_collector_ == nullptr) {
333       if (line >= 0) {
334         GOOGLE_LOG(WARNING) << "Warning parsing text-format "
335                      << root_message_type_->full_name() << ": " << (line + 1)
336                      << ":" << (col + 1) << ": " << message;
337       } else {
338         GOOGLE_LOG(WARNING) << "Warning parsing text-format "
339                      << root_message_type_->full_name() << ": " << message;
340       }
341     } else {
342       error_collector_->AddWarning(line, col, message);
343     }
344   }
345 
346  private:
347   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
348 
349   // Reports an error with the given message with information indicating
350   // the position (as derived from the current token).
ReportError(const std::string & message)351   void ReportError(const std::string& message) {
352     ReportError(tokenizer_.current().line, tokenizer_.current().column,
353                 message);
354   }
355 
356   // Reports a warning with the given message with information indicating
357   // the position (as derived from the current token).
ReportWarning(const std::string & message)358   void ReportWarning(const std::string& message) {
359     ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
360                   message);
361   }
362 
363   // Consumes the specified message with the given starting delimiter.
364   // This method checks to see that the end delimiter at the conclusion of
365   // the consumption matches the starting delimiter passed in here.
ConsumeMessage(Message * message,const std::string delimiter)366   bool ConsumeMessage(Message* message, const std::string delimiter) {
367     while (!LookingAt(">") && !LookingAt("}")) {
368       DO(ConsumeField(message));
369     }
370 
371     // Confirm that we have a valid ending delimiter.
372     DO(Consume(delimiter));
373     return true;
374   }
375 
376   // Consume either "<" or "{".
ConsumeMessageDelimiter(std::string * delimiter)377   bool ConsumeMessageDelimiter(std::string* delimiter) {
378     if (TryConsume("<")) {
379       *delimiter = ">";
380     } else {
381       DO(Consume("{"));
382       *delimiter = "}";
383     }
384     return true;
385   }
386 
387 
388   // Consumes the current field (as returned by the tokenizer) on the
389   // passed in message.
ConsumeField(Message * message)390   bool ConsumeField(Message* message) {
391     const Reflection* reflection = message->GetReflection();
392     const Descriptor* descriptor = message->GetDescriptor();
393 
394     std::string field_name;
395     bool reserved_field = false;
396     const FieldDescriptor* field = nullptr;
397     int start_line = tokenizer_.current().line;
398     int start_column = tokenizer_.current().column;
399 
400     const FieldDescriptor* any_type_url_field;
401     const FieldDescriptor* any_value_field;
402     if (internal::GetAnyFieldDescriptors(*message, &any_type_url_field,
403                                          &any_value_field) &&
404         TryConsume("[")) {
405       std::string full_type_name, prefix;
406       DO(ConsumeAnyTypeUrl(&full_type_name, &prefix));
407       DO(Consume("]"));
408       TryConsume(":");  // ':' is optional between message labels and values.
409       std::string serialized_value;
410       const Descriptor* value_descriptor =
411           finder_ ? finder_->FindAnyType(*message, prefix, full_type_name)
412                   : DefaultFinderFindAnyType(*message, prefix, full_type_name);
413       if (value_descriptor == nullptr) {
414         ReportError("Could not find type \"" + prefix + full_type_name +
415                     "\" stored in google.protobuf.Any.");
416         return false;
417       }
418       DO(ConsumeAnyValue(value_descriptor, &serialized_value));
419       if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
420         // Fail if any_type_url_field has already been specified.
421         if ((!any_type_url_field->is_repeated() &&
422              reflection->HasField(*message, any_type_url_field)) ||
423             (!any_value_field->is_repeated() &&
424              reflection->HasField(*message, any_value_field))) {
425           ReportError("Non-repeated Any specified multiple times.");
426           return false;
427         }
428       }
429       reflection->SetString(message, any_type_url_field,
430                             std::string(prefix + full_type_name));
431       reflection->SetString(message, any_value_field, serialized_value);
432       return true;
433     }
434     if (TryConsume("[")) {
435       // Extension.
436       DO(ConsumeFullTypeName(&field_name));
437       DO(Consume("]"));
438 
439       field = finder_ ? finder_->FindExtension(message, field_name)
440                       : DefaultFinderFindExtension(message, field_name);
441 
442       if (field == nullptr) {
443         if (!allow_unknown_field_ && !allow_unknown_extension_) {
444           ReportError("Extension \"" + field_name +
445                       "\" is not defined or "
446                       "is not an extension of \"" +
447                       descriptor->full_name() + "\".");
448           return false;
449         } else {
450           ReportWarning("Ignoring extension \"" + field_name +
451                         "\" which is not defined or is not an extension of \"" +
452                         descriptor->full_name() + "\".");
453         }
454       }
455     } else {
456       DO(ConsumeIdentifier(&field_name));
457 
458       int32 field_number;
459       if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
460         if (descriptor->IsExtensionNumber(field_number)) {
461           field = finder_
462                       ? finder_->FindExtensionByNumber(descriptor, field_number)
463                       : DefaultFinderFindExtensionByNumber(descriptor,
464                                                            field_number);
465         } else if (descriptor->IsReservedNumber(field_number)) {
466           reserved_field = true;
467         } else {
468           field = descriptor->FindFieldByNumber(field_number);
469         }
470       } else {
471         field = descriptor->FindFieldByName(field_name);
472         // Group names are expected to be capitalized as they appear in the
473         // .proto file, which actually matches their type names, not their
474         // field names.
475         if (field == nullptr) {
476           std::string lower_field_name = field_name;
477           LowerString(&lower_field_name);
478           field = descriptor->FindFieldByName(lower_field_name);
479           // If the case-insensitive match worked but the field is NOT a group,
480           if (field != nullptr &&
481               field->type() != FieldDescriptor::TYPE_GROUP) {
482             field = nullptr;
483           }
484         }
485         // Again, special-case group names as described above.
486         if (field != nullptr && field->type() == FieldDescriptor::TYPE_GROUP &&
487             field->message_type()->name() != field_name) {
488           field = nullptr;
489         }
490 
491         if (field == nullptr && allow_case_insensitive_field_) {
492           std::string lower_field_name = field_name;
493           LowerString(&lower_field_name);
494           field = descriptor->FindFieldByLowercaseName(lower_field_name);
495         }
496 
497         if (field == nullptr) {
498           reserved_field = descriptor->IsReservedName(field_name);
499         }
500       }
501 
502       if (field == nullptr && !reserved_field) {
503         if (!allow_unknown_field_) {
504           ReportError("Message type \"" + descriptor->full_name() +
505                       "\" has no field named \"" + field_name + "\".");
506           return false;
507         } else {
508           ReportWarning("Message type \"" + descriptor->full_name() +
509                         "\" has no field named \"" + field_name + "\".");
510         }
511       }
512     }
513 
514     // Skips unknown or reserved fields.
515     if (field == nullptr) {
516       GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field);
517 
518       // Try to guess the type of this field.
519       // If this field is not a message, there should be a ":" between the
520       // field name and the field value and also the field value should not
521       // start with "{" or "<" which indicates the beginning of a message body.
522       // If there is no ":" or there is a "{" or "<" after ":", this field has
523       // to be a message or the input is ill-formed.
524       if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
525         return SkipFieldValue();
526       } else {
527         return SkipFieldMessage();
528       }
529     }
530 
531     if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
532       // Fail if the field is not repeated and it has already been specified.
533       if (!field->is_repeated() && reflection->HasField(*message, field)) {
534         ReportError("Non-repeated field \"" + field_name +
535                     "\" is specified multiple times.");
536         return false;
537       }
538       // Fail if the field is a member of a oneof and another member has already
539       // been specified.
540       const OneofDescriptor* oneof = field->containing_oneof();
541       if (oneof != nullptr && reflection->HasOneof(*message, oneof)) {
542         const FieldDescriptor* other_field =
543             reflection->GetOneofFieldDescriptor(*message, oneof);
544         ReportError("Field \"" + field_name +
545                     "\" is specified along with "
546                     "field \"" +
547                     other_field->name() +
548                     "\", another member "
549                     "of oneof \"" +
550                     oneof->name() + "\".");
551         return false;
552       }
553     }
554 
555     // Perform special handling for embedded message types.
556     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
557       // ':' is optional here.
558       bool consumed_semicolon = TryConsume(":");
559       if (consumed_semicolon && field->options().weak() &&
560           LookingAtType(io::Tokenizer::TYPE_STRING)) {
561         // we are getting a bytes string for a weak field.
562         std::string tmp;
563         DO(ConsumeString(&tmp));
564         MessageFactory* factory =
565             finder_ ? finder_->FindExtensionFactory(field) : nullptr;
566         reflection->MutableMessage(message, field, factory)
567             ->ParseFromString(tmp);
568         goto label_skip_parsing;
569       }
570     } else {
571       // ':' is required here.
572       DO(Consume(":"));
573     }
574 
575     if (field->is_repeated() && TryConsume("[")) {
576       // Short repeated format, e.g.  "foo: [1, 2, 3]".
577       if (!TryConsume("]")) {
578         // "foo: []" is treated as empty.
579         while (true) {
580           if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
581             // Perform special handling for embedded message types.
582             DO(ConsumeFieldMessage(message, reflection, field));
583           } else {
584             DO(ConsumeFieldValue(message, reflection, field));
585           }
586           if (TryConsume("]")) {
587             break;
588           }
589           DO(Consume(","));
590         }
591       }
592     } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
593       DO(ConsumeFieldMessage(message, reflection, field));
594     } else {
595       DO(ConsumeFieldValue(message, reflection, field));
596     }
597   label_skip_parsing:
598     // For historical reasons, fields may optionally be separated by commas or
599     // semicolons.
600     TryConsume(";") || TryConsume(",");
601 
602     if (field->options().deprecated()) {
603       ReportWarning("text format contains deprecated field \"" + field_name +
604                     "\"");
605     }
606 
607     // If a parse info tree exists, add the location for the parsed
608     // field.
609     if (parse_info_tree_ != nullptr) {
610       RecordLocation(parse_info_tree_, field,
611                      ParseLocation(start_line, start_column));
612     }
613 
614     return true;
615   }
616 
617   // Skips the next field including the field's name and value.
SkipField()618   bool SkipField() {
619     if (TryConsume("[")) {
620       // Extension name or type URL.
621       DO(ConsumeTypeUrlOrFullTypeName());
622       DO(Consume("]"));
623     } else {
624       std::string field_name;
625       DO(ConsumeIdentifier(&field_name));
626     }
627 
628     // Try to guess the type of this field.
629     // If this field is not a message, there should be a ":" between the
630     // field name and the field value and also the field value should not
631     // start with "{" or "<" which indicates the beginning of a message body.
632     // If there is no ":" or there is a "{" or "<" after ":", this field has
633     // to be a message or the input is ill-formed.
634     if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
635       DO(SkipFieldValue());
636     } else {
637       DO(SkipFieldMessage());
638     }
639     // For historical reasons, fields may optionally be separated by commas or
640     // semicolons.
641     TryConsume(";") || TryConsume(",");
642     return true;
643   }
644 
ConsumeFieldMessage(Message * message,const Reflection * reflection,const FieldDescriptor * field)645   bool ConsumeFieldMessage(Message* message, const Reflection* reflection,
646                            const FieldDescriptor* field) {
647     if (--recursion_limit_ < 0) {
648       ReportError(
649           StrCat("Message is too deep, the parser exceeded the "
650                        "configured recursion limit of ",
651                        initial_recursion_limit_, "."));
652       return false;
653     }
654     // If the parse information tree is not nullptr, create a nested one
655     // for the nested message.
656     ParseInfoTree* parent = parse_info_tree_;
657     if (parent != nullptr) {
658       parse_info_tree_ = CreateNested(parent, field);
659     }
660 
661     std::string delimiter;
662     DO(ConsumeMessageDelimiter(&delimiter));
663     MessageFactory* factory =
664         finder_ ? finder_->FindExtensionFactory(field) : nullptr;
665     if (field->is_repeated()) {
666       DO(ConsumeMessage(reflection->AddMessage(message, field, factory),
667                         delimiter));
668     } else {
669       DO(ConsumeMessage(reflection->MutableMessage(message, field, factory),
670                         delimiter));
671     }
672 
673     ++recursion_limit_;
674 
675     // Reset the parse information tree.
676     parse_info_tree_ = parent;
677     return true;
678   }
679 
680   // Skips the whole body of a message including the beginning delimiter and
681   // the ending delimiter.
SkipFieldMessage()682   bool SkipFieldMessage() {
683     if (--recursion_limit_ < 0) {
684       ReportError(
685           StrCat("Message is too deep, the parser exceeded the "
686                        "configured recursion limit of ",
687                        initial_recursion_limit_, "."));
688       return false;
689     }
690 
691     std::string delimiter;
692     DO(ConsumeMessageDelimiter(&delimiter));
693     while (!LookingAt(">") && !LookingAt("}")) {
694       DO(SkipField());
695     }
696     DO(Consume(delimiter));
697 
698     ++recursion_limit_;
699     return true;
700   }
701 
ConsumeFieldValue(Message * message,const Reflection * reflection,const FieldDescriptor * field)702   bool ConsumeFieldValue(Message* message, const Reflection* reflection,
703                          const FieldDescriptor* field) {
704 // Define an easy to use macro for setting fields. This macro checks
705 // to see if the field is repeated (in which case we need to use the Add
706 // methods or not (in which case we need to use the Set methods).
707 #define SET_FIELD(CPPTYPE, VALUE)                    \
708   if (field->is_repeated()) {                        \
709     reflection->Add##CPPTYPE(message, field, VALUE); \
710   } else {                                           \
711     reflection->Set##CPPTYPE(message, field, VALUE); \
712   }
713 
714     switch (field->cpp_type()) {
715       case FieldDescriptor::CPPTYPE_INT32: {
716         int64 value;
717         DO(ConsumeSignedInteger(&value, kint32max));
718         SET_FIELD(Int32, static_cast<int32>(value));
719         break;
720       }
721 
722       case FieldDescriptor::CPPTYPE_UINT32: {
723         uint64 value;
724         DO(ConsumeUnsignedInteger(&value, kuint32max));
725         SET_FIELD(UInt32, static_cast<uint32>(value));
726         break;
727       }
728 
729       case FieldDescriptor::CPPTYPE_INT64: {
730         int64 value;
731         DO(ConsumeSignedInteger(&value, kint64max));
732         SET_FIELD(Int64, value);
733         break;
734       }
735 
736       case FieldDescriptor::CPPTYPE_UINT64: {
737         uint64 value;
738         DO(ConsumeUnsignedInteger(&value, kuint64max));
739         SET_FIELD(UInt64, value);
740         break;
741       }
742 
743       case FieldDescriptor::CPPTYPE_FLOAT: {
744         double value;
745         DO(ConsumeDouble(&value));
746         SET_FIELD(Float, io::SafeDoubleToFloat(value));
747         break;
748       }
749 
750       case FieldDescriptor::CPPTYPE_DOUBLE: {
751         double value;
752         DO(ConsumeDouble(&value));
753         SET_FIELD(Double, value);
754         break;
755       }
756 
757       case FieldDescriptor::CPPTYPE_STRING: {
758         std::string value;
759         DO(ConsumeString(&value));
760         SET_FIELD(String, value);
761         break;
762       }
763 
764       case FieldDescriptor::CPPTYPE_BOOL: {
765         if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
766           uint64 value;
767           DO(ConsumeUnsignedInteger(&value, 1));
768           SET_FIELD(Bool, value);
769         } else {
770           std::string value;
771           DO(ConsumeIdentifier(&value));
772           if (value == "true" || value == "True" || value == "t") {
773             SET_FIELD(Bool, true);
774           } else if (value == "false" || value == "False" || value == "f") {
775             SET_FIELD(Bool, false);
776           } else {
777             ReportError("Invalid value for boolean field \"" + field->name() +
778                         "\". Value: \"" + value + "\".");
779             return false;
780           }
781         }
782         break;
783       }
784 
785       case FieldDescriptor::CPPTYPE_ENUM: {
786         std::string value;
787         int64 int_value = kint64max;
788         const EnumDescriptor* enum_type = field->enum_type();
789         const EnumValueDescriptor* enum_value = nullptr;
790 
791         if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
792           DO(ConsumeIdentifier(&value));
793           // Find the enumeration value.
794           enum_value = enum_type->FindValueByName(value);
795 
796         } else if (LookingAt("-") ||
797                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
798           DO(ConsumeSignedInteger(&int_value, kint32max));
799           value = StrCat(int_value);  // for error reporting
800           enum_value = enum_type->FindValueByNumber(int_value);
801         } else {
802           ReportError("Expected integer or identifier, got: " +
803                       tokenizer_.current().text);
804           return false;
805         }
806 
807         if (enum_value == nullptr) {
808           if (int_value != kint64max &&
809               reflection->SupportsUnknownEnumValues()) {
810             SET_FIELD(EnumValue, int_value);
811             return true;
812           } else if (!allow_unknown_enum_) {
813             ReportError("Unknown enumeration value of \"" + value +
814                         "\" for "
815                         "field \"" +
816                         field->name() + "\".");
817             return false;
818           } else {
819             ReportWarning("Unknown enumeration value of \"" + value +
820                           "\" for "
821                           "field \"" +
822                           field->name() + "\".");
823             return true;
824           }
825         }
826 
827         SET_FIELD(Enum, enum_value);
828         break;
829       }
830 
831       case FieldDescriptor::CPPTYPE_MESSAGE: {
832         // We should never get here. Put here instead of a default
833         // so that if new types are added, we get a nice compiler warning.
834         GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
835         break;
836       }
837     }
838 #undef SET_FIELD
839     return true;
840   }
841 
SkipFieldValue()842   bool SkipFieldValue() {
843     if (--recursion_limit_ < 0) {
844       ReportError(
845           StrCat("Message is too deep, the parser exceeded the "
846                        "configured recursion limit of ",
847                        initial_recursion_limit_, "."));
848       return false;
849     }
850 
851     if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
852       while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
853         tokenizer_.Next();
854       }
855       ++recursion_limit_;
856       return true;
857     }
858     if (TryConsume("[")) {
859       while (true) {
860         if (!LookingAt("{") && !LookingAt("<")) {
861           DO(SkipFieldValue());
862         } else {
863           DO(SkipFieldMessage());
864         }
865         if (TryConsume("]")) {
866           break;
867         }
868         DO(Consume(","));
869       }
870       ++recursion_limit_;
871       return true;
872     }
873     // Possible field values other than string:
874     //   12345        => TYPE_INTEGER
875     //   -12345       => TYPE_SYMBOL + TYPE_INTEGER
876     //   1.2345       => TYPE_FLOAT
877     //   -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
878     //   inf          => TYPE_IDENTIFIER
879     //   -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
880     //   TYPE_INTEGER => TYPE_IDENTIFIER
881     // Divides them into two group, one with TYPE_SYMBOL
882     // and the other without:
883     //   Group one:
884     //     12345        => TYPE_INTEGER
885     //     1.2345       => TYPE_FLOAT
886     //     inf          => TYPE_IDENTIFIER
887     //     TYPE_INTEGER => TYPE_IDENTIFIER
888     //   Group two:
889     //     -12345       => TYPE_SYMBOL + TYPE_INTEGER
890     //     -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
891     //     -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
892     // As we can see, the field value consists of an optional '-' and one of
893     // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
894     bool has_minus = TryConsume("-");
895     if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
896         !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
897         !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
898       std::string text = tokenizer_.current().text;
899       ReportError("Cannot skip field value, unexpected token: " + text);
900       ++recursion_limit_;
901       return false;
902     }
903     // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
904     // value while other combinations all generate valid values.
905     // We check if the value of this combination is valid here.
906     // TYPE_IDENTIFIER after a '-' should be one of the float values listed
907     // below:
908     //   inf, inff, infinity, nan
909     if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
910       std::string text = tokenizer_.current().text;
911       LowerString(&text);
912       if (text != "inf" &&
913           text != "infinity" && text != "nan") {
914         ReportError("Invalid float number: " + text);
915         ++recursion_limit_;
916         return false;
917       }
918     }
919     tokenizer_.Next();
920     ++recursion_limit_;
921     return true;
922   }
923 
924   // Returns true if the current token's text is equal to that specified.
LookingAt(const std::string & text)925   bool LookingAt(const std::string& text) {
926     return tokenizer_.current().text == text;
927   }
928 
929   // Returns true if the current token's type is equal to that specified.
LookingAtType(io::Tokenizer::TokenType token_type)930   bool LookingAtType(io::Tokenizer::TokenType token_type) {
931     return tokenizer_.current().type == token_type;
932   }
933 
934   // Consumes an identifier and saves its value in the identifier parameter.
935   // Returns false if the token is not of type IDENTFIER.
ConsumeIdentifier(std::string * identifier)936   bool ConsumeIdentifier(std::string* identifier) {
937     if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
938       *identifier = tokenizer_.current().text;
939       tokenizer_.Next();
940       return true;
941     }
942 
943     // If allow_field_numer_ or allow_unknown_field_ is true, we should able
944     // to parse integer identifiers.
945     if ((allow_field_number_ || allow_unknown_field_ ||
946          allow_unknown_extension_) &&
947         LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
948       *identifier = tokenizer_.current().text;
949       tokenizer_.Next();
950       return true;
951     }
952 
953     ReportError("Expected identifier, got: " + tokenizer_.current().text);
954     return false;
955   }
956 
957   // Consume a string of form "<id1>.<id2>....<idN>".
ConsumeFullTypeName(std::string * name)958   bool ConsumeFullTypeName(std::string* name) {
959     DO(ConsumeIdentifier(name));
960     while (TryConsume(".")) {
961       std::string part;
962       DO(ConsumeIdentifier(&part));
963       *name += ".";
964       *name += part;
965     }
966     return true;
967   }
968 
ConsumeTypeUrlOrFullTypeName()969   bool ConsumeTypeUrlOrFullTypeName() {
970     std::string discarded;
971     DO(ConsumeIdentifier(&discarded));
972     while (TryConsume(".") || TryConsume("/")) {
973       DO(ConsumeIdentifier(&discarded));
974     }
975     return true;
976   }
977 
978   // Consumes a string and saves its value in the text parameter.
979   // Returns false if the token is not of type STRING.
ConsumeString(std::string * text)980   bool ConsumeString(std::string* text) {
981     if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
982       ReportError("Expected string, got: " + tokenizer_.current().text);
983       return false;
984     }
985 
986     text->clear();
987     while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
988       io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
989 
990       tokenizer_.Next();
991     }
992 
993     return true;
994   }
995 
996   // Consumes a uint64 and saves its value in the value parameter.
997   // Returns false if the token is not of type INTEGER.
ConsumeUnsignedInteger(uint64 * value,uint64 max_value)998   bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
999     if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1000       ReportError("Expected integer, got: " + tokenizer_.current().text);
1001       return false;
1002     }
1003 
1004     if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, max_value,
1005                                      value)) {
1006       ReportError("Integer out of range (" + tokenizer_.current().text + ")");
1007       return false;
1008     }
1009 
1010     tokenizer_.Next();
1011     return true;
1012   }
1013 
1014   // Consumes an int64 and saves its value in the value parameter.
1015   // Note that since the tokenizer does not support negative numbers,
1016   // we actually may consume an additional token (for the minus sign) in this
1017   // method. Returns false if the token is not an integer
1018   // (signed or otherwise).
ConsumeSignedInteger(int64 * value,uint64 max_value)1019   bool ConsumeSignedInteger(int64* value, uint64 max_value) {
1020     bool negative = false;
1021 
1022     if (TryConsume("-")) {
1023       negative = true;
1024       // Two's complement always allows one more negative integer than
1025       // positive.
1026       ++max_value;
1027     }
1028 
1029     uint64 unsigned_value;
1030 
1031     DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
1032 
1033     if (negative) {
1034       if ((static_cast<uint64>(kint64max) + 1) == unsigned_value) {
1035         *value = kint64min;
1036       } else {
1037         *value = -static_cast<int64>(unsigned_value);
1038       }
1039     } else {
1040       *value = static_cast<int64>(unsigned_value);
1041     }
1042 
1043     return true;
1044   }
1045 
1046   // Consumes a double and saves its value in the value parameter.
1047   // Accepts decimal numbers only, rejects hex or oct numbers.
ConsumeUnsignedDecimalAsDouble(double * value,uint64 max_value)1048   bool ConsumeUnsignedDecimalAsDouble(double* value, uint64 max_value) {
1049     if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1050       ReportError("Expected integer, got: " + tokenizer_.current().text);
1051       return false;
1052     }
1053 
1054     const std::string& text = tokenizer_.current().text;
1055     if (IsHexNumber(text) || IsOctNumber(text)) {
1056       ReportError("Expect a decimal number, got: " + text);
1057       return false;
1058     }
1059 
1060     uint64 uint64_value;
1061     if (io::Tokenizer::ParseInteger(text, max_value, &uint64_value)) {
1062       *value = static_cast<double>(uint64_value);
1063     } else {
1064       // Uint64 overflow, attempt to parse as a double instead.
1065       *value = io::Tokenizer::ParseFloat(text);
1066     }
1067 
1068     tokenizer_.Next();
1069     return true;
1070   }
1071 
1072   // Consumes a double and saves its value in the value parameter.
1073   // Note that since the tokenizer does not support negative numbers,
1074   // we actually may consume an additional token (for the minus sign) in this
1075   // method. Returns false if the token is not a double
1076   // (signed or otherwise).
ConsumeDouble(double * value)1077   bool ConsumeDouble(double* value) {
1078     bool negative = false;
1079 
1080     if (TryConsume("-")) {
1081       negative = true;
1082     }
1083 
1084     // A double can actually be an integer, according to the tokenizer.
1085     // Therefore, we must check both cases here.
1086     if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
1087       // We have found an integer value for the double.
1088       DO(ConsumeUnsignedDecimalAsDouble(value, kuint64max));
1089     } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
1090       // We have found a float value for the double.
1091       *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
1092 
1093       // Mark the current token as consumed.
1094       tokenizer_.Next();
1095     } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
1096       std::string text = tokenizer_.current().text;
1097       LowerString(&text);
1098       if (text == "inf" ||
1099           text == "infinity") {
1100         *value = std::numeric_limits<double>::infinity();
1101         tokenizer_.Next();
1102       } else if (text == "nan") {
1103         *value = std::numeric_limits<double>::quiet_NaN();
1104         tokenizer_.Next();
1105       } else {
1106         ReportError("Expected double, got: " + text);
1107         return false;
1108       }
1109     } else {
1110       ReportError("Expected double, got: " + tokenizer_.current().text);
1111       return false;
1112     }
1113 
1114     if (negative) {
1115       *value = -*value;
1116     }
1117 
1118     return true;
1119   }
1120 
1121   // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name"
1122   // or "type.googleprod.com/full.type.Name"
ConsumeAnyTypeUrl(std::string * full_type_name,std::string * prefix)1123   bool ConsumeAnyTypeUrl(std::string* full_type_name, std::string* prefix) {
1124     // TODO(saito) Extend Consume() to consume multiple tokens at once, so that
1125     // this code can be written as just DO(Consume(kGoogleApisTypePrefix)).
1126     DO(ConsumeIdentifier(prefix));
1127     while (TryConsume(".")) {
1128       std::string url;
1129       DO(ConsumeIdentifier(&url));
1130       *prefix += "." + url;
1131     }
1132     DO(Consume("/"));
1133     *prefix += "/";
1134     DO(ConsumeFullTypeName(full_type_name));
1135 
1136     return true;
1137   }
1138 
1139   // A helper function for reconstructing Any::value. Consumes a text of
1140   // full_type_name, then serializes it into serialized_value.
ConsumeAnyValue(const Descriptor * value_descriptor,std::string * serialized_value)1141   bool ConsumeAnyValue(const Descriptor* value_descriptor,
1142                        std::string* serialized_value) {
1143     DynamicMessageFactory factory;
1144     const Message* value_prototype = factory.GetPrototype(value_descriptor);
1145     if (value_prototype == nullptr) {
1146       return false;
1147     }
1148     std::unique_ptr<Message> value(value_prototype->New());
1149     std::string sub_delimiter;
1150     DO(ConsumeMessageDelimiter(&sub_delimiter));
1151     DO(ConsumeMessage(value.get(), sub_delimiter));
1152 
1153     if (allow_partial_) {
1154       value->AppendPartialToString(serialized_value);
1155     } else {
1156       if (!value->IsInitialized()) {
1157         ReportError(
1158             "Value of type \"" + value_descriptor->full_name() +
1159             "\" stored in google.protobuf.Any has missing required fields");
1160         return false;
1161       }
1162       value->AppendToString(serialized_value);
1163     }
1164     return true;
1165   }
1166 
1167   // Consumes a token and confirms that it matches that specified in the
1168   // value parameter. Returns false if the token found does not match that
1169   // which was specified.
Consume(const std::string & value)1170   bool Consume(const std::string& value) {
1171     const std::string& current_value = tokenizer_.current().text;
1172 
1173     if (current_value != value) {
1174       ReportError("Expected \"" + value + "\", found \"" + current_value +
1175                   "\".");
1176       return false;
1177     }
1178 
1179     tokenizer_.Next();
1180 
1181     return true;
1182   }
1183 
1184   // Attempts to consume the supplied value. Returns false if a the
1185   // token found does not match the value specified.
TryConsume(const std::string & value)1186   bool TryConsume(const std::string& value) {
1187     if (tokenizer_.current().text == value) {
1188       tokenizer_.Next();
1189       return true;
1190     } else {
1191       return false;
1192     }
1193   }
1194 
1195   // An internal instance of the Tokenizer's error collector, used to
1196   // collect any base-level parse errors and feed them to the ParserImpl.
1197   class ParserErrorCollector : public io::ErrorCollector {
1198    public:
ParserErrorCollector(TextFormat::Parser::ParserImpl * parser)1199     explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser)
1200         : parser_(parser) {}
1201 
~ParserErrorCollector()1202     ~ParserErrorCollector() override {}
1203 
AddError(int line,int column,const std::string & message)1204     void AddError(int line, int column, const std::string& message) override {
1205       parser_->ReportError(line, column, message);
1206     }
1207 
AddWarning(int line,int column,const std::string & message)1208     void AddWarning(int line, int column, const std::string& message) override {
1209       parser_->ReportWarning(line, column, message);
1210     }
1211 
1212    private:
1213     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
1214     TextFormat::Parser::ParserImpl* parser_;
1215   };
1216 
1217   io::ErrorCollector* error_collector_;
1218   const TextFormat::Finder* finder_;
1219   ParseInfoTree* parse_info_tree_;
1220   ParserErrorCollector tokenizer_error_collector_;
1221   io::Tokenizer tokenizer_;
1222   const Descriptor* root_message_type_;
1223   SingularOverwritePolicy singular_overwrite_policy_;
1224   const bool allow_case_insensitive_field_;
1225   const bool allow_unknown_field_;
1226   const bool allow_unknown_extension_;
1227   const bool allow_unknown_enum_;
1228   const bool allow_field_number_;
1229   const bool allow_partial_;
1230   const int initial_recursion_limit_;
1231   int recursion_limit_;
1232   bool had_errors_;
1233 };
1234 
1235 // ===========================================================================
1236 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
1237 // from the Printer found in //net/proto2/io/public/printer.h
1238 class TextFormat::Printer::TextGenerator
1239     : public TextFormat::BaseTextGenerator {
1240  public:
TextGenerator(io::ZeroCopyOutputStream * output,int initial_indent_level)1241   explicit TextGenerator(io::ZeroCopyOutputStream* output,
1242                          int initial_indent_level)
1243       : output_(output),
1244         buffer_(nullptr),
1245         buffer_size_(0),
1246         at_start_of_line_(true),
1247         failed_(false),
1248         indent_level_(initial_indent_level),
1249         initial_indent_level_(initial_indent_level) {}
1250 
~TextGenerator()1251   ~TextGenerator() {
1252     // Only BackUp() if we're sure we've successfully called Next() at least
1253     // once.
1254     if (!failed_ && buffer_size_ > 0) {
1255       output_->BackUp(buffer_size_);
1256     }
1257   }
1258 
1259   // Indent text by two spaces.  After calling Indent(), two spaces will be
1260   // inserted at the beginning of each line of text.  Indent() may be called
1261   // multiple times to produce deeper indents.
Indent()1262   void Indent() override { ++indent_level_; }
1263 
1264   // Reduces the current indent level by two spaces, or crashes if the indent
1265   // level is zero.
Outdent()1266   void Outdent() override {
1267     if (indent_level_ == 0 || indent_level_ < initial_indent_level_) {
1268       GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
1269       return;
1270     }
1271 
1272     --indent_level_;
1273   }
1274 
GetCurrentIndentationSize() const1275   size_t GetCurrentIndentationSize() const override {
1276     return 2 * indent_level_;
1277   }
1278 
1279   // Print text to the output stream.
Print(const char * text,size_t size)1280   void Print(const char* text, size_t size) override {
1281     if (indent_level_ > 0) {
1282       size_t pos = 0;  // The number of bytes we've written so far.
1283       for (size_t i = 0; i < size; i++) {
1284         if (text[i] == '\n') {
1285           // Saw newline.  If there is more text, we may need to insert an
1286           // indent here.  So, write what we have so far, including the '\n'.
1287           Write(text + pos, i - pos + 1);
1288           pos = i + 1;
1289 
1290           // Setting this true will cause the next Write() to insert an indent
1291           // first.
1292           at_start_of_line_ = true;
1293         }
1294       }
1295       // Write the rest.
1296       Write(text + pos, size - pos);
1297     } else {
1298       Write(text, size);
1299       if (size > 0 && text[size - 1] == '\n') {
1300         at_start_of_line_ = true;
1301       }
1302     }
1303   }
1304 
1305   // True if any write to the underlying stream failed.  (We don't just
1306   // crash in this case because this is an I/O failure, not a programming
1307   // error.)
failed() const1308   bool failed() const { return failed_; }
1309 
1310  private:
1311   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
1312 
Write(const char * data,size_t size)1313   void Write(const char* data, size_t size) {
1314     if (failed_) return;
1315     if (size == 0) return;
1316 
1317     if (at_start_of_line_) {
1318       // Insert an indent.
1319       at_start_of_line_ = false;
1320       WriteIndent();
1321       if (failed_) return;
1322     }
1323 
1324     while (size > buffer_size_) {
1325       // Data exceeds space in the buffer.  Copy what we can and request a
1326       // new buffer.
1327       if (buffer_size_ > 0) {
1328         memcpy(buffer_, data, buffer_size_);
1329         data += buffer_size_;
1330         size -= buffer_size_;
1331       }
1332       void* void_buffer = nullptr;
1333       failed_ = !output_->Next(&void_buffer, &buffer_size_);
1334       if (failed_) return;
1335       buffer_ = reinterpret_cast<char*>(void_buffer);
1336     }
1337 
1338     // Buffer is big enough to receive the data; copy it.
1339     memcpy(buffer_, data, size);
1340     buffer_ += size;
1341     buffer_size_ -= size;
1342   }
1343 
WriteIndent()1344   void WriteIndent() {
1345     if (indent_level_ == 0) {
1346       return;
1347     }
1348     GOOGLE_DCHECK(!failed_);
1349     int size = GetCurrentIndentationSize();
1350 
1351     while (size > buffer_size_) {
1352       // Data exceeds space in the buffer. Write what we can and request a new
1353       // buffer.
1354       if (buffer_size_ > 0) {
1355         memset(buffer_, ' ', buffer_size_);
1356       }
1357       size -= buffer_size_;
1358       void* void_buffer;
1359       failed_ = !output_->Next(&void_buffer, &buffer_size_);
1360       if (failed_) return;
1361       buffer_ = reinterpret_cast<char*>(void_buffer);
1362     }
1363 
1364     // Buffer is big enough to receive the data; copy it.
1365     memset(buffer_, ' ', size);
1366     buffer_ += size;
1367     buffer_size_ -= size;
1368   }
1369 
1370   io::ZeroCopyOutputStream* const output_;
1371   char* buffer_;
1372   int buffer_size_;
1373   bool at_start_of_line_;
1374   bool failed_;
1375 
1376   int indent_level_;
1377   int initial_indent_level_;
1378 };
1379 
1380 // ===========================================================================
1381 // Implementation of the default Finder for extensions.
~Finder()1382 TextFormat::Finder::~Finder() {}
1383 
FindExtension(Message * message,const std::string & name) const1384 const FieldDescriptor* TextFormat::Finder::FindExtension(
1385     Message* message, const std::string& name) const {
1386   return DefaultFinderFindExtension(message, name);
1387 }
1388 
FindExtensionByNumber(const Descriptor * descriptor,int number) const1389 const FieldDescriptor* TextFormat::Finder::FindExtensionByNumber(
1390     const Descriptor* descriptor, int number) const {
1391   return DefaultFinderFindExtensionByNumber(descriptor, number);
1392 }
1393 
FindAnyType(const Message & message,const std::string & prefix,const std::string & name) const1394 const Descriptor* TextFormat::Finder::FindAnyType(
1395     const Message& message, const std::string& prefix,
1396     const std::string& name) const {
1397   return DefaultFinderFindAnyType(message, prefix, name);
1398 }
1399 
FindExtensionFactory(const FieldDescriptor * field) const1400 MessageFactory* TextFormat::Finder::FindExtensionFactory(
1401     const FieldDescriptor* field) const {
1402   return nullptr;
1403 }
1404 
1405 // ===========================================================================
1406 
Parser()1407 TextFormat::Parser::Parser()
1408     : error_collector_(nullptr),
1409       finder_(nullptr),
1410       parse_info_tree_(nullptr),
1411       allow_partial_(false),
1412       allow_case_insensitive_field_(false),
1413       allow_unknown_field_(false),
1414       allow_unknown_extension_(false),
1415       allow_unknown_enum_(false),
1416       allow_field_number_(false),
1417       allow_relaxed_whitespace_(false),
1418       allow_singular_overwrites_(false),
1419       recursion_limit_(std::numeric_limits<int>::max()) {}
1420 
~Parser()1421 TextFormat::Parser::~Parser() {}
1422 
1423 namespace {
1424 
CheckParseInputSize(StringPiece input,io::ErrorCollector * error_collector)1425 bool CheckParseInputSize(StringPiece input,
1426                          io::ErrorCollector* error_collector) {
1427   if (input.size() > INT_MAX) {
1428     error_collector->AddError(
1429         -1, 0,
1430         StrCat("Input size too large: ", static_cast<int64>(input.size()),
1431                      " bytes", " > ", INT_MAX, " bytes."));
1432     return false;
1433   }
1434   return true;
1435 }
1436 
1437 }  // namespace
1438 
Parse(io::ZeroCopyInputStream * input,Message * output)1439 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
1440                                Message* output) {
1441   output->Clear();
1442 
1443   ParserImpl::SingularOverwritePolicy overwrites_policy =
1444       allow_singular_overwrites_ ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
1445                                  : ParserImpl::FORBID_SINGULAR_OVERWRITES;
1446 
1447   ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
1448                     parse_info_tree_, overwrites_policy,
1449                     allow_case_insensitive_field_, allow_unknown_field_,
1450                     allow_unknown_extension_, allow_unknown_enum_,
1451                     allow_field_number_, allow_relaxed_whitespace_,
1452                     allow_partial_, recursion_limit_);
1453   return MergeUsingImpl(input, output, &parser);
1454 }
1455 
ParseFromString(ConstStringParam input,Message * output)1456 bool TextFormat::Parser::ParseFromString(ConstStringParam input,
1457                                          Message* output) {
1458   DO(CheckParseInputSize(input, error_collector_));
1459   io::ArrayInputStream input_stream(input.data(), input.size());
1460   return Parse(&input_stream, output);
1461 }
1462 
1463 
Merge(io::ZeroCopyInputStream * input,Message * output)1464 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
1465                                Message* output) {
1466   ParserImpl parser(output->GetDescriptor(), input, error_collector_, finder_,
1467                     parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1468                     allow_case_insensitive_field_, allow_unknown_field_,
1469                     allow_unknown_extension_, allow_unknown_enum_,
1470                     allow_field_number_, allow_relaxed_whitespace_,
1471                     allow_partial_, recursion_limit_);
1472   return MergeUsingImpl(input, output, &parser);
1473 }
1474 
MergeFromString(ConstStringParam input,Message * output)1475 bool TextFormat::Parser::MergeFromString(ConstStringParam input,
1476                                          Message* output) {
1477   DO(CheckParseInputSize(input, error_collector_));
1478   io::ArrayInputStream input_stream(input.data(), input.size());
1479   return Merge(&input_stream, output);
1480 }
1481 
1482 
MergeUsingImpl(io::ZeroCopyInputStream *,Message * output,ParserImpl * parser_impl)1483 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
1484                                         Message* output,
1485                                         ParserImpl* parser_impl) {
1486   if (!parser_impl->Parse(output)) return false;
1487   if (!allow_partial_ && !output->IsInitialized()) {
1488     std::vector<std::string> missing_fields;
1489     output->FindInitializationErrors(&missing_fields);
1490     parser_impl->ReportError(-1, 0,
1491                              "Message missing required fields: " +
1492                                  Join(missing_fields, ", "));
1493     return false;
1494   }
1495   return true;
1496 }
1497 
ParseFieldValueFromString(const std::string & input,const FieldDescriptor * field,Message * output)1498 bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input,
1499                                                    const FieldDescriptor* field,
1500                                                    Message* output) {
1501   io::ArrayInputStream input_stream(input.data(), input.size());
1502   ParserImpl parser(
1503       output->GetDescriptor(), &input_stream, error_collector_, finder_,
1504       parse_info_tree_, ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1505       allow_case_insensitive_field_, allow_unknown_field_,
1506       allow_unknown_extension_, allow_unknown_enum_, allow_field_number_,
1507       allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
1508   return parser.ParseField(field, output);
1509 }
1510 
Parse(io::ZeroCopyInputStream * input,Message * output)1511 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1512                                     Message* output) {
1513   return Parser().Parse(input, output);
1514 }
1515 
Merge(io::ZeroCopyInputStream * input,Message * output)1516 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1517                                     Message* output) {
1518   return Parser().Merge(input, output);
1519 }
1520 
ParseFromString(ConstStringParam input,Message * output)1521 /* static */ bool TextFormat::ParseFromString(ConstStringParam input,
1522                                               Message* output) {
1523   return Parser().ParseFromString(input, output);
1524 }
1525 
MergeFromString(ConstStringParam input,Message * output)1526 /* static */ bool TextFormat::MergeFromString(ConstStringParam input,
1527                                               Message* output) {
1528   return Parser().MergeFromString(input, output);
1529 }
1530 
1531 
1532 #undef DO
1533 
1534 // ===========================================================================
1535 
~BaseTextGenerator()1536 TextFormat::BaseTextGenerator::~BaseTextGenerator() {}
1537 
1538 namespace {
1539 
1540 // A BaseTextGenerator that writes to a string.
1541 class StringBaseTextGenerator : public TextFormat::BaseTextGenerator {
1542  public:
Print(const char * text,size_t size)1543   void Print(const char* text, size_t size) override {
1544     output_.append(text, size);
1545   }
1546 
1547 // Some compilers do not support ref-qualifiers even in C++11 mode.
1548 // Disable the optimization for now and revisit it later.
1549 #if 0  // LANG_CXX11
1550   std::string Consume() && { return std::move(output_); }
1551 #else  // !LANG_CXX11
Get()1552   const std::string& Get() { return output_; }
1553 #endif  // LANG_CXX11
1554 
1555  private:
1556   std::string output_;
1557 };
1558 
1559 }  // namespace
1560 
1561 // The default implementation for FieldValuePrinter. We just delegate the
1562 // implementation to the default FastFieldValuePrinter to avoid duplicating the
1563 // logic.
FieldValuePrinter()1564 TextFormat::FieldValuePrinter::FieldValuePrinter() {}
~FieldValuePrinter()1565 TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
1566 
1567 #if 0  // LANG_CXX11
1568 #define FORWARD_IMPL(fn, ...)            \
1569   StringBaseTextGenerator generator;     \
1570   delegate_.fn(__VA_ARGS__, &generator); \
1571   return std::move(generator).Consume()
1572 #else  // !LANG_CXX11
1573 #define FORWARD_IMPL(fn, ...)            \
1574   StringBaseTextGenerator generator;     \
1575   delegate_.fn(__VA_ARGS__, &generator); \
1576   return generator.Get()
1577 #endif  // LANG_CXX11
1578 
PrintBool(bool val) const1579 std::string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
1580   FORWARD_IMPL(PrintBool, val);
1581 }
PrintInt32(int32 val) const1582 std::string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const {
1583   FORWARD_IMPL(PrintInt32, val);
1584 }
PrintUInt32(uint32 val) const1585 std::string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const {
1586   FORWARD_IMPL(PrintUInt32, val);
1587 }
PrintInt64(int64 val) const1588 std::string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const {
1589   FORWARD_IMPL(PrintInt64, val);
1590 }
PrintUInt64(uint64 val) const1591 std::string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const {
1592   FORWARD_IMPL(PrintUInt64, val);
1593 }
PrintFloat(float val) const1594 std::string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
1595   FORWARD_IMPL(PrintFloat, val);
1596 }
PrintDouble(double val) const1597 std::string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
1598   FORWARD_IMPL(PrintDouble, val);
1599 }
PrintString(const std::string & val) const1600 std::string TextFormat::FieldValuePrinter::PrintString(
1601     const std::string& val) const {
1602   FORWARD_IMPL(PrintString, val);
1603 }
PrintBytes(const std::string & val) const1604 std::string TextFormat::FieldValuePrinter::PrintBytes(
1605     const std::string& val) const {
1606   return PrintString(val);
1607 }
PrintEnum(int32 val,const std::string & name) const1608 std::string TextFormat::FieldValuePrinter::PrintEnum(
1609     int32 val, const std::string& name) const {
1610   FORWARD_IMPL(PrintEnum, val, name);
1611 }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field) const1612 std::string TextFormat::FieldValuePrinter::PrintFieldName(
1613     const Message& message, const Reflection* reflection,
1614     const FieldDescriptor* field) const {
1615   FORWARD_IMPL(PrintFieldName, message, reflection, field);
1616 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode) const1617 std::string TextFormat::FieldValuePrinter::PrintMessageStart(
1618     const Message& message, int field_index, int field_count,
1619     bool single_line_mode) const {
1620   FORWARD_IMPL(PrintMessageStart, message, field_index, field_count,
1621                single_line_mode);
1622 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode) const1623 std::string TextFormat::FieldValuePrinter::PrintMessageEnd(
1624     const Message& message, int field_index, int field_count,
1625     bool single_line_mode) const {
1626   FORWARD_IMPL(PrintMessageEnd, message, field_index, field_count,
1627                single_line_mode);
1628 }
1629 #undef FORWARD_IMPL
1630 
FastFieldValuePrinter()1631 TextFormat::FastFieldValuePrinter::FastFieldValuePrinter() {}
~FastFieldValuePrinter()1632 TextFormat::FastFieldValuePrinter::~FastFieldValuePrinter() {}
PrintBool(bool val,BaseTextGenerator * generator) const1633 void TextFormat::FastFieldValuePrinter::PrintBool(
1634     bool val, BaseTextGenerator* generator) const {
1635   if (val) {
1636     generator->PrintLiteral("true");
1637   } else {
1638     generator->PrintLiteral("false");
1639   }
1640 }
PrintInt32(int32 val,BaseTextGenerator * generator) const1641 void TextFormat::FastFieldValuePrinter::PrintInt32(
1642     int32 val, BaseTextGenerator* generator) const {
1643   generator->PrintString(StrCat(val));
1644 }
PrintUInt32(uint32 val,BaseTextGenerator * generator) const1645 void TextFormat::FastFieldValuePrinter::PrintUInt32(
1646     uint32 val, BaseTextGenerator* generator) const {
1647   generator->PrintString(StrCat(val));
1648 }
PrintInt64(int64 val,BaseTextGenerator * generator) const1649 void TextFormat::FastFieldValuePrinter::PrintInt64(
1650     int64 val, BaseTextGenerator* generator) const {
1651   generator->PrintString(StrCat(val));
1652 }
PrintUInt64(uint64 val,BaseTextGenerator * generator) const1653 void TextFormat::FastFieldValuePrinter::PrintUInt64(
1654     uint64 val, BaseTextGenerator* generator) const {
1655   generator->PrintString(StrCat(val));
1656 }
PrintFloat(float val,BaseTextGenerator * generator) const1657 void TextFormat::FastFieldValuePrinter::PrintFloat(
1658     float val, BaseTextGenerator* generator) const {
1659   generator->PrintString(!std::isnan(val) ? SimpleFtoa(val) : "nan");
1660 }
PrintDouble(double val,BaseTextGenerator * generator) const1661 void TextFormat::FastFieldValuePrinter::PrintDouble(
1662     double val, BaseTextGenerator* generator) const {
1663   generator->PrintString(!std::isnan(val) ? SimpleDtoa(val) : "nan");
1664 }
PrintEnum(int32 val,const std::string & name,BaseTextGenerator * generator) const1665 void TextFormat::FastFieldValuePrinter::PrintEnum(
1666     int32 val, const std::string& name, BaseTextGenerator* generator) const {
1667   generator->PrintString(name);
1668 }
1669 
PrintString(const std::string & val,BaseTextGenerator * generator) const1670 void TextFormat::FastFieldValuePrinter::PrintString(
1671     const std::string& val, BaseTextGenerator* generator) const {
1672   generator->PrintLiteral("\"");
1673   generator->PrintString(CEscape(val));
1674   generator->PrintLiteral("\"");
1675 }
PrintBytes(const std::string & val,BaseTextGenerator * generator) const1676 void TextFormat::FastFieldValuePrinter::PrintBytes(
1677     const std::string& val, BaseTextGenerator* generator) const {
1678   PrintString(val, generator);
1679 }
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,BaseTextGenerator * generator) const1680 void TextFormat::FastFieldValuePrinter::PrintFieldName(
1681     const Message& message, int field_index, int field_count,
1682     const Reflection* reflection, const FieldDescriptor* field,
1683     BaseTextGenerator* generator) const {
1684   PrintFieldName(message, reflection, field, generator);
1685 }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,BaseTextGenerator * generator) const1686 void TextFormat::FastFieldValuePrinter::PrintFieldName(
1687     const Message& message, const Reflection* reflection,
1688     const FieldDescriptor* field, BaseTextGenerator* generator) const {
1689   if (field->is_extension()) {
1690     generator->PrintLiteral("[");
1691     generator->PrintString(field->PrintableNameForExtension());
1692     generator->PrintLiteral("]");
1693   } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
1694     // Groups must be serialized with their original capitalization.
1695     generator->PrintString(field->message_type()->name());
1696   } else {
1697     generator->PrintString(field->name());
1698   }
1699 }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode,BaseTextGenerator * generator) const1700 void TextFormat::FastFieldValuePrinter::PrintMessageStart(
1701     const Message& message, int field_index, int field_count,
1702     bool single_line_mode, BaseTextGenerator* generator) const {
1703   if (single_line_mode) {
1704     generator->PrintLiteral(" { ");
1705   } else {
1706     generator->PrintLiteral(" {\n");
1707   }
1708 }
PrintMessageContent(const Message & message,int field_index,int field_count,bool single_line_mode,BaseTextGenerator * generator) const1709 bool TextFormat::FastFieldValuePrinter::PrintMessageContent(
1710     const Message& message, int field_index, int field_count,
1711     bool single_line_mode, BaseTextGenerator* generator) const {
1712   return false;  // Use the default printing function.
1713 }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode,BaseTextGenerator * generator) const1714 void TextFormat::FastFieldValuePrinter::PrintMessageEnd(
1715     const Message& message, int field_index, int field_count,
1716     bool single_line_mode, BaseTextGenerator* generator) const {
1717   if (single_line_mode) {
1718     generator->PrintLiteral("} ");
1719   } else {
1720     generator->PrintLiteral("}\n");
1721   }
1722 }
1723 
1724 namespace {
1725 
1726 // A legacy compatibility wrapper. Takes ownership of the delegate.
1727 class FieldValuePrinterWrapper : public TextFormat::FastFieldValuePrinter {
1728  public:
FieldValuePrinterWrapper(const TextFormat::FieldValuePrinter * delegate)1729   explicit FieldValuePrinterWrapper(
1730       const TextFormat::FieldValuePrinter* delegate)
1731       : delegate_(delegate) {}
1732 
SetDelegate(const TextFormat::FieldValuePrinter * delegate)1733   void SetDelegate(const TextFormat::FieldValuePrinter* delegate) {
1734     delegate_.reset(delegate);
1735   }
1736 
PrintBool(bool val,TextFormat::BaseTextGenerator * generator) const1737   void PrintBool(bool val,
1738                  TextFormat::BaseTextGenerator* generator) const override {
1739     generator->PrintString(delegate_->PrintBool(val));
1740   }
PrintInt32(int32 val,TextFormat::BaseTextGenerator * generator) const1741   void PrintInt32(int32 val,
1742                   TextFormat::BaseTextGenerator* generator) const override {
1743     generator->PrintString(delegate_->PrintInt32(val));
1744   }
PrintUInt32(uint32 val,TextFormat::BaseTextGenerator * generator) const1745   void PrintUInt32(uint32 val,
1746                    TextFormat::BaseTextGenerator* generator) const override {
1747     generator->PrintString(delegate_->PrintUInt32(val));
1748   }
PrintInt64(int64 val,TextFormat::BaseTextGenerator * generator) const1749   void PrintInt64(int64 val,
1750                   TextFormat::BaseTextGenerator* generator) const override {
1751     generator->PrintString(delegate_->PrintInt64(val));
1752   }
PrintUInt64(uint64 val,TextFormat::BaseTextGenerator * generator) const1753   void PrintUInt64(uint64 val,
1754                    TextFormat::BaseTextGenerator* generator) const override {
1755     generator->PrintString(delegate_->PrintUInt64(val));
1756   }
PrintFloat(float val,TextFormat::BaseTextGenerator * generator) const1757   void PrintFloat(float val,
1758                   TextFormat::BaseTextGenerator* generator) const override {
1759     generator->PrintString(delegate_->PrintFloat(val));
1760   }
PrintDouble(double val,TextFormat::BaseTextGenerator * generator) const1761   void PrintDouble(double val,
1762                    TextFormat::BaseTextGenerator* generator) const override {
1763     generator->PrintString(delegate_->PrintDouble(val));
1764   }
PrintString(const std::string & val,TextFormat::BaseTextGenerator * generator) const1765   void PrintString(const std::string& val,
1766                    TextFormat::BaseTextGenerator* generator) const override {
1767     generator->PrintString(delegate_->PrintString(val));
1768   }
PrintBytes(const std::string & val,TextFormat::BaseTextGenerator * generator) const1769   void PrintBytes(const std::string& val,
1770                   TextFormat::BaseTextGenerator* generator) const override {
1771     generator->PrintString(delegate_->PrintBytes(val));
1772   }
PrintEnum(int32 val,const std::string & name,TextFormat::BaseTextGenerator * generator) const1773   void PrintEnum(int32 val, const std::string& name,
1774                  TextFormat::BaseTextGenerator* generator) const override {
1775     generator->PrintString(delegate_->PrintEnum(val, name));
1776   }
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,TextFormat::BaseTextGenerator * generator) const1777   void PrintFieldName(const Message& message, int field_index, int field_count,
1778                       const Reflection* reflection,
1779                       const FieldDescriptor* field,
1780                       TextFormat::BaseTextGenerator* generator) const override {
1781     generator->PrintString(
1782         delegate_->PrintFieldName(message, reflection, field));
1783   }
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextFormat::BaseTextGenerator * generator) const1784   void PrintFieldName(const Message& message, const Reflection* reflection,
1785                       const FieldDescriptor* field,
1786                       TextFormat::BaseTextGenerator* generator) const override {
1787     generator->PrintString(
1788         delegate_->PrintFieldName(message, reflection, field));
1789   }
PrintMessageStart(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const1790   void PrintMessageStart(
1791       const Message& message, int field_index, int field_count,
1792       bool single_line_mode,
1793       TextFormat::BaseTextGenerator* generator) const override {
1794     generator->PrintString(delegate_->PrintMessageStart(
1795         message, field_index, field_count, single_line_mode));
1796   }
PrintMessageEnd(const Message & message,int field_index,int field_count,bool single_line_mode,TextFormat::BaseTextGenerator * generator) const1797   void PrintMessageEnd(
1798       const Message& message, int field_index, int field_count,
1799       bool single_line_mode,
1800       TextFormat::BaseTextGenerator* generator) const override {
1801     generator->PrintString(delegate_->PrintMessageEnd(
1802         message, field_index, field_count, single_line_mode));
1803   }
1804 
1805  private:
1806   std::unique_ptr<const TextFormat::FieldValuePrinter> delegate_;
1807 };
1808 
1809 // Our own specialization: for UTF8 escaped strings.
1810 class FastFieldValuePrinterUtf8Escaping
1811     : public TextFormat::FastFieldValuePrinter {
1812  public:
PrintString(const std::string & val,TextFormat::BaseTextGenerator * generator) const1813   void PrintString(const std::string& val,
1814                    TextFormat::BaseTextGenerator* generator) const override {
1815     generator->PrintLiteral("\"");
1816     generator->PrintString(strings::Utf8SafeCEscape(val));
1817     generator->PrintLiteral("\"");
1818   }
PrintBytes(const std::string & val,TextFormat::BaseTextGenerator * generator) const1819   void PrintBytes(const std::string& val,
1820                   TextFormat::BaseTextGenerator* generator) const override {
1821     return FastFieldValuePrinter::PrintString(val, generator);
1822   }
1823 };
1824 
1825 }  // namespace
1826 
1827 const char* const TextFormat::Printer::kDoNotParse =
1828     "DO NOT PARSE: fields may be stripped and missing.\n";
1829 
Printer()1830 TextFormat::Printer::Printer()
1831     : initial_indent_level_(0),
1832       single_line_mode_(false),
1833       use_field_number_(false),
1834       use_short_repeated_primitives_(false),
1835       hide_unknown_fields_(false),
1836       print_message_fields_in_index_order_(false),
1837       expand_any_(false),
1838       truncate_string_field_longer_than_(0LL),
1839       finder_(nullptr) {
1840   SetUseUtf8StringEscaping(false);
1841 }
1842 
SetUseUtf8StringEscaping(bool as_utf8)1843 void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
1844   SetDefaultFieldValuePrinter(as_utf8 ? new FastFieldValuePrinterUtf8Escaping()
1845                                       : new FastFieldValuePrinter());
1846 }
1847 
SetDefaultFieldValuePrinter(const FieldValuePrinter * printer)1848 void TextFormat::Printer::SetDefaultFieldValuePrinter(
1849     const FieldValuePrinter* printer) {
1850   default_field_value_printer_.reset(new FieldValuePrinterWrapper(printer));
1851 }
1852 
SetDefaultFieldValuePrinter(const FastFieldValuePrinter * printer)1853 void TextFormat::Printer::SetDefaultFieldValuePrinter(
1854     const FastFieldValuePrinter* printer) {
1855   default_field_value_printer_.reset(printer);
1856 }
1857 
RegisterFieldValuePrinter(const FieldDescriptor * field,const FieldValuePrinter * printer)1858 bool TextFormat::Printer::RegisterFieldValuePrinter(
1859     const FieldDescriptor* field, const FieldValuePrinter* printer) {
1860   if (field == nullptr || printer == nullptr) {
1861     return false;
1862   }
1863   std::unique_ptr<FieldValuePrinterWrapper> wrapper(
1864       new FieldValuePrinterWrapper(nullptr));
1865   auto pair = custom_printers_.insert(std::make_pair(field, nullptr));
1866   if (pair.second) {
1867     wrapper->SetDelegate(printer);
1868     pair.first->second = std::move(wrapper);
1869     return true;
1870   } else {
1871     return false;
1872   }
1873 }
1874 
RegisterFieldValuePrinter(const FieldDescriptor * field,const FastFieldValuePrinter * printer)1875 bool TextFormat::Printer::RegisterFieldValuePrinter(
1876     const FieldDescriptor* field, const FastFieldValuePrinter* printer) {
1877   if (field == nullptr || printer == nullptr) {
1878     return false;
1879   }
1880   auto pair = custom_printers_.insert(std::make_pair(field, nullptr));
1881   if (pair.second) {
1882     pair.first->second.reset(printer);
1883     return true;
1884   } else {
1885     return false;
1886   }
1887 }
1888 
RegisterMessagePrinter(const Descriptor * descriptor,const MessagePrinter * printer)1889 bool TextFormat::Printer::RegisterMessagePrinter(
1890     const Descriptor* descriptor, const MessagePrinter* printer) {
1891   if (descriptor == nullptr || printer == nullptr) {
1892     return false;
1893   }
1894   auto pair =
1895       custom_message_printers_.insert(std::make_pair(descriptor, nullptr));
1896   if (pair.second) {
1897     pair.first->second.reset(printer);
1898     return true;
1899   } else {
1900     return false;
1901   }
1902 }
1903 
PrintToString(const Message & message,std::string * output) const1904 bool TextFormat::Printer::PrintToString(const Message& message,
1905                                         std::string* output) const {
1906   GOOGLE_DCHECK(output) << "output specified is nullptr";
1907 
1908   output->clear();
1909   io::StringOutputStream output_stream(output);
1910 
1911   return Print(message, &output_stream);
1912 }
1913 
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,std::string * output) const1914 bool TextFormat::Printer::PrintUnknownFieldsToString(
1915     const UnknownFieldSet& unknown_fields, std::string* output) const {
1916   GOOGLE_DCHECK(output) << "output specified is nullptr";
1917 
1918   output->clear();
1919   io::StringOutputStream output_stream(output);
1920   return PrintUnknownFields(unknown_fields, &output_stream);
1921 }
1922 
Print(const Message & message,io::ZeroCopyOutputStream * output) const1923 bool TextFormat::Printer::Print(const Message& message,
1924                                 io::ZeroCopyOutputStream* output) const {
1925   TextGenerator generator(output, initial_indent_level_);
1926 
1927   Print(message, &generator);
1928 
1929   // Output false if the generator failed internally.
1930   return !generator.failed();
1931 }
1932 
1933 // Maximum recursion depth for heuristically printing out length-delimited
1934 // unknown fields as messages.
1935 static constexpr int kUnknownFieldRecursionLimit = 10;
1936 
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output) const1937 bool TextFormat::Printer::PrintUnknownFields(
1938     const UnknownFieldSet& unknown_fields,
1939     io::ZeroCopyOutputStream* output) const {
1940   TextGenerator generator(output, initial_indent_level_);
1941 
1942   PrintUnknownFields(unknown_fields, &generator, kUnknownFieldRecursionLimit);
1943 
1944   // Output false if the generator failed internally.
1945   return !generator.failed();
1946 }
1947 
1948 namespace {
1949 // Comparison functor for sorting FieldDescriptors by field index.
1950 // Normal fields have higher precedence than extensions.
1951 struct FieldIndexSorter {
operator ()google::protobuf::__anon7d089a660611::FieldIndexSorter1952   bool operator()(const FieldDescriptor* left,
1953                   const FieldDescriptor* right) const {
1954     if (left->is_extension() && right->is_extension()) {
1955       return left->number() < right->number();
1956     } else if (left->is_extension()) {
1957       return false;
1958     } else if (right->is_extension()) {
1959       return true;
1960     } else {
1961       return left->index() < right->index();
1962     }
1963   }
1964 };
1965 
1966 }  // namespace
1967 
PrintAny(const Message & message,TextGenerator * generator) const1968 bool TextFormat::Printer::PrintAny(const Message& message,
1969                                    TextGenerator* generator) const {
1970   const FieldDescriptor* type_url_field;
1971   const FieldDescriptor* value_field;
1972   if (!internal::GetAnyFieldDescriptors(message, &type_url_field,
1973                                         &value_field)) {
1974     return false;
1975   }
1976 
1977   const Reflection* reflection = message.GetReflection();
1978 
1979   // Extract the full type name from the type_url field.
1980   const std::string& type_url = reflection->GetString(message, type_url_field);
1981   std::string url_prefix;
1982   std::string full_type_name;
1983   if (!internal::ParseAnyTypeUrl(type_url, &url_prefix, &full_type_name)) {
1984     return false;
1985   }
1986 
1987   // Print the "value" in text.
1988   const Descriptor* value_descriptor =
1989       finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name)
1990               : DefaultFinderFindAnyType(message, url_prefix, full_type_name);
1991   if (value_descriptor == nullptr) {
1992     GOOGLE_LOG(WARNING) << "Can't print proto content: proto type " << type_url
1993                  << " not found";
1994     return false;
1995   }
1996   DynamicMessageFactory factory;
1997   std::unique_ptr<Message> value_message(
1998       factory.GetPrototype(value_descriptor)->New());
1999   std::string serialized_value = reflection->GetString(message, value_field);
2000   if (!value_message->ParseFromString(serialized_value)) {
2001     GOOGLE_LOG(WARNING) << type_url << ": failed to parse contents";
2002     return false;
2003   }
2004   generator->PrintLiteral("[");
2005   generator->PrintString(type_url);
2006   generator->PrintLiteral("]");
2007   const FastFieldValuePrinter* printer = GetFieldPrinter(value_field);
2008   printer->PrintMessageStart(message, -1, 0, single_line_mode_, generator);
2009   generator->Indent();
2010   Print(*value_message, generator);
2011   generator->Outdent();
2012   printer->PrintMessageEnd(message, -1, 0, single_line_mode_, generator);
2013   return true;
2014 }
2015 
Print(const Message & message,TextGenerator * generator) const2016 void TextFormat::Printer::Print(const Message& message,
2017                                 TextGenerator* generator) const {
2018   const Reflection* reflection = message.GetReflection();
2019   if (!reflection) {
2020     // This message does not provide any way to describe its structure.
2021     // Parse it again in an UnknownFieldSet, and display this instead.
2022     UnknownFieldSet unknown_fields;
2023     {
2024       std::string serialized = message.SerializeAsString();
2025       io::ArrayInputStream input(serialized.data(), serialized.size());
2026       unknown_fields.ParseFromZeroCopyStream(&input);
2027     }
2028     PrintUnknownFields(unknown_fields, generator, kUnknownFieldRecursionLimit);
2029     return;
2030   }
2031   const Descriptor* descriptor = message.GetDescriptor();
2032   auto itr = custom_message_printers_.find(descriptor);
2033   if (itr != custom_message_printers_.end()) {
2034     itr->second->Print(message, single_line_mode_, generator);
2035     return;
2036   }
2037   if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ &&
2038       PrintAny(message, generator)) {
2039     return;
2040   }
2041   std::vector<const FieldDescriptor*> fields;
2042   if (descriptor->options().map_entry()) {
2043     fields.push_back(descriptor->field(0));
2044     fields.push_back(descriptor->field(1));
2045   } else {
2046     reflection->ListFieldsOmitStripped(message, &fields);
2047     if (reflection->IsMessageStripped(message.GetDescriptor())) {
2048       generator->Print(kDoNotParse, std::strlen(kDoNotParse));
2049     }
2050   }
2051 
2052   if (print_message_fields_in_index_order_) {
2053     std::sort(fields.begin(), fields.end(), FieldIndexSorter());
2054   }
2055   for (const FieldDescriptor* field : fields) {
2056     PrintField(message, reflection, field, generator);
2057   }
2058   if (!hide_unknown_fields_) {
2059     PrintUnknownFields(reflection->GetUnknownFields(message), generator,
2060                        kUnknownFieldRecursionLimit);
2061   }
2062 }
2063 
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,std::string * output) const2064 void TextFormat::Printer::PrintFieldValueToString(const Message& message,
2065                                                   const FieldDescriptor* field,
2066                                                   int index,
2067                                                   std::string* output) const {
2068   GOOGLE_DCHECK(output) << "output specified is nullptr";
2069 
2070   output->clear();
2071   io::StringOutputStream output_stream(output);
2072   TextGenerator generator(&output_stream, initial_indent_level_);
2073 
2074   PrintFieldValue(message, message.GetReflection(), field, index, &generator);
2075 }
2076 
2077 class MapEntryMessageComparator {
2078  public:
MapEntryMessageComparator(const Descriptor * descriptor)2079   explicit MapEntryMessageComparator(const Descriptor* descriptor)
2080       : field_(descriptor->field(0)) {}
2081 
operator ()(const Message * a,const Message * b)2082   bool operator()(const Message* a, const Message* b) {
2083     const Reflection* reflection = a->GetReflection();
2084     switch (field_->cpp_type()) {
2085       case FieldDescriptor::CPPTYPE_BOOL: {
2086         bool first = reflection->GetBool(*a, field_);
2087         bool second = reflection->GetBool(*b, field_);
2088         return first < second;
2089       }
2090       case FieldDescriptor::CPPTYPE_INT32: {
2091         int32 first = reflection->GetInt32(*a, field_);
2092         int32 second = reflection->GetInt32(*b, field_);
2093         return first < second;
2094       }
2095       case FieldDescriptor::CPPTYPE_INT64: {
2096         int64 first = reflection->GetInt64(*a, field_);
2097         int64 second = reflection->GetInt64(*b, field_);
2098         return first < second;
2099       }
2100       case FieldDescriptor::CPPTYPE_UINT32: {
2101         uint32 first = reflection->GetUInt32(*a, field_);
2102         uint32 second = reflection->GetUInt32(*b, field_);
2103         return first < second;
2104       }
2105       case FieldDescriptor::CPPTYPE_UINT64: {
2106         uint64 first = reflection->GetUInt64(*a, field_);
2107         uint64 second = reflection->GetUInt64(*b, field_);
2108         return first < second;
2109       }
2110       case FieldDescriptor::CPPTYPE_STRING: {
2111         std::string first = reflection->GetString(*a, field_);
2112         std::string second = reflection->GetString(*b, field_);
2113         return first < second;
2114       }
2115       default:
2116         GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
2117         return true;
2118     }
2119   }
2120 
2121  private:
2122   const FieldDescriptor* field_;
2123 };
2124 
2125 namespace internal {
2126 class MapFieldPrinterHelper {
2127  public:
2128   // DynamicMapSorter::Sort cannot be used because it enfores syncing with
2129   // repeated field.
2130   static bool SortMap(const Message& message, const Reflection* reflection,
2131                       const FieldDescriptor* field, MessageFactory* factory,
2132                       std::vector<const Message*>* sorted_map_field);
2133   static void CopyKey(const MapKey& key, Message* message,
2134                       const FieldDescriptor* field_desc);
2135   static void CopyValue(const MapValueRef& value, Message* message,
2136                         const FieldDescriptor* field_desc);
2137 };
2138 
2139 // 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)2140 bool MapFieldPrinterHelper::SortMap(
2141     const Message& message, const Reflection* reflection,
2142     const FieldDescriptor* field, MessageFactory* factory,
2143     std::vector<const Message*>* sorted_map_field) {
2144   bool need_release = false;
2145   const MapFieldBase& base = *reflection->GetMapData(message, field);
2146 
2147   if (base.IsRepeatedFieldValid()) {
2148     const RepeatedPtrField<Message>& map_field =
2149         reflection->GetRepeatedPtrFieldInternal<Message>(message, field);
2150     for (int i = 0; i < map_field.size(); ++i) {
2151       sorted_map_field->push_back(
2152           const_cast<RepeatedPtrField<Message>*>(&map_field)->Mutable(i));
2153     }
2154   } else {
2155     // TODO(teboring): For performance, instead of creating map entry message
2156     // for each element, just store map keys and sort them.
2157     const Descriptor* map_entry_desc = field->message_type();
2158     const Message* prototype = factory->GetPrototype(map_entry_desc);
2159     for (MapIterator iter =
2160              reflection->MapBegin(const_cast<Message*>(&message), field);
2161          iter != reflection->MapEnd(const_cast<Message*>(&message), field);
2162          ++iter) {
2163       Message* map_entry_message = prototype->New();
2164       CopyKey(iter.GetKey(), map_entry_message, map_entry_desc->field(0));
2165       CopyValue(iter.GetValueRef(), map_entry_message,
2166                 map_entry_desc->field(1));
2167       sorted_map_field->push_back(map_entry_message);
2168     }
2169     need_release = true;
2170   }
2171 
2172   MapEntryMessageComparator comparator(field->message_type());
2173   std::stable_sort(sorted_map_field->begin(), sorted_map_field->end(),
2174                    comparator);
2175   return need_release;
2176 }
2177 
CopyKey(const MapKey & key,Message * message,const FieldDescriptor * field_desc)2178 void MapFieldPrinterHelper::CopyKey(const MapKey& key, Message* message,
2179                                     const FieldDescriptor* field_desc) {
2180   const Reflection* reflection = message->GetReflection();
2181   switch (field_desc->cpp_type()) {
2182     case FieldDescriptor::CPPTYPE_DOUBLE:
2183     case FieldDescriptor::CPPTYPE_FLOAT:
2184     case FieldDescriptor::CPPTYPE_ENUM:
2185     case FieldDescriptor::CPPTYPE_MESSAGE:
2186       GOOGLE_LOG(ERROR) << "Not supported.";
2187       break;
2188     case FieldDescriptor::CPPTYPE_STRING:
2189       reflection->SetString(message, field_desc, key.GetStringValue());
2190       return;
2191     case FieldDescriptor::CPPTYPE_INT64:
2192       reflection->SetInt64(message, field_desc, key.GetInt64Value());
2193       return;
2194     case FieldDescriptor::CPPTYPE_INT32:
2195       reflection->SetInt32(message, field_desc, key.GetInt32Value());
2196       return;
2197     case FieldDescriptor::CPPTYPE_UINT64:
2198       reflection->SetUInt64(message, field_desc, key.GetUInt64Value());
2199       return;
2200     case FieldDescriptor::CPPTYPE_UINT32:
2201       reflection->SetUInt32(message, field_desc, key.GetUInt32Value());
2202       return;
2203     case FieldDescriptor::CPPTYPE_BOOL:
2204       reflection->SetBool(message, field_desc, key.GetBoolValue());
2205       return;
2206   }
2207 }
2208 
CopyValue(const MapValueRef & value,Message * message,const FieldDescriptor * field_desc)2209 void MapFieldPrinterHelper::CopyValue(const MapValueRef& value,
2210                                       Message* message,
2211                                       const FieldDescriptor* field_desc) {
2212   const Reflection* reflection = message->GetReflection();
2213   switch (field_desc->cpp_type()) {
2214     case FieldDescriptor::CPPTYPE_DOUBLE:
2215       reflection->SetDouble(message, field_desc, value.GetDoubleValue());
2216       return;
2217     case FieldDescriptor::CPPTYPE_FLOAT:
2218       reflection->SetFloat(message, field_desc, value.GetFloatValue());
2219       return;
2220     case FieldDescriptor::CPPTYPE_ENUM:
2221       reflection->SetEnumValue(message, field_desc, value.GetEnumValue());
2222       return;
2223     case FieldDescriptor::CPPTYPE_MESSAGE: {
2224       Message* sub_message = value.GetMessageValue().New();
2225       sub_message->CopyFrom(value.GetMessageValue());
2226       reflection->SetAllocatedMessage(message, sub_message, field_desc);
2227       return;
2228     }
2229     case FieldDescriptor::CPPTYPE_STRING:
2230       reflection->SetString(message, field_desc, value.GetStringValue());
2231       return;
2232     case FieldDescriptor::CPPTYPE_INT64:
2233       reflection->SetInt64(message, field_desc, value.GetInt64Value());
2234       return;
2235     case FieldDescriptor::CPPTYPE_INT32:
2236       reflection->SetInt32(message, field_desc, value.GetInt32Value());
2237       return;
2238     case FieldDescriptor::CPPTYPE_UINT64:
2239       reflection->SetUInt64(message, field_desc, value.GetUInt64Value());
2240       return;
2241     case FieldDescriptor::CPPTYPE_UINT32:
2242       reflection->SetUInt32(message, field_desc, value.GetUInt32Value());
2243       return;
2244     case FieldDescriptor::CPPTYPE_BOOL:
2245       reflection->SetBool(message, field_desc, value.GetBoolValue());
2246       return;
2247   }
2248 }
2249 }  // namespace internal
2250 
PrintField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator * generator) const2251 void TextFormat::Printer::PrintField(const Message& message,
2252                                      const Reflection* reflection,
2253                                      const FieldDescriptor* field,
2254                                      TextGenerator* generator) const {
2255   if (use_short_repeated_primitives_ && field->is_repeated() &&
2256       field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
2257       field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
2258     PrintShortRepeatedField(message, reflection, field, generator);
2259     return;
2260   }
2261 
2262   int count = 0;
2263 
2264   if (field->is_repeated()) {
2265     count = reflection->FieldSize(message, field);
2266   } else if (reflection->HasField(message, field) ||
2267              field->containing_type()->options().map_entry()) {
2268     count = 1;
2269   }
2270 
2271   DynamicMessageFactory factory;
2272   std::vector<const Message*> sorted_map_field;
2273   bool need_release = false;
2274   bool is_map = field->is_map();
2275   if (is_map) {
2276     need_release = internal::MapFieldPrinterHelper::SortMap(
2277         message, reflection, field, &factory, &sorted_map_field);
2278   }
2279 
2280   for (int j = 0; j < count; ++j) {
2281     const int field_index = field->is_repeated() ? j : -1;
2282 
2283     PrintFieldName(message, field_index, count, reflection, field, generator);
2284 
2285     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2286       const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2287       const Message& sub_message =
2288           field->is_repeated()
2289               ? (is_map ? *sorted_map_field[j]
2290                         : reflection->GetRepeatedMessage(message, field, j))
2291               : reflection->GetMessage(message, field);
2292       printer->PrintMessageStart(sub_message, field_index, count,
2293                                  single_line_mode_, generator);
2294       generator->Indent();
2295       if (!printer->PrintMessageContent(sub_message, field_index, count,
2296                                         single_line_mode_, generator)) {
2297         Print(sub_message, generator);
2298       }
2299       generator->Outdent();
2300       printer->PrintMessageEnd(sub_message, field_index, count,
2301                                single_line_mode_, generator);
2302     } else {
2303       generator->PrintLiteral(": ");
2304       // Write the field value.
2305       PrintFieldValue(message, reflection, field, field_index, generator);
2306       if (single_line_mode_) {
2307         generator->PrintLiteral(" ");
2308       } else {
2309         generator->PrintLiteral("\n");
2310       }
2311     }
2312   }
2313 
2314   if (need_release) {
2315     for (const Message* message_to_delete : sorted_map_field) {
2316       delete message_to_delete;
2317     }
2318   }
2319 }
2320 
PrintShortRepeatedField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator * generator) const2321 void TextFormat::Printer::PrintShortRepeatedField(
2322     const Message& message, const Reflection* reflection,
2323     const FieldDescriptor* field, TextGenerator* generator) const {
2324   // Print primitive repeated field in short form.
2325   int size = reflection->FieldSize(message, field);
2326   PrintFieldName(message, /*field_index=*/-1, /*field_count=*/size, reflection,
2327                  field, generator);
2328   generator->PrintLiteral(": [");
2329   for (int i = 0; i < size; i++) {
2330     if (i > 0) generator->PrintLiteral(", ");
2331     PrintFieldValue(message, reflection, field, i, generator);
2332   }
2333   if (single_line_mode_) {
2334     generator->PrintLiteral("] ");
2335   } else {
2336     generator->PrintLiteral("]\n");
2337   }
2338 }
2339 
PrintFieldName(const Message & message,int field_index,int field_count,const Reflection * reflection,const FieldDescriptor * field,TextGenerator * generator) const2340 void TextFormat::Printer::PrintFieldName(const Message& message,
2341                                          int field_index, int field_count,
2342                                          const Reflection* reflection,
2343                                          const FieldDescriptor* field,
2344                                          TextGenerator* generator) const {
2345   // if use_field_number_ is true, prints field number instead
2346   // of field name.
2347   if (use_field_number_) {
2348     generator->PrintString(StrCat(field->number()));
2349     return;
2350   }
2351 
2352   const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2353   printer->PrintFieldName(message, field_index, field_count, reflection, field,
2354                           generator);
2355 }
2356 
PrintFieldValue(const Message & message,const Reflection * reflection,const FieldDescriptor * field,int index,TextGenerator * generator) const2357 void TextFormat::Printer::PrintFieldValue(const Message& message,
2358                                           const Reflection* reflection,
2359                                           const FieldDescriptor* field,
2360                                           int index,
2361                                           TextGenerator* generator) const {
2362   GOOGLE_DCHECK(field->is_repeated() || (index == -1))
2363       << "Index must be -1 for non-repeated fields";
2364 
2365   const FastFieldValuePrinter* printer = GetFieldPrinter(field);
2366 
2367   switch (field->cpp_type()) {
2368 #define OUTPUT_FIELD(CPPTYPE, METHOD)                                \
2369   case FieldDescriptor::CPPTYPE_##CPPTYPE:                           \
2370     printer->Print##METHOD(                                          \
2371         field->is_repeated()                                         \
2372             ? reflection->GetRepeated##METHOD(message, field, index) \
2373             : reflection->Get##METHOD(message, field),               \
2374         generator);                                                  \
2375     break
2376 
2377     OUTPUT_FIELD(INT32, Int32);
2378     OUTPUT_FIELD(INT64, Int64);
2379     OUTPUT_FIELD(UINT32, UInt32);
2380     OUTPUT_FIELD(UINT64, UInt64);
2381     OUTPUT_FIELD(FLOAT, Float);
2382     OUTPUT_FIELD(DOUBLE, Double);
2383     OUTPUT_FIELD(BOOL, Bool);
2384 #undef OUTPUT_FIELD
2385 
2386     case FieldDescriptor::CPPTYPE_STRING: {
2387       std::string scratch;
2388       const std::string& value =
2389           field->is_repeated()
2390               ? reflection->GetRepeatedStringReference(message, field, index,
2391                                                        &scratch)
2392               : reflection->GetStringReference(message, field, &scratch);
2393       const std::string* value_to_print = &value;
2394       std::string truncated_value;
2395       if (truncate_string_field_longer_than_ > 0 &&
2396           truncate_string_field_longer_than_ < value.size()) {
2397         truncated_value = value.substr(0, truncate_string_field_longer_than_) +
2398                           "...<truncated>...";
2399         value_to_print = &truncated_value;
2400       }
2401       if (field->type() == FieldDescriptor::TYPE_STRING) {
2402         printer->PrintString(*value_to_print, generator);
2403       } else {
2404         GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
2405         printer->PrintBytes(*value_to_print, generator);
2406       }
2407       break;
2408     }
2409 
2410     case FieldDescriptor::CPPTYPE_ENUM: {
2411       int enum_value =
2412           field->is_repeated()
2413               ? reflection->GetRepeatedEnumValue(message, field, index)
2414               : reflection->GetEnumValue(message, field);
2415       const EnumValueDescriptor* enum_desc =
2416           field->enum_type()->FindValueByNumber(enum_value);
2417       if (enum_desc != nullptr) {
2418         printer->PrintEnum(enum_value, enum_desc->name(), generator);
2419       } else {
2420         // Ordinarily, enum_desc should not be null, because proto2 has the
2421         // invariant that set enum field values must be in-range, but with the
2422         // new integer-based API for enums (or the RepeatedField<int> loophole),
2423         // it is possible for the user to force an unknown integer value.  So we
2424         // simply use the integer value itself as the enum value name in this
2425         // case.
2426         printer->PrintEnum(enum_value, StrCat(enum_value), generator);
2427       }
2428       break;
2429     }
2430 
2431     case FieldDescriptor::CPPTYPE_MESSAGE:
2432       Print(field->is_repeated()
2433                 ? reflection->GetRepeatedMessage(message, field, index)
2434                 : reflection->GetMessage(message, field),
2435             generator);
2436       break;
2437   }
2438 }
2439 
Print(const Message & message,io::ZeroCopyOutputStream * output)2440 /* static */ bool TextFormat::Print(const Message& message,
2441                                     io::ZeroCopyOutputStream* output) {
2442   return Printer().Print(message, output);
2443 }
2444 
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output)2445 /* static */ bool TextFormat::PrintUnknownFields(
2446     const UnknownFieldSet& unknown_fields, io::ZeroCopyOutputStream* output) {
2447   return Printer().PrintUnknownFields(unknown_fields, output);
2448 }
2449 
PrintToString(const Message & message,std::string * output)2450 /* static */ bool TextFormat::PrintToString(const Message& message,
2451                                             std::string* output) {
2452   return Printer().PrintToString(message, output);
2453 }
2454 
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,std::string * output)2455 /* static */ bool TextFormat::PrintUnknownFieldsToString(
2456     const UnknownFieldSet& unknown_fields, std::string* output) {
2457   return Printer().PrintUnknownFieldsToString(unknown_fields, output);
2458 }
2459 
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,std::string * output)2460 /* static */ void TextFormat::PrintFieldValueToString(
2461     const Message& message, const FieldDescriptor* field, int index,
2462     std::string* output) {
2463   return Printer().PrintFieldValueToString(message, field, index, output);
2464 }
2465 
ParseFieldValueFromString(const std::string & input,const FieldDescriptor * field,Message * message)2466 /* static */ bool TextFormat::ParseFieldValueFromString(
2467     const std::string& input, const FieldDescriptor* field, Message* message) {
2468   return Parser().ParseFieldValueFromString(input, field, message);
2469 }
2470 
PrintUnknownFields(const UnknownFieldSet & unknown_fields,TextGenerator * generator,int recursion_budget) const2471 void TextFormat::Printer::PrintUnknownFields(
2472     const UnknownFieldSet& unknown_fields, TextGenerator* generator,
2473     int recursion_budget) const {
2474   for (int i = 0; i < unknown_fields.field_count(); i++) {
2475     const UnknownField& field = unknown_fields.field(i);
2476     std::string field_number = StrCat(field.number());
2477 
2478     switch (field.type()) {
2479       case UnknownField::TYPE_VARINT:
2480         generator->PrintString(field_number);
2481         generator->PrintLiteral(": ");
2482         generator->PrintString(StrCat(field.varint()));
2483         if (single_line_mode_) {
2484           generator->PrintLiteral(" ");
2485         } else {
2486           generator->PrintLiteral("\n");
2487         }
2488         break;
2489       case UnknownField::TYPE_FIXED32: {
2490         generator->PrintString(field_number);
2491         generator->PrintLiteral(": 0x");
2492         generator->PrintString(
2493             StrCat(strings::Hex(field.fixed32(), strings::ZERO_PAD_8)));
2494         if (single_line_mode_) {
2495           generator->PrintLiteral(" ");
2496         } else {
2497           generator->PrintLiteral("\n");
2498         }
2499         break;
2500       }
2501       case UnknownField::TYPE_FIXED64: {
2502         generator->PrintString(field_number);
2503         generator->PrintLiteral(": 0x");
2504         generator->PrintString(
2505             StrCat(strings::Hex(field.fixed64(), strings::ZERO_PAD_16)));
2506         if (single_line_mode_) {
2507           generator->PrintLiteral(" ");
2508         } else {
2509           generator->PrintLiteral("\n");
2510         }
2511         break;
2512       }
2513       case UnknownField::TYPE_LENGTH_DELIMITED: {
2514         generator->PrintString(field_number);
2515         const std::string& value = field.length_delimited();
2516         // We create a CodedInputStream so that we can adhere to our recursion
2517         // budget when we attempt to parse the data. UnknownFieldSet parsing is
2518         // recursive because of groups.
2519         io::CodedInputStream input_stream(
2520             reinterpret_cast<const uint8*>(value.data()), value.size());
2521         input_stream.SetRecursionLimit(recursion_budget);
2522         UnknownFieldSet embedded_unknown_fields;
2523         if (!value.empty() && recursion_budget > 0 &&
2524             embedded_unknown_fields.ParseFromCodedStream(&input_stream)) {
2525           // This field is parseable as a Message.
2526           // So it is probably an embedded message.
2527           if (single_line_mode_) {
2528             generator->PrintLiteral(" { ");
2529           } else {
2530             generator->PrintLiteral(" {\n");
2531             generator->Indent();
2532           }
2533           PrintUnknownFields(embedded_unknown_fields, generator,
2534                              recursion_budget - 1);
2535           if (single_line_mode_) {
2536             generator->PrintLiteral("} ");
2537           } else {
2538             generator->Outdent();
2539             generator->PrintLiteral("}\n");
2540           }
2541         } else {
2542           // This field is not parseable as a Message (or we ran out of
2543           // recursion budget). So it is probably just a plain string.
2544           generator->PrintLiteral(": \"");
2545           generator->PrintString(CEscape(value));
2546           if (single_line_mode_) {
2547             generator->PrintLiteral("\" ");
2548           } else {
2549             generator->PrintLiteral("\"\n");
2550           }
2551         }
2552         break;
2553       }
2554       case UnknownField::TYPE_GROUP:
2555         generator->PrintString(field_number);
2556         if (single_line_mode_) {
2557           generator->PrintLiteral(" { ");
2558         } else {
2559           generator->PrintLiteral(" {\n");
2560           generator->Indent();
2561         }
2562         // For groups, we recurse without checking the budget. This is OK,
2563         // because if the groups were too deeply nested then we would have
2564         // already rejected the message when we originally parsed it.
2565         PrintUnknownFields(field.group(), generator, recursion_budget - 1);
2566         if (single_line_mode_) {
2567           generator->PrintLiteral("} ");
2568         } else {
2569           generator->Outdent();
2570           generator->PrintLiteral("}\n");
2571         }
2572         break;
2573     }
2574   }
2575 }
2576 
2577 }  // namespace protobuf
2578 }  // namespace google
2579