1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // http://code.google.com/p/protobuf/
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 <float.h>
36 #include <math.h>
37 #include <stdio.h>
38 #include <stack>
39 #include <limits>
40 #include <vector>
41 
42 #include <google/protobuf/text_format.h>
43 
44 #include <google/protobuf/descriptor.h>
45 #include <google/protobuf/io/coded_stream.h>
46 #include <google/protobuf/io/zero_copy_stream.h>
47 #include <google/protobuf/io/zero_copy_stream_impl.h>
48 #include <google/protobuf/unknown_field_set.h>
49 #include <google/protobuf/descriptor.pb.h>
50 #include <google/protobuf/io/tokenizer.h>
51 #include <google/protobuf/stubs/strutil.h>
52 #include <google/protobuf/stubs/map-util.h>
53 #include <google/protobuf/stubs/stl_util.h>
54 
55 namespace google {
56 namespace protobuf {
57 
DebugString() const58 string Message::DebugString() const {
59   string debug_string;
60 
61   TextFormat::PrintToString(*this, &debug_string);
62 
63   return debug_string;
64 }
65 
ShortDebugString() const66 string Message::ShortDebugString() const {
67   string debug_string;
68 
69   TextFormat::Printer printer;
70   printer.SetSingleLineMode(true);
71 
72   printer.PrintToString(*this, &debug_string);
73   // Single line mode currently might have an extra space at the end.
74   if (debug_string.size() > 0 &&
75       debug_string[debug_string.size() - 1] == ' ') {
76     debug_string.resize(debug_string.size() - 1);
77   }
78 
79   return debug_string;
80 }
81 
Utf8DebugString() const82 string Message::Utf8DebugString() const {
83   string debug_string;
84 
85   TextFormat::Printer printer;
86   printer.SetUseUtf8StringEscaping(true);
87 
88   printer.PrintToString(*this, &debug_string);
89 
90   return debug_string;
91 }
92 
PrintDebugString() const93 void Message::PrintDebugString() const {
94   printf("%s", DebugString().c_str());
95 }
96 
97 
98 // ===========================================================================
99 // Implementation of the parse information tree class.
ParseInfoTree()100 TextFormat::ParseInfoTree::ParseInfoTree() { }
101 
~ParseInfoTree()102 TextFormat::ParseInfoTree::~ParseInfoTree() {
103   // Remove any nested information trees, as they are owned by this tree.
104   for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) {
105     STLDeleteElements(&(it->second));
106   }
107 }
108 
RecordLocation(const FieldDescriptor * field,TextFormat::ParseLocation location)109 void TextFormat::ParseInfoTree::RecordLocation(
110     const FieldDescriptor* field,
111     TextFormat::ParseLocation location) {
112   locations_[field].push_back(location);
113 }
114 
CreateNested(const FieldDescriptor * field)115 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
116     const FieldDescriptor* field) {
117   // Owned by us in the map.
118   TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
119   vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
120   GOOGLE_CHECK(trees);
121   trees->push_back(instance);
122   return instance;
123 }
124 
CheckFieldIndex(const FieldDescriptor * field,int index)125 void CheckFieldIndex(const FieldDescriptor* field, int index) {
126   if (field == NULL) { return; }
127 
128   if (field->is_repeated() && index == -1) {
129     GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
130                 << "Field: " << field->name();
131   } else if (!field->is_repeated() && index != -1) {
132     GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
133                 << "Field: " << field->name();
134   }
135 }
136 
GetLocation(const FieldDescriptor * field,int index) const137 TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
138     const FieldDescriptor* field, int index) const {
139   CheckFieldIndex(field, index);
140   if (index == -1) { index = 0; }
141 
142   const vector<TextFormat::ParseLocation>* locations =
143       FindOrNull(locations_, field);
144   if (locations == NULL || index >= locations->size()) {
145     return TextFormat::ParseLocation();
146   }
147 
148   return (*locations)[index];
149 }
150 
GetTreeForNested(const FieldDescriptor * field,int index) const151 TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
152     const FieldDescriptor* field, int index) const {
153   CheckFieldIndex(field, index);
154   if (index == -1) { index = 0; }
155 
156   const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field);
157   if (trees == NULL || index >= trees->size()) {
158     return NULL;
159   }
160 
161   return (*trees)[index];
162 }
163 
164 
165 // ===========================================================================
166 // Internal class for parsing an ASCII representation of a Protocol Message.
167 // This class makes use of the Protocol Message compiler's tokenizer found
168 // in //google/protobuf/io/tokenizer.h. Note that class's Parse
169 // method is *not* thread-safe and should only be used in a single thread at
170 // a time.
171 
172 // Makes code slightly more readable.  The meaning of "DO(foo)" is
173 // "Execute foo and fail if it fails.", where failure is indicated by
174 // returning false. Borrowed from parser.cc (Thanks Kenton!).
175 #define DO(STATEMENT) if (STATEMENT) {} else return false
176 
177 class TextFormat::Parser::ParserImpl {
178  public:
179 
180   // Determines if repeated values for a non-repeated field are
181   // permitted, e.g., the string "foo: 1 foo: 2" for a
182   // required/optional field named "foo".
183   enum SingularOverwritePolicy {
184     ALLOW_SINGULAR_OVERWRITES = 0,   // the last value is retained
185     FORBID_SINGULAR_OVERWRITES = 1,  // an error is issued
186   };
187 
ParserImpl(const Descriptor * root_message_type,io::ZeroCopyInputStream * input_stream,io::ErrorCollector * error_collector,TextFormat::Finder * finder,ParseInfoTree * parse_info_tree,SingularOverwritePolicy singular_overwrite_policy,bool allow_unknown_field)188   ParserImpl(const Descriptor* root_message_type,
189              io::ZeroCopyInputStream* input_stream,
190              io::ErrorCollector* error_collector,
191              TextFormat::Finder* finder,
192              ParseInfoTree* parse_info_tree,
193              SingularOverwritePolicy singular_overwrite_policy,
194              bool allow_unknown_field)
195     : error_collector_(error_collector),
196       finder_(finder),
197       parse_info_tree_(parse_info_tree),
198       tokenizer_error_collector_(this),
199       tokenizer_(input_stream, &tokenizer_error_collector_),
200       root_message_type_(root_message_type),
201       singular_overwrite_policy_(singular_overwrite_policy),
202       allow_unknown_field_(allow_unknown_field),
203       had_errors_(false) {
204     // For backwards-compatibility with proto1, we need to allow the 'f' suffix
205     // for floats.
206     tokenizer_.set_allow_f_after_float(true);
207 
208     // '#' starts a comment.
209     tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE);
210 
211     // Consume the starting token.
212     tokenizer_.Next();
213   }
~ParserImpl()214   ~ParserImpl() { }
215 
216   // Parses the ASCII representation specified in input and saves the
217   // information into the output pointer (a Message). Returns
218   // false if an error occurs (an error will also be logged to
219   // GOOGLE_LOG(ERROR)).
Parse(Message * output)220   bool Parse(Message* output) {
221     // Consume fields until we cannot do so anymore.
222     while(true) {
223       if (LookingAtType(io::Tokenizer::TYPE_END)) {
224         return !had_errors_;
225       }
226 
227       DO(ConsumeField(output));
228     }
229   }
230 
ParseField(const FieldDescriptor * field,Message * output)231   bool ParseField(const FieldDescriptor* field, Message* output) {
232     bool suc;
233     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
234       suc = ConsumeFieldMessage(output, output->GetReflection(), field);
235     } else {
236       suc = ConsumeFieldValue(output, output->GetReflection(), field);
237     }
238     return suc && LookingAtType(io::Tokenizer::TYPE_END);
239   }
240 
ReportError(int line,int col,const string & message)241   void ReportError(int line, int col, const string& message) {
242     had_errors_ = true;
243     if (error_collector_ == NULL) {
244       if (line >= 0) {
245         GOOGLE_LOG(ERROR) << "Error parsing text-format "
246                    << root_message_type_->full_name()
247                    << ": " << (line + 1) << ":"
248                    << (col + 1) << ": " << message;
249       } else {
250         GOOGLE_LOG(ERROR) << "Error parsing text-format "
251                    << root_message_type_->full_name()
252                    << ": " << message;
253       }
254     } else {
255       error_collector_->AddError(line, col, message);
256     }
257   }
258 
ReportWarning(int line,int col,const string & message)259   void ReportWarning(int line, int col, const string& message) {
260     if (error_collector_ == NULL) {
261       if (line >= 0) {
262         GOOGLE_LOG(WARNING) << "Warning parsing text-format "
263                      << root_message_type_->full_name()
264                      << ": " << (line + 1) << ":"
265                      << (col + 1) << ": " << message;
266       } else {
267         GOOGLE_LOG(WARNING) << "Warning parsing text-format "
268                      << root_message_type_->full_name()
269                      << ": " << message;
270       }
271     } else {
272       error_collector_->AddWarning(line, col, message);
273     }
274   }
275 
276  private:
277   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl);
278 
279   // Reports an error with the given message with information indicating
280   // the position (as derived from the current token).
ReportError(const string & message)281   void ReportError(const string& message) {
282     ReportError(tokenizer_.current().line, tokenizer_.current().column,
283                 message);
284   }
285 
286   // Reports a warning with the given message with information indicating
287   // the position (as derived from the current token).
ReportWarning(const string & message)288   void ReportWarning(const string& message) {
289     ReportWarning(tokenizer_.current().line, tokenizer_.current().column,
290                   message);
291   }
292 
293   // Consumes the specified message with the given starting delimeter.
294   // This method checks to see that the end delimeter at the conclusion of
295   // the consumption matches the starting delimeter passed in here.
ConsumeMessage(Message * message,const string delimeter)296   bool ConsumeMessage(Message* message, const string delimeter) {
297     while (!LookingAt(">") &&  !LookingAt("}")) {
298       DO(ConsumeField(message));
299     }
300 
301     // Confirm that we have a valid ending delimeter.
302     DO(Consume(delimeter));
303 
304     return true;
305   }
306 
307   // Consumes the current field (as returned by the tokenizer) on the
308   // passed in message.
ConsumeField(Message * message)309   bool ConsumeField(Message* message) {
310     const Reflection* reflection = message->GetReflection();
311     const Descriptor* descriptor = message->GetDescriptor();
312 
313     string field_name;
314 
315     const FieldDescriptor* field = NULL;
316     int start_line = tokenizer_.current().line;
317     int start_column = tokenizer_.current().column;
318 
319     if (TryConsume("[")) {
320       // Extension.
321       DO(ConsumeIdentifier(&field_name));
322       while (TryConsume(".")) {
323         string part;
324         DO(ConsumeIdentifier(&part));
325         field_name += ".";
326         field_name += part;
327       }
328       DO(Consume("]"));
329 
330       field = (finder_ != NULL
331                ? finder_->FindExtension(message, field_name)
332                : reflection->FindKnownExtensionByName(field_name));
333 
334       if (field == NULL) {
335         if (!allow_unknown_field_) {
336           ReportError("Extension \"" + field_name + "\" is not defined or "
337                       "is not an extension of \"" +
338                       descriptor->full_name() + "\".");
339           return false;
340         } else {
341           ReportWarning("Extension \"" + field_name + "\" is not defined or "
342                         "is not an extension of \"" +
343                         descriptor->full_name() + "\".");
344         }
345       }
346     } else {
347       DO(ConsumeIdentifier(&field_name));
348 
349       field = descriptor->FindFieldByName(field_name);
350       // Group names are expected to be capitalized as they appear in the
351       // .proto file, which actually matches their type names, not their field
352       // names.
353       if (field == NULL) {
354         string lower_field_name = field_name;
355         LowerString(&lower_field_name);
356         field = descriptor->FindFieldByName(lower_field_name);
357         // If the case-insensitive match worked but the field is NOT a group,
358         if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
359           field = NULL;
360         }
361       }
362       // Again, special-case group names as described above.
363       if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP
364           && field->message_type()->name() != field_name) {
365         field = NULL;
366       }
367 
368       if (field == NULL) {
369         if (!allow_unknown_field_) {
370           ReportError("Message type \"" + descriptor->full_name() +
371                       "\" has no field named \"" + field_name + "\".");
372           return false;
373         } else {
374           ReportWarning("Message type \"" + descriptor->full_name() +
375                         "\" has no field named \"" + field_name + "\".");
376         }
377       }
378     }
379 
380     // Skips unknown field.
381     if (field == NULL) {
382       GOOGLE_CHECK(allow_unknown_field_);
383       // Try to guess the type of this field.
384       // If this field is not a message, there should be a ":" between the
385       // field name and the field value and also the field value should not
386       // start with "{" or "<" which indicates the begining of a message body.
387       // If there is no ":" or there is a "{" or "<" after ":", this field has
388       // to be a message or the input is ill-formed.
389       if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
390         return SkipFieldValue();
391       } else {
392         return SkipFieldMessage();
393       }
394     }
395 
396     // Fail if the field is not repeated and it has already been specified.
397     if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) &&
398         !field->is_repeated() && reflection->HasField(*message, field)) {
399       ReportError("Non-repeated field \"" + field_name +
400                   "\" is specified multiple times.");
401       return false;
402     }
403 
404     // Perform special handling for embedded message types.
405     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
406       // ':' is optional here.
407       TryConsume(":");
408       DO(ConsumeFieldMessage(message, reflection, field));
409     } else {
410       DO(Consume(":"));
411       if (field->is_repeated() && TryConsume("[")) {
412         // Short repeated format, e.g.  "foo: [1, 2, 3]"
413         while (true) {
414           DO(ConsumeFieldValue(message, reflection, field));
415           if (TryConsume("]")) {
416             break;
417           }
418           DO(Consume(","));
419         }
420       } else {
421         DO(ConsumeFieldValue(message, reflection, field));
422       }
423     }
424 
425     // For historical reasons, fields may optionally be separated by commas or
426     // semicolons.
427     TryConsume(";") || TryConsume(",");
428 
429     if (field->options().deprecated()) {
430       ReportWarning("text format contains deprecated field \""
431                     + field_name + "\"");
432     }
433 
434     // If a parse info tree exists, add the location for the parsed
435     // field.
436     if (parse_info_tree_ != NULL) {
437       RecordLocation(parse_info_tree_, field,
438                      ParseLocation(start_line, start_column));
439     }
440 
441     return true;
442   }
443 
444   // Skips the next field including the field's name and value.
SkipField()445   bool SkipField() {
446     string field_name;
447     if (TryConsume("[")) {
448       // Extension name.
449       DO(ConsumeIdentifier(&field_name));
450       while (TryConsume(".")) {
451         string part;
452         DO(ConsumeIdentifier(&part));
453         field_name += ".";
454         field_name += part;
455       }
456       DO(Consume("]"));
457     } else {
458       DO(ConsumeIdentifier(&field_name));
459     }
460 
461     // Try to guess the type of this field.
462     // If this field is not a message, there should be a ":" between the
463     // field name and the field value and also the field value should not
464     // start with "{" or "<" which indicates the begining of a message body.
465     // If there is no ":" or there is a "{" or "<" after ":", this field has
466     // to be a message or the input is ill-formed.
467     if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
468       DO(SkipFieldValue());
469     } else {
470       DO(SkipFieldMessage());
471     }
472     // For historical reasons, fields may optionally be separated by commas or
473     // semicolons.
474     TryConsume(";") || TryConsume(",");
475     return true;
476   }
477 
ConsumeFieldMessage(Message * message,const Reflection * reflection,const FieldDescriptor * field)478   bool ConsumeFieldMessage(Message* message,
479                            const Reflection* reflection,
480                            const FieldDescriptor* field) {
481 
482     // If the parse information tree is not NULL, create a nested one
483     // for the nested message.
484     ParseInfoTree* parent = parse_info_tree_;
485     if (parent != NULL) {
486       parse_info_tree_ = CreateNested(parent, field);
487     }
488 
489     string delimeter;
490     if (TryConsume("<")) {
491       delimeter = ">";
492     } else {
493       DO(Consume("{"));
494       delimeter = "}";
495     }
496 
497     if (field->is_repeated()) {
498       DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
499     } else {
500       DO(ConsumeMessage(reflection->MutableMessage(message, field),
501                         delimeter));
502     }
503 
504     // Reset the parse information tree.
505     parse_info_tree_ = parent;
506     return true;
507   }
508 
509   // Skips the whole body of a message including the begining delimeter and
510   // the ending delimeter.
SkipFieldMessage()511   bool SkipFieldMessage() {
512     string delimeter;
513     if (TryConsume("<")) {
514       delimeter = ">";
515     } else {
516       DO(Consume("{"));
517       delimeter = "}";
518     }
519     while (!LookingAt(">") &&  !LookingAt("}")) {
520       DO(SkipField());
521     }
522     DO(Consume(delimeter));
523     return true;
524   }
525 
ConsumeFieldValue(Message * message,const Reflection * reflection,const FieldDescriptor * field)526   bool ConsumeFieldValue(Message* message,
527                          const Reflection* reflection,
528                          const FieldDescriptor* field) {
529 
530 // Define an easy to use macro for setting fields. This macro checks
531 // to see if the field is repeated (in which case we need to use the Add
532 // methods or not (in which case we need to use the Set methods).
533 #define SET_FIELD(CPPTYPE, VALUE)                                  \
534         if (field->is_repeated()) {                                \
535           reflection->Add##CPPTYPE(message, field, VALUE);         \
536         } else {                                                   \
537           reflection->Set##CPPTYPE(message, field, VALUE);         \
538         }                                                          \
539 
540     switch(field->cpp_type()) {
541       case FieldDescriptor::CPPTYPE_INT32: {
542         int64 value;
543         DO(ConsumeSignedInteger(&value, kint32max));
544         SET_FIELD(Int32, static_cast<int32>(value));
545         break;
546       }
547 
548       case FieldDescriptor::CPPTYPE_UINT32: {
549         uint64 value;
550         DO(ConsumeUnsignedInteger(&value, kuint32max));
551         SET_FIELD(UInt32, static_cast<uint32>(value));
552         break;
553       }
554 
555       case FieldDescriptor::CPPTYPE_INT64: {
556         int64 value;
557         DO(ConsumeSignedInteger(&value, kint64max));
558         SET_FIELD(Int64, value);
559         break;
560       }
561 
562       case FieldDescriptor::CPPTYPE_UINT64: {
563         uint64 value;
564         DO(ConsumeUnsignedInteger(&value, kuint64max));
565         SET_FIELD(UInt64, value);
566         break;
567       }
568 
569       case FieldDescriptor::CPPTYPE_FLOAT: {
570         double value;
571         DO(ConsumeDouble(&value));
572         SET_FIELD(Float, static_cast<float>(value));
573         break;
574       }
575 
576       case FieldDescriptor::CPPTYPE_DOUBLE: {
577         double value;
578         DO(ConsumeDouble(&value));
579         SET_FIELD(Double, value);
580         break;
581       }
582 
583       case FieldDescriptor::CPPTYPE_STRING: {
584         string value;
585         DO(ConsumeString(&value));
586         SET_FIELD(String, value);
587         break;
588       }
589 
590       case FieldDescriptor::CPPTYPE_BOOL: {
591         if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
592           uint64 value;
593           DO(ConsumeUnsignedInteger(&value, 1));
594           SET_FIELD(Bool, value);
595         } else {
596           string value;
597           DO(ConsumeIdentifier(&value));
598           if (value == "true" || value == "t") {
599             SET_FIELD(Bool, true);
600           } else if (value == "false" || value == "f") {
601             SET_FIELD(Bool, false);
602           } else {
603             ReportError("Invalid value for boolean field \"" + field->name()
604                         + "\". Value: \"" + value  + "\".");
605             return false;
606           }
607         }
608         break;
609       }
610 
611       case FieldDescriptor::CPPTYPE_ENUM: {
612         string value;
613         const EnumDescriptor* enum_type = field->enum_type();
614         const EnumValueDescriptor* enum_value = NULL;
615 
616         if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
617           DO(ConsumeIdentifier(&value));
618           // Find the enumeration value.
619           enum_value = enum_type->FindValueByName(value);
620 
621         } else if (LookingAt("-") ||
622                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
623           int64 int_value;
624           DO(ConsumeSignedInteger(&int_value, kint32max));
625           value = SimpleItoa(int_value);        // for error reporting
626           enum_value = enum_type->FindValueByNumber(int_value);
627         } else {
628           ReportError("Expected integer or identifier.");
629           return false;
630         }
631 
632         if (enum_value == NULL) {
633           ReportError("Unknown enumeration value of \"" + value  + "\" for "
634                       "field \"" + field->name() + "\".");
635           return false;
636         }
637 
638         SET_FIELD(Enum, enum_value);
639         break;
640       }
641 
642       case FieldDescriptor::CPPTYPE_MESSAGE: {
643         // We should never get here. Put here instead of a default
644         // so that if new types are added, we get a nice compiler warning.
645         GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE";
646         break;
647       }
648     }
649 #undef SET_FIELD
650     return true;
651   }
652 
SkipFieldValue()653   bool SkipFieldValue() {
654     if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
655       while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
656         tokenizer_.Next();
657       }
658       return true;
659     }
660     // Possible field values other than string:
661     //   12345        => TYPE_INTEGER
662     //   -12345       => TYPE_SYMBOL + TYPE_INTEGER
663     //   1.2345       => TYPE_FLOAT
664     //   -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
665     //   inf          => TYPE_IDENTIFIER
666     //   -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
667     //   TYPE_INTEGER => TYPE_IDENTIFIER
668     // Divides them into two group, one with TYPE_SYMBOL
669     // and the other without:
670     //   Group one:
671     //     12345        => TYPE_INTEGER
672     //     1.2345       => TYPE_FLOAT
673     //     inf          => TYPE_IDENTIFIER
674     //     TYPE_INTEGER => TYPE_IDENTIFIER
675     //   Group two:
676     //     -12345       => TYPE_SYMBOL + TYPE_INTEGER
677     //     -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
678     //     -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
679     // As we can see, the field value consists of an optional '-' and one of
680     // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
681     bool has_minus = TryConsume("-");
682     if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
683         !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
684         !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
685       return false;
686     }
687     // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
688     // value while other combinations all generate valid values.
689     // We check if the value of this combination is valid here.
690     // TYPE_IDENTIFIER after a '-' should be one of the float values listed
691     // below:
692     //   inf, inff, infinity, nan
693     if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
694       string text = tokenizer_.current().text;
695       LowerString(&text);
696       if (text != "inf" &&
697           text != "infinity" &&
698           text != "nan") {
699         ReportError("Invalid float number: " + text);
700         return false;
701       }
702     }
703     tokenizer_.Next();
704     return true;
705   }
706 
707   // Returns true if the current token's text is equal to that specified.
LookingAt(const string & text)708   bool LookingAt(const string& text) {
709     return tokenizer_.current().text == text;
710   }
711 
712   // Returns true if the current token's type is equal to that specified.
LookingAtType(io::Tokenizer::TokenType token_type)713   bool LookingAtType(io::Tokenizer::TokenType token_type) {
714     return tokenizer_.current().type == token_type;
715   }
716 
717   // Consumes an identifier and saves its value in the identifier parameter.
718   // Returns false if the token is not of type IDENTFIER.
ConsumeIdentifier(string * identifier)719   bool ConsumeIdentifier(string* identifier) {
720     if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
721       ReportError("Expected identifier.");
722       return false;
723     }
724 
725     *identifier = tokenizer_.current().text;
726 
727     tokenizer_.Next();
728     return true;
729   }
730 
731   // Consumes a string and saves its value in the text parameter.
732   // Returns false if the token is not of type STRING.
ConsumeString(string * text)733   bool ConsumeString(string* text) {
734     if (!LookingAtType(io::Tokenizer::TYPE_STRING)) {
735       ReportError("Expected string.");
736       return false;
737     }
738 
739     text->clear();
740     while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
741       io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text);
742 
743       tokenizer_.Next();
744     }
745 
746     return true;
747   }
748 
749   // Consumes a uint64 and saves its value in the value parameter.
750   // Returns false if the token is not of type INTEGER.
ConsumeUnsignedInteger(uint64 * value,uint64 max_value)751   bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) {
752     if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
753       ReportError("Expected integer.");
754       return false;
755     }
756 
757     if (!io::Tokenizer::ParseInteger(tokenizer_.current().text,
758                                      max_value, value)) {
759       ReportError("Integer out of range.");
760       return false;
761     }
762 
763     tokenizer_.Next();
764     return true;
765   }
766 
767   // Consumes an int64 and saves its value in the value parameter.
768   // Note that since the tokenizer does not support negative numbers,
769   // we actually may consume an additional token (for the minus sign) in this
770   // method. Returns false if the token is not an integer
771   // (signed or otherwise).
ConsumeSignedInteger(int64 * value,uint64 max_value)772   bool ConsumeSignedInteger(int64* value, uint64 max_value) {
773     bool negative = false;
774 
775     if (TryConsume("-")) {
776       negative = true;
777       // Two's complement always allows one more negative integer than
778       // positive.
779       ++max_value;
780     }
781 
782     uint64 unsigned_value;
783 
784     DO(ConsumeUnsignedInteger(&unsigned_value, max_value));
785 
786     *value = static_cast<int64>(unsigned_value);
787 
788     if (negative) {
789       *value = -*value;
790     }
791 
792     return true;
793   }
794 
795   // Consumes a double and saves its value in the value parameter.
796   // Note that since the tokenizer does not support negative numbers,
797   // we actually may consume an additional token (for the minus sign) in this
798   // method. Returns false if the token is not a double
799   // (signed or otherwise).
ConsumeDouble(double * value)800   bool ConsumeDouble(double* value) {
801     bool negative = false;
802 
803     if (TryConsume("-")) {
804       negative = true;
805     }
806 
807     // A double can actually be an integer, according to the tokenizer.
808     // Therefore, we must check both cases here.
809     if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
810       // We have found an integer value for the double.
811       uint64 integer_value;
812       DO(ConsumeUnsignedInteger(&integer_value, kuint64max));
813 
814       *value = static_cast<double>(integer_value);
815     } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) {
816       // We have found a float value for the double.
817       *value = io::Tokenizer::ParseFloat(tokenizer_.current().text);
818 
819       // Mark the current token as consumed.
820       tokenizer_.Next();
821     } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
822       string text = tokenizer_.current().text;
823       LowerString(&text);
824       if (text == "inf" ||
825           text == "infinity") {
826         *value = std::numeric_limits<double>::infinity();
827         tokenizer_.Next();
828       } else if (text == "nan") {
829         *value = std::numeric_limits<double>::quiet_NaN();
830         tokenizer_.Next();
831       } else {
832         ReportError("Expected double.");
833         return false;
834       }
835     } else {
836       ReportError("Expected double.");
837       return false;
838     }
839 
840     if (negative) {
841       *value = -*value;
842     }
843 
844     return true;
845   }
846 
847   // Consumes a token and confirms that it matches that specified in the
848   // value parameter. Returns false if the token found does not match that
849   // which was specified.
Consume(const string & value)850   bool Consume(const string& value) {
851     const string& current_value = tokenizer_.current().text;
852 
853     if (current_value != value) {
854       ReportError("Expected \"" + value + "\", found \"" + current_value
855                   + "\".");
856       return false;
857     }
858 
859     tokenizer_.Next();
860 
861     return true;
862   }
863 
864   // Attempts to consume the supplied value. Returns false if a the
865   // token found does not match the value specified.
TryConsume(const string & value)866   bool TryConsume(const string& value) {
867     if (tokenizer_.current().text == value) {
868       tokenizer_.Next();
869       return true;
870     } else {
871       return false;
872     }
873   }
874 
875   // An internal instance of the Tokenizer's error collector, used to
876   // collect any base-level parse errors and feed them to the ParserImpl.
877   class ParserErrorCollector : public io::ErrorCollector {
878    public:
ParserErrorCollector(TextFormat::Parser::ParserImpl * parser)879     explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
880         parser_(parser) { }
881 
~ParserErrorCollector()882     virtual ~ParserErrorCollector() { };
883 
AddError(int line,int column,const string & message)884     virtual void AddError(int line, int column, const string& message) {
885       parser_->ReportError(line, column, message);
886     }
887 
AddWarning(int line,int column,const string & message)888     virtual void AddWarning(int line, int column, const string& message) {
889       parser_->ReportWarning(line, column, message);
890     }
891 
892    private:
893     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
894     TextFormat::Parser::ParserImpl* parser_;
895   };
896 
897   io::ErrorCollector* error_collector_;
898   TextFormat::Finder* finder_;
899   ParseInfoTree* parse_info_tree_;
900   ParserErrorCollector tokenizer_error_collector_;
901   io::Tokenizer tokenizer_;
902   const Descriptor* root_message_type_;
903   SingularOverwritePolicy singular_overwrite_policy_;
904   bool allow_unknown_field_;
905   bool had_errors_;
906 };
907 
908 #undef DO
909 
910 // ===========================================================================
911 // Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
912 // from the Printer found in //google/protobuf/io/printer.h
913 class TextFormat::Printer::TextGenerator {
914  public:
TextGenerator(io::ZeroCopyOutputStream * output,int initial_indent_level)915   explicit TextGenerator(io::ZeroCopyOutputStream* output,
916                          int initial_indent_level)
917     : output_(output),
918       buffer_(NULL),
919       buffer_size_(0),
920       at_start_of_line_(true),
921       failed_(false),
922       indent_(""),
923       initial_indent_level_(initial_indent_level) {
924     indent_.resize(initial_indent_level_ * 2, ' ');
925   }
926 
~TextGenerator()927   ~TextGenerator() {
928     // Only BackUp() if we're sure we've successfully called Next() at least
929     // once.
930     if (!failed_ && buffer_size_ > 0) {
931       output_->BackUp(buffer_size_);
932     }
933   }
934 
935   // Indent text by two spaces.  After calling Indent(), two spaces will be
936   // inserted at the beginning of each line of text.  Indent() may be called
937   // multiple times to produce deeper indents.
Indent()938   void Indent() {
939     indent_ += "  ";
940   }
941 
942   // Reduces the current indent level by two spaces, or crashes if the indent
943   // level is zero.
Outdent()944   void Outdent() {
945     if (indent_.empty() ||
946         indent_.size() < initial_indent_level_ * 2) {
947       GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent().";
948       return;
949     }
950 
951     indent_.resize(indent_.size() - 2);
952   }
953 
954   // Print text to the output stream.
Print(const string & str)955   void Print(const string& str) {
956     Print(str.data(), str.size());
957   }
958 
959   // Print text to the output stream.
Print(const char * text)960   void Print(const char* text) {
961     Print(text, strlen(text));
962   }
963 
964   // Print text to the output stream.
Print(const char * text,int size)965   void Print(const char* text, int size) {
966     int pos = 0;  // The number of bytes we've written so far.
967 
968     for (int i = 0; i < size; i++) {
969       if (text[i] == '\n') {
970         // Saw newline.  If there is more text, we may need to insert an indent
971         // here.  So, write what we have so far, including the '\n'.
972         Write(text + pos, i - pos + 1);
973         pos = i + 1;
974 
975         // Setting this true will cause the next Write() to insert an indent
976         // first.
977         at_start_of_line_ = true;
978       }
979     }
980 
981     // Write the rest.
982     Write(text + pos, size - pos);
983   }
984 
985   // True if any write to the underlying stream failed.  (We don't just
986   // crash in this case because this is an I/O failure, not a programming
987   // error.)
failed() const988   bool failed() const { return failed_; }
989 
990  private:
991   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
992 
Write(const char * data,int size)993   void Write(const char* data, int size) {
994     if (failed_) return;
995     if (size == 0) return;
996 
997     if (at_start_of_line_) {
998       // Insert an indent.
999       at_start_of_line_ = false;
1000       Write(indent_.data(), indent_.size());
1001       if (failed_) return;
1002     }
1003 
1004     while (size > buffer_size_) {
1005       // Data exceeds space in the buffer.  Copy what we can and request a
1006       // new buffer.
1007       memcpy(buffer_, data, buffer_size_);
1008       data += buffer_size_;
1009       size -= buffer_size_;
1010       void* void_buffer;
1011       failed_ = !output_->Next(&void_buffer, &buffer_size_);
1012       if (failed_) return;
1013       buffer_ = reinterpret_cast<char*>(void_buffer);
1014     }
1015 
1016     // Buffer is big enough to receive the data; copy it.
1017     memcpy(buffer_, data, size);
1018     buffer_ += size;
1019     buffer_size_ -= size;
1020   }
1021 
1022   io::ZeroCopyOutputStream* const output_;
1023   char* buffer_;
1024   int buffer_size_;
1025   bool at_start_of_line_;
1026   bool failed_;
1027 
1028   string indent_;
1029   int initial_indent_level_;
1030 };
1031 
1032 // ===========================================================================
1033 
~Finder()1034 TextFormat::Finder::~Finder() {
1035 }
1036 
Parser()1037 TextFormat::Parser::Parser()
1038   : error_collector_(NULL),
1039     finder_(NULL),
1040     parse_info_tree_(NULL),
1041     allow_partial_(false),
1042     allow_unknown_field_(false) {
1043 }
1044 
~Parser()1045 TextFormat::Parser::~Parser() {}
1046 
Parse(io::ZeroCopyInputStream * input,Message * output)1047 bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
1048                                Message* output) {
1049   output->Clear();
1050   ParserImpl parser(output->GetDescriptor(), input, error_collector_,
1051                     finder_, parse_info_tree_,
1052                     ParserImpl::FORBID_SINGULAR_OVERWRITES,
1053                     allow_unknown_field_);
1054   return MergeUsingImpl(input, output, &parser);
1055 }
1056 
ParseFromString(const string & input,Message * output)1057 bool TextFormat::Parser::ParseFromString(const string& input,
1058                                          Message* output) {
1059   io::ArrayInputStream input_stream(input.data(), input.size());
1060   return Parse(&input_stream, output);
1061 }
1062 
Merge(io::ZeroCopyInputStream * input,Message * output)1063 bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
1064                                Message* output) {
1065   ParserImpl parser(output->GetDescriptor(), input, error_collector_,
1066                     finder_, parse_info_tree_,
1067                     ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1068                     allow_unknown_field_);
1069   return MergeUsingImpl(input, output, &parser);
1070 }
1071 
MergeFromString(const string & input,Message * output)1072 bool TextFormat::Parser::MergeFromString(const string& input,
1073                                          Message* output) {
1074   io::ArrayInputStream input_stream(input.data(), input.size());
1075   return Merge(&input_stream, output);
1076 }
1077 
MergeUsingImpl(io::ZeroCopyInputStream * input,Message * output,ParserImpl * parser_impl)1078 bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input,
1079                                         Message* output,
1080                                         ParserImpl* parser_impl) {
1081   if (!parser_impl->Parse(output)) return false;
1082   if (!allow_partial_ && !output->IsInitialized()) {
1083     vector<string> missing_fields;
1084     output->FindInitializationErrors(&missing_fields);
1085     parser_impl->ReportError(-1, 0, "Message missing required fields: " +
1086                                     JoinStrings(missing_fields, ", "));
1087     return false;
1088   }
1089   return true;
1090 }
1091 
ParseFieldValueFromString(const string & input,const FieldDescriptor * field,Message * output)1092 bool TextFormat::Parser::ParseFieldValueFromString(
1093     const string& input,
1094     const FieldDescriptor* field,
1095     Message* output) {
1096   io::ArrayInputStream input_stream(input.data(), input.size());
1097   ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
1098                     finder_, parse_info_tree_,
1099                     ParserImpl::ALLOW_SINGULAR_OVERWRITES,
1100                     allow_unknown_field_);
1101   return parser.ParseField(field, output);
1102 }
1103 
Parse(io::ZeroCopyInputStream * input,Message * output)1104 /* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1105                                     Message* output) {
1106   return Parser().Parse(input, output);
1107 }
1108 
Merge(io::ZeroCopyInputStream * input,Message * output)1109 /* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1110                                     Message* output) {
1111   return Parser().Merge(input, output);
1112 }
1113 
ParseFromString(const string & input,Message * output)1114 /* static */ bool TextFormat::ParseFromString(const string& input,
1115                                               Message* output) {
1116   return Parser().ParseFromString(input, output);
1117 }
1118 
MergeFromString(const string & input,Message * output)1119 /* static */ bool TextFormat::MergeFromString(const string& input,
1120                                               Message* output) {
1121   return Parser().MergeFromString(input, output);
1122 }
1123 
1124 // ===========================================================================
1125 
Printer()1126 TextFormat::Printer::Printer()
1127   : initial_indent_level_(0),
1128     single_line_mode_(false),
1129     use_short_repeated_primitives_(false),
1130     utf8_string_escaping_(false) {}
1131 
~Printer()1132 TextFormat::Printer::~Printer() {}
1133 
PrintToString(const Message & message,string * output) const1134 bool TextFormat::Printer::PrintToString(const Message& message,
1135                                         string* output) const {
1136   GOOGLE_DCHECK(output) << "output specified is NULL";
1137 
1138   output->clear();
1139   io::StringOutputStream output_stream(output);
1140 
1141   bool result = Print(message, &output_stream);
1142 
1143   return result;
1144 }
1145 
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,string * output) const1146 bool TextFormat::Printer::PrintUnknownFieldsToString(
1147     const UnknownFieldSet& unknown_fields,
1148     string* output) const {
1149   GOOGLE_DCHECK(output) << "output specified is NULL";
1150 
1151   output->clear();
1152   io::StringOutputStream output_stream(output);
1153   return PrintUnknownFields(unknown_fields, &output_stream);
1154 }
1155 
Print(const Message & message,io::ZeroCopyOutputStream * output) const1156 bool TextFormat::Printer::Print(const Message& message,
1157                                 io::ZeroCopyOutputStream* output) const {
1158   TextGenerator generator(output, initial_indent_level_);
1159 
1160   Print(message, generator);
1161 
1162   // Output false if the generator failed internally.
1163   return !generator.failed();
1164 }
1165 
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output) const1166 bool TextFormat::Printer::PrintUnknownFields(
1167     const UnknownFieldSet& unknown_fields,
1168     io::ZeroCopyOutputStream* output) const {
1169   TextGenerator generator(output, initial_indent_level_);
1170 
1171   PrintUnknownFields(unknown_fields, generator);
1172 
1173   // Output false if the generator failed internally.
1174   return !generator.failed();
1175 }
1176 
Print(const Message & message,TextGenerator & generator) const1177 void TextFormat::Printer::Print(const Message& message,
1178                                 TextGenerator& generator) const {
1179   const Reflection* reflection = message.GetReflection();
1180   vector<const FieldDescriptor*> fields;
1181   reflection->ListFields(message, &fields);
1182   for (int i = 0; i < fields.size(); i++) {
1183     PrintField(message, reflection, fields[i], generator);
1184   }
1185   PrintUnknownFields(reflection->GetUnknownFields(message), generator);
1186 }
1187 
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,string * output) const1188 void TextFormat::Printer::PrintFieldValueToString(
1189     const Message& message,
1190     const FieldDescriptor* field,
1191     int index,
1192     string* output) const {
1193 
1194   GOOGLE_DCHECK(output) << "output specified is NULL";
1195 
1196   output->clear();
1197   io::StringOutputStream output_stream(output);
1198   TextGenerator generator(&output_stream, initial_indent_level_);
1199 
1200   PrintFieldValue(message, message.GetReflection(), field, index, generator);
1201 }
1202 
PrintField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1203 void TextFormat::Printer::PrintField(const Message& message,
1204                                      const Reflection* reflection,
1205                                      const FieldDescriptor* field,
1206                                      TextGenerator& generator) const {
1207   if (use_short_repeated_primitives_ &&
1208       field->is_repeated() &&
1209       field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
1210       field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
1211     PrintShortRepeatedField(message, reflection, field, generator);
1212     return;
1213   }
1214 
1215   int count = 0;
1216 
1217   if (field->is_repeated()) {
1218     count = reflection->FieldSize(message, field);
1219   } else if (reflection->HasField(message, field)) {
1220     count = 1;
1221   }
1222 
1223   for (int j = 0; j < count; ++j) {
1224     PrintFieldName(message, reflection, field, generator);
1225 
1226     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1227       if (single_line_mode_) {
1228         generator.Print(" { ");
1229       } else {
1230         generator.Print(" {\n");
1231         generator.Indent();
1232       }
1233     } else {
1234       generator.Print(": ");
1235     }
1236 
1237     // Write the field value.
1238     int field_index = j;
1239     if (!field->is_repeated()) {
1240       field_index = -1;
1241     }
1242 
1243     PrintFieldValue(message, reflection, field, field_index, generator);
1244 
1245     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
1246       if (single_line_mode_) {
1247         generator.Print("} ");
1248       } else {
1249         generator.Outdent();
1250         generator.Print("}\n");
1251       }
1252     } else {
1253       if (single_line_mode_) {
1254         generator.Print(" ");
1255       } else {
1256         generator.Print("\n");
1257       }
1258     }
1259   }
1260 }
1261 
PrintShortRepeatedField(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1262 void TextFormat::Printer::PrintShortRepeatedField(
1263     const Message& message,
1264     const Reflection* reflection,
1265     const FieldDescriptor* field,
1266     TextGenerator& generator) const {
1267   // Print primitive repeated field in short form.
1268   PrintFieldName(message, reflection, field, generator);
1269 
1270   int size = reflection->FieldSize(message, field);
1271   generator.Print(": [");
1272   for (int i = 0; i < size; i++) {
1273     if (i > 0) generator.Print(", ");
1274     PrintFieldValue(message, reflection, field, i, generator);
1275   }
1276   if (single_line_mode_) {
1277     generator.Print("] ");
1278   } else {
1279     generator.Print("]\n");
1280   }
1281 }
1282 
PrintFieldName(const Message & message,const Reflection * reflection,const FieldDescriptor * field,TextGenerator & generator) const1283 void TextFormat::Printer::PrintFieldName(const Message& message,
1284                                          const Reflection* reflection,
1285                                          const FieldDescriptor* field,
1286                                          TextGenerator& generator) const {
1287   if (field->is_extension()) {
1288     generator.Print("[");
1289     // We special-case MessageSet elements for compatibility with proto1.
1290     if (field->containing_type()->options().message_set_wire_format()
1291         && field->type() == FieldDescriptor::TYPE_MESSAGE
1292         && field->is_optional()
1293         && field->extension_scope() == field->message_type()) {
1294       generator.Print(field->message_type()->full_name());
1295     } else {
1296       generator.Print(field->full_name());
1297     }
1298     generator.Print("]");
1299   } else {
1300     if (field->type() == FieldDescriptor::TYPE_GROUP) {
1301       // Groups must be serialized with their original capitalization.
1302       generator.Print(field->message_type()->name());
1303     } else {
1304       generator.Print(field->name());
1305     }
1306   }
1307 }
1308 
PrintFieldValue(const Message & message,const Reflection * reflection,const FieldDescriptor * field,int index,TextGenerator & generator) const1309 void TextFormat::Printer::PrintFieldValue(
1310     const Message& message,
1311     const Reflection* reflection,
1312     const FieldDescriptor* field,
1313     int index,
1314     TextGenerator& generator) const {
1315   GOOGLE_DCHECK(field->is_repeated() || (index == -1))
1316       << "Index must be -1 for non-repeated fields";
1317 
1318   switch (field->cpp_type()) {
1319 #define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING)                             \
1320       case FieldDescriptor::CPPTYPE_##CPPTYPE:                               \
1321         generator.Print(TO_STRING(field->is_repeated() ?                     \
1322           reflection->GetRepeated##METHOD(message, field, index) :           \
1323           reflection->Get##METHOD(message, field)));                         \
1324         break;                                                               \
1325 
1326       OUTPUT_FIELD( INT32,  Int32, SimpleItoa);
1327       OUTPUT_FIELD( INT64,  Int64, SimpleItoa);
1328       OUTPUT_FIELD(UINT32, UInt32, SimpleItoa);
1329       OUTPUT_FIELD(UINT64, UInt64, SimpleItoa);
1330       OUTPUT_FIELD( FLOAT,  Float, SimpleFtoa);
1331       OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa);
1332 #undef OUTPUT_FIELD
1333 
1334       case FieldDescriptor::CPPTYPE_STRING: {
1335         string scratch;
1336         const string& value = field->is_repeated() ?
1337             reflection->GetRepeatedStringReference(
1338               message, field, index, &scratch) :
1339             reflection->GetStringReference(message, field, &scratch);
1340 
1341         generator.Print("\"");
1342         if (utf8_string_escaping_) {
1343           generator.Print(strings::Utf8SafeCEscape(value));
1344         } else {
1345           generator.Print(CEscape(value));
1346         }
1347         generator.Print("\"");
1348 
1349         break;
1350       }
1351 
1352       case FieldDescriptor::CPPTYPE_BOOL:
1353         if (field->is_repeated()) {
1354           generator.Print(reflection->GetRepeatedBool(message, field, index)
1355                           ? "true" : "false");
1356         } else {
1357           generator.Print(reflection->GetBool(message, field)
1358                           ? "true" : "false");
1359         }
1360         break;
1361 
1362       case FieldDescriptor::CPPTYPE_ENUM:
1363         generator.Print(field->is_repeated() ?
1364           reflection->GetRepeatedEnum(message, field, index)->name() :
1365           reflection->GetEnum(message, field)->name());
1366         break;
1367 
1368       case FieldDescriptor::CPPTYPE_MESSAGE:
1369         Print(field->is_repeated() ?
1370                 reflection->GetRepeatedMessage(message, field, index) :
1371                 reflection->GetMessage(message, field),
1372               generator);
1373         break;
1374   }
1375 }
1376 
Print(const Message & message,io::ZeroCopyOutputStream * output)1377 /* static */ bool TextFormat::Print(const Message& message,
1378                                     io::ZeroCopyOutputStream* output) {
1379   return Printer().Print(message, output);
1380 }
1381 
PrintUnknownFields(const UnknownFieldSet & unknown_fields,io::ZeroCopyOutputStream * output)1382 /* static */ bool TextFormat::PrintUnknownFields(
1383     const UnknownFieldSet& unknown_fields,
1384     io::ZeroCopyOutputStream* output) {
1385   return Printer().PrintUnknownFields(unknown_fields, output);
1386 }
1387 
PrintToString(const Message & message,string * output)1388 /* static */ bool TextFormat::PrintToString(
1389     const Message& message, string* output) {
1390   return Printer().PrintToString(message, output);
1391 }
1392 
PrintUnknownFieldsToString(const UnknownFieldSet & unknown_fields,string * output)1393 /* static */ bool TextFormat::PrintUnknownFieldsToString(
1394     const UnknownFieldSet& unknown_fields, string* output) {
1395   return Printer().PrintUnknownFieldsToString(unknown_fields, output);
1396 }
1397 
PrintFieldValueToString(const Message & message,const FieldDescriptor * field,int index,string * output)1398 /* static */ void TextFormat::PrintFieldValueToString(
1399     const Message& message,
1400     const FieldDescriptor* field,
1401     int index,
1402     string* output) {
1403   return Printer().PrintFieldValueToString(message, field, index, output);
1404 }
1405 
ParseFieldValueFromString(const string & input,const FieldDescriptor * field,Message * message)1406 /* static */ bool TextFormat::ParseFieldValueFromString(
1407     const string& input,
1408     const FieldDescriptor* field,
1409     Message* message) {
1410   return Parser().ParseFieldValueFromString(input, field, message);
1411 }
1412 
1413 // Prints an integer as hex with a fixed number of digits dependent on the
1414 // integer type.
1415 template<typename IntType>
PaddedHex(IntType value)1416 static string PaddedHex(IntType value) {
1417   string result;
1418   result.reserve(sizeof(value) * 2);
1419   for (int i = sizeof(value) * 2 - 1; i >= 0; i--) {
1420     result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F));
1421   }
1422   return result;
1423 }
1424 
PrintUnknownFields(const UnknownFieldSet & unknown_fields,TextGenerator & generator) const1425 void TextFormat::Printer::PrintUnknownFields(
1426     const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
1427   for (int i = 0; i < unknown_fields.field_count(); i++) {
1428     const UnknownField& field = unknown_fields.field(i);
1429     string field_number = SimpleItoa(field.number());
1430 
1431     switch (field.type()) {
1432       case UnknownField::TYPE_VARINT:
1433         generator.Print(field_number);
1434         generator.Print(": ");
1435         generator.Print(SimpleItoa(field.varint()));
1436         if (single_line_mode_) {
1437           generator.Print(" ");
1438         } else {
1439           generator.Print("\n");
1440         }
1441         break;
1442       case UnknownField::TYPE_FIXED32: {
1443         generator.Print(field_number);
1444         generator.Print(": 0x");
1445         char buffer[kFastToBufferSize];
1446         generator.Print(FastHex32ToBuffer(field.fixed32(), buffer));
1447         if (single_line_mode_) {
1448           generator.Print(" ");
1449         } else {
1450           generator.Print("\n");
1451         }
1452         break;
1453       }
1454       case UnknownField::TYPE_FIXED64: {
1455         generator.Print(field_number);
1456         generator.Print(": 0x");
1457         char buffer[kFastToBufferSize];
1458         generator.Print(FastHex64ToBuffer(field.fixed64(), buffer));
1459         if (single_line_mode_) {
1460           generator.Print(" ");
1461         } else {
1462           generator.Print("\n");
1463         }
1464         break;
1465       }
1466       case UnknownField::TYPE_LENGTH_DELIMITED: {
1467         generator.Print(field_number);
1468         const string& value = field.length_delimited();
1469         UnknownFieldSet embedded_unknown_fields;
1470         if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
1471           // This field is parseable as a Message.
1472           // So it is probably an embedded message.
1473           if (single_line_mode_) {
1474             generator.Print(" { ");
1475           } else {
1476             generator.Print(" {\n");
1477             generator.Indent();
1478           }
1479           PrintUnknownFields(embedded_unknown_fields, generator);
1480           if (single_line_mode_) {
1481             generator.Print("} ");
1482           } else {
1483             generator.Outdent();
1484             generator.Print("}\n");
1485           }
1486         } else {
1487           // This field is not parseable as a Message.
1488           // So it is probably just a plain string.
1489           generator.Print(": \"");
1490           generator.Print(CEscape(value));
1491           generator.Print("\"");
1492           if (single_line_mode_) {
1493             generator.Print(" ");
1494           } else {
1495             generator.Print("\n");
1496           }
1497         }
1498         break;
1499       }
1500       case UnknownField::TYPE_GROUP:
1501         generator.Print(field_number);
1502         if (single_line_mode_) {
1503           generator.Print(" { ");
1504         } else {
1505           generator.Print(" {\n");
1506           generator.Indent();
1507         }
1508         PrintUnknownFields(field.group(), generator);
1509         if (single_line_mode_) {
1510           generator.Print("} ");
1511         } else {
1512           generator.Outdent();
1513           generator.Print("}\n");
1514         }
1515         break;
1516     }
1517   }
1518 }
1519 
1520 }  // namespace protobuf
1521 }  // namespace google
1522