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
55namespace google {
56namespace protobuf {
57
58string Message::DebugString() const {
59  string debug_string;
60
61  TextFormat::PrintToString(*this, &debug_string);
62
63  return debug_string;
64}
65
66string 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
82string 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
93void Message::PrintDebugString() const {
94  printf("%s", DebugString().c_str());
95}
96
97
98// ===========================================================================
99// Implementation of the parse information tree class.
100TextFormat::ParseInfoTree::ParseInfoTree() { }
101
102TextFormat::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
109void TextFormat::ParseInfoTree::RecordLocation(
110    const FieldDescriptor* field,
111    TextFormat::ParseLocation location) {
112  locations_[field].push_back(location);
113}
114
115TextFormat::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
125void 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
137TextFormat::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
151TextFormat::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
177class 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
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  }
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)).
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
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
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
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).
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).
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.
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.
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.
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
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.
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
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
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.
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.
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.
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.
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.
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).
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).
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.
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.
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:
879    explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) :
880        parser_(parser) { }
881
882    virtual ~ParserErrorCollector() { };
883
884    virtual void AddError(int line, int column, const string& message) {
885      parser_->ReportError(line, column, message);
886    }
887
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
913class TextFormat::Printer::TextGenerator {
914 public:
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
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.
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.
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.
955  void Print(const string& str) {
956    Print(str.data(), str.size());
957  }
958
959  // Print text to the output stream.
960  void Print(const char* text) {
961    Print(text, strlen(text));
962  }
963
964  // Print text to the output stream.
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.)
988  bool failed() const { return failed_; }
989
990 private:
991  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator);
992
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
1034TextFormat::Finder::~Finder() {
1035}
1036
1037TextFormat::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
1045TextFormat::Parser::~Parser() {}
1046
1047bool 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
1057bool 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
1063bool 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
1072bool 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
1078bool 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
1092bool 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
1104/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input,
1105                                    Message* output) {
1106  return Parser().Parse(input, output);
1107}
1108
1109/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input,
1110                                    Message* output) {
1111  return Parser().Merge(input, output);
1112}
1113
1114/* static */ bool TextFormat::ParseFromString(const string& input,
1115                                              Message* output) {
1116  return Parser().ParseFromString(input, output);
1117}
1118
1119/* static */ bool TextFormat::MergeFromString(const string& input,
1120                                              Message* output) {
1121  return Parser().MergeFromString(input, output);
1122}
1123
1124// ===========================================================================
1125
1126TextFormat::Printer::Printer()
1127  : initial_indent_level_(0),
1128    single_line_mode_(false),
1129    use_short_repeated_primitives_(false),
1130    utf8_string_escaping_(false) {}
1131
1132TextFormat::Printer::~Printer() {}
1133
1134bool 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
1146bool 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
1156bool 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
1166bool 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
1177void 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
1188void 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
1203void 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
1262void 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
1283void 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
1309void 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
1377/* static */ bool TextFormat::Print(const Message& message,
1378                                    io::ZeroCopyOutputStream* output) {
1379  return Printer().Print(message, output);
1380}
1381
1382/* static */ bool TextFormat::PrintUnknownFields(
1383    const UnknownFieldSet& unknown_fields,
1384    io::ZeroCopyOutputStream* output) {
1385  return Printer().PrintUnknownFields(unknown_fields, output);
1386}
1387
1388/* static */ bool TextFormat::PrintToString(
1389    const Message& message, string* output) {
1390  return Printer().PrintToString(message, output);
1391}
1392
1393/* static */ bool TextFormat::PrintUnknownFieldsToString(
1394    const UnknownFieldSet& unknown_fields, string* output) {
1395  return Printer().PrintUnknownFieldsToString(unknown_fields, output);
1396}
1397
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
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.
1415template<typename IntType>
1416static 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
1425void 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