Home | History | Annotate | Download | only in protobuf
      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 (at) 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 
     58 string Message::DebugString() const {
     59   string debug_string;
     60 
     61   TextFormat::PrintToString(*this, &debug_string);
     62 
     63   return debug_string;
     64 }
     65 
     66 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 
     82 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 
     93 void Message::PrintDebugString() const {
     94   printf("%s", DebugString().c_str());
     95 }
     96 
     97 
     98 // ===========================================================================
     99 // Implementation of the parse information tree class.
    100 TextFormat::ParseInfoTree::ParseInfoTree() { }
    101 
    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 
    109 void TextFormat::ParseInfoTree::RecordLocation(
    110     const FieldDescriptor* field,
    111     TextFormat::ParseLocation location) {
    112   locations_[field].push_back(location);
    113 }
    114 
    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 
    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 
    137 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 
    151 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 
    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
    913 class 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 
   1034 TextFormat::Finder::~Finder() {
   1035 }
   1036 
   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 
   1045 TextFormat::Parser::~Parser() {}
   1046 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1132 TextFormat::Printer::~Printer() {}
   1133 
   1134 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 
   1146 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 
   1156 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 
   1166 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 
   1177 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 
   1188 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 
   1203 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 
   1262 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 
   1283 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 
   1309 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 
   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.
   1415 template<typename IntType>
   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 
   1425 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