15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: jschorr@google.com (Joseph Schorr) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <float.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stack> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/text_format.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unknown_field_set.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/tokenizer.h> 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 52ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/map-util.h> 53ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/stl_util.h> 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Message::DebugString() const { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string debug_string; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::PrintToString(*this, &debug_string); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return debug_string; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Message::ShortDebugString() const { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string debug_string; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::Printer printer; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.SetSingleLineMode(true); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.PrintToString(*this, &debug_string); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Single line mode currently might have an extra space at the end. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (debug_string.size() > 0 && 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_string[debug_string.size() - 1] == ' ') { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_string.resize(debug_string.size() - 1); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return debug_string; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Message::Utf8DebugString() const { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string debug_string; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::Printer printer; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.SetUseUtf8StringEscaping(true); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printer.PrintToString(*this, &debug_string); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return debug_string; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Message::PrintDebugString() const { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s", DebugString().c_str()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =========================================================================== 99ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Implementation of the parse information tree class. 100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTextFormat::ParseInfoTree::ParseInfoTree() { } 101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTextFormat::ParseInfoTree::~ParseInfoTree() { 103ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Remove any nested information trees, as they are owned by this tree. 104ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) { 105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch STLDeleteElements(&(it->second)); 106ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 107ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 108ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 109ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid TextFormat::ParseInfoTree::RecordLocation( 110ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor* field, 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch TextFormat::ParseLocation location) { 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch locations_[field].push_back(location); 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested( 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor* field) { 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Owned by us in the map. 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree(); 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<TextFormat::ParseInfoTree*>* trees = &nested_[field]; 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(trees); 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch trees->push_back(instance); 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return instance; 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid CheckFieldIndex(const FieldDescriptor* field, int index) { 126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field == NULL) { return; } 127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field->is_repeated() && index == -1) { 129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. " 130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << "Field: " << field->name(); 131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else if (!field->is_repeated() && index != -1) { 132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields." 133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch << "Field: " << field->name(); 134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation( 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor* field, int index) const { 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CheckFieldIndex(field, index); 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (index == -1) { index = 0; } 141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const vector<TextFormat::ParseLocation>* locations = 143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FindOrNull(locations_, field); 144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (locations == NULL || index >= locations->size()) { 145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return TextFormat::ParseLocation(); 146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return (*locations)[index]; 149ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 150ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested( 152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor* field, int index) const { 153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CheckFieldIndex(field, index); 154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (index == -1) { index = 0; } 155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field); 157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (trees == NULL || index >= trees->size()) { 158ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return NULL; 159ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 160ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 161ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return (*trees)[index]; 162ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 163ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 164ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// =========================================================================== 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Internal class for parsing an ASCII representation of a Protocol Message. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class makes use of the Protocol Message compiler's tokenizer found 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in //google/protobuf/io/tokenizer.h. Note that class's Parse 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// method is *not* thread-safe and should only be used in a single thread at 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a time. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes code slightly more readable. The meaning of "DO(foo)" is 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "Execute foo and fail if it fails.", where failure is indicated by 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returning false. Borrowed from parser.cc (Thanks Kenton!). 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DO(STATEMENT) if (STATEMENT) {} else return false 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextFormat::Parser::ParserImpl { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Determines if repeated values for a non-repeated field are 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // permitted, e.g., the string "foo: 1 foo: 2" for a 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // required/optional field named "foo". 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum SingularOverwritePolicy { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ALLOW_SINGULAR_OVERWRITES = 0, // the last value is retained 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FORBID_SINGULAR_OVERWRITES = 1, // an error is issued 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParserImpl(const Descriptor* root_message_type, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ZeroCopyInputStream* input_stream, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ErrorCollector* error_collector, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::Finder* finder, 192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ParseInfoTree* parse_info_tree, 193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SingularOverwritePolicy singular_overwrite_policy, 194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool allow_unknown_field) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : error_collector_(error_collector), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finder_(finder), 197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch parse_info_tree_(parse_info_tree), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_error_collector_(this), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_(input_stream, &tokenizer_error_collector_), 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_message_type_(root_message_type), 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) singular_overwrite_policy_(singular_overwrite_policy), 202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allow_unknown_field_(allow_unknown_field), 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) had_errors_(false) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For backwards-compatibility with proto1, we need to allow the 'f' suffix 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for floats. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.set_allow_f_after_float(true); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // '#' starts a comment. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.set_comment_style(io::Tokenizer::SH_COMMENT_STYLE); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume the starting token. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ParserImpl() { } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parses the ASCII representation specified in input and saves the 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // information into the output pointer (a Message). Returns 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // false if an error occurs (an error will also be logged to 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GOOGLE_LOG(ERROR)). 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Parse(Message* output) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume fields until we cannot do so anymore. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(true) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LookingAtType(io::Tokenizer::TYPE_END)) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !had_errors_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeField(output)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ParseField(const FieldDescriptor* field, Message* output) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool suc; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suc = ConsumeFieldMessage(output, output->GetReflection(), field); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suc = ConsumeFieldValue(output, output->GetReflection(), field); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return suc && LookingAtType(io::Tokenizer::TYPE_END); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReportError(int line, int col, const string& message) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) had_errors_ = true; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_collector_ == NULL) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line >= 0) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(ERROR) << "Error parsing text-format " 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << root_message_type_->full_name() 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << (line + 1) << ":" 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (col + 1) << ": " << message; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(ERROR) << "Error parsing text-format " 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << root_message_type_->full_name() 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << message; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_collector_->AddError(line, col, message); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReportWarning(int line, int col, const string& message) { 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_collector_ == NULL) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (line >= 0) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(WARNING) << "Warning parsing text-format " 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << root_message_type_->full_name() 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << (line + 1) << ":" 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (col + 1) << ": " << message; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(WARNING) << "Warning parsing text-format " 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << root_message_type_->full_name() 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << message; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_collector_->AddWarning(line, col, message); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserImpl); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reports an error with the given message with information indicating 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the position (as derived from the current token). 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReportError(const string& message) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError(tokenizer_.current().line, tokenizer_.current().column, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reports a warning with the given message with information indicating 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the position (as derived from the current token). 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReportWarning(const string& message) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportWarning(tokenizer_.current().line, tokenizer_.current().column, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes the specified message with the given starting delimeter. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method checks to see that the end delimeter at the conclusion of 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the consumption matches the starting delimeter passed in here. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeMessage(Message* message, const string delimeter) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!LookingAt(">") && !LookingAt("}")) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeField(message)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Confirm that we have a valid ending delimeter. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(Consume(delimeter)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes the current field (as returned by the tokenizer) on the 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // passed in message. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeField(Message* message) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection = message->GetReflection(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* descriptor = message->GetDescriptor(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string field_name; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = NULL; 316ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int start_line = tokenizer_.current().line; 317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int start_column = tokenizer_.current().column; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryConsume("[")) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extension. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeIdentifier(&field_name)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (TryConsume(".")) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string part; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeIdentifier(&part)); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_name += "."; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_name += part; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(Consume("]")); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = (finder_ != NULL 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? finder_->FindExtension(message, field_name) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : reflection->FindKnownExtensionByName(field_name)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field == NULL) { 335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!allow_unknown_field_) { 336ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ReportError("Extension \"" + field_name + "\" is not defined or " 337ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "is not an extension of \"" + 338ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch descriptor->full_name() + "\"."); 339ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 340ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 341ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ReportWarning("Extension \"" + field_name + "\" is not defined or " 342ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "is not an extension of \"" + 343ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch descriptor->full_name() + "\"."); 344ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeIdentifier(&field_name)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = descriptor->FindFieldByName(field_name); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Group names are expected to be capitalized as they appear in the 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // .proto file, which actually matches their type names, not their field 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // names. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field == NULL) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string lower_field_name = field_name; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LowerString(&lower_field_name); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = descriptor->FindFieldByName(lower_field_name); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the case-insensitive match worked but the field is NOT a group, 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = NULL; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Again, special-case group names as described above. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && field->message_type()->name() != field_name) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = NULL; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field == NULL) { 369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!allow_unknown_field_) { 370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ReportError("Message type \"" + descriptor->full_name() + 371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "\" has no field named \"" + field_name + "\"."); 372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ReportWarning("Message type \"" + descriptor->full_name() + 375ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "\" has no field named \"" + field_name + "\"."); 376ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 377ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 378ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 379ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 380ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Skips unknown field. 381ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field == NULL) { 382ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK(allow_unknown_field_); 383ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Try to guess the type of this field. 384ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If this field is not a message, there should be a ":" between the 385ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // field name and the field value and also the field value should not 386ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // start with "{" or "<" which indicates the begining of a message body. 387ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If there is no ":" or there is a "{" or "<" after ":", this field has 388ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // to be a message or the input is ill-formed. 389ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { 390ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return SkipFieldValue(); 391ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 392ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return SkipFieldMessage(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fail if the field is not repeated and it has already been specified. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) && 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !field->is_repeated() && reflection->HasField(*message, field)) { 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Non-repeated field \"" + field_name + 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" is specified multiple times."); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Perform special handling for embedded message types. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ':' is optional here. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryConsume(":"); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeFieldMessage(message, reflection, field)); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(Consume(":")); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated() && TryConsume("[")) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Short repeated format, e.g. "foo: [1, 2, 3]" 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeFieldValue(message, reflection, field)); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryConsume("]")) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(Consume(",")); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeFieldValue(message, reflection, field)); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For historical reasons, fields may optionally be separated by commas or 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // semicolons. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryConsume(";") || TryConsume(","); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->options().deprecated()) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportWarning("text format contains deprecated field \"" 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + field_name + "\""); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 434ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If a parse info tree exists, add the location for the parsed 435ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // field. 436ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (parse_info_tree_ != NULL) { 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RecordLocation(parse_info_tree_, field, 4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ParseLocation(start_line, start_column)); 439ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 440ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 441ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 442ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 443ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 444ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Skips the next field including the field's name and value. 445ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool SkipField() { 446ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string field_name; 447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (TryConsume("[")) { 448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Extension name. 449ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(ConsumeIdentifier(&field_name)); 450ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (TryConsume(".")) { 451ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string part; 452ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(ConsumeIdentifier(&part)); 453ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field_name += "."; 454ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch field_name += part; 455ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 456ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(Consume("]")); 457ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 458ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(ConsumeIdentifier(&field_name)); 459ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 460ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 461ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Try to guess the type of this field. 462ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If this field is not a message, there should be a ":" between the 463ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // field name and the field value and also the field value should not 464ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // start with "{" or "<" which indicates the begining of a message body. 465ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If there is no ":" or there is a "{" or "<" after ":", this field has 466ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // to be a message or the input is ill-formed. 467ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) { 468ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(SkipFieldValue()); 469ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 470ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(SkipFieldMessage()); 471ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 472ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // For historical reasons, fields may optionally be separated by commas or 473ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // semicolons. 474ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch TryConsume(";") || TryConsume(","); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeFieldMessage(Message* message, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection, 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field) { 481ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 482ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If the parse information tree is not NULL, create a nested one 483ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // for the nested message. 484ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ParseInfoTree* parent = parse_info_tree_; 485ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (parent != NULL) { 4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) parse_info_tree_ = CreateNested(parent, field); 487ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string delimeter; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryConsume("<")) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delimeter = ">"; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(Consume("{")); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delimeter = "}"; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter)); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeMessage(reflection->MutableMessage(message, field), 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delimeter)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Reset the parse information tree. 505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch parse_info_tree_ = parent; 506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 507ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 508ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 509ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Skips the whole body of a message including the begining delimeter and 510ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the ending delimeter. 511ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool SkipFieldMessage() { 512ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string delimeter; 513ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (TryConsume("<")) { 514ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch delimeter = ">"; 515ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 516ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(Consume("{")); 517ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch delimeter = "}"; 518ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 519ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (!LookingAt(">") && !LookingAt("}")) { 520ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(SkipField()); 521ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 522ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DO(Consume(delimeter)); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeFieldValue(Message* message, 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection, 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Define an easy to use macro for setting fields. This macro checks 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to see if the field is repeated (in which case we need to use the Add 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// methods or not (in which case we need to use the Set methods). 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SET_FIELD(CPPTYPE, VALUE) \ 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { \ 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->Add##CPPTYPE(message, field, VALUE); \ 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { \ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->Set##CPPTYPE(message, field, VALUE); \ 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(field->cpp_type()) { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT32: { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 value; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeSignedInteger(&value, kint32max)); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Int32, static_cast<int32>(value)); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT32: { 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 value; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeUnsignedInteger(&value, kuint32max)); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(UInt32, static_cast<uint32>(value)); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT64: { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 value; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeSignedInteger(&value, kint64max)); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Int64, value); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT64: { 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 value; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeUnsignedInteger(&value, kuint64max)); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(UInt64, value); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_FLOAT: { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeDouble(&value)); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Float, static_cast<float>(value)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_DOUBLE: { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeDouble(&value)); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Double, value); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string value; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeString(&value)); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(String, value); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 value; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeUnsignedInteger(&value, 1)); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Bool, value); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string value; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeIdentifier(&value)); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value == "true" || value == "t") { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Bool, true); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (value == "false" || value == "f") { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Bool, false); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Invalid value for boolean field \"" + field->name() 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + "\". Value: \"" + value + "\"."); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: { 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string value; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* enum_type = field->enum_type(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptor* enum_value = NULL; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeIdentifier(&value)); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the enumeration value. 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_value = enum_type->FindValueByName(value); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LookingAt("-") || 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 int_value; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeSignedInteger(&int_value, kint32max)); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = SimpleItoa(int_value); // for error reporting 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_value = enum_type->FindValueByNumber(int_value); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected integer or identifier."); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enum_value == NULL) { 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Unknown enumeration value of \"" + value + "\" for " 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "field \"" + field->name() + "\"."); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET_FIELD(Enum, enum_value); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_MESSAGE: { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should never get here. Put here instead of a default 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that if new types are added, we get a nice compiler warning. 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Reached an unintended state: CPPTYPE_MESSAGE"; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef SET_FIELD 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 653ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool SkipFieldValue() { 654ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (LookingAtType(io::Tokenizer::TYPE_STRING)) { 655ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch while (LookingAtType(io::Tokenizer::TYPE_STRING)) { 656ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tokenizer_.Next(); 657ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 658ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 659ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 660ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Possible field values other than string: 661ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 12345 => TYPE_INTEGER 662ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // -12345 => TYPE_SYMBOL + TYPE_INTEGER 663ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 1.2345 => TYPE_FLOAT 664ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT 665ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // inf => TYPE_IDENTIFIER 666ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER 667ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TYPE_INTEGER => TYPE_IDENTIFIER 668ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Divides them into two group, one with TYPE_SYMBOL 669ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // and the other without: 670ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Group one: 671ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 12345 => TYPE_INTEGER 672ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 1.2345 => TYPE_FLOAT 673ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // inf => TYPE_IDENTIFIER 674ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TYPE_INTEGER => TYPE_IDENTIFIER 675ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Group two: 676ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // -12345 => TYPE_SYMBOL + TYPE_INTEGER 677ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // -1.2345 => TYPE_SYMBOL + TYPE_FLOAT 678ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // -inf => TYPE_SYMBOL + TYPE_IDENTIFIER 679ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // As we can see, the field value consists of an optional '-' and one of 680ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER. 681ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool has_minus = TryConsume("-"); 682ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) && 683ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch !LookingAtType(io::Tokenizer::TYPE_FLOAT) && 684ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 685ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 686ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 687ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field 688ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // value while other combinations all generate valid values. 689ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // We check if the value of this combination is valid here. 690ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // TYPE_IDENTIFIER after a '-' should be one of the float values listed 691ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // below: 692ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // inf, inff, infinity, nan 693ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 694ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string text = tokenizer_.current().text; 695ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch LowerString(&text); 696ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (text != "inf" && 697ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch text != "infinity" && 698ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch text != "nan") { 699ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ReportError("Invalid float number: " + text); 700ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 701ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 702ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 703ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tokenizer_.Next(); 704ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 705ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 706ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the current token's text is equal to that specified. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool LookingAt(const string& text) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tokenizer_.current().text == text; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the current token's type is equal to that specified. 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool LookingAtType(io::Tokenizer::TokenType token_type) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tokenizer_.current().type == token_type; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes an identifier and saves its value in the identifier parameter. 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns false if the token is not of type IDENTFIER. 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeIdentifier(string* identifier) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected identifier."); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *identifier = tokenizer_.current().text; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes a string and saves its value in the text parameter. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns false if the token is not of type STRING. 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeString(string* text) { 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LookingAtType(io::Tokenizer::TYPE_STRING)) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected string."); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text->clear(); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (LookingAtType(io::Tokenizer::TYPE_STRING)) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Tokenizer::ParseStringAppend(tokenizer_.current().text, text); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes a uint64 and saves its value in the value parameter. 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns false if the token is not of type INTEGER. 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeUnsignedInteger(uint64* value, uint64 max_value) { 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected integer."); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!io::Tokenizer::ParseInteger(tokenizer_.current().text, 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_value, value)) { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Integer out of range."); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes an int64 and saves its value in the value parameter. 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that since the tokenizer does not support negative numbers, 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we actually may consume an additional token (for the minus sign) in this 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method. Returns false if the token is not an integer 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (signed or otherwise). 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeSignedInteger(int64* value, uint64 max_value) { 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool negative = false; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryConsume("-")) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) negative = true; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Two's complement always allows one more negative integer than 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // positive. 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++max_value; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 unsigned_value; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeUnsignedInteger(&unsigned_value, max_value)); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = static_cast<int64>(unsigned_value); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (negative) { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = -*value; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes a double and saves its value in the value parameter. 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that since the tokenizer does not support negative numbers, 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we actually may consume an additional token (for the minus sign) in this 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // method. Returns false if the token is not a double 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (signed or otherwise). 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ConsumeDouble(double* value) { 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool negative = false; 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryConsume("-")) { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) negative = true; 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A double can actually be an integer, according to the tokenizer. 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Therefore, we must check both cases here. 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have found an integer value for the double. 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 integer_value; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DO(ConsumeUnsignedInteger(&integer_value, kuint64max)); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = static_cast<double>(integer_value); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LookingAtType(io::Tokenizer::TYPE_FLOAT)) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have found a float value for the double. 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = io::Tokenizer::ParseFloat(tokenizer_.current().text); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark the current token as consumed. 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string text = tokenizer_.current().text; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LowerString(&text); 824ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (text == "inf" || 825ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch text == "infinity") { 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = std::numeric_limits<double>::infinity(); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (text == "nan") { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = std::numeric_limits<double>::quiet_NaN(); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected double."); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected double."); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (negative) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *value = -*value; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consumes a token and confirms that it matches that specified in the 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value parameter. Returns false if the token found does not match that 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which was specified. 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Consume(const string& value) { 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& current_value = tokenizer_.current().text; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current_value != value) { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportError("Expected \"" + value + "\", found \"" + current_value 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + "\"."); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempts to consume the supplied value. Returns false if a the 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // token found does not match the value specified. 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool TryConsume(const string& value) { 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tokenizer_.current().text == value) { 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tokenizer_.Next(); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An internal instance of the Tokenizer's error collector, used to 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // collect any base-level parse errors and feed them to the ParserImpl. 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ParserErrorCollector : public io::ErrorCollector { 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ParserErrorCollector(TextFormat::Parser::ParserImpl* parser) : 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_(parser) { } 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ParserErrorCollector() { }; 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddError(int line, int column, const string& message) { 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_->ReportError(line, column, message); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddWarning(int line, int column, const string& message) { 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_->ReportWarning(line, column, message); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::Parser::ParserImpl* parser_; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ErrorCollector* error_collector_; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::Finder* finder_; 899ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ParseInfoTree* parse_info_tree_; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParserErrorCollector tokenizer_error_collector_; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::Tokenizer tokenizer_; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* root_message_type_; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SingularOverwritePolicy singular_overwrite_policy_; 904ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool allow_unknown_field_; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool had_errors_; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef DO 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =========================================================================== 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the Printer found in //google/protobuf/io/printer.h 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TextFormat::Printer::TextGenerator { 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TextGenerator(io::ZeroCopyOutputStream* output, 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int initial_indent_level) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : output_(output), 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_(NULL), 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size_(0), 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) at_start_of_line_(true), 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_(false), 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent_(""), 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_indent_level_(initial_indent_level) { 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent_.resize(initial_indent_level_ * 2, ' '); 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~TextGenerator() { 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only BackUp() if we're sure we've successfully called Next() at least 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // once. 930ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!failed_ && buffer_size_ > 0) { 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_->BackUp(buffer_size_); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indent text by two spaces. After calling Indent(), two spaces will be 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inserted at the beginning of each line of text. Indent() may be called 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // multiple times to produce deeper indents. 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Indent() { 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent_ += " "; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reduces the current indent level by two spaces, or crashes if the indent 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // level is zero. 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Outdent() { 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (indent_.empty() || 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent_.size() < initial_indent_level_ * 2) { 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(DFATAL) << " Outdent() without matching Indent()."; 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indent_.resize(indent_.size() - 2); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print text to the output stream. 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Print(const string& str) { 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Print(str.data(), str.size()); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print text to the output stream. 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Print(const char* text) { 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Print(text, strlen(text)); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print text to the output stream. 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Print(const char* text, int size) { 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pos = 0; // The number of bytes we've written so far. 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < size; i++) { 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (text[i] == '\n') { 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Saw newline. If there is more text, we may need to insert an indent 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. So, write what we have so far, including the '\n'. 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Write(text + pos, i - pos + 1); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = i + 1; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setting this true will cause the next Write() to insert an indent 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // first. 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) at_start_of_line_ = true; 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the rest. 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Write(text + pos, size - pos); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if any write to the underlying stream failed. (We don't just 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // crash in this case because this is an I/O failure, not a programming 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error.) 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool failed() const { return failed_; } 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextGenerator); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Write(const char* data, int size) { 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (failed_) return; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size == 0) return; 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (at_start_of_line_) { 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert an indent. 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) at_start_of_line_ = false; 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Write(indent_.data(), indent_.size()); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (failed_) return; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (size > buffer_size_) { 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Data exceeds space in the buffer. Copy what we can and request a 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new buffer. 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer_, data, buffer_size_); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data += buffer_size_; 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size -= buffer_size_; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* void_buffer; 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_ = !output_->Next(&void_buffer, &buffer_size_); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (failed_) return; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = reinterpret_cast<char*>(void_buffer); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffer is big enough to receive the data; copy it. 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buffer_, data, size); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ += size; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size_ -= size; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ZeroCopyOutputStream* const output_; 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* buffer_; 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size_; 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool at_start_of_line_; 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool failed_; 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string indent_; 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int initial_indent_level_; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =========================================================================== 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextFormat::Finder::~Finder() { 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextFormat::Parser::Parser() 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : error_collector_(NULL), 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finder_(NULL), 1040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch parse_info_tree_(NULL), 1041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allow_partial_(false), 1042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allow_unknown_field_(false) { 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextFormat::Parser::~Parser() {} 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->Clear(); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParserImpl parser(output->GetDescriptor(), input, error_collector_, 1051ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch finder_, parse_info_tree_, 1052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ParserImpl::FORBID_SINGULAR_OVERWRITES, 1053ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allow_unknown_field_); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MergeUsingImpl(input, output, &parser); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Parser::ParseFromString(const string& input, 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ArrayInputStream input_stream(input.data(), input.size()); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Parse(&input_stream, output); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParserImpl parser(output->GetDescriptor(), input, error_collector_, 1066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch finder_, parse_info_tree_, 1067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ParserImpl::ALLOW_SINGULAR_OVERWRITES, 1068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allow_unknown_field_); 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return MergeUsingImpl(input, output, &parser); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Parser::MergeFromString(const string& input, 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ArrayInputStream input_stream(input.data(), input.size()); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Merge(&input_stream, output); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* input, 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output, 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParserImpl* parser_impl) { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parser_impl->Parse(output)) return false; 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!allow_partial_ && !output->IsInitialized()) { 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string> missing_fields; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->FindInitializationErrors(&missing_fields); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser_impl->ReportError(-1, 0, "Message missing required fields: " + 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) JoinStrings(missing_fields, ", ")); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Parser::ParseFieldValueFromString( 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& input, 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ArrayInputStream input_stream(input.data(), input.size()); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_, 1098ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch finder_, parse_info_tree_, 1099ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch ParserImpl::ALLOW_SINGULAR_OVERWRITES, 1100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allow_unknown_field_); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return parser.ParseField(field, output); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::Parse(io::ZeroCopyInputStream* input, 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Parser().Parse(input, output); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::Merge(io::ZeroCopyInputStream* input, 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Parser().Merge(input, output); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::ParseFromString(const string& input, 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Parser().ParseFromString(input, output); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::MergeFromString(const string& input, 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* output) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Parser().MergeFromString(input, output); 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =========================================================================== 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextFormat::Printer::Printer() 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : initial_indent_level_(0), 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) single_line_mode_(false), 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) use_short_repeated_primitives_(false), 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) utf8_string_escaping_(false) {} 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TextFormat::Printer::~Printer() {} 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Printer::PrintToString(const Message& message, 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* output) const { 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DCHECK(output) << "output specified is NULL"; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->clear(); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::StringOutputStream output_stream(output); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = Print(message, &output_stream); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Printer::PrintUnknownFieldsToString( 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields, 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* output) const { 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DCHECK(output) << "output specified is NULL"; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->clear(); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::StringOutputStream output_stream(output); 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PrintUnknownFields(unknown_fields, &output_stream); 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Printer::Print(const Message& message, 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ZeroCopyOutputStream* output) const { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator generator(output, initial_indent_level_); 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Print(message, generator); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output false if the generator failed internally. 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !generator.failed(); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TextFormat::Printer::PrintUnknownFields( 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields, 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ZeroCopyOutputStream* output) const { 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator generator(output, initial_indent_level_); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintUnknownFields(unknown_fields, generator); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output false if the generator failed internally. 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !generator.failed(); 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::Print(const Message& message, 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator& generator) const { 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection = message.GetReflection(); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*> fields; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->ListFields(message, &fields); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < fields.size(); i++) { 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintField(message, reflection, fields[i], generator); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintUnknownFields(reflection->GetUnknownFields(message), generator); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::PrintFieldValueToString( 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& message, 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* output) const { 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DCHECK(output) << "output specified is NULL"; 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->clear(); 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::StringOutputStream output_stream(output); 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator generator(&output_stream, initial_indent_level_); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldValue(message, message.GetReflection(), field, index, generator); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::PrintField(const Message& message, 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection, 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator& generator) const { 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_short_repeated_primitives_ && 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->is_repeated() && 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() != FieldDescriptor::CPPTYPE_STRING && 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintShortRepeatedField(message, reflection, field, generator); 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = reflection->FieldSize(message, field); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (reflection->HasField(message, field)) { 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = 1; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < count; ++j) { 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldName(message, reflection, field, generator); 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" { "); 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" {\n"); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Indent(); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(": "); 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the field value. 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int field_index = j; 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_index = -1; 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldValue(message, reflection, field, field_index, generator); 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("} "); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Outdent(); 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("}\n"); 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" "); 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\n"); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::PrintShortRepeatedField( 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& message, 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection, 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator& generator) const { 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Print primitive repeated field in short form. 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldName(message, reflection, field, generator); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = reflection->FieldSize(message, field); 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(": ["); 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < size; i++) { 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) generator.Print(", "); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintFieldValue(message, reflection, field, i, generator); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("] "); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("]\n"); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::PrintFieldName(const Message& message, 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection, 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator& generator) const { 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_extension()) { 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("["); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We special-case MessageSet elements for compatibility with proto1. 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->containing_type()->options().message_set_wire_format() 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && field->type() == FieldDescriptor::TYPE_MESSAGE 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && field->is_optional() 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && field->extension_scope() == field->message_type()) { 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field->message_type()->full_name()); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field->full_name()); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("]"); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->type() == FieldDescriptor::TYPE_GROUP) { 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Groups must be serialized with their original capitalization. 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field->message_type()->name()); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field->name()); 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::PrintFieldValue( 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& message, 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection, 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextGenerator& generator) const { 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DCHECK(field->is_repeated() || (index == -1)) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Index must be -1 for non-repeated fields"; 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (field->cpp_type()) { 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OUTPUT_FIELD(CPPTYPE, METHOD, TO_STRING) \ 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_##CPPTYPE: \ 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(TO_STRING(field->is_repeated() ? \ 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetRepeated##METHOD(message, field, index) : \ 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->Get##METHOD(message, field))); \ 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; \ 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT_FIELD( INT32, Int32, SimpleItoa); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT_FIELD( INT64, Int64, SimpleItoa); 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT_FIELD(UINT32, UInt32, SimpleItoa); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT_FIELD(UINT64, UInt64, SimpleItoa); 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT_FIELD( FLOAT, Float, SimpleFtoa); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT_FIELD(DOUBLE, Double, SimpleDtoa); 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef OUTPUT_FIELD 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: { 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string scratch; 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& value = field->is_repeated() ? 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetRepeatedStringReference( 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message, field, index, &scratch) : 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetStringReference(message, field, &scratch); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\""); 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (utf8_string_escaping_) { 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(strings::Utf8SafeCEscape(value)); 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(CEscape(value)); 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\""); 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_repeated()) { 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(reflection->GetRepeatedBool(message, field, index) 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? "true" : "false"); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(reflection->GetBool(message, field) 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ? "true" : "false"); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field->is_repeated() ? 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetRepeatedEnum(message, field, index)->name() : 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetEnum(message, field)->name()); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_MESSAGE: 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Print(field->is_repeated() ? 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetRepeatedMessage(message, field, index) : 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->GetMessage(message, field), 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator); 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::Print(const Message& message, 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ZeroCopyOutputStream* output) { 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Printer().Print(message, output); 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::PrintUnknownFields( 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields, 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::ZeroCopyOutputStream* output) { 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Printer().PrintUnknownFields(unknown_fields, output); 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::PrintToString( 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& message, string* output) { 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Printer().PrintToString(message, output); 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::PrintUnknownFieldsToString( 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields, string* output) { 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Printer().PrintUnknownFieldsToString(unknown_fields, output); 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ void TextFormat::PrintFieldValueToString( 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& message, 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int index, 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* output) { 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Printer().PrintFieldValueToString(message, field, index, output); 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* static */ bool TextFormat::ParseFieldValueFromString( 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& input, 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field, 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* message) { 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Parser().ParseFieldValueFromString(input, field, message); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Prints an integer as hex with a fixed number of digits dependent on the 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// integer type. 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename IntType> 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static string PaddedHex(IntType value) { 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result; 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.reserve(sizeof(value) * 2); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = sizeof(value) * 2 - 1; i >= 0; i--) { 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back(int_to_hex_digit(value >> (i*4) & 0x0F)); 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TextFormat::Printer::PrintUnknownFields( 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields, TextGenerator& generator) const { 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < unknown_fields.field_count(); i++) { 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownField& field = unknown_fields.field(i); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string field_number = SimpleItoa(field.number()); 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (field.type()) { 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UnknownField::TYPE_VARINT: 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field_number); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(": "); 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(SimpleItoa(field.varint())); 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" "); 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\n"); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UnknownField::TYPE_FIXED32: { 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field_number); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(": 0x"); 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[kFastToBufferSize]; 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(FastHex32ToBuffer(field.fixed32(), buffer)); 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" "); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\n"); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UnknownField::TYPE_FIXED64: { 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field_number); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(": 0x"); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer[kFastToBufferSize]; 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(FastHex64ToBuffer(field.fixed64(), buffer)); 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" "); 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\n"); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UnknownField::TYPE_LENGTH_DELIMITED: { 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field_number); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& value = field.length_delimited(); 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet embedded_unknown_fields; 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) { 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This field is parseable as a Message. 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So it is probably an embedded message. 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" { "); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" {\n"); 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Indent(); 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintUnknownFields(embedded_unknown_fields, generator); 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("} "); 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Outdent(); 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("}\n"); 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This field is not parseable as a Message. 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So it is probably just a plain string. 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(": \""); 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(CEscape(value)); 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\""); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" "); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("\n"); 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case UnknownField::TYPE_GROUP: 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(field_number); 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" { "); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print(" {\n"); 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Indent(); 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintUnknownFields(field.group(), generator); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (single_line_mode_) { 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("} "); 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Outdent(); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generator.Print("}\n"); 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 1522