1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: jschorr@google.com (Joseph Schorr) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <float.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <math.h> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stdio.h> 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stack> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <limits> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/text_format.h> 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h> 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream.h> 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h> 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/unknown_field_set.h> 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h> 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/tokenizer.h> 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Message::DebugString() const { 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string debug_string; 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TextFormat::PrintToString(*this, &debug_string); 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return debug_string; 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Message::ShortDebugString() const { 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string debug_string; 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextFormat::Printer printer; 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printer.SetSingleLineMode(true); 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 69d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville printer.PrintToString(*this, &debug_string); 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Single line mode currently might have an extra space at the end. 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (debug_string.size() > 0 && 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville debug_string[debug_string.size() - 1] == ' ') { 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville debug_string.resize(debug_string.size() - 1); 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return debug_string; 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 79d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillestring Message::Utf8DebugString() const { 80d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville string debug_string; 81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 82d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TextFormat::Printer printer; 83d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville printer.SetUseUtf8StringEscaping(true); 84d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 85d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville printer.PrintToString(*this, &debug_string); 86d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 87d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return debug_string; 88d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Message::PrintDebugString() const { 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville printf("%s", DebugString().c_str()); 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 94d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =========================================================================== 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Internal class for parsing an ASCII representation of a Protocol Message. 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This class makes use of the Protocol Message compiler's tokenizer found 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in //google/protobuf/io/tokenizer.h. Note that class's Parse 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// method is *not* thread-safe and should only be used in a single thread at 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// a time. 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Makes code slightly more readable. The meaning of "DO(foo)" is 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "Execute foo and fail if it fails.", where failure is indicated by 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// returning false. Borrowed from parser.cc (Thanks Kenton!). 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define DO(STATEMENT) if (STATEMENT) {} else return false 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass TextFormat::Parser::ParserImpl { 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Determines if repeated values for a non-repeated field are 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // permitted, e.g., the string "foo: 1 foo: 2" for a 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // required/optional field named "foo". 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum SingularOverwritePolicy { 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FORBID_SINGULAR_OVERWRITES = 1, // an error is issued 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl(const Descriptor* root_message_type, 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyInputStream* input_stream, 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ErrorCollector* error_collector, 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SingularOverwritePolicy singular_overwrite_policy) 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : error_collector_(error_collector), 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_error_collector_(this), 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_(input_stream, &tokenizer_error_collector_), 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville root_message_type_(root_message_type), 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville singular_overwrite_policy_(singular_overwrite_policy), 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville had_errors_(false) { 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // For backwards-compatibility with proto1, we need to allow the 'f' suffix 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // for floats. 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.set_allow_f_after_float(true); 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // '#' starts a comment. 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consume the starting token. 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~ParserImpl() { } 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Parses the ASCII representation specified in input and saves the 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // information into the output pointer (a Message). Returns 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // false if an error occurs (an error will also be logged to 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // GOOGLE_LOG(ERROR)). 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool Parse(Message* output) { 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consume fields until we cannot do so anymore. 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while(true) { 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (LookingAtType(io::Tokenizer::TYPE_END)) { 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !had_errors_; 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeField(output)); 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ParseField(const FieldDescriptor* field, Message* output) { 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool suc; 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville suc = ConsumeFieldMessage(output, output->GetReflection(), field); 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville suc = ConsumeFieldValue(output, output->GetReflection(), field); 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return suc && LookingAtType(io::Tokenizer::TYPE_END); 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ReportError(int line, int col, const string& message) { 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville had_errors_ = true; 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (error_collector_ == NULL) { 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (line >= 0) { 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << "Error parsing text-format " 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << root_message_type_->full_name() 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << ": " << (line + 1) << ":" 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << (col + 1) << ": " << message; 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << "Error parsing text-format " 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << root_message_type_->full_name() 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << ": " << message; 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector_->AddError(line, col, message); 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 183d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void ReportWarning(int line, int col, const string& message) { 184d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (error_collector_ == NULL) { 185d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (line >= 0) { 186d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_LOG(WARNING) << "Warning parsing text-format " 187d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << root_message_type_->full_name() 188d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << ": " << (line + 1) << ":" 189d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << (col + 1) << ": " << message; 190d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 191d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville GOOGLE_LOG(WARNING) << "Warning parsing text-format " 192d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << root_message_type_->full_name() 193d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville << ": " << message; 194d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 195d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 196d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville error_collector_->AddWarning(line, col, message); 197d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 198d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 199d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Reports an error with the given message with information indicating 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the position (as derived from the current token). 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ReportError(const string& message) { 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError(tokenizer_.current().line, tokenizer_.current().column, 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message); 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 210d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Reports a warning with the given message with information indicating 211d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // the position (as derived from the current token). 212d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void ReportWarning(const string& message) { 213d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ReportWarning(tokenizer_.current().line, tokenizer_.current().column, 214d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville message); 215d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 216d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes the specified message with the given starting delimeter. 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This method checks to see that the end delimeter at the conclusion of 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the consumption matches the starting delimeter passed in here. 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeMessage(Message* message, const string delimeter) { 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (!LookingAt(">") && !LookingAt("}")) { 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeField(message)); 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Confirm that we have a valid ending delimeter. 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(Consume(delimeter)); 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes the current field (as returned by the tokenizer) on the 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // passed in message. 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeField(Message* message) { 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = message->GetReflection(); 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* descriptor = message->GetDescriptor(); 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string field_name; 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = NULL; 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryConsume("[")) { 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Extension. 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeIdentifier(&field_name)); 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (TryConsume(".")) { 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string part; 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeIdentifier(&part)); 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_name += "."; 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_name += part; 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(Consume("]")); 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = reflection->FindKnownExtensionByName(field_name); 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field == NULL) { 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Extension \"" + field_name + "\" is not defined or " 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "is not an extension of \"" + 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor->full_name() + "\"."); 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeIdentifier(&field_name)); 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = descriptor->FindFieldByName(field_name); 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Group names are expected to be capitalized as they appear in the 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // .proto file, which actually matches their type names, not their field 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // names. 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field == NULL) { 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string lower_field_name = field_name; 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LowerString(&lower_field_name); 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = descriptor->FindFieldByName(lower_field_name); 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the case-insensitive match worked but the field is NOT a group, 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = NULL; 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Again, special-case group names as described above. 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville && field->message_type()->name() != field_name) { 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = NULL; 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field == NULL) { 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Message type \"" + descriptor->full_name() + 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" has no field named \"" + field_name + "\"."); 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fail if the field is not repeated and it has already been specified. 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) && 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville !field->is_repeated() && reflection->HasField(*message, field)) { 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Non-repeated field \"" + field_name + 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" is specified multiple times."); 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Perform special handling for embedded message types. 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ':' is optional here. 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TryConsume(":"); 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeFieldMessage(message, reflection, field)); 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(Consume(":")); 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeFieldValue(message, reflection, field)); 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 307d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (field->options().deprecated()) { 308d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville ReportWarning("text format contains deprecated field \"" 309d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville + field_name + "\""); 310d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 311d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeFieldMessage(Message* message, 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection, 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field) { 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string delimeter; 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryConsume("<")) { 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delimeter = ">"; 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(Consume("{")); 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delimeter = "}"; 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeMessage(reflection->MutableMessage(message, field), 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delimeter)); 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeFieldValue(Message* message, 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection, 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field) { 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Define an easy to use macro for setting fields. This macro checks 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to see if the field is repeated (in which case we need to use the Add 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// methods or not (in which case we need to use the Set methods). 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define SET_FIELD(CPPTYPE, VALUE) \ 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { \ 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->Add##CPPTYPE(message, field, VALUE); \ 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { \ 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->Set##CPPTYPE(message, field, VALUE); \ 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } \ 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch(field->cpp_type()) { 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT32: { 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int64 value; 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeSignedInteger(&value, kint32max)); 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Int32, static_cast<int32>(value)); 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT32: { 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 value; 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeUnsignedInteger(&value, kuint32max)); 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(UInt32, static_cast<uint32>(value)); 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT64: { 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int64 value; 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeSignedInteger(&value, kint64max)); 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Int64, value); 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT64: { 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 value; 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeUnsignedInteger(&value, kuint64max)); 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(UInt64, value); 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_FLOAT: { 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville double value; 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeDouble(&value)); 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Float, static_cast<float>(value)); 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_DOUBLE: { 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville double value; 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeDouble(&value)); 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Double, value); 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_STRING: { 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string value; 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeString(&value)); 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(String, value); 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_BOOL: { 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string value; 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeIdentifier(&value)); 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (value == "true") { 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Bool, true); 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (value == "false") { 406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Bool, false); 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Invalid value for boolean field \"" + field->name() 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville + "\". Value: \"" + value + "\"."); 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_ENUM: { 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string value; 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeIdentifier(&value)); 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find the enumeration value. 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* enum_type = field->enum_type(); 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* enum_value 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville = enum_type->FindValueByName(value); 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (enum_value == NULL) { 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Unknown enumeration value of \"" + value + "\" for " 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "field \"" + field->name() + "\"."); 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SET_FIELD(Enum, enum_value); 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: { 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We should never get here. Put here instead of a default 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // so that if new types are added, we get a nice compiler warning. 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef SET_FIELD 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Returns true if the current token's text is equal to that specified. 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool LookingAt(const string& text) { 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return tokenizer_.current().text == text; 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Returns true if the current token's type is equal to that specified. 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool LookingAtType(io::Tokenizer::TokenType token_type) { 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return tokenizer_.current().type == token_type; 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes an identifier and saves its value in the identifier parameter. 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Returns false if the token is not of type IDENTFIER. 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeIdentifier(string* identifier) { 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Expected identifier."); 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *identifier = tokenizer_.current().text; 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes a string and saves its value in the text parameter. 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Returns false if the token is not of type STRING. 471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeString(string* text) { 472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Expected string."); 474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville text->clear(); 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (LookingAtType(io::Tokenizer::TYPE_STRING)) { 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes a uint64 and saves its value in the value parameter. 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Returns false if the token is not of type INTEGER. 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Expected integer."); 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, 496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville max_value, value)) { 497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Integer out of range."); 498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes an int64 and saves its value in the value parameter. 506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that since the tokenizer does not support negative numbers, 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we actually may consume an additional token (for the minus sign) in this 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // method. Returns false if the token is not an integer 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // (signed or otherwise). 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeSignedInteger(int64* value, uint64 max_value) { 511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool negative = false; 512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryConsume("-")) { 514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville negative = true; 515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Two's complement always allows one more negative integer than 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // positive. 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++max_value; 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 unsigned_value; 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = static_cast<int64>(unsigned_value); 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (negative) { 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = -*value; 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes a double and saves its value in the value parameter. 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that since the tokenizer does not support negative numbers, 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we actually may consume an additional token (for the minus sign) in this 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // method. Returns false if the token is not a double 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // (signed or otherwise). 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ConsumeDouble(double* value) { 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool negative = false; 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryConsume("-")) { 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville negative = true; 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A double can actually be an integer, according to the tokenizer. 546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Therefore, we must check both cases here. 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We have found an integer value for the double. 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 integer_value; 550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DO(ConsumeUnsignedInteger(&integer_value, kuint64max)); 551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = static_cast<double>(integer_value); 553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { 554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We have found a float value for the double. 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); 556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Mark the current token as consumed. 558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string text = tokenizer_.current().text; 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LowerString(&text); 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (text == "inf" || text == "infinity") { 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = std::numeric_limits<double>::infinity(); 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (text == "nan") { 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = std::numeric_limits<double>::quiet_NaN(); 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Expected double."); 570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Expected double."); 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (negative) { 578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *value = -*value; 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Consumes a token and confirms that it matches that specified in the 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // value parameter. Returns false if the token found does not match that 586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // which was specified. 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool Consume(const string& value) { 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& current_value = tokenizer_.current().text; 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (current_value != value) { 591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReportError("Expected \"" + value + "\", found \"" + current_value 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville + "\"."); 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Attempts to consume the supplied value. Returns false if a the 602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // token found does not match the value specified. 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool TryConsume(const string& value) { 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tokenizer_.current().text == value) { 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tokenizer_.Next(); 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // An internal instance of the Tokenizer's error collector, used to 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // collect any base-level parse errors and feed them to the ParserImpl. 614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville class ParserErrorCollector : public io::ErrorCollector { 615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : 617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parser_(parser) { } 618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual ~ParserErrorCollector() { }; 620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville virtual void AddError(int line, int column, const string& message) { 622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parser_->ReportError(line, column, message); 623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 625d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville virtual void AddWarning(int line, int column, const string& message) { 626d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville parser_->ReportWarning(line, column, message); 627d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 628d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextFormat::Parser::ParserImpl* parser_; 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ErrorCollector* error_collector_; 635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserErrorCollector tokenizer_error_collector_; 636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::Tokenizer tokenizer_; 637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* root_message_type_; 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SingularOverwritePolicy singular_overwrite_policy_; 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool had_errors_; 640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef DO 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =========================================================================== 645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted 646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// from the Printer found in //google/protobuf/io/printer.h 647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass TextFormat::Printer::TextGenerator { 648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville explicit TextGenerator(io::ZeroCopyOutputStream* output, 650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int initial_indent_level) 651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : output_(output), 652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_(NULL), 653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_(0), 654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville at_start_of_line_(true), 655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville failed_(false), 656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville indent_(""), 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville initial_indent_level_(initial_indent_level) { 658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville indent_.resize(initial_indent_level_ * 2, ' '); 659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~TextGenerator() { 662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Only BackUp() if we're sure we've successfully called Next() at least 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // once. 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (buffer_size_ > 0) { 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output_->BackUp(buffer_size_); 666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Indent text by two spaces. After calling Indent(), two spaces will be 670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // inserted at the beginning of each line of text. Indent() may be called 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // multiple times to produce deeper indents. 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void Indent() { 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville indent_ += " "; 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Reduces the current indent level by two spaces, or crashes if the indent 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // level is zero. 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void Outdent() { 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (indent_.empty() || 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville indent_.size() < initial_indent_level_ * 2) { 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville indent_.resize(indent_.size() - 2); 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Print text to the output stream. 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void Print(const string& str) { 690d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Print(str.data(), str.size()); 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Print text to the output stream. 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void Print(const char* text) { 695d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville Print(text, strlen(text)); 696d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 697d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 698d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Print text to the output stream. 699d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville void Print(const char* text, int size) { 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int pos = 0; // The number of bytes we've written so far. 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < size; i++) { 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (text[i] == '\n') { 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Saw newline. If there is more text, we may need to insert an indent 705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // here. So, write what we have so far, including the '\n'. 706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Write(text + pos, i - pos + 1); 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pos = i + 1; 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Setting this true will cause the next Write() to insert an indent 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // first. 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville at_start_of_line_ = true; 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Write the rest. 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Write(text + pos, size - pos); 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // True if any write to the underlying stream failed. (We don't just 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // crash in this case because this is an I/O failure, not a programming 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // error.) 722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool failed() const { return failed_; } 723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); 726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void Write(const char* data, int size) { 728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (failed_) return; 729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (size == 0) return; 730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (at_start_of_line_) { 732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Insert an indent. 733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville at_start_of_line_ = false; 734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Write(indent_.data(), indent_.size()); 735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (failed_) return; 736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (size > buffer_size_) { 739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Data exceeds space in the buffer. Copy what we can and request a 740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // new buffer. 741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(buffer_, data, buffer_size_); 742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville data += buffer_size_; 743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size -= buffer_size_; 744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* void_buffer; 745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville failed_ = !output_->Next(&void_buffer, &buffer_size_); 746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (failed_) return; 747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ = reinterpret_cast<char*>(void_buffer); 748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Buffer is big enough to receive the data; copy it. 751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(buffer_, data, size); 752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_ += size; 753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer_size_ -= size; 754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* const output_; 757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* buffer_; 758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int buffer_size_; 759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool at_start_of_line_; 760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool failed_; 761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string indent_; 763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int initial_indent_level_; 764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =========================================================================== 767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTextFormat::Parser::Parser() 769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : error_collector_(NULL), 770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville allow_partial_(false) {} 771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTextFormat::Parser::~Parser() {} 773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, 775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->Clear(); 777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl parser(output->GetDescriptor(), input, error_collector_, 778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl::FORBID_SINGULAR_OVERWRITES); 779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return MergeUsingImpl(input, output, &parser); 780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Parser::ParseFromString(const string& input, 783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ArrayInputStream input_stream(input.data(), input.size()); 785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Parse(&input_stream, output); 786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, 789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl parser(output->GetDescriptor(), input, error_collector_, 791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl::ALLOW_SINGULAR_OVERWRITES); 792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return MergeUsingImpl(input, output, &parser); 793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Parser::MergeFromString(const string& input, 796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ArrayInputStream input_stream(input.data(), input.size()); 798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Merge(&input_stream, output); 799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input, 802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output, 803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl* parser_impl) { 804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!parser_impl->Parse(output)) return false; 805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!allow_partial_ && !output->IsInitialized()) { 806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> missing_fields; 807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->FindInitializationErrors(&missing_fields); 808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parser_impl->ReportError(-1, 0, "Message missing required fields: " + 809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville JoinStrings(missing_fields, ", ")); 810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Parser::ParseFieldValueFromString( 816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& input, 817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ArrayInputStream input_stream(input.data(), input.size()); 820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, 821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ParserImpl::ALLOW_SINGULAR_OVERWRITES); 822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return parser.ParseField(field, output); 823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, 826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Parser().Parse(input, output); 828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, 831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Parser().Merge(input, output); 833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::ParseFromString(const string& input, 836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Parser().ParseFromString(input, output); 838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::MergeFromString(const string& input, 841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* output) { 842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Parser().MergeFromString(input, output); 843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =========================================================================== 846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTextFormat::Printer::Printer() 848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : initial_indent_level_(0), 849d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville single_line_mode_(false), 850d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville use_short_repeated_primitives_(false), 851d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville utf8_string_escaping_(false) {} 852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTextFormat::Printer::~Printer() {} 854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Printer::PrintToString(const Message& message, 856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* output) { 857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(output) << "output specified is NULL"; 858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->clear(); 860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::StringOutputStream output_stream(output); 861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool result = Print(message, &output_stream); 863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Printer::PrintUnknownFieldsToString( 868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields, 869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* output) { 870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(output) << "output specified is NULL"; 871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->clear(); 873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::StringOutputStream output_stream(output); 874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return PrintUnknownFields(unknown_fields, &output_stream); 875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Printer::Print(const Message& message, 878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* output) { 879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextGenerator generator(output, initial_indent_level_); 880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Print(message, generator); 882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Output false if the generator failed internally. 884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !generator.failed(); 885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool TextFormat::Printer::PrintUnknownFields( 888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields, 889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* output) { 890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextGenerator generator(output, initial_indent_level_); 891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintUnknownFields(unknown_fields, generator); 893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Output false if the generator failed internally. 895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !generator.failed(); 896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid TextFormat::Printer::Print(const Message& message, 899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextGenerator& generator) { 900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = message.GetReflection(); 901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ListFields(message, &fields); 903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintField(message, reflection, fields[i], generator); 905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintUnknownFields(reflection->GetUnknownFields(message), generator); 907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid TextFormat::Printer::PrintFieldValueToString( 910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& message, 911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int index, 913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* output) { 914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(output) << "output specified is NULL"; 916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->clear(); 918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::StringOutputStream output_stream(output); 919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextGenerator generator(&output_stream, initial_indent_level_); 920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintFieldValue(message, message.GetReflection(), field, index, generator); 922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid TextFormat::Printer::PrintField(const Message& message, 925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection, 926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextGenerator& generator) { 928d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (use_short_repeated_primitives_ && 929d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field->is_repeated() && 930d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && 931d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 932d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville PrintShortRepeatedField(message, reflection, field, generator); 933d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville return; 934d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 935d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int count = 0; 937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville count = reflection->FieldSize(message, field); 940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (reflection->HasField(message, field)) { 941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville count = 1; 942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < count; ++j) { 945d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville PrintFieldName(message, reflection, field, generator); 946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" { "); 950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" {\n"); 952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Indent(); 953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(": "); 956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Write the field value. 959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int field_index = j; 960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!field->is_repeated()) { 961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_index = -1; 962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintFieldValue(message, reflection, field, field_index, generator); 965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 967d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (single_line_mode_) { 968d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("} "); 969d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Outdent(); 971d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("}\n"); 972d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 973d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 974d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (single_line_mode_) { 975d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(" "); 976d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 977d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("\n"); 978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 980d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 981d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 982d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 983d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid TextFormat::Printer::PrintShortRepeatedField(const Message& message, 984d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const Reflection* reflection, 985d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const FieldDescriptor* field, 986d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TextGenerator& generator) { 987d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Print primitive repeated field in short form. 988d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville PrintFieldName(message, reflection, field, generator); 989d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 990d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville int size = reflection->FieldSize(message, field); 991d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(": ["); 992d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville for (int i = 0; i < size; i++) { 993d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (i > 0) generator.Print(", "); 994d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville PrintFieldValue(message, reflection, field, i, generator); 995d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 996d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (single_line_mode_) { 997d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("] "); 998d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 999d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("]\n"); 1000d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 1001d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville} 1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1003d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillevoid TextFormat::Printer::PrintFieldName(const Message& message, 1004d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const Reflection* reflection, 1005d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville const FieldDescriptor* field, 1006d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TextGenerator& generator) { 1007d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (field->is_extension()) { 1008d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("["); 1009d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // We special-case MessageSet elements for compatibility with proto1. 1010d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (field->containing_type()->options().message_set_wire_format() 1011d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville && field->type() == FieldDescriptor::TYPE_MESSAGE 1012d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville && field->is_optional() 1013d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville && field->extension_scope() == field->message_type()) { 1014d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(field->message_type()->full_name()); 1015d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 1016d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(field->full_name()); 1017d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 1018d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print("]"); 1019d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 1020d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (field->type() == FieldDescriptor::TYPE_GROUP) { 1021d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville // Groups must be serialized with their original capitalization. 1022d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(field->message_type()->name()); 1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1024d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(field->name()); 1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid TextFormat::Printer::PrintFieldValue( 1030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& message, 1031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection, 1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int index, 1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TextGenerator& generator) { 1035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DCHECK(field->is_repeated() || (index == -1)) 1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Index must be -1 for non-repeated fields"; 1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (field->cpp_type()) { 1039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \ 1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(TO_STRING(field->is_repeated() ? \ 1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetRepeated##METHOD(message, field, index) : \ 1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->Get##METHOD(message, field))); \ 1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; \ 1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT_FIELD( INT32, Int32, SimpleItoa); 1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT_FIELD( INT64, Int64, SimpleItoa); 1048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT_FIELD(UINT32, UInt32, SimpleItoa); 1049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT_FIELD(UINT64, UInt64, SimpleItoa); 1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT_FIELD( FLOAT, Float, SimpleFtoa); 1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa); 1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef OUTPUT_FIELD 1053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_STRING: { 1055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string scratch; 1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& value = field->is_repeated() ? 1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetRepeatedStringReference( 1058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message, field, index, &scratch) : 1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetStringReference(message, field, &scratch); 1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\""); 1062d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (utf8_string_escaping_) { 1063d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(strings::Utf8SafeCEscape(value)); 1064d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 1065d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville generator.Print(CEscape(value)); 1066d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\""); 1068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_BOOL: 1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_repeated()) { 1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(reflection->GetRepeatedBool(message, field, index) 1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ? "true" : "false"); 1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(reflection->GetBool(message, field) 1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ? "true" : "false"); 1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_ENUM: 1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(field->is_repeated() ? 1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetRepeatedEnum(message, field, index)->name() : 1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetEnum(message, field)->name()); 1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 1089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Print(field->is_repeated() ? 1090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetRepeatedMessage(message, field, index) : 1091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->GetMessage(message, field), 1092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator); 1093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::Print(const Message& message, 1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* output) { 1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Printer().Print(message, output); 1100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::PrintUnknownFields( 1103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields, 1104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::ZeroCopyOutputStream* output) { 1105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Printer().PrintUnknownFields(unknown_fields, output); 1106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::PrintToString( 1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& message, string* output) { 1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Printer().PrintToString(message, output); 1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::PrintUnknownFieldsToString( 1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields, string* output) { 1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Printer().PrintUnknownFieldsToString(unknown_fields, output); 1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ void TextFormat::PrintFieldValueToString( 1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& message, 1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int index, 1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* output) { 1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Printer().PrintFieldValueToString(message, field, index, output); 1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville/* static */ bool TextFormat::ParseFieldValueFromString( 1127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& input, 1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field, 1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* message) { 1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Parser().ParseFieldValueFromString(input, field, message); 1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Prints an integer as hex with a fixed number of digits dependent on the 1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// integer type. 1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<typename IntType> 1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic string PaddedHex(IntType value) { 1137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.reserve(sizeof(value) * 2); 1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = sizeof(value) * 2 - 1; i >= 0; i--) { 1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F)); 1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid TextFormat::Printer::PrintUnknownFields( 1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields, TextGenerator& generator) { 1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < unknown_fields.field_count(); i++) { 1148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownField& field = unknown_fields.field(i); 1149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string field_number = SimpleItoa(field.number()); 1150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (field.type()) { 1152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case UnknownField::TYPE_VARINT: 1153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(field_number); 1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(": "); 1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(SimpleItoa(field.varint())); 1156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" "); 1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\n"); 1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case UnknownField::TYPE_FIXED32: { 1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(field_number); 1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(": 0x"); 1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(FastHex32ToBuffer(field.fixed32(), buffer)); 1167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" "); 1169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\n"); 1171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case UnknownField::TYPE_FIXED64: { 1175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(field_number); 1176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(": 0x"); 1177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char buffer[kFastToBufferSize]; 1178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(FastHex64ToBuffer(field.fixed64(), buffer)); 1179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" "); 1181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\n"); 1183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case UnknownField::TYPE_LENGTH_DELIMITED: { 1187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(field_number); 1188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& value = field.length_delimited(); 1189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet embedded_unknown_fields; 1190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { 1191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This field is parseable as a Message. 1192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // So it is probably an embedded message. 1193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" { "); 1195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" {\n"); 1197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Indent(); 1198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintUnknownFields(embedded_unknown_fields, generator); 1200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("} "); 1202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Outdent(); 1204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("}\n"); 1205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This field is not parseable as a Message. 1208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // So it is probably just a plain string. 1209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(": \""); 1210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(CEscape(value)); 1211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\""); 1212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" "); 1214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("\n"); 1216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case UnknownField::TYPE_GROUP: 1221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(field_number); 1222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" { "); 1224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print(" {\n"); 1226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Indent(); 1227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PrintUnknownFields(field.group(), generator); 1229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (single_line_mode_) { 1230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("} "); 1231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Outdent(); 1233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generator.Print("}\n"); 1234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 1241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 1242