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: kenton@google.com (Kenton Varda) 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 <google/protobuf/stubs/hash.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.h> 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor_database.h> 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/descriptor.pb.h> 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/dynamic_message.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/text_format.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/unknown_field_set.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/wire_format.h> 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h> 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/tokenizer.h> 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h> 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/once.h> 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/strutil.h> 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/substitute.h> 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/map-util.h> 57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <google/protobuf/stubs/stl_util.h> 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef PACKAGE // autoheader #defines this. :( 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor::CppType 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<CppType>(0), // 0 is reserved for errors 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_DOUBLE, // TYPE_DOUBLE 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_FLOAT, // TYPE_FLOAT 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_INT64, // TYPE_INT64 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_UINT64, // TYPE_UINT64 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_INT32, // TYPE_INT32 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_UINT64, // TYPE_FIXED64 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_UINT32, // TYPE_FIXED32 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_BOOL, // TYPE_BOOL 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_STRING, // TYPE_STRING 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_MESSAGE, // TYPE_GROUP 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_MESSAGE, // TYPE_MESSAGE 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_STRING, // TYPE_BYTES 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_UINT32, // TYPE_UINT32 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_ENUM, // TYPE_ENUM 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_INT32, // TYPE_SFIXED32 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_INT64, // TYPE_SFIXED64 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_INT32, // TYPE_SINT32 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CPPTYPE_INT64, // TYPE_SINT64 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ERROR", // 0 is reserved for errors 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "double", // TYPE_DOUBLE 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "float", // TYPE_FLOAT 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int64", // TYPE_INT64 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "uint64", // TYPE_UINT64 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "int32", // TYPE_INT32 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "fixed64", // TYPE_FIXED64 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "fixed32", // TYPE_FIXED32 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bool", // TYPE_BOOL 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "string", // TYPE_STRING 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "group", // TYPE_GROUP 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "message", // TYPE_MESSAGE 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "bytes", // TYPE_BYTES 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "uint32", // TYPE_UINT32 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "enum", // TYPE_ENUM 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sfixed32", // TYPE_SFIXED32 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sfixed64", // TYPE_SFIXED64 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sint32", // TYPE_SINT32 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "sint64", // TYPE_SINT64 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 111ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst char * const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = { 112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "ERROR", // 0 is reserved for errors 113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "int32", // CPPTYPE_INT32 115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "int64", // CPPTYPE_INT64 116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "uint32", // CPPTYPE_UINT32 117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "uint64", // CPPTYPE_UINT64 118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "double", // CPPTYPE_DOUBLE 119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "float", // CPPTYPE_FLOAT 120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "bool", // CPPTYPE_BOOL 121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "enum", // CPPTYPE_ENUM 122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "string", // CPPTYPE_STRING 123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "message", // CPPTYPE_MESSAGE 124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}; 125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ERROR", // 0 is reserved for errors 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "optional", // LABEL_OPTIONAL 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "required", // LABEL_REQUIRED 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "repeated", // LABEL_REPEATED 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int FieldDescriptor::kMaxNumber; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int FieldDescriptor::kFirstReservedNumber; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int FieldDescriptor::kLastReservedNumber; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ToCamelCase(const string& input) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool capitalize_next = false; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.reserve(input.size()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < input.size(); i++) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input[i] == '_') { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) capitalize_next = true; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (capitalize_next) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: I distrust ctype.h due to locales. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ('a' <= input[i] && input[i] <= 'z') { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back(input[i] - 'a' + 'A'); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back(input[i]); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) capitalize_next = false; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.push_back(input[i]); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lower-case the first letter. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result[0] = result[0] - 'A' + 'a'; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A DescriptorPool contains a bunch of hash_maps to implement the 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// various Find*By*() methods. Since hashtable lookups are O(1), it's 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// most efficient to construct a fixed set of large hash_maps used by 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// all objects in the pool rather than construct one or more small 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// hash_maps for each object. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The keys to these hash_maps are (parent, name) or (parent, number) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pairs. Unfortunately STL doesn't provide hash functions for pair<>, 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// so we must invent our own. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kenton): Use StringPiece rather than const char* in keys? It would 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be a lot cleaner but we'd just have to convert it back to const char* 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the open source release. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef pair<const void*, const char*> PointerStringPair; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PointerStringPairEqual { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool operator()(const PointerStringPair& a, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PointerStringPair& b) const { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a.first == b.first && strcmp(a.second, b.second) == 0; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename PairType> 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PointerIntegerPairHash { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t operator()(const PairType& p) const { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME(kenton): What is the best way to compute this hash? I have 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no idea! This seems a bit better than an XOR. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only by MSVC and platforms where hash_map is not available. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t bucket_size = 4; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t min_buckets = 8; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool operator()(const PairType& a, const PairType& b) const { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a.first < b.first || 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (a.first == b.first && a.second < b.second); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef pair<const Descriptor*, int> DescriptorIntPair; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef pair<const EnumDescriptor*, int> EnumIntPair; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PointerStringPairHash { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t operator()(const PointerStringPair& p) const { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME(kenton): What is the best way to compute this hash? I have 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no idea! This seems a bit better than an XOR. 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash<const char*> cstring_hash; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cstring_hash(p.second); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used only by MSVC and platforms where hash_map is not available. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t bucket_size = 4; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t min_buckets = 8; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool operator()(const PointerStringPair& a, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PointerStringPair& b) const { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a.first < b.first) return true; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (a.first > b.first) return false; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return strcmp(a.second, b.second) < 0; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Symbol { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Type { 237ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch NULL_SYMBOL, MESSAGE, FIELD, ENUM, ENUM_VALUE, SERVICE, METHOD, 238ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch PACKAGE 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* descriptor; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field_descriptor; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* enum_descriptor; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptor* enum_value_descriptor; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptor* service_descriptor; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MethodDescriptor* method_descriptor; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* package_file_descriptor; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool IsNull() const { return type == NULL_SYMBOL; } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool IsType() const { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type == MESSAGE || type == ENUM; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline bool IsAggregate() const { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return type == MESSAGE || type == PACKAGE 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || type == ENUM || type == SERVICE; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline explicit Symbol(const TYPE* value) { \ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type = TYPE_CONSTANT; \ 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->FIELD = value; \ 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CONSTRUCTOR 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* GetFile() const { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case NULL_SYMBOL: return NULL; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MESSAGE : return descriptor ->file(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FIELD : return field_descriptor ->file(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ENUM : return enum_descriptor ->file(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ENUM_VALUE : return enum_value_descriptor->type()->file(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SERVICE : return service_descriptor ->file(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case METHOD : return method_descriptor ->service()->file(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PACKAGE : return package_file_descriptor; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Symbol kNullSymbol; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<const char*, Symbol, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash<const char*>, streq> 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymbolsByNameMap; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<PointerStringPair, Symbol, 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPairHash, PointerStringPairEqual> 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymbolsByParentMap; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<const char*, const FileDescriptor*, 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash<const char*>, streq> 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilesByNameMap; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<PointerStringPair, const FieldDescriptor*, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPairHash, PointerStringPairEqual> 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldsByNameMap; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<DescriptorIntPair, const FieldDescriptor*, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerIntegerPairHash<DescriptorIntPair> > 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldsByNumberMap; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef hash_map<EnumIntPair, const EnumValueDescriptor*, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerIntegerPairHash<EnumIntPair> > 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValuesByNumberMap; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a map rather than a hash_map, since we use it to iterate 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through all the extensions that extend a given Descriptor, and an 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ordered data structure that implements lower_bound is convenient 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for that. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef map<DescriptorIntPair, const FieldDescriptor*> 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionsGroupedByDescriptorMap; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DescriptorPool::Tables 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DescriptorPool::Tables { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tables(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Tables(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 328ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Record the current state of the tables to the stack of checkpoints. 329ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Each call to AddCheckpoint() must be paired with exactly one call to either 330ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // ClearLastCheckpoint() or RollbackToLastCheckpoint(). 331ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 332ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // This is used when building files, since some kinds of validation errors 333ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // cannot be detected until the file's descriptors have already been added to 334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the tables. 335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 336ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // This supports recursive checkpoints, since building a file may trigger 337ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // recursive building of other files. Note that recursive checkpoints are not 338ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // normally necessary; explicit dependencies are built prior to checkpointing. 339ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // So although we recursively build transitive imports, there is at most one 340ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // checkpoint in the stack during dependency building. 341ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 342ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Recursive checkpoints only arise during cross-linking of the descriptors. 343ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and 344ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // friends. If the pending file references an unknown symbol 345ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // (e.g., it is not defined in the pending file's explicit dependencies), and 346ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the pool is using a fallback database, and that database contains a file 347ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // defining that symbol, and that file has not yet been built by the pool, 348ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the pool builds the file during cross-linking, leading to another 349ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // checkpoint. 350ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void AddCheckpoint(); 351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Mark the last checkpoint as having cleared successfully, removing it from 353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the stack. If the stack is empty, all pending symbols will be committed. 354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 355ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Note that this does not guarantee that the symbols added since the last 356ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // checkpoint won't be rolled back: if a checkpoint gets rolled back, 357ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // everything past that point gets rolled back, including symbols added after 358ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // checkpoints that were pushed onto the stack after it and marked as cleared. 359ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void ClearLastCheckpoint(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 361ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Roll back the Tables to the state of the checkpoint at the top of the 362ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // stack, removing everything that was added after that point. 363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void RollbackToLastCheckpoint(); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The stack of files which are currently being built. Used to detect 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cyclic dependencies when loading files from a DescriptorDatabase. Not 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // used when fallback_database_ == NULL. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string> pending_files_; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A set of files which we have tried to load from the fallback database 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and encountered errors. We will not attempt to load them again. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not used when fallback_database_ == NULL. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_set<string> known_bad_files_; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The set of descriptors for which we've already loaded the full 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // set of extensions numbers from fallback_database_. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hash_set<const Descriptor*> extensions_loaded_from_db_; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finding items. 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find symbols. This returns a null Symbol (symbol.IsNull() is true) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if not found. 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Symbol FindSymbol(const string& key) const; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This implements the body of DescriptorPool::Find*ByName(). It should 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // really be a private method of DescriptorPool, but that would require 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // declaring Symbol in descriptor.h, which would drag all kinds of other 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stuff into the header. Yay C++. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol FindByNameHelper( 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorPool* pool, const string& name) const; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These return NULL if not found. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const FileDescriptor* FindFile(const string& key) const; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const FieldDescriptor* FindExtension(const Descriptor* extendee, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int number); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void FindAllExtensions(const Descriptor* extendee, 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*>* out) const; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adding items. 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These add items to the corresponding tables. They return false if 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the key already exists in the table. For AddSymbol(), the string passed 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in must be one that was constructed using AllocateString(), as it will 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be used as a key in the symbols_by_name_ map without copying. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddSymbol(const string& full_name, Symbol symbol); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddFile(const FileDescriptor* file); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddExtension(const FieldDescriptor* field); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocating memory. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate an object which will be reclaimed when the pool is 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroyed. Note that the object's destructor will never be called, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so its fields must be plain old data (primitive data types and 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pointers). All of the descriptor types are such objects. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename Type> Type* Allocate(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate an array of objects which will be reclaimed when the 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pool in destroyed. Again, destructors are never called. 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename Type> Type* AllocateArray(int count); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a string which will be destroyed when the pool is destroyed. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string is initialized to the given value for convenience. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* AllocateString(const string& value); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a protocol message object. Some older versions of GCC have 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // trouble understanding explicit template instantiations in some cases, so 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in those cases we have to pass a dummy pointer of the right type as the 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter instead of specifying the type explicitly. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename Type> Type* AllocateMessage(Type* dummy = NULL); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate a FileDescriptorTables object. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorTables* AllocateFileTables(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string*> strings_; // All strings in the pool. 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<Message*> messages_; // All messages in the pool. 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<FileDescriptorTables*> file_tables_; // All file tables in the pool. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<void*> allocations_; // All other memory allocated in the pool. 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymbolsByNameMap symbols_by_name_; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilesByNameMap files_by_name_; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionsGroupedByDescriptorMap extensions_; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch struct CheckPoint { 448ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch explicit CheckPoint(const Tables* tables) 449ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : strings_before_checkpoint(tables->strings_.size()), 450ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch messages_before_checkpoint(tables->messages_.size()), 451ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_tables_before_checkpoint(tables->file_tables_.size()), 452ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allocations_before_checkpoint(tables->allocations_.size()), 453ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_symbols_before_checkpoint( 454ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables->symbols_after_checkpoint_.size()), 455ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_files_before_checkpoint( 456ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables->files_after_checkpoint_.size()), 457ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pending_extensions_before_checkpoint( 458ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables->extensions_after_checkpoint_.size()) { 459ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 460ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int strings_before_checkpoint; 461ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int messages_before_checkpoint; 462ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int file_tables_before_checkpoint; 463ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int allocations_before_checkpoint; 464ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int pending_symbols_before_checkpoint; 465ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int pending_files_before_checkpoint; 466ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int pending_extensions_before_checkpoint; 467ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch }; 468ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<CheckPoint> checkpoints_; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const char* > symbols_after_checkpoint_; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const char* > files_after_checkpoint_; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<DescriptorIntPair> extensions_after_checkpoint_; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate some bytes which will be reclaimed when the pool is 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroyed. 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* AllocateBytes(int size); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Contains tables specific to a particular file. These tables are not 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modified once the file has been constructed, so they need not be 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// protected by a mutex. This makes operations that depend only on the 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contents of a single file -- e.g. Descriptor::FindFieldByName() -- 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// lock-free. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For historical reasons, the definitions of the methods of 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FileDescriptorTables and DescriptorPool::Tables are interleaved below. 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These used to be a single class. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FileDescriptorTables { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorTables(); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~FileDescriptorTables(); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Empty table, used with placeholder files. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const FileDescriptorTables kEmpty; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finding items. 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find symbols. These return a null Symbol (symbol.IsNull() is true) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if not found. 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Symbol FindNestedSymbol(const void* parent, 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline Symbol FindNestedSymbolOfType(const void* parent, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol::Type type) const; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These return NULL if not found. 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const FieldDescriptor* FindFieldByNumber( 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, int number) const; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const FieldDescriptor* FindFieldByLowercaseName( 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& lowercase_name) const; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const FieldDescriptor* FindFieldByCamelcaseName( 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& camelcase_name) const; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline const EnumValueDescriptor* FindEnumValueByNumber( 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* parent, int number) const; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ----------------------------------------------------------------- 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adding items. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These add items to the corresponding tables. They return false if 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the key already exists in the table. For AddAliasUnderParent(), the 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string passed in must be one that was constructed using AllocateString(), 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as it will be used as a key in the symbols_by_parent_ map without copying. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddAliasUnderParent(const void* parent, const string& name, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol symbol); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddFieldByNumber(const FieldDescriptor* field); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddEnumValueByNumber(const EnumValueDescriptor* value); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the field to the lowercase_name and camelcase_name maps. Never 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fails because we allow duplicates; the first field by the name wins. 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddFieldByStylizedNames(const FieldDescriptor* field); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymbolsByParentMap symbols_by_parent_; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldsByNameMap fields_by_lowercase_name_; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldsByNameMap fields_by_camelcase_name_; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldsByNumberMap fields_by_number_; // Not including extensions. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValuesByNumberMap enum_values_by_number_; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::Tables::Tables() 541ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Start some hash_map and hash_set objects with a small # of buckets 542ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : known_bad_files_(3), 543ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extensions_loaded_from_db_(3), 544ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch symbols_by_name_(3), 545ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch files_by_name_(3) {} 546ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::Tables::~Tables() { 549ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_DCHECK(checkpoints_.empty()); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the deletion order is important, since the destructors of some 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages may refer to objects in allocations_. 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&messages_); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < allocations_.size(); i++) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator delete(allocations_[i]); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&strings_); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&file_tables_); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 560ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochFileDescriptorTables::FileDescriptorTables() 561ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Initialize all the hash tables to start out with a small # of buckets 562ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : symbols_by_parent_(3), 563ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fields_by_lowercase_name_(3), 564ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fields_by_camelcase_name_(3), 565ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fields_by_number_(3), 566ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch enum_values_by_number_(3) { 567ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 568ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptorTables::~FileDescriptorTables() {} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptorTables FileDescriptorTables::kEmpty; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 573ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid DescriptorPool::Tables::AddCheckpoint() { 574ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch checkpoints_.push_back(CheckPoint(this)); 575ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 577ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid DescriptorPool::Tables::ClearLastCheckpoint() { 578ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_DCHECK(!checkpoints_.empty()); 579ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch checkpoints_.pop_back(); 580ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (checkpoints_.empty()) { 581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // All checkpoints have been cleared: we can now commit all of the pending 582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // data. 583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch symbols_after_checkpoint_.clear(); 584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch files_after_checkpoint_.clear(); 585ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extensions_after_checkpoint_.clear(); 586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 589ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid DescriptorPool::Tables::RollbackToLastCheckpoint() { 590ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_DCHECK(!checkpoints_.empty()); 591ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const CheckPoint& checkpoint = checkpoints_.back(); 592ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 593ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = checkpoint.pending_symbols_before_checkpoint; 594ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i < symbols_after_checkpoint_.size(); 595ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i++) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbols_by_name_.erase(symbols_after_checkpoint_[i]); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 598ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = checkpoint.pending_files_before_checkpoint; 599ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i < files_after_checkpoint_.size(); 600ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i++) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files_by_name_.erase(files_after_checkpoint_[i]); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 603ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = checkpoint.pending_extensions_before_checkpoint; 604ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i < extensions_after_checkpoint_.size(); 605ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i++) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_.erase(extensions_after_checkpoint_[i]); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 609ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch symbols_after_checkpoint_.resize( 610ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch checkpoint.pending_symbols_before_checkpoint); 611ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint); 612ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extensions_after_checkpoint_.resize( 613ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch checkpoint.pending_extensions_before_checkpoint); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers( 616ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end()); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers( 618ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch messages_.begin() + checkpoint.messages_before_checkpoint, 619ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch messages_.end()); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers( 621ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_tables_.begin() + checkpoint.file_tables_before_checkpoint, 622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_tables_.end()); 623ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = checkpoint.allocations_before_checkpoint; 624ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i < allocations_.size(); 625ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch i++) { 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator delete(allocations_[i]); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 629ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch strings_.resize(checkpoint.strings_before_checkpoint); 630ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch messages_.resize(checkpoint.messages_before_checkpoint); 631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch file_tables_.resize(checkpoint.file_tables_before_checkpoint); 632ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch allocations_.resize(checkpoint.allocations_before_checkpoint); 633ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch checkpoints_.pop_back(); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL) { 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kNullSymbol; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *result; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline Symbol FileDescriptorTables::FindNestedSymbol( 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& name) const { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol* result = 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str())); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL) { 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kNullSymbol; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *result; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline Symbol FileDescriptorTables::FindNestedSymbolOfType( 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& name, const Symbol::Type type) const { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = FindNestedSymbol(parent, name); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.type != type) return kNullSymbol; 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol DescriptorPool::Tables::FindByNameHelper( 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorPool* pool, const string& name) const { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLockMaybe lock(pool->mutex_); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = FindSymbol(name); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.IsNull() && pool->underlay_ != NULL) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Symbol not found; check the underlay. 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.IsNull()) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Symbol still not found, so check fallback database. 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool->TryFindSymbolInFallbackDatabase(name)) { 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = FindSymbol(name); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const FileDescriptor* DescriptorPool::Tables::FindFile( 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& key) const { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindPtrOrNull(files_by_name_, key.c_str()); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, int number) const { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindPtrOrNull(fields_by_number_, make_pair(parent, number)); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& lowercase_name) const { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindPtrOrNull(fields_by_lowercase_name_, 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPair(parent, lowercase_name.c_str())); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& camelcase_name) const { 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindPtrOrNull(fields_by_camelcase_name_, 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPair(parent, camelcase_name.c_str())); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* parent, int number) const { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number)); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline const FieldDescriptor* DescriptorPool::Tables::FindExtension( 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* extendee, int number) { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindPtrOrNull(extensions_, make_pair(extendee, number)); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void DescriptorPool::Tables::FindAllExtensions( 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionsGroupedByDescriptorMap::const_iterator it = 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_.lower_bound(make_pair(extendee, 0)); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; it != extensions_.end() && it->first.first == extendee; ++it) { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out->push_back(it->second); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::Tables::AddSymbol( 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& full_name, Symbol symbol) { 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) { 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) symbols_after_checkpoint_.push_back(full_name.c_str()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileDescriptorTables::AddAliasUnderParent( 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& name, Symbol symbol) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPair by_parent_key(parent, name.c_str()); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) { 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files_after_checkpoint_.push_back(file->name().c_str()); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileDescriptorTables::AddFieldByStylizedNames( 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_extension()) { 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->extension_scope() == NULL) { 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = field->file(); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = field->extension_scope(); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = field->containing_type(); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorIntPair key(field->containing_type(), field->number()); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InsertIfNotPresent(&fields_by_number_, key, field); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FileDescriptorTables::AddEnumValueByNumber( 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptor* value) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumIntPair key(value->type(), value->number()); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return InsertIfNotPresent(&enum_values_by_number_, key, value); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) { 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorIntPair key(field->containing_type(), field->number()); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (InsertIfNotPresent(&extensions_, key, field)) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_after_checkpoint_.push_back(key); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Type> 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Type* DescriptorPool::Tables::Allocate() { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type))); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Type> 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Type* DescriptorPool::Tables::AllocateArray(int count) { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count)); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string* DescriptorPool::Tables::AllocateString(const string& value) { 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* result = new string(value); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings_.push_back(result); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Type> 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Type* DescriptorPool::Tables::AllocateMessage(Type* dummy) { 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type* result = new Type; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) messages_.push_back(result); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorTables* result = new FileDescriptorTables; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_tables_.push_back(result); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* DescriptorPool::Tables::AllocateBytes(int size) { 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Would it be worthwhile to implement this in some more 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sophisticated way? Probably not for the open source release, but for 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // internal use we could easily plug in one of our existing memory pool 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allocators... 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size == 0) return NULL; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* result = operator new(size); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allocations_.push_back(result); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DescriptorPool 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::ErrorCollector::~ErrorCollector() {} 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::DescriptorPool() 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : mutex_(NULL), 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback_database_(NULL), 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_error_collector_(NULL), 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) underlay_(NULL), 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_(new Tables), 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enforce_dependencies_(true), 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_unknown_(false) {} 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCollector* error_collector) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : mutex_(new Mutex), 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback_database_(fallback_database), 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_error_collector_(error_collector), 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) underlay_(NULL), 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_(new Tables), 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enforce_dependencies_(true), 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_unknown_(false) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::DescriptorPool(const DescriptorPool* underlay) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : mutex_(NULL), 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fallback_database_(NULL), 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_error_collector_(NULL), 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) underlay_(underlay), 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_(new Tables), 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enforce_dependencies_(true), 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_unknown_(false) {} 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool::~DescriptorPool() { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mutex_ != NULL) delete mutex_; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DescriptorPool::BuildFile() defined later. 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DescriptorPool::BuildFileCollectingErrors() defined later. 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorPool::InternalDontEnforceDependencies() { 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enforce_dependencies_ = false; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::InternalIsFileLoaded(const string& filename) const { 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLockMaybe lock(mutex_); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return tables_->FindFile(filename) != NULL; 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// generated_pool ==================================================== 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EncodedDescriptorDatabase* generated_database_ = NULL; 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool* generated_pool_ = NULL; 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DeleteGeneratedPool() { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete generated_database_; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generated_database_ = NULL; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete generated_pool_; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generated_pool_ = NULL; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 904ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstatic void InitGeneratedPool() { 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generated_database_ = new EncodedDescriptorDatabase; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generated_pool_ = new DescriptorPool(generated_database_); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::OnShutdown(&DeleteGeneratedPool); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline void InitGeneratedPoolOnce() { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const DescriptorPool* DescriptorPool::generated_pool() { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitGeneratedPoolOnce(); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return generated_pool_; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorPool* DescriptorPool::internal_generated_pool() { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitGeneratedPoolOnce(); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return generated_pool_; 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorPool::InternalAddGeneratedFile( 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* encoded_file_descriptor, int size) { 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So, this function is called in the process of initializing the 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptors for generated proto classes. Each generated .pb.cc file 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has an internal procedure called AddDescriptors() which is called at 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process startup, and that function calls this one in order to register 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the raw bytes of the FileDescriptorProto representing the file. 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not actually construct the descriptor objects right away. We just 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hang on to the bytes until they are actually needed. We actually construct 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the descriptor the first time one of the following things happens: 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // * Someone calls a method like descriptor(), GetDescriptor(), or 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetReflection() on the generated types, which requires returning the 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor or an object based on it. 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // * Someone looks up the descriptor in DescriptorPool::generated_pool(). 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once one of these happens, the DescriptorPool actually parses the 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FileDescriptorProto and generates a FileDescriptor (and all its children) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // based on it. 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that FileDescriptorProto is itself a generated protocol message. 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Therefore, when we parse one, we have to be very careful to avoid using 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any descriptor-based operations, since this might cause infinite recursion 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or deadlock. 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitGeneratedPoolOnce(); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size)); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Find*By* methods ================================================== 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kenton): There's a lot of repeated code here, but I'm not sure if 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there's any good way to factor it out. Think about this some time when 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there's nothing more important to do (read: never). 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorPool::FindFileByName(const string& name) const { 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLockMaybe lock(mutex_); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* result = tables_->FindFile(name); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) return result; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (underlay_ != NULL) { 967ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = underlay_->FindFileByName(name); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) return result; 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryFindFileInFallbackDatabase(name)) { 971ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = tables_->FindFile(name); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) return result; 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorPool::FindFileContainingSymbol( 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& symbol_name) const { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLockMaybe lock(mutex_); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindSymbol(symbol_name); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) return result.GetFile(); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (underlay_ != NULL) { 983ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FileDescriptor* file_result = 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) underlay_->FindFileContainingSymbol(symbol_name); 985ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (file_result != NULL) return file_result; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryFindSymbolInFallbackDatabase(symbol_name)) { 988ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = tables_->FindSymbol(symbol_name); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) return result.GetFile(); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Descriptor* DescriptorPool::FindMessageTypeByName( 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL; 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* DescriptorPool::FindFieldByName( 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.type == Symbol::FIELD && 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !result.field_descriptor->is_extension()) { 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.field_descriptor; 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* DescriptorPool::FindExtensionByName( 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.type == Symbol::FIELD && 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.field_descriptor->is_extension()) { 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.field_descriptor; 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumDescriptor* DescriptorPool::FindEnumTypeByName( 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL; 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumValueDescriptor* DescriptorPool::FindEnumValueByName( 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result.type == Symbol::ENUM_VALUE) ? 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.enum_value_descriptor : NULL; 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ServiceDescriptor* DescriptorPool::FindServiceByName( 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MethodDescriptor* DescriptorPool::FindMethodByName( 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) const { 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindByNameHelper(this, name); 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* DescriptorPool::FindExtensionByNumber( 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* extendee, int number) const { 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLockMaybe lock(mutex_); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = tables_->FindExtension(extendee, number); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (underlay_ != NULL) { 1055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = underlay_->FindExtensionByNumber(extendee, number); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) return result; 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TryFindExtensionInFallbackDatabase(extendee, number)) { 1059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = tables_->FindExtension(extendee, number); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != NULL) { 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorPool::FindAllExtensions( 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MutexLockMaybe lock(mutex_); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize tables_->extensions_ from the fallback database first 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (but do this only once per descriptor). 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fallback_database_ != NULL && 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->extensions_loaded_from_db_.count(extendee) == 0) { 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<int> numbers; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &numbers)) { 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < numbers.size(); ++i) { 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int number = numbers[i]; 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->FindExtension(extendee, number) == NULL) { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryFindExtensionInFallbackDatabase(extendee, number); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->extensions_loaded_from_db_.insert(extendee); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->FindAllExtensions(extendee, out); 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (underlay_ != NULL) { 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) underlay_->FindAllExtensions(extendee, out); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindFieldByNumber(int key) const { 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindFieldByNumber(this, key); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || result->is_extension()) { 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindFieldByLowercaseName(const string& key) const { 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindFieldByLowercaseName(this, key); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || result->is_extension()) { 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindFieldByCamelcaseName(const string& key) const { 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindFieldByCamelcaseName(this, key); 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || result->is_extension()) { 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindFieldByName(const string& key) const { 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull() && !result.field_descriptor->is_extension()) { 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.field_descriptor; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindExtensionByName(const string& key) const { 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull() && result.field_descriptor->is_extension()) { 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.field_descriptor; 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindExtensionByLowercaseName(const string& key) const { 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindFieldByLowercaseName(this, key); 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || !result->is_extension()) { 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindExtensionByCamelcaseName(const string& key) const { 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindFieldByCamelcaseName(this, key); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || !result->is_extension()) { 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Descriptor* 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindNestedTypeByName(const string& key) const { 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.descriptor; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumDescriptor* 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindEnumTypeByName(const string& key) const { 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.enum_descriptor; 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumValueDescriptor* 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Descriptor::FindEnumValueByName(const string& key) const { 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.enum_value_descriptor; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumValueDescriptor* 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnumDescriptor::FindValueByName(const string& key) const { 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.enum_value_descriptor; 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumValueDescriptor* 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnumDescriptor::FindValueByNumber(int key) const { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file()->tables_->FindEnumValueByNumber(this, key); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const MethodDescriptor* 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ServiceDescriptor::FindMethodByName(const string& key) const { 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.method_descriptor; 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Descriptor* 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindMessageTypeByName(const string& key) const { 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.descriptor; 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumDescriptor* 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindEnumTypeByName(const string& key) const { 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.enum_descriptor; 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EnumValueDescriptor* 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindEnumValueByName(const string& key) const { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.enum_value_descriptor; 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ServiceDescriptor* 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindServiceByName(const string& key) const { 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.service_descriptor; 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindExtensionByName(const string& key) const { 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull() && result.field_descriptor->is_extension()) { 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.field_descriptor; 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindExtensionByLowercaseName(const string& key) const { 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || !result->is_extension()) { 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FieldDescriptor* 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileDescriptor::FindExtensionByCamelcaseName(const string& key) const { 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == NULL || !result->is_extension()) { 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Descriptor::IsExtensionNumber(int number) const { 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Linear search should be fine because we don't expect a message to have 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // more than a couple extension ranges. 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_range_count(); i++) { 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (number >= extension_range(i)->start && 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number < extension_range(i)->end) { 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fallback_database_ == NULL) return false; 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->known_bad_files_.count(name) > 0) return false; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorProto file_proto; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!fallback_database_->FindFileByName(name, &file_proto) || 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildFileFromDatabase(file_proto) == NULL) { 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->known_bad_files_.insert(name); 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1333ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const { 1334ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string prefix = name; 1335ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (;;) { 1336ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string::size_type dot_pos = prefix.find_last_of('.'); 1337ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (dot_pos == string::npos) { 1338ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch break; 1339ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1340ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch prefix = prefix.substr(0, dot_pos); 1341ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Symbol symbol = tables_->FindSymbol(prefix); 1342ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If the symbol type is anything other than PACKAGE, then its complete 1343ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // definition is already known. 1344ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) { 1345ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 1346ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1347ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1348ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (underlay_ != NULL) { 1349ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Check to see if any prefix of this symbol exists in the underlay. 1350ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return underlay_->IsSubSymbolOfBuiltType(name); 1351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1352ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 1353ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1354ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const { 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fallback_database_ == NULL) return false; 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1358ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // We skip looking in the fallback database if the name is a sub-symbol of 1359ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // any descriptor that already exists in the descriptor pool (except for 1360ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // package descriptors). This is valid because all symbols except for 1361ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // packages are defined in a single file, so if the symbol exists then we 1362ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // should already have its definition. 1363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // 1364ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The other reason to do this is to support "overriding" type definitions 1365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // by merging two databases that define the same type. (Yes, people do 1366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // this.) The main difficulty with making this work is that 1367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // FindFileContainingSymbol() is allowed to return both false positives 1368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false 1369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase). When two 1370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // such databases are merged, looking up a non-existent sub-symbol of a type 1371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // that already exists in the descriptor pool can result in an attempt to 1372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // load multiple definitions of the same type. The check below avoids this. 1373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (IsSubSymbolOfBuiltType(name)) return false; 1374ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorProto file_proto; 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!fallback_database_->FindFileContainingSymbol(name, &file_proto)) { 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->FindFile(file_proto.name()) != NULL) { 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've already loaded this file, and it apparently doesn't contain the 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // symbol we're looking for. Some DescriptorDatabases return false 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // positives. 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BuildFileFromDatabase(file_proto) == NULL) { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorPool::TryFindExtensionInFallbackDatabase( 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* containing_type, int field_number) const { 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fallback_database_ == NULL) return false; 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorProto file_proto; 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!fallback_database_->FindFileContainingExtension( 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_type->full_name(), field_number, &file_proto)) { 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->FindFile(file_proto.name()) != NULL) { 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've already loaded this file, and it apparently doesn't contain the 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension we're looking for. Some DescriptorDatabases return false 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // positives. 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BuildFileFromDatabase(file_proto) == NULL) { 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const { 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(has_default_value()) << "No default value"; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cpp_type()) { 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_INT32: 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(default_value_int32()); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_INT64: 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(default_value_int64()); 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_UINT32: 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(default_value_uint32()); 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_UINT64: 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleItoa(default_value_uint64()); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_FLOAT: 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleFtoa(default_value_float()); 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_DOUBLE: 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SimpleDtoa(default_value_double()); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_BOOL: 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_value_bool() ? "true" : "false"; 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_STRING: 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (quote_string_type) { 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "\"" + CEscape(default_value_string()) + "\""; 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type() == TYPE_BYTES) { 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CEscape(default_value_string()); 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_value_string(); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_ENUM: 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return default_value_enum()->name(); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case CPPTYPE_MESSAGE: 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// CopyTo methods ==================================================== 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FileDescriptor::CopyTo(FileDescriptorProto* proto) const { 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!package().empty()) proto->set_package(package()); 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < dependency_count(); i++) { 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->add_dependency(dependency(i)->name()); 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1476ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < public_dependency_count(); i++) { 1477ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch proto->add_public_dependency(public_dependencies_[i]); 1478ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1479ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1480ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < weak_dependency_count(); i++) { 1481ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch proto->add_weak_dependency(weak_dependencies_[i]); 1482ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1483ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message_type_count(); i++) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_type(i)->CopyTo(proto->add_message_type()); 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < enum_type_count(); i++) { 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_type(i)->CopyTo(proto->add_enum_type()); 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < service_count(); i++) { 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service(i)->CopyTo(proto->add_service()); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_count(); i++) { 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension(i)->CopyTo(proto->add_extension()); 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &FileOptions::default_instance()) { 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const { 1503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (source_code_info_ != &SourceCodeInfo::default_instance()) { 1504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch proto->mutable_source_code_info()->CopyFrom(*source_code_info_); 1505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1507ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Descriptor::CopyTo(DescriptorProto* proto) const { 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < field_count(); i++) { 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field(i)->CopyTo(proto->add_field()); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < nested_type_count(); i++) { 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_type(i)->CopyTo(proto->add_nested_type()); 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < enum_type_count(); i++) { 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_type(i)->CopyTo(proto->add_enum_type()); 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_range_count(); i++) { 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorProto::ExtensionRange* range = proto->add_extension_range(); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->set_start(extension_range(i)->start); 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->set_end(extension_range(i)->end); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_count(); i++) { 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension(i)->CopyTo(proto->add_extension()); 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &MessageOptions::default_instance()) { 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_number(number()); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some compilers do not allow static_cast directly between two enum types, 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we must cast to int first. 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_label(static_cast<FieldDescriptorProto::Label>( 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<int>(label()))); 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_type(static_cast<FieldDescriptorProto::Type>( 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<int>(type()))); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_extension()) { 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!containing_type()->is_unqualified_placeholder_) { 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_extendee("."); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_extendee()->append(containing_type()->full_name()); 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cpp_type() == CPPTYPE_MESSAGE) { 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_type()->is_placeholder_) { 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't actually know if the type is a message type. It could be 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an enum. 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->clear_type(); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!message_type()->is_unqualified_placeholder_) { 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_type_name("."); 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_type_name()->append(message_type()->full_name()); 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (cpp_type() == CPPTYPE_ENUM) { 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!enum_type()->is_unqualified_placeholder_) { 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_type_name("."); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_type_name()->append(enum_type()->full_name()); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_default_value()) { 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_default_value(DefaultValueAsString(false)); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &FieldOptions::default_instance()) { 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < value_count(); i++) { 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value(i)->CopyTo(proto->add_value()); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &EnumOptions::default_instance()) { 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_number(number()); 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &EnumValueOptions::default_instance()) { 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < method_count(); i++) { 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method(i)->CopyTo(proto->add_method()); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &ServiceOptions::default_instance()) { 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_name(name()); 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input_type()->is_unqualified_placeholder_) { 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_input_type("."); 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_input_type()->append(input_type()->full_name()); 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!output_type()->is_unqualified_placeholder_) { 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->set_output_type("."); 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_output_type()->append(output_type()->full_name()); 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (&options() != &MethodOptions::default_instance()) { 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto->mutable_options()->CopyFrom(options()); 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DebugString methods =============================================== 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used by each of the option formatters. 1635ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool RetrieveOptions(int depth, 1636ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Message &options, 1637ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<string> *option_entries) { 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_entries->clear(); 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Reflection* reflection = options.GetReflection(); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*> fields; 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reflection->ListFields(options, &fields); 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < fields.size(); i++) { 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 1; 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool repeated = false; 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fields[i]->is_repeated()) { 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count = reflection->FieldSize(options, fields[i]); 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) repeated = true; 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < count; j++) { 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string fieldval; 1651ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1652ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string tmp; 1653ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch TextFormat::Printer printer; 1654ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer.SetInitialIndentLevel(depth + 1); 1655ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch printer.PrintFieldValueToString(options, fields[i], 1656ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch repeated ? j : -1, &tmp); 1657ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fieldval.append("{\n"); 1658ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fieldval.append(tmp); 1659ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fieldval.append(depth * 2, ' '); 1660ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch fieldval.append("}"); 1661ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 1662ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch TextFormat::PrintFieldValueToString(options, fields[i], 1663ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch repeated ? j : -1, &fieldval); 1664ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1665ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch string name; 1666ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (fields[i]->is_extension()) { 1667ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch name = "(." + fields[i]->full_name() + ")"; 1668ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 1669ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch name = fields[i]->name(); 1670ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1671ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch option_entries->push_back(name + " = " + fieldval); 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !option_entries->empty(); 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Formats options that all appear together in brackets. Does not include 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// brackets. 1679ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool FormatBracketedOptions(int depth, const Message &options, string *output) { 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string> all_options; 1681ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (RetrieveOptions(depth, options, &all_options)) { 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->append(JoinStrings(all_options, ", ")); 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !all_options.empty(); 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Formats options one per line 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FormatLineOptions(int depth, const Message &options, string *output) { 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix(depth * 2, ' '); 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<string> all_options; 1691ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (RetrieveOptions(depth, options, &all_options)) { 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < all_options.size(); i++) { 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(output, "$0option $1;\n", 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, all_options[i]); 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !all_options.empty(); 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FileDescriptor::DebugString() const { 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents = "syntax = \"proto2\";\n\n"; 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch set<int> public_dependencies; 1706ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch set<int> weak_dependencies; 1707ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public_dependencies.insert(public_dependencies_, 1708ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public_dependencies_ + public_dependency_count_); 1709ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_dependencies.insert(weak_dependencies_, 1710ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch weak_dependencies_ + weak_dependency_count_); 1711ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < dependency_count(); i++) { 1713ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (public_dependencies.count(i) > 0) { 1714ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", 1715ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch dependency(i)->name()); 1716ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else if (weak_dependencies.count(i) > 0) { 1717ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", 1718ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch dependency(i)->name()); 1719ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 1720ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch strings::SubstituteAndAppend(&contents, "import \"$0\";\n", 1721ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch dependency(i)->name()); 1722ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!package().empty()) { 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FormatLineOptions(0, options(), &contents)) { 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents.append("\n"); // add some space if we had options 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < enum_type_count(); i++) { 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_type(i)->DebugString(0, &contents); 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents.append("\n"); 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find all the 'group' type extensions; we will not output their nested 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // definitions (those will be done with their group field descriptor). 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set<const Descriptor*> groups; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_count(); i++) { 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) groups.insert(extension(i)->message_type()); 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message_type_count(); i++) { 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (groups.count(message_type(i)) == 0) { 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(&contents, "message $0", 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_type(i)->name()); 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_type(i)->DebugString(0, &contents); 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents.append("\n"); 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < service_count(); i++) { 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service(i)->DebugString(&contents); 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents.append("\n"); 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* containing_type = NULL; 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_count(); i++) { 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension(i)->containing_type() != containing_type) { 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) contents.append("}\n\n"); 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_type = extension(i)->containing_type(); 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(&contents, "extend .$0 {\n", 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_type->full_name()); 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension(i)->DebugString(1, &contents); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_count() > 0) contents.append("}\n\n"); 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string Descriptor::DebugString() const { 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents; 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(&contents, "message $0", name()); 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugString(0, &contents); 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Descriptor::DebugString(int depth, string *contents) const { 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix(depth * 2, ' '); 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++depth; 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append(" {\n"); 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatLineOptions(depth, options(), contents); 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find all the 'group' types for fields and extensions; we will not output 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // their nested definitions (those will be done with their group field 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor). 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set<const Descriptor*> groups; 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < field_count(); i++) { 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) groups.insert(field(i)->message_type()); 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_count(); i++) { 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) groups.insert(extension(i)->message_type()); 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < nested_type_count(); i++) { 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (groups.count(nested_type(i)) == 0) { 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0 message $1", 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, nested_type(i)->name()); 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nested_type(i)->DebugString(depth, contents); 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < enum_type_count(); i++) { 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_type(i)->DebugString(depth, contents); 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < field_count(); i++) { 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field(i)->DebugString(depth, contents); 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_range_count(); i++) { 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_range(i)->start, 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_range(i)->end - 1); 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Group extensions by what they extend, so they can be printed out together. 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* containing_type = NULL; 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < extension_count(); i++) { 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension(i)->containing_type() != containing_type) { 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_type = extension(i)->containing_type(); 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, containing_type->full_name()); 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension(i)->DebugString(depth + 1, contents); 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_count() > 0) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0}\n", prefix); 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string FieldDescriptor::DebugString() const { 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents; 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int depth = 0; 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_extension()) { 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(&contents, "extend .$0 {\n", 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) containing_type()->full_name()); 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) depth = 1; 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugString(depth, &contents); 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_extension()) { 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents.append("}\n"); 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FieldDescriptor::DebugString(int depth, string *contents) const { 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix(depth * 2, ' '); 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string field_type; 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type()) { 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_MESSAGE: 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_type = "." + message_type()->full_name(); 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_ENUM: 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_type = "." + enum_type()->full_name(); 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_type = kTypeToName[type()]; 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0$1 $2 $3 = $4", 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLabelToName[label()], 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field_type, 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type() == TYPE_GROUP ? message_type()->name() : 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name(), 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) number()); 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool bracketed = false; 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_default_value()) { 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bracketed = true; 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, " [default = $0", 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultValueAsString(true)); 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string formatted_options; 1888ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (FormatBracketedOptions(depth, options(), &formatted_options)) { 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append(bracketed ? ", " : " ["); 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bracketed = true; 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append(formatted_options); 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bracketed) { 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append("]"); 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type() == TYPE_GROUP) { 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_type()->DebugString(depth, contents); 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append(";\n"); 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string EnumDescriptor::DebugString() const { 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents; 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugString(0, &contents); 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnumDescriptor::DebugString(int depth, string *contents) const { 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix(depth * 2, ' '); 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++depth; 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0enum $1 {\n", 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, name()); 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatLineOptions(depth, options(), contents); 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < value_count(); i++) { 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value(i)->DebugString(depth, contents); 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0}\n", prefix); 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string EnumValueDescriptor::DebugString() const { 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents; 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugString(0, &contents); 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnumValueDescriptor::DebugString(int depth, string *contents) const { 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix(depth * 2, ' '); 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0$1 = $2", 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, name(), number()); 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string formatted_options; 1937ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (FormatBracketedOptions(depth, options(), &formatted_options)) { 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, " [$0]", formatted_options); 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append(";\n"); 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string ServiceDescriptor::DebugString() const { 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents; 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugString(&contents); 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ServiceDescriptor::DebugString(string *contents) const { 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "service $0 {\n", name()); 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FormatLineOptions(1, options(), contents); 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < method_count(); i++) { 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method(i)->DebugString(1, contents); 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append("}\n"); 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string MethodDescriptor::DebugString() const { 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string contents; 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugString(0, &contents); 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return contents; 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MethodDescriptor::DebugString(int depth, string *contents) const { 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string prefix(depth * 2, ' '); 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++depth; 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)", 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix, name(), 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_type()->full_name(), 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_type()->full_name()); 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string formatted_options; 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FormatLineOptions(depth, options(), &formatted_options)) { 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::SubstituteAndAppend(contents, " {\n$0$1}\n", 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatted_options, prefix); 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) contents->append(";\n"); 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1983ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1984ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1985ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Location methods =============================================== 1986ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1987ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstatic bool PathsEqual(const vector<int>& x, const RepeatedField<int32>& y) { 1988ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (x.size() != y.size()) return false; 1989ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < x.size(); ++i) { 1990ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (x[i] != y.Get(i)) return false; 1991ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 1992ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 1993ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 1994ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 1995ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool FileDescriptor::GetSourceLocation(const vector<int>& path, 1996ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SourceLocation* out_location) const { 1997ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK_NOTNULL(out_location); 1998ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const SourceCodeInfo* info = source_code_info_; 1999ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; info && i < info->location_size(); ++i) { 2000ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (PathsEqual(path, info->location(i).path())) { 2001ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const RepeatedField<int32>& span = info->location(i).span(); 2002ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (span.size() == 3 || span.size() == 4) { 2003ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_location->start_line = span.Get(0); 2004ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_location->start_column = span.Get(1); 2005ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); 2006ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_location->end_column = span.Get(span.size() - 1); 2007ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2008ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_location->leading_comments = info->location(i).leading_comments(); 2009ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch out_location->trailing_comments = info->location(i).trailing_comments(); 2010ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return true; 2011ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 2012ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 2013ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 2014ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return false; 2015ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2016ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2017ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool FieldDescriptor::is_packed() const { 2018ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return is_packable() && (options_ != NULL) && options_->packed(); 2019ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2020ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2021ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool Descriptor::GetSourceLocation(SourceLocation* out_location) const { 2022ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<int> path; 2023ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetLocationPath(&path); 2024ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return file()->GetSourceLocation(path, out_location); 2025ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2026ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2027ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2028ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<int> path; 2029ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetLocationPath(&path); 2030ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return file()->GetSourceLocation(path, out_location); 2031ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2032ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2033ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2034ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<int> path; 2035ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetLocationPath(&path); 2036ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return file()->GetSourceLocation(path, out_location); 2037ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2038ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2039ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<int> path; 2041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetLocationPath(&path); 2042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return service()->file()->GetSourceLocation(path, out_location); 2043ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2044ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2045ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2046ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<int> path; 2047ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetLocationPath(&path); 2048ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return file()->GetSourceLocation(path, out_location); 2049ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2050ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2051ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochbool EnumValueDescriptor::GetSourceLocation( 2052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SourceLocation* out_location) const { 2053ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch vector<int> path; 2054ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GetLocationPath(&path); 2055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return type()->file()->GetSourceLocation(path, out_location); 2056ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2057ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Descriptor::GetLocationPath(vector<int>* output) const { 2059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (containing_type()) { 2060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch containing_type()->GetLocationPath(output); 2061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(DescriptorProto::kNestedTypeFieldNumber); 2062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 2064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); 2065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 2067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid FieldDescriptor::GetLocationPath(vector<int>* output) const { 2070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch containing_type()->GetLocationPath(output); 2071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(DescriptorProto::kFieldFieldNumber); 2072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2074ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2075ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid EnumDescriptor::GetLocationPath(vector<int>* output) const { 2076ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (containing_type()) { 2077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch containing_type()->GetLocationPath(output); 2078ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(DescriptorProto::kEnumTypeFieldNumber); 2079ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2080ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 2081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); 2082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 2084ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2085ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid EnumValueDescriptor::GetLocationPath(vector<int>* output) const { 2087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch type()->GetLocationPath(output); 2088ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(EnumDescriptorProto::kValueFieldNumber); 2089ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2090ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2091ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2092ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid ServiceDescriptor::GetLocationPath(vector<int>* output) const { 2093ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(FileDescriptorProto::kServiceFieldNumber); 2094ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2095ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2096ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2097ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid MethodDescriptor::GetLocationPath(vector<int>* output) const { 2098ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch service()->GetLocationPath(output); 2099ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(ServiceDescriptorProto::kMethodFieldNumber); 2100ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch output->push_back(index()); 2101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2102ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Represents an options message to interpret. Extension names in the option 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// name are respolved relative to name_scope. element_name and orig_opt are 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// used only for error reporting (since the parser records locations against 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pointers in the original options, not the mutable copy). The Message must be 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// one of the Options messages in descriptor.proto. 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct OptionsToInterpret { 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptionsToInterpret(const string& ns, 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& el, 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message* orig_opt, 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* opt) 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : name_scope(ns), 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element_name(el), 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_options(orig_opt), 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options(opt) { 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string name_scope; 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string element_name; 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message* original_options; 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* options; 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DescriptorBuilder { 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorBuilder(const DescriptorPool* pool, 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::Tables* tables, 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector* error_collector); 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~DescriptorBuilder(); 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* BuildFile(const FileDescriptorProto& proto); 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class OptionInterpreter; 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorPool* pool_; 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::Tables* tables_; // for convenience 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector* error_collector_; 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As we build descriptors we store copies of the options messages in 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them. We put pointers to those copies in this vector, as we build, so we 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can later (after cross-linking) interpret those options. 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<OptionsToInterpret> options_to_interpret_; 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool had_errors_; 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string filename_; 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* file_; 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorTables* file_tables_; 2155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch set<const FileDescriptor*> dependencies_; 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If LookupSymbol() finds a symbol that is in a file which is not a declared 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dependency of this file, it will fail, but will set 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible_undeclared_dependency_ to point at that file. This is only used 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by AddNotDefinedError() to report a more useful error message. 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible_undeclared_dependency_name_ is the name of the symbol that was 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually found in possible_undeclared_dependency_, which may be a parent 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the symbol actually looked for. 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* possible_undeclared_dependency_; 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string possible_undeclared_dependency_name_; 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddError(const string& element_name, 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& descriptor, 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::ErrorLocation location, 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& error); 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds an error indicating that undefined_symbol was not defined. Must 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only be called after LookupSymbol() fails. 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddNotDefinedError( 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& element_name, 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& descriptor, 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::ErrorLocation location, 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& undefined_symbol); 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Silly helper which determines if the given file is in the given package. 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I.e., either file->package() == package_name or file->package() is a 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nested package within package_name. 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsInPackage(const FileDescriptor* file, const string& package_name); 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Helper function which finds all public dependencies of the given file, and 2186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // stores the them in the dependencies_ set in the builder. 2187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch void RecordPublicDependencies(const FileDescriptor* file); 2188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like tables_->FindSymbol(), but additionally: 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - Search the pool's underlay if not found in tables_. 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // - Insure that the resulting Symbol is from one of the file's declared 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dependencies. 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol FindSymbol(const string& name); 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like FindSymbol() but does not require that the symbol is in one of the 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file's declared dependencies. 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol FindSymbolNotEnforcingDeps(const string& name); 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // This implements the body of FindSymbolNotEnforcingDeps(). 2200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool, 2201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const string& name); 2202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like FindSymbol(), but looks up the name relative to some other symbol 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name. This first searches siblings of relative_to, then siblings of its 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the following calls, returning the first non-null result: 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the DescriptorPool, this will generate a placeholder type if 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the name is not found (unless the name itself is malformed). The 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // placeholder_type parameter indicates what kind of placeholder should be 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // constructed in this case. The resolve_mode parameter determines whether 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any symbol is returned, or only symbols that are types. Note, however, 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if it believes that's all it could refer to. The caller should always 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check that it receives the type of symbol it was expecting. 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum PlaceholderType { 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLACEHOLDER_MESSAGE, 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLACEHOLDER_ENUM, 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLACEHOLDER_EXTENDABLE_MESSAGE 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum ResolveMode { 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOOKUP_ALL, LOOKUP_TYPES 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol LookupSymbol(const string& name, const string& relative_to, 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE, 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveMode resolve_mode = LOOKUP_ALL); 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like LookupSymbol() but will not return a placeholder even if 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AllowUnknownDependencies() has been used. 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol LookupSymbolNoPlaceholder(const string& name, 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& relative_to, 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResolveMode resolve_mode = LOOKUP_ALL); 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a placeholder type suitable for return from LookupSymbol(). May 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // return kNullSymbol if the name is not a valid type name. 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type); 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a placeholder file. Never returns NULL. This is used when an 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // import is not found and AllowUnknownDependencies() is enabled. 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* NewPlaceholderFile(const string& name); 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calls tables_->AddSymbol() and records an error if it fails. Returns 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // true if successful or false if failed, though most callers can ignore 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the return value since an error has already been recorded. 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddSymbol(const string& full_name, 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* parent, const string& name, 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& proto, Symbol symbol); 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like AddSymbol(), but succeeds if the symbol is already defined as long 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as the existing definition is also a package (because it's OK to define 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the same package in two different files). Also adds all parents of the 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "foo.bar" and "foo" to the table). 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddPackage(const string& name, const Message& proto, 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* file); 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks that the symbol name contains only alphanumeric characters and 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // underscores. Records an error otherwise. 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateSymbolName(const string& name, const string& full_name, 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& proto); 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Like ValidateSymbolName(), but the name is allowed to contain periods and 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an error is indicated by returning false (not recording the error). 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ValidateQualifiedName(const string& name); 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used by BUILD_ARRAY macro (below) to avoid having to have the type 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified as a macro parameter. 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename Type> 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline void AllocateArray(int size, Type** output) { 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *output = tables_->AllocateArray<Type>(size); 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocates a copy of orig_options in tables_ and stores it in the 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor. Remembers its uninterpreted options, to be interpreted 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // later. DescriptorT must be one of the Descriptor messages from 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor.proto. 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<class DescriptorT> void AllocateOptions( 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const typename DescriptorT::OptionsType& orig_options, 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorT* descriptor); 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Specialization for FileOptions. 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AllocateOptions(const FileOptions& orig_options, 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* descriptor); 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implementation for AllocateOptions(). Don't call this directly. 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<class DescriptorT> void AllocateOptionsImpl( 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name_scope, 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& element_name, 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const typename DescriptorT::OptionsType& orig_options, 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorT* descriptor); 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These methods all have the same signature for the sake of the BUILD_ARRAY 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // macro, below. 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildMessage(const DescriptorProto& proto, 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Descriptor* result); 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildFieldOrExtension(const FieldDescriptorProto& proto, 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor* result, 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_extension); 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildField(const FieldDescriptorProto& proto, 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor* result) { 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildFieldOrExtension(proto, parent, result, false); 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildExtension(const FieldDescriptorProto& proto, 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor* result) { 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildFieldOrExtension(proto, parent, result, true); 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Descriptor::ExtensionRange* result); 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildEnum(const EnumDescriptorProto& proto, 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumDescriptor* result); 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildEnumValue(const EnumValueDescriptorProto& proto, 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* parent, 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValueDescriptor* result); 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildService(const ServiceDescriptorProto& proto, 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* dummy, 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceDescriptor* result); 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BuildMethod(const MethodDescriptorProto& proto, 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptor* parent, 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodDescriptor* result); 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be run only after building. 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Options will not be available during cross-linking, as they 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have not yet been interpreted. Defer any handling of options to the 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate*Options methods. 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkField(FieldDescriptor* field, 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptorProto& proto); 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkEnum(EnumDescriptor* enum_type, 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptorProto& proto); 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkEnumValue(EnumValueDescriptor* enum_value, 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptorProto& proto); 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkService(ServiceDescriptor* service, 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptorProto& proto); 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CrossLinkMethod(MethodDescriptor* method, 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MethodDescriptorProto& proto); 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be run only after cross-linking. 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InterpretOptions(); 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper class for interpreting options. 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class OptionInterpreter { 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an interpreter that operates in the context of the pool of the 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // specified builder, which must not be NULL. We don't take ownership of the 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // builder. 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit OptionInterpreter(DescriptorBuilder* builder); 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~OptionInterpreter(); 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Interprets the uninterpreted options in the specified Options message. 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On error, calls AddError() on the underlying builder and returns false. 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise returns true. 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InterpretOptions(OptionsToInterpret* options_to_interpret); 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class AggregateOptionFinder; 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Interprets uninterpreted_option_ on the specified message, which 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must be the mutable copy of the original options message to which 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uninterpreted_option_ belongs. 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InterpretSingleOption(Message* options); 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds the uninterpreted_option to the given options message verbatim. 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used when AllowUnknownDependencies() is in effect and we can't find 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the option's definition. 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* options); 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A recursive helper function that drills into the intermediate fields 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in unknown_fields to check if field innermost_field is set on the 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // innermost message. Returns false and sets an error if so. 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ExamineIfOptionIsSet( 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* innermost_field, const string& debug_msg_name, 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields); 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validates the value for the option field of the currently interpreted 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // option and then sets it on the unknown_field. 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetOptionValue(const FieldDescriptor* option_field, 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields); 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parses an aggregate value for a CPPTYPE_MESSAGE option and 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // saves it into *unknown_fields. 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetAggregateOption(const FieldDescriptor* option_field, 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields); 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convenience functions to set an int field the right way, depending on 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its wire type (a single int CppType can represent multiple wire types). 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetInt32(int number, int32 value, FieldDescriptor::Type type, 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields); 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetInt64(int number, int64 value, FieldDescriptor::Type type, 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields); 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields); 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields); 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper function that adds an error at the specified location of the 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // option we're currently interpreting, and returns false. 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& msg) { 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder_->AddError(options_to_interpret_->element_name, 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *uninterpreted_option_, location, msg); 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper function that adds an error at the location of the option name 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and returns false. 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddNameError(const string& msg) { 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A helper function that adds an error at the location of the option name 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and returns false. 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddValueError(const string& msg) { 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg); 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We interpret against this builder's pool. Is never NULL. We don't own 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this pointer. 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorBuilder* builder_; 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The options we're currently interpreting, or NULL if we're not in a call 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to InterpretOptions. 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OptionsToInterpret* options_to_interpret_; 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The option we're currently interpreting within options_to_interpret_, or 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NULL if we're not in a call to InterpretOptions(). This points to a 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // submessage of the original option, not the mutable copy. Therefore we 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can use it to find locations recorded by the parser. 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UninterpretedOption* uninterpreted_option_; 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Factory used to create the dynamic messages we need to parse 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any aggregate option values we encounter. 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DynamicMessageFactory dynamic_factory_; 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Work-around for broken compilers: According to the C++ standard, 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OptionInterpreter should have access to the private members of any class 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which has declared DescriptorBuilder as a friend. Unfortunately some old 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // versions of GCC and other compilers do not implement this correctly. So, 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we have to have these intermediate methods to provide access. We also 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redundantly declare OptionInterpreter a friend just to make things extra 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clear for these bad compilers. 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class OptionInterpreter; 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class OptionInterpreter::AggregateOptionFinder; 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline bool get_allow_unknown(const DescriptorPool* pool) { 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pool->allow_unknown_; 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline bool get_is_placeholder(const Descriptor* descriptor) { 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return descriptor->is_placeholder_; 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static inline void assert_mutex_held(const DescriptorPool* pool) { 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool->mutex_ != NULL) { 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool->mutex_->AssertHeld(); 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be run only after options have been interpreted. 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: Validation code must only reference the options in the mutable 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptors, which are the ones that have been interpreted. The const 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // proto references are passed in only so they can be provided to calls to 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AddError(). Do not look at their options, which have not been interpreted. 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateFileOptions(FileDescriptor* file, 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptorProto& proto); 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateMessageOptions(Descriptor* message, 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorProto& proto); 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateFieldOptions(FieldDescriptor* field, 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptorProto& proto); 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateEnumOptions(EnumDescriptor* enm, 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptorProto& proto); 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptorProto& proto); 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateServiceOptions(ServiceDescriptor* service, 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptorProto& proto); 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateMethodOptions(MethodDescriptor* method, 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MethodDescriptorProto& proto); 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ValidateMapKey(FieldDescriptor* field, 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptorProto& proto); 2494ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorPool::BuildFile( 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptorProto& proto) { 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(fallback_database_ == NULL) 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Cannot call BuildFile on a DescriptorPool that uses a " 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DescriptorDatabase. You must instead find a way to get your file " 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "into the underlying database."; 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto); 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorPool::BuildFileCollectingErrors( 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptorProto& proto, 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ErrorCollector* error_collector) { 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(fallback_database_ == NULL) 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Cannot call BuildFile on a DescriptorPool that uses a " 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DescriptorDatabase. You must instead find a way to get your file " 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "into the underlying database."; 25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. 25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DescriptorBuilder(this, tables_.get(), 25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_collector).BuildFile(proto); 25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorPool::BuildFileFromDatabase( 25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptorProto& proto) const { 25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutex_->AssertHeld(); 25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DescriptorBuilder(this, tables_.get(), 25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_error_collector_).BuildFile(proto); 25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorBuilder::DescriptorBuilder( 25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorPool* pool, 25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::Tables* tables, 25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector* error_collector) 25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pool_(pool), 25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_(tables), 25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_collector_(error_collector), 25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) had_errors_(false), 25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) possible_undeclared_dependency_(NULL) {} 25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorBuilder::~DescriptorBuilder() {} 25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::AddError( 25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& element_name, 25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& descriptor, 25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::ErrorLocation location, 25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& error) { 25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_collector_ == NULL) { 25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!had_errors_) { 25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ 25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "\":"; 25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_collector_->AddError(filename_, element_name, 25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &descriptor, location, error); 25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) had_errors_ = true; 25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::AddNotDefinedError( 25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& element_name, 25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& descriptor, 25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::ErrorLocation location, 25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& undefined_symbol) { 25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (possible_undeclared_dependency_ == NULL) { 25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(element_name, descriptor, location, 25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + undefined_symbol + "\" is not defined."); 25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(element_name, descriptor, location, 25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + possible_undeclared_dependency_name_ + 25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" seems to be defined in \"" + 25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) possible_undeclared_dependency_->name() + "\", which is not " 25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "imported by \"" + filename_ + "\". To use it here, please " 25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "add the necessary import."); 25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::IsInPackage(const FileDescriptor* file, 25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& package_name) { 25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HasPrefixString(file->package(), package_name) && 25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (file->package().size() == package_name.size() || 25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->package()[package_name.size()] == '.'); 25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2581ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { 2582ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (file == NULL || !dependencies_.insert(file).second) return; 2583ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) { 2584ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RecordPublicDependencies(file->public_dependency(i)); 2585ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 2586ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2588ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochSymbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( 2589ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const DescriptorPool* pool, const string& name) { 2590ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // If we are looking at an underlay, we must lock its mutex_, since we are 2591ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // accessing the underlay's tables_ directly. 2592ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); 2593ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 2594ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch Symbol result = pool->tables_->FindSymbol(name); 2595ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (result.IsNull() && pool->underlay_ != NULL) { 2596ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Symbol not found; check the underlay. 2597ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name); 2598ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2600ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (result.IsNull()) { 2601ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // In theory, we shouldn't need to check fallback_database_ because the 2602ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // symbol should be in one of its file's direct dependencies, and we have 2603ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // already loaded those by the time we get here. But we check anyway so 2604ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // that we can generate better error message when dependencies are missing 2605ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // (i.e., "missing dependency" rather than "type is not defined"). 2606ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (pool->TryFindSymbolInFallbackDatabase(name)) { 2607ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result = pool->tables_->FindSymbol(name); 2608ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2614ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochSymbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) { 2615ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return FindSymbolNotEnforcingDepsHelper(pool_, name); 2616ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch} 2617ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol DescriptorBuilder::FindSymbol(const string& name) { 26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = FindSymbolNotEnforcingDeps(name); 26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2621ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (result.IsNull()) return result; 2622ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pool_->enforce_dependencies_) { 26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hack for CompilerUpgrader. 26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only find symbols which were defined in this file or one of its 26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dependencies. 26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* file = result.GetFile(); 2631ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (file == file_ || dependencies_.count(file) > 0) return result; 26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.type == Symbol::PACKAGE) { 26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Arg, this is overcomplicated. The symbol is a package name. It could 26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be that the package was defined in multiple files. result.GetFile() 26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns the first file we saw that used this package. We've determined 26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that that file is not a direct dependency of the file we are currently 26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // building, but it could be that some other file which *is* a direct 26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dependency also defines the same package. We can't really rule out this 26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // symbol unless none of the dependencies define it. 26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsInPackage(file_, name)) return result; 2642ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (set<const FileDescriptor*>::const_iterator it = dependencies_.begin(); 2643ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch it != dependencies_.end(); ++it) { 26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: A dependency may be NULL if it was not found or had errors. 2645ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (*it != NULL && IsInPackage(*it, name)) return result; 26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) possible_undeclared_dependency_ = file; 26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) possible_undeclared_dependency_name_ = name; 26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kNullSymbol; 26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( 26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name, const string& relative_to, ResolveMode resolve_mode) { 26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) possible_undeclared_dependency_ = NULL; 26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name.size() > 0 && name[0] == '.') { 26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fully-qualified name. 26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindSymbol(name.substr(1)); 26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If name is something like "Foo.Bar.baz", and symbols named "Foo" are 26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // defined in multiple parent scopes, we only want to find "Bar.baz" in the 26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // innermost one. E.g., the following should produce an error: 26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message Bar { message Baz {} } 26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message Foo { 26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message Bar { 26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // } 26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // optional Bar.Baz baz = 1; 26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // } 26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So, we look for just "Foo" first, then look for "Bar.baz" within it if 26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // found. 26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string::size_type name_dot_pos = name.find_first_of('.'); 26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string first_part_of_name; 26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name_dot_pos == string::npos) { 26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_part_of_name = name; 26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_part_of_name = name.substr(0, name_dot_pos); 26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string scope_to_try(relative_to); 26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Chop off the last component of the scope. 26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string::size_type dot_pos = scope_to_try.find_last_of('.'); 26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dot_pos == string::npos) { 26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindSymbol(name); 26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope_to_try.erase(dot_pos); 26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Append ".first_part_of_name" and try to find. 26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string::size_type old_size = scope_to_try.size(); 26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope_to_try.append(1, '.'); 26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope_to_try.append(first_part_of_name); 26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = FindSymbol(scope_to_try); 26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result.IsNull()) { 26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first_part_of_name.size() < name.size()) { 27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name is a compound symbol, of which we only found the first part. 27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now try to look up the rest of it. 27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.IsAggregate()) { 27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope_to_try.append(name, first_part_of_name.size(), 27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name.size() - first_part_of_name.size()); 27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FindSymbol(scope_to_try); 27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We found a symbol but it's not an aggregate. Continue the loop. 27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resolve_mode == LOOKUP_TYPES && !result.IsType()) { 27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We found a symbol but it's not a type. Continue the loop. 27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not found. Remove the name so we can try again. 27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scope_to_try.erase(old_size); 27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol DescriptorBuilder::LookupSymbol( 27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name, const string& relative_to, 27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlaceholderType placeholder_type, ResolveMode resolve_mode) { 27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = LookupSymbolNoPlaceholder( 27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, relative_to, resolve_mode); 27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.IsNull() && pool_->allow_unknown_) { 27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not found, but AllowUnknownDependencies() is enabled. Return a 27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // placeholder instead. 27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = NewPlaceholder(name, placeholder_type); 27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Symbol DescriptorBuilder::NewPlaceholder(const string& name, 27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlaceholderType placeholder_type) { 27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Compute names. 27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string* placeholder_full_name; 27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string* placeholder_name; 27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string* placeholder_package; 27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ValidateQualifiedName(name)) return kNullSymbol; 27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name[0] == '.') { 27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fully-qualified. 27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_full_name = tables_->AllocateString(name.substr(1)); 27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_full_name = tables_->AllocateString(name); 27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string::size_type dotpos = placeholder_full_name->find_last_of('.'); 27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dotpos != string::npos) { 27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_package = tables_->AllocateString( 27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_full_name->substr(0, dotpos)); 27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_name = tables_->AllocateString( 27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_full_name->substr(dotpos + 1)); 27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 27585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) placeholder_package = &::google::protobuf::internal::GetEmptyString(); 27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_name = placeholder_full_name; 27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the placeholders. 27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* placeholder_file = tables_->Allocate<FileDescriptor>(); 27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(placeholder_file, 0, sizeof(*placeholder_file)); 27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2766ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance(); 2767ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->name_ = 27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AllocateString(*placeholder_full_name + ".placeholder.proto"); 27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->package_ = placeholder_package; 27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->pool_ = pool_; 27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->options_ = &FileOptions::default_instance(); 27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->tables_ = &FileDescriptorTables::kEmpty; 27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All other fields are zero or NULL. 27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (placeholder_type == PLACEHOLDER_ENUM) { 27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->enum_type_count_ = 1; 27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->enum_types_ = 27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AllocateArray<EnumDescriptor>(1); 27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; 27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(placeholder_enum, 0, sizeof(*placeholder_enum)); 27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->full_name_ = placeholder_full_name; 27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->name_ = placeholder_name; 27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->file_ = placeholder_file; 27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->options_ = &EnumOptions::default_instance(); 27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->is_placeholder_ = true; 27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); 27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enums must have at least one value. 27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->value_count_ = 1; 27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1); 27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0]; 27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(placeholder_value, 0, sizeof(*placeholder_value)); 27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE"); 27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that enum value names are siblings of their type, not children. 28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_value->full_name_ = 28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_package->empty() ? placeholder_value->name_ : 28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE"); 28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_value->number_ = 0; 28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_value->type_ = placeholder_enum; 28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_value->options_ = &EnumValueOptions::default_instance(); 28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Symbol(placeholder_enum); 28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->message_type_count_ = 1; 28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_file->message_types_ = 28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AllocateArray<Descriptor>(1); 28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Descriptor* placeholder_message = &placeholder_file->message_types_[0]; 28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(placeholder_message, 0, sizeof(*placeholder_message)); 28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->full_name_ = placeholder_full_name; 28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->name_ = placeholder_name; 28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->file_ = placeholder_file; 28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->options_ = &MessageOptions::default_instance(); 28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->is_placeholder_ = true; 28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->is_unqualified_placeholder_ = (name[0] != '.'); 28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) { 28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->extension_range_count_ = 1; 28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->extension_ranges_ = 28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AllocateArray<Descriptor::ExtensionRange>(1); 28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->extension_ranges_->start = 1; 28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // kMaxNumber + 1 because ExtensionRange::end is exclusive. 28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder_message->extension_ranges_->end = 28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::kMaxNumber + 1; 28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Symbol(placeholder_message); 28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorBuilder::NewPlaceholderFile( 28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name) { 28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>(); 28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(placeholder, 0, sizeof(*placeholder)); 28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder->name_ = tables_->AllocateString(name); 28445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) placeholder->package_ = &::google::protobuf::internal::GetEmptyString(); 28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder->pool_ = pool_; 28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder->options_ = &FileOptions::default_instance(); 28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) placeholder->tables_ = &FileDescriptorTables::kEmpty; 28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All other fields are zero or NULL. 28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return placeholder; 28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::AddSymbol( 28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& full_name, const void* parent, const string& name, 28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message& proto, Symbol symbol) { 28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the caller passed NULL for the parent, the symbol is at file scope. 28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use its file as the parent instead. 28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent == NULL) parent = file_; 28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->AddSymbol(full_name, symbol)) { 28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { 28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " 28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "symbols_by_name_, but was defined in symbols_by_parent_; " 28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "this shouldn't be possible."; 28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); 28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (other_file == file_) { 28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string::size_type dot_pos = full_name.find_last_of('.'); 28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dot_pos == string::npos) { 28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + full_name + "\" is already defined."); 28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + full_name.substr(dot_pos + 1) + 28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" is already defined in \"" + 28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name.substr(0, dot_pos) + "\"."); 28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Symbol seems to have been defined in a different file. 28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + full_name + "\" is already defined in file \"" + 28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_file->name() + "\"."); 28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::AddPackage( 28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name, const Message& proto, const FileDescriptor* file) { 28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->AddSymbol(name, Symbol(file))) { 28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Success. Also add parent package, if any. 28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string::size_type dot_pos = name.find_last_of('.'); 28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dot_pos == string::npos) { 28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No parents. 28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(name, name, proto); 28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Has parent. 29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* parent_name = tables_->AllocateString(name.substr(0, dot_pos)); 29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddPackage(*parent_name, proto, file); 29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(name.substr(dot_pos + 1), name, proto); 29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol existing_symbol = tables_->FindSymbol(name); 29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's OK to redefine a package. 29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_symbol.type != Symbol::PACKAGE) { 29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Symbol seems to have been defined in a different file. 29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(name, proto, DescriptorPool::ErrorCollector::NAME, 29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + name + "\" is already defined (as something other than " 29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "a package) in file \"" + existing_symbol.GetFile()->name() + 29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"."); 29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateSymbolName( 29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name, const string& full_name, const Message& proto) { 29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name.empty()) { 29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing name."); 29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < name.size(); i++) { 29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I don't trust isalnum() due to locales. :( 29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((name[i] < 'a' || 'z' < name[i]) && 29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (name[i] < 'A' || 'Z' < name[i]) && 29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (name[i] < '0' || '9' < name[i]) && 29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (name[i] != '_')) { 29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + name + "\" is not a valid identifier."); 29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::ValidateQualifiedName(const string& name) { 29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool last_was_period = false; 29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < name.size(); i++) { 29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I don't trust isalnum() due to locales. :( 29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (('a' <= name[i] && name[i] <= 'z') || 29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('A' <= name[i] && name[i] <= 'Z') || 29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ('0' <= name[i] && name[i] <= '9') || 29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (name[i] == '_')) { 29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_was_period = false; 29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (name[i] == '.') { 29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_was_period) return false; 29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_was_period = true; 29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !name.empty() && !last_was_period; 29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This generic implementation is good for all descriptors except 29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FileDescriptor. 29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class DescriptorT> void DescriptorBuilder::AllocateOptions( 29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const typename DescriptorT::OptionsType& orig_options, 29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorT* descriptor) { 29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(), 29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orig_options, descriptor); 29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We specialize for FileDescriptor. 29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options, 29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* descriptor) { 29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We add the dummy token so that LookupSymbol does the right thing. 29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(), 29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orig_options, descriptor); 29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl( 29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name_scope, 29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& element_name, 29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const typename DescriptorT::OptionsType& orig_options, 29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorT* descriptor) { 29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to use a dummy pointer to work around a bug in older versions of 29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GCC. Otherwise, the following two lines could be replaced with: 29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typename DescriptorT::OptionsType* options = 29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tables_->AllocateMessage<typename DescriptorT::OptionsType>(); 29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename DescriptorT::OptionsType* const dummy = NULL; 29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy); 29883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti 29893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the 29903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // reflection based method, which requires the Descriptor. However, we are in 29913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the middle of building the descriptors, thus the deadlock. 29923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) options->ParseFromString(orig_options.SerializeAsString()); 29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->options_ = options; 29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't add to options_to_interpret_ unless there were uninterpreted 29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // options. This not only avoids unnecessary work, but prevents a 29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bootstrapping problem when building descriptors for descriptor.proto. 29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor.proto does not contain any uninterpreted options, but 29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // attempting to interpret options anyway will cause 30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OptionsType::GetDescriptor() to be called which may then deadlock since 30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're still trying to build it. 30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (options->uninterpreted_option_size() > 0) { 30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_to_interpret_.push_back( 30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptionsToInterpret(name_scope, element_name, &orig_options, options)); 30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A common pattern: We want to convert a repeated field in the descriptor 30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to an array of values, calling some method to build each value. 30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ 30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ 30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ 30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < INPUT.NAME##_size(); i++) { \ 30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ 30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const FileDescriptor* DescriptorBuilder::BuildFile( 30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptorProto& proto) { 30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filename_ = proto.name(); 30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the file already exists and is identical to the one being built. 30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: This only works if the input is canonical -- that is, it 30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fully-qualifies all type names, has no UninterpretedOptions, etc. 30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is fine, because this idempotency "feature" really only exists to 30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accomodate one hack in the proto1->proto2 migration layer. 30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* existing_file = tables_->FindFile(filename_); 30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_file != NULL) { 30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // File already in pool. Compare the existing one to the input. 30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptorProto existing_proto; 30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_file->CopyTo(&existing_proto); 30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_proto.SerializeAsString() == proto.SerializeAsString()) { 30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // They're identical. Return the existing descriptor. 30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return existing_file; 30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not a match. The error will be detected and handled later. 30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to see if this file is already on the pending files list. 30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): Allow recursive imports? It may not work with some 30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (most?) programming languages. E.g., in C++, a forward declaration 30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of a type is not sufficient to allow it to be used even in a 30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // generated header file due to inlining. This could perhaps be 30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // worked around using tricks involving inserting #include statements 30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mid-file, but that's pretty ugly, and I'm pretty sure there are 30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // some languages out there that do not allow recursive dependencies 30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at all. 30495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < tables_->pending_files_.size(); i++) { 30505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->pending_files_[i] == proto.name()) { 30515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string error_message("File recursively imports itself: "); 30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < tables_->pending_files_.size(); i++) { 30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_message.append(tables_->pending_files_[i]); 30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_message.append(" -> "); 30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_message.append(proto.name()); 30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_message); 30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we have a fallback_database_, attempt to load all dependencies now, 30655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before checkpointing tables_. This avoids confusion with recursive 30665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // checkpoints. 30675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool_->fallback_database_ != NULL) { 30685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->pending_files_.push_back(proto.name()); 30695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < proto.dependency_size(); i++) { 30705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tables_->FindFile(proto.dependency(i)) == NULL && 30715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (pool_->underlay_ == NULL || 30725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { 30735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't care what this returns since we'll find out below anyway. 30745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); 30755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->pending_files_.pop_back(); 30785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 30795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checkpoint the tables so that we can roll back if something goes wrong. 3081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables_->AddCheckpoint(); 30825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* result = tables_->Allocate<FileDescriptor>(); 30845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_ = result; 30855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (proto.has_source_code_info()) { 3087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>(); 3088ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch info->CopyFrom(proto.source_code_info()); 3089ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->source_code_info_ = info; 3090ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 3091ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->source_code_info_ = &SourceCodeInfo::default_instance(); 3092ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3093ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 30945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_tables_ = tables_->AllocateFileTables(); 30955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->tables_ = file_tables_; 30965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 30975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_name()) { 30985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError("", proto, DescriptorPool::ErrorCollector::OTHER, 30995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Missing field: FileDescriptorProto.name."); 31005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 31035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_package()) { 31045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->package_ = tables_->AllocateString(proto.package()); 31055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 31065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We cannot rely on proto.package() returning a valid string if 31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // proto.has_package() is false, because we might be running at static 31085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialization time, in which case default values have not yet been 31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialized. 31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->package_ = tables_->AllocateString(""); 31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->pool_ = pool_; 31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add to tables. 31155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tables_->AddFile(result)) { 31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "A file with this name is already in the pool."); 31185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bail out early so that if this is actually the exact same file, we 31195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't end up reporting that every single symbol is already defined. 3120ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables_->RollbackToLastCheckpoint(); 31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result->package().empty()) { 31245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddPackage(result->package(), proto, result); 31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure all dependencies are loaded. 31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set<string> seen_dependencies; 31295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->dependency_count_ = proto.dependency_size(); 31305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->dependencies_ = 31315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); 31325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < proto.dependency_size(); i++) { 31335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!seen_dependencies.insert(proto.dependency(i)).second) { 31345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(proto.name(), proto, 31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::OTHER, 31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Import \"" + proto.dependency(i) + "\" was listed twice."); 31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); 31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dependency == NULL && pool_->underlay_ != NULL) { 31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); 31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dependency == NULL) { 31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool_->allow_unknown_) { 31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dependency = NewPlaceholderFile(proto.dependency(i)); 31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string message; 31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pool_->fallback_database_ == NULL) { 31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message = "Import \"" + proto.dependency(i) + 31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" has not been loaded."; 31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message = "Import \"" + proto.dependency(i) + 31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" was not found or had errors."; 31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(proto.name(), proto, 31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::OTHER, 31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message); 31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->dependencies_[i] = dependency; 31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Check public dependencies. 3166ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int public_dependency_count = 0; 3167ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->public_dependencies_ = tables_->AllocateArray<int>( 3168ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch proto.public_dependency_size()); 3169ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < proto.public_dependency_size(); i++) { 3170ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Only put valid public dependency indexes. 3171ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int index = proto.public_dependency(i); 3172ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (index >= 0 && index < proto.dependency_size()) { 3173ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->public_dependencies_[public_dependency_count++] = index; 3174ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 3175ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AddError(proto.name(), proto, 3176ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DescriptorPool::ErrorCollector::OTHER, 3177ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "Invalid public dependency index."); 3178ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3179ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3180ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->public_dependency_count_ = public_dependency_count; 3181ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3182ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Build dependency set 3183ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch dependencies_.clear(); 3184ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < result->dependency_count(); i++) { 3185ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RecordPublicDependencies(result->dependency(i)); 3186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3187ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3188ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Check weak dependencies. 3189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int weak_dependency_count = 0; 3190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->weak_dependencies_ = tables_->AllocateArray<int>( 3191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch proto.weak_dependency_size()); 3192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < proto.weak_dependency_size(); i++) { 3193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int index = proto.weak_dependency(i); 3194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (index >= 0 && index < proto.dependency_size()) { 3195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->weak_dependencies_[weak_dependency_count++] = index; 3196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 3197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AddError(proto.name(), proto, 3198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DescriptorPool::ErrorCollector::OTHER, 3199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "Invalid weak dependency index."); 3200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 3202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch result->weak_dependency_count_ = weak_dependency_count; 3203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert children. 32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL); 32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL); 32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, service , BuildService , NULL); 32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, extension , BuildExtension, NULL); 32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the following steps must occur in exactly the specified order. 32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cross-link. 32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkFile(result, proto); 32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Interpret any remaining uninterpreted options gathered into 32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // options_to_interpret_ during descriptor building. Cross-linking has made 32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension options known, so all interpretations should now succeed. 32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!had_errors_) { 32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptionInterpreter option_interpreter(this); 32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (vector<OptionsToInterpret>::iterator iter = 32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_to_interpret_.begin(); 32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != options_to_interpret_.end(); ++iter) { 32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_interpreter.InterpretOptions(&(*iter)); 32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_to_interpret_.clear(); 32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate options. 32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!had_errors_) { 32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateFileOptions(result, proto); 32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (had_errors_) { 3241ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables_->RollbackToLastCheckpoint(); 32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables_->ClearLastCheckpoint(); 32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, 32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Descriptor* result) { 32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& scope = (parent == NULL) ? 32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->package() : parent->full_name(); 32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* full_name = tables_->AllocateString(scope); 32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!full_name->empty()) full_name->append(1, '.'); 32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(proto.name()); 32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(proto.name(), *full_name, proto); 32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->full_name_ = full_name; 32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->file_ = file_; 32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->containing_type_ = parent; 32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->is_placeholder_ = false; 32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->is_unqualified_placeholder_ = false; 32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, field , BuildField , result); 32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, nested_type , BuildMessage , result); 32695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, enum_type , BuildEnum , result); 32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); 32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, extension , BuildExtension , result); 32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSymbol(result->full_name(), parent, result->name(), 32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto, Symbol(result)); 32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that no fields have numbers in extension ranges. 32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < result->field_count(); i++) { 32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = result->field(i); 32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < result->extension_range_count(); j++) { 32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor::ExtensionRange* range = result->extension_range(j); 32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range->start <= field->number() && field->number() < range->end) { 32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto.extension_range(j), 32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute( 32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extension range $0 to $1 includes field \"$2\" ($3).", 32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range->start, range->end - 1, 32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->name(), field->number())); 32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that extension ranges don't overlap. 33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < result->extension_range_count(); i++) { 33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor::ExtensionRange* range1 = result->extension_range(i); 33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = i + 1; j < result->extension_range_count(); j++) { 33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor::ExtensionRange* range2 = result->extension_range(j); 33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (range1->end > range2->start && range2->end > range1->start) { 33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto.extension_range(j), 33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute("Extension range $0 to $1 overlaps with " 33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "already-defined range $2 to $3.", 33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range2->start, range2->end - 1, 33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range1->start, range1->end - 1)); 33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, 33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor* result, 33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_extension) { 33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& scope = (parent == NULL) ? 33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->package() : parent->full_name(); 33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* full_name = tables_->AllocateString(scope); 33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!full_name->empty()) full_name->append(1, '.'); 33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(proto.name()); 33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(proto.name(), *full_name, proto); 33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->full_name_ = full_name; 33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->file_ = file_; 33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->number_ = proto.number(); 33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->is_extension_ = is_extension; 33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If .proto files follow the style guide then the name should already be 33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // lower-cased. If that's the case we can just reuse the string we already 33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allocated rather than allocate a new one. 33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string lowercase_name(proto.name()); 33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LowerString(&lowercase_name); 33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lowercase_name == proto.name()) { 33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->lowercase_name_ = result->name_; 33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->lowercase_name_ = tables_->AllocateString(lowercase_name); 33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't bother with the above optimization for camel-case names since 33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // .proto files that follow the guide shouldn't be using names in this 33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // format, so the optimization wouldn't help much. 33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name())); 33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some compilers do not allow static_cast directly between two enum types, 33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we must cast to int first. 33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->type_ = static_cast<FieldDescriptor::Type>( 33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<int>(proto.type())); 33545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->label_ = static_cast<FieldDescriptor::Label>( 33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) implicit_cast<int>(proto.label())); 33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some of these may be filled in when cross-linking. 33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->containing_type_ = NULL; 33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->extension_scope_ = NULL; 33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->experimental_map_key_ = NULL; 33615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->message_type_ = NULL; 33625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->enum_type_ = NULL; 33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->has_default_value_ = proto.has_default_value(); 33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_default_value() && result->is_repeated()) { 33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::DEFAULT_VALUE, 33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Repeated fields can't have default values."); 33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_type()) { 33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_default_value()) { 33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* end_pos = NULL; 33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (result->cpp_type()) { 33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT32: 33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_int32_ = 33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strtol(proto.default_value().c_str(), &end_pos, 0); 33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT64: 33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_int64_ = 33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strto64(proto.default_value().c_str(), &end_pos, 0); 33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT32: 33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_uint32_ = 33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strtoul(proto.default_value().c_str(), &end_pos, 0); 33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT64: 33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_uint64_ = 33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strtou64(proto.default_value().c_str(), &end_pos, 0); 33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_FLOAT: 33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.default_value() == "inf") { 33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_float_ = numeric_limits<float>::infinity(); 33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto.default_value() == "-inf") { 33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_float_ = -numeric_limits<float>::infinity(); 33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto.default_value() == "nan") { 33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_float_ = numeric_limits<float>::quiet_NaN(); 33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_float_ = 34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NoLocaleStrtod(proto.default_value().c_str(), &end_pos); 34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_DOUBLE: 34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.default_value() == "inf") { 34055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_double_ = numeric_limits<double>::infinity(); 34065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto.default_value() == "-inf") { 34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_double_ = -numeric_limits<double>::infinity(); 34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto.default_value() == "nan") { 34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_double_ = numeric_limits<double>::quiet_NaN(); 34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_double_ = 34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NoLocaleStrtod(proto.default_value().c_str(), &end_pos); 34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: 34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.default_value() == "true") { 34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_bool_ = true; 34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (proto.default_value() == "false") { 34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_bool_ = false; 34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::DEFAULT_VALUE, 34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Boolean default must be true or false."); 34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: 34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will be filled in when cross-linking. 34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_enum_ = NULL; 34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: 34315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->type() == FieldDescriptor::TYPE_BYTES) { 34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_string_ = tables_->AllocateString( 34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnescapeCEscapeString(proto.default_value())); 34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_string_ = 3436ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch tables_->AllocateString(proto.default_value()); 34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_MESSAGE: 34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::DEFAULT_VALUE, 34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Messages can't have default values."); 34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->has_default_value_ = false; 34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end_pos != NULL) { 34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // end_pos is only set non-NULL by the parsers for numeric types, above. 34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This checks that the default was non-empty and had no extra junk 34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after the end of the number. 34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.default_value().empty() || *end_pos != '\0') { 34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::DEFAULT_VALUE, 34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Couldn't parse default value."); 34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No explicit default value 34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (result->cpp_type()) { 34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT32: 34615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_int32_ = 0; 34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT64: 34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_int64_ = 0; 34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT32: 34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_uint32_ = 0; 34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT64: 34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_uint64_ = 0; 34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_FLOAT: 34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_float_ = 0.0f; 34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_DOUBLE: 34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_double_ = 0.0; 34775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: 34795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_bool_ = false; 34805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: 34825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will be filled in when cross-linking. 34835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->default_value_enum_ = NULL; 34845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: 34865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result->default_value_string_ = &::google::protobuf::internal::GetEmptyString(); 34875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_MESSAGE: 34895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 34905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 34935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 34945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->number() <= 0) { 34955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 34965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Field numbers must be positive integers."); 3497ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) { 3498ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Only validate that the number is within the valid field range if it is 3499ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // not an extension. Since extension numbers are validated with the 3500ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // extendee's valid set of extension numbers, and those are in turn 3501ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // validated against the max allowed number, the check is unnecessary for 3502ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // extension fields. 3503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // This avoids cross-linking issues that arise when attempting to check if 3504ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the extendee is a message_set_wire_format message, which has a higher max 3505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // on extension numbers. 35065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 35075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute("Field numbers cannot be greater than $0.", 35085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::kMaxNumber)); 35095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && 35105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->number() <= FieldDescriptor::kLastReservedNumber) { 35115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 35125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute( 35135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Field numbers $0 through $1 are reserved for the protocol " 35145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "buffer library implementation.", 35155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::kFirstReservedNumber, 35165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::kLastReservedNumber)); 35175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_extension) { 35205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_extendee()) { 35215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 35225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::EXTENDEE, 35235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FieldDescriptorProto.extendee not set for extension field."); 35245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->extension_scope_ = parent; 35275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 35285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_extendee()) { 35295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 35305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::EXTENDEE, 35315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FieldDescriptorProto.extendee set for non-extension field."); 35325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->containing_type_ = parent; 35355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 35385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 35395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 35405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 35415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 35425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSymbol(result->full_name(), parent, result->name(), 35455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto, Symbol(result)); 35465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildExtensionRange( 35495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorProto::ExtensionRange& proto, 35505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 35515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Descriptor::ExtensionRange* result) { 35525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->start = proto.start(); 35535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->end = proto.end(); 35545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->start <= 0) { 35555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(parent->full_name(), proto, 35565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 35575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extension numbers must be positive integers."); 35585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3560ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Checking of the upper bound of the extension range is deferred until after 3561ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // options interpreting. This allows messages with message_set_wire_format to 3562ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // have extensions beyond FieldDescriptor::kMaxNumber, since the extension 3563ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // numbers are actually used as int32s in the message_set_wire_format. 35645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result->start >= result->end) { 35665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(parent->full_name(), proto, 35675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 35685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extension range end number must be greater than start number."); 35695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 35715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, 35735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* parent, 35745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumDescriptor* result) { 35755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& scope = (parent == NULL) ? 35765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_->package() : parent->full_name(); 35775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* full_name = tables_->AllocateString(scope); 35785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!full_name->empty()) full_name->append(1, '.'); 35795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(proto.name()); 35805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(proto.name(), *full_name, proto); 35825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 35845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->full_name_ = full_name; 35855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->file_ = file_; 35865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->containing_type_ = parent; 35875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->is_placeholder_ = false; 35885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->is_unqualified_placeholder_ = false; 35895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.value_size() == 0) { 35915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We cannot allow enums with no values because this would mean there 35925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // would be no valid default value for fields of this type. 35935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 35945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NAME, 35955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Enums must contain at least one value."); 35965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 35975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, value, BuildEnumValue, result); 35995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 36015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 36025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 36035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 36045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 36055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSymbol(result->full_name(), parent, result->name(), 36085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto, Symbol(result)); 36095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, 36125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* parent, 36135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValueDescriptor* result) { 36145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 36155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->number_ = proto.number(); 36165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->type_ = parent; 36175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: full_name for enum values is a sibling to the parent's name, not a 36195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // child of it. 36205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* full_name = tables_->AllocateString(*parent->full_name_); 36215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->resize(full_name->size() - parent->name_->size()); 36225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(*result->name_); 36235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->full_name_ = full_name; 36245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(proto.name(), *full_name, proto); 36265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 36285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 36295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 36305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 36315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 36325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Again, enum values are weird because we makes them appear as siblings 36355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the enum type instead of children of it. So, we use 36365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parent->containing_type() as the value's parent. 36375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool added_to_outer_scope = 36385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSymbol(result->full_name(), parent->containing_type(), result->name(), 36395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto, Symbol(result)); 36405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // However, we also want to be able to search for values within a single 36425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enum type, so we add it as a child of the enum type itself, too. 36435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: This could fail, but if it does, the error has already been 36445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reported by the above AddSymbol() call, so we ignore the return code. 36455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool added_to_inner_scope = 36465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); 36475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (added_to_inner_scope && !added_to_outer_scope) { 36495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This value did not conflict with any values defined in the same enum, 36505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but it did conflict with some other symbol defined in the enum type's 36515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // scope. Let's print an additional error to explain this. 36525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string outer_scope; 36535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent->containing_type() == NULL) { 36545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outer_scope = file_->package(); 36555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 36565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outer_scope = parent->containing_type()->full_name(); 36575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (outer_scope.empty()) { 36605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outer_scope = "the global scope"; 36615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 36625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outer_scope = "\"" + outer_scope + "\""; 36635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(result->full_name(), proto, 36665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NAME, 36675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Note that enum values use C++ scoping rules, meaning that " 36685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "enum values are siblings of their type, not children of it. " 36695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Therefore, \"" + result->name() + "\" must be unique within " 36705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) + outer_scope + ", not just within \"" + parent->name() + "\"."); 36715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 36725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An enum is allowed to define two numbers that refer to the same value. 36745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FindValueByNumber() should return the first such value, so we simply 36755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ignore AddEnumValueByNumber()'s return code. 36765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_tables_->AddEnumValueByNumber(result); 36775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 36785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, 36805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* dummy, 36815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceDescriptor* result) { 36825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* full_name = tables_->AllocateString(file_->package()); 36835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!full_name->empty()) full_name->append(1, '.'); 36845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(proto.name()); 36855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(proto.name(), *full_name, proto); 36875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 36895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->full_name_ = full_name; 36905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->file_ = file_; 36915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BUILD_ARRAY(proto, result, method, BuildMethod, result); 36935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 36955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 36965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 36975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 36985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 36995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSymbol(result->full_name(), NULL, result->name(), 37025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto, Symbol(result)); 37035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, 37065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptor* parent, 37075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodDescriptor* result) { 37085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->name_ = tables_->AllocateString(proto.name()); 37095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->service_ = parent; 37105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string* full_name = tables_->AllocateString(parent->full_name()); 37125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(1, '.'); 37135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) full_name->append(*result->name_); 37145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->full_name_ = full_name; 37155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateSymbolName(proto.name(), *full_name, proto); 37175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These will be filled in when cross-linking. 37195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->input_type_ = NULL; 37205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->output_type_ = NULL; 37215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy options. 37235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_options()) { 37245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->options_ = NULL; // Will set to default_instance later. 37255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 37265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AllocateOptions(proto.options(), result); 37275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddSymbol(result->full_name(), parent, result->name(), 37305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto, Symbol(result)); 37315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef BUILD_ARRAY 37345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 37365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkFile( 37385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileDescriptor* file, const FileDescriptorProto& proto) { 37395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (file->options_ == NULL) { 37405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->options_ = &FileOptions::default_instance(); 37415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file->message_type_count(); i++) { 37445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); 37455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file->extension_count(); i++) { 37485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkField(&file->extensions_[i], proto.extension(i)); 37495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file->enum_type_count(); i++) { 37525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i)); 37535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file->service_count(); i++) { 37565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkService(&file->services_[i], proto.service(i)); 37575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkMessage( 37615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Descriptor* message, const DescriptorProto& proto) { 37625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message->options_ == NULL) { 37635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message->options_ = &MessageOptions::default_instance(); 37645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message->nested_type_count(); i++) { 37675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); 37685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message->enum_type_count(); i++) { 37715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i)); 37725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message->field_count(); i++) { 37755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkField(&message->fields_[i], proto.field(i)); 37765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < message->extension_count(); i++) { 37795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkField(&message->extensions_[i], proto.extension(i)); 37805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 37825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkField( 37845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor* field, const FieldDescriptorProto& proto) { 37855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->options_ == NULL) { 37865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->options_ = &FieldOptions::default_instance(); 37875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 37885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_extendee()) { 37905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(), 37915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLACEHOLDER_EXTENDABLE_MESSAGE); 37925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extendee.IsNull()) { 37935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddNotDefinedError(field->full_name(), proto, 37945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::EXTENDEE, 37955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.extendee()); 37965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 37975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (extendee.type != Symbol::MESSAGE) { 37985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 37995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::EXTENDEE, 38005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + proto.extendee() + "\" is not a message type."); 38015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 38025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->containing_type_ = extendee.descriptor; 38045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->containing_type()->IsExtensionNumber(field->number())) { 38065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 38075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 38085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute("\"$0\" does not declare $1 as an " 38095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "extension number.", 38105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->containing_type()->full_name(), 38115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->number())); 38125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (proto.has_type_name()) { 38165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assume we are expecting a message type unless the proto contains some 38175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // evidence that it expects an enum type. This only makes a difference if 38185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we end up creating a placeholder. 38195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) || 38205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.has_default_value(); 38215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol type = 38235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupSymbol(proto.type_name(), field->full_name(), 38245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE, 38255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOOKUP_TYPES); 38265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type.IsNull()) { 38285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddNotDefinedError(field->full_name(), proto, 38295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::TYPE, 38305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.type_name()); 38315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 38325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!proto.has_type()) { 38355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Choose field type based on symbol. 38365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type.type == Symbol::MESSAGE) { 38375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->type_ = FieldDescriptor::TYPE_MESSAGE; 38385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type.type == Symbol::ENUM) { 38395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->type_ = FieldDescriptor::TYPE_ENUM; 38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 38415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::TYPE, 38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + proto.type_name() + "\" is not a type."); 38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 38495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type.type != Symbol::MESSAGE) { 38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::TYPE, 38525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + proto.type_name() + "\" is not a message type."); 38535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->message_type_ = type.descriptor; 38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->has_default_value()) { 38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::DEFAULT_VALUE, 38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Messages can't have default values."); 38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { 38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type.type != Symbol::ENUM) { 38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::TYPE, 38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + proto.type_name() + "\" is not an enum type."); 38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->enum_type_ = type.enum_descriptor; 38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->enum_type()->is_placeholder_) { 38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't look up default values for placeholder types. We'll have 38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to just drop them. 38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->has_default_value_ = false; 38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->has_default_value()) { 38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't just use field->enum_type()->FindValueByName() here 38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because that locks the pool's mutex, which we have already locked 38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at this point. 38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol default_value = 38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LookupSymbolNoPlaceholder(proto.default_value(), 38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->enum_type()->full_name()); 38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (default_value.type == Symbol::ENUM_VALUE && 38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default_value.enum_value_descriptor->type() == field->enum_type()) { 38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->default_value_enum_ = default_value.enum_value_descriptor; 38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::DEFAULT_VALUE, 38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Enum type \"" + field->enum_type()->full_name() + 38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" has no value named \"" + proto.default_value() + "\"."); 38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (field->enum_type()->value_count() > 0) { 38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All enums must have at least one value, or we would have reported 38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an error elsewhere. We use the first defined value as the default 38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if a default is not explicitly defined. 38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->default_value_enum_ = field->enum_type()->value(0); 38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Field with primitive type has type_name."); 39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { 39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Field with message or enum type missing type_name."); 39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the field to the fields-by-number table. 39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: We have to do this *after* cross-linking because extensions do not 39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // know their containing type until now. 39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_tables_->AddFieldByNumber(field)) { 39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* conflicting_field = 39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_tables_->FindFieldByNumber(field->containing_type(), 39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->number()); 39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_extension()) { 39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute("Extension number $0 has already been used " 39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "in \"$1\" by extension \"$2\".", 39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->number(), 39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->containing_type()->full_name(), 39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) conflicting_field->full_name())); 39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strings::Substitute("Field number $0 has already been used in " 39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"$1\" by field \"$2\".", 39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->number(), 39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->containing_type()->full_name(), 39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) conflicting_field->name())); 39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_extension()) { 39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need for error checking: if the extension number collided, 39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we've already been informed of it by the if() above. 39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tables_->AddExtension(field); 39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the field to the lowercase-name and camelcase-name tables. 39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_tables_->AddFieldByStylizedNames(field); 39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkEnum( 39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumDescriptor* enum_type, const EnumDescriptorProto& proto) { 39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enum_type->options_ == NULL) { 39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_type->options_ = &EnumOptions::default_instance(); 39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < enum_type->value_count(); i++) { 39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkEnumValue(&enum_type->values_[i], proto.value(i)); 39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkEnumValue( 39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) { 39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enum_value->options_ == NULL) { 39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_value->options_ = &EnumValueOptions::default_instance(); 39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkService( 39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServiceDescriptor* service, const ServiceDescriptorProto& proto) { 39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (service->options_ == NULL) { 39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->options_ = &ServiceOptions::default_instance(); 39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < service->method_count(); i++) { 39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrossLinkMethod(&service->methods_[i], proto.method(i)); 39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::CrossLinkMethod( 39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MethodDescriptor* method, const MethodDescriptorProto& proto) { 39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (method->options_ == NULL) { 39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->options_ = &MethodOptions::default_instance(); 39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); 39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_type.IsNull()) { 39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddNotDefinedError(method->full_name(), proto, 39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::INPUT_TYPE, 39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.input_type()); 39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (input_type.type != Symbol::MESSAGE) { 39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(method->full_name(), proto, 39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::INPUT_TYPE, 39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + proto.input_type() + "\" is not a message type."); 39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->input_type_ = input_type.descriptor; 39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); 39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output_type.IsNull()) { 39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddNotDefinedError(method->full_name(), proto, 39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::OUTPUT_TYPE, 40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.output_type()); 40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (output_type.type != Symbol::MESSAGE) { 40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(method->full_name(), proto, 40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::OUTPUT_TYPE, 40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + proto.output_type() + "\" is not a message type."); 40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) method->output_type_ = output_type.descriptor; 40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \ 40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < descriptor->array_name##_count(); ++i) { \ 40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Validate##type##Options(descriptor->array_name##s_ + i, \ 40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proto.array_name(i)); \ 40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to 40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoid problems that exist at init time. 40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool IsLite(const FileDescriptor* file) { 40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(kenton): I don't even remember how many of these conditions are 40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actually possible. I'm just being super-safe. 40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return file != NULL && 40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &file->options() != &FileOptions::default_instance() && 40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->options().optimize_for() == FileOptions::LITE_RUNTIME; 40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, 40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FileDescriptorProto& proto) { 40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); 40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); 40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); 40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); 40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lite files can only be imported by other Lite files. 40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsLite(file)) { 40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < file->dependency_count(); i++) { 40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsLite(file->dependency(i))) { 40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError( 40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file->name(), proto, 40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::OTHER, 40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Files that do not use optimize_for = LITE_RUNTIME cannot import " 40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "files which do use this option. This file is not lite, but it " 40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "imports \"" + file->dependency(i)->name() + "\" which is."); 40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, 40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DescriptorProto& proto) { 40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); 40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message); 40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); 40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); 4057ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 4058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const int64 max_extension_range = 4059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch static_cast<int64>(message->options().message_set_wire_format() ? 4060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch kint32max : 4061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch FieldDescriptor::kMaxNumber); 4062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < message->extension_range_count(); ++i) { 4063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (message->extension_range(i)->end > max_extension_range + 1) { 4064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AddError( 4065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch message->full_name(), proto.extension_range(i), 4066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DescriptorPool::ErrorCollector::NUMBER, 4067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch strings::Substitute("Extension numbers cannot be greater than $0.", 4068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch max_extension_range)); 4069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 4070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, 40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptorProto& proto) { 40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->options().has_experimental_map_key()) { 40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValidateMapKey(field, proto); 40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4079ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Only message type fields may be lazy. 4080ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field->options().lazy()) { 4081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (field->type() != FieldDescriptor::TYPE_MESSAGE) { 4082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AddError(field->full_name(), proto, 4083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch DescriptorPool::ErrorCollector::TYPE, 4084ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "[lazy = true] can only be specified for submessage fields."); 4085ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 4086ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 4087ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only repeated primitive fields may be packed. 40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->options().packed() && !field->is_packable()) { 40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError( 40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->full_name(), proto, 40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::TYPE, 40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "[packed = true] can only be specified for repeated primitive fields."); 40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: Default instance may not yet be initialized here, so we have to 40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // avoid reading from it. 40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->containing_type_ != NULL && 40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &field->containing_type()->options() != 41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MessageOptions::default_instance() && 41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->containing_type()->options().message_set_wire_format()) { 41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->is_extension()) { 41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_optional() || 41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->type() != FieldDescriptor::TYPE_MESSAGE) { 41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::TYPE, 41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extensions of MessageSets must be optional messages."); 41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NAME, 41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MessageSets cannot have fields, only extensions."); 41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Lite extensions can only be of Lite types. 41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsLite(field->file()) && 41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->containing_type_ != NULL && 41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !IsLite(field->containing_type()->file())) { 41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, 41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::EXTENDEE, 41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Extensions to non-lite types can only be declared in non-lite " 41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "files. Note that you cannot extend a non-lite type to contain " 41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "a lite type, but the reverse is allowed."); 41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, 41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptorProto& proto) { 41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); 41323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { 4133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch map<int, string> used_values; 4134ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < enm->value_count(); ++i) { 4135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const EnumValueDescriptor* enum_value = enm->value(i); 4136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (used_values.find(enum_value->number()) != used_values.end()) { 41373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) string error = 41383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\"" + enum_value->full_name() + 41393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\" uses the same enum value as \"" + 41403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) used_values[enum_value->number()] + "\". If this is intended, set " 41413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "'option allow_alias = true;' to the enum definition."; 41423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!enm->options().allow_alias()) { 41433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Generate error if duplicated enum values are explicitly disallowed. 41443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) AddError(enm->full_name(), proto, 41453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DescriptorPool::ErrorCollector::NUMBER, 41463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) error); 41473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 41483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Generate warning if duplicated values are found but the option 41493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // isn't set. 41503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) GOOGLE_LOG(ERROR) << error; 41513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4152ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 4153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch used_values[enum_value->number()] = enum_value->full_name(); 4154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 4155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 4156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateEnumValueOptions( 41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnumValueDescriptor* enum_value, const EnumValueDescriptorProto& proto) { 41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing to do so far. 41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service, 41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ServiceDescriptorProto& proto) { 41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsLite(service->file()) && 41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (service->file()->options().cc_generic_services() || 41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->file()->options().java_generic_services())) { 41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(service->full_name(), proto, 41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorPool::ErrorCollector::NAME, 41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Files with optimize_for = LITE_RUNTIME cannot define services " 41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "unless you set both options cc_generic_services and " 41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "java_generic_sevices to false."); 41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); 41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* method, 41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MethodDescriptorProto& proto) { 41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nothing to do so far. 41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::ValidateMapKey(FieldDescriptor* field, 41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptorProto& proto) { 41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!field->is_repeated()) { 41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "map type is only allowed for repeated fields."); 41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "map type is only allowed for fields with a message type."); 41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* item_type = field->message_type(); 41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item_type == NULL) { 41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Could not find field type."); 42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the field in item_type named by "experimental_map_key" 42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& key_name = field->options().experimental_map_key(); 42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Symbol key_symbol = LookupSymbol( 42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key_name, 42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We append ".key_name" to the containing type's name since 42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LookupSymbol() searches for peers of the supplied name, not 42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // children of the supplied name. 42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_type->full_name() + "." + key_name); 42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) { 42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Could not find field named \"" + key_name + "\" in type \"" + 42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item_type->full_name() + "\"."); 42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* key_field = key_symbol.field_descriptor; 42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_field->is_repeated()) { 42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "map_key must not name a repeated field."); 42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "map key must name a scalar or string field."); 42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field->experimental_map_key_ = key_field; 42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4236ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef VALIDATE_OPTIONS_FROM_ARRAY 42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------------------------------------------------------------- 42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorBuilder::OptionInterpreter::OptionInterpreter( 42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorBuilder* builder) : builder_(builder) { 42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(builder_); 42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DescriptorBuilder::OptionInterpreter::~OptionInterpreter() { 42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::OptionInterpreter::InterpretOptions( 42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OptionsToInterpret* options_to_interpret) { 42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that these may be in different pools, so we can't use the same 42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // descriptor and reflection objects on both. 42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* options = options_to_interpret->options; 42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Message* original_options = options_to_interpret->original_options; 42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool failed = false; 42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_to_interpret_ = options_to_interpret; 42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the uninterpreted_option field in the mutable copy of the options 42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and clear them, since we're about to interpret them. 42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* uninterpreted_options_field = 42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetDescriptor()->FindFieldByName("uninterpreted_option"); 42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(uninterpreted_options_field != NULL) 42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "No field named \"uninterpreted_option\" in the Options proto."; 42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetReflection()->ClearField(options, uninterpreted_options_field); 42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the uninterpreted_option field in the original options. 42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* original_uninterpreted_options_field = 42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_options->GetDescriptor()-> 42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FindFieldByName("uninterpreted_option"); 42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(original_uninterpreted_options_field != NULL) 42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "No field named \"uninterpreted_option\" in the Options proto."; 42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int num_uninterpreted_options = original_options->GetReflection()-> 42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldSize(*original_options, original_uninterpreted_options_field); 42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num_uninterpreted_options; ++i) { 42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_ = down_cast<const UninterpretedOption*>( 42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &original_options->GetReflection()->GetRepeatedMessage( 42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *original_options, original_uninterpreted_options_field, i)); 42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!InterpretSingleOption(options)) { 42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Error already added by InterpretSingleOption(). 42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed = true; 42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset these, so we don't have any dangling pointers. 42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_ = NULL; 42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_to_interpret_ = NULL; 42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!failed) { 42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InterpretSingleOption() added the interpreted options in the 42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnknownFieldSet, in case the option isn't yet known to us. Now we 42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // serialize the options message and deserialize it back. That way, any 42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // option fields that we do happen to know about will get moved from the 42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnknownFieldSet into the real fields, and thus be available right away. 42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If they are not known, that's OK too. They will get reparsed into the 42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // UnknownFieldSet and wait there until the message is parsed by something 42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that does know about the options. 42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string buf; 43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->AppendToString(&buf); 43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(options->ParseFromString(buf)) 43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Protocol message serialized itself in invalid fashion."; 43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !failed; 43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( 43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* options) { 43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First do some basic validation. 43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->name_size() == 0) { 43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This should never happen unless the parser has gone seriously awry or 43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // someone has manually created the uninterpreted option badly. 43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option must have a name."); 43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { 43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option must not use reserved name " 43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"uninterpreted_option\"."); 43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* options_descriptor = NULL; 43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the options message's descriptor from the builder's pool, so that we 43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get the version that knows about any extension options declared in the 43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // file we're currently building. The descriptor should be there as long as 43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the file we're building imported "google/protobuf/descriptors.proto". 43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4327ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not 43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DescriptorPool::FindMessageTypeByName() because we're already holding the 4329ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // pool's mutex, and the latter method locks it again. We don't use 4330ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // FindSymbol() because files that use custom options only need to depend on 4331ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the file that defines the option, not descriptor.proto itself. 43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol symbol = builder_->FindSymbolNotEnforcingDeps( 43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetDescriptor()->full_name()); 43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) { 43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_descriptor = symbol.descriptor; 43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The options message's descriptor was not in the builder's pool, so use 43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the standard version from the generated pool. We're not holding the 43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // generated pool's mutex, so we can search it the straightforward way. 43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options_descriptor = options->GetDescriptor(); 43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(options_descriptor); 43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We iterate over the name parts to drill into the submessages until we find 43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the leaf field for the option. As we drill down we remember the current 43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // submessage's descriptor in |descriptor| and the next field in that 43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // submessage in |field|. We also track the fields we're drilling down 43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // through in |intermediate_fields|. As we go, we reconstruct the full option 43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // name in |debug_msg_name|, for use in error messages. 43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* descriptor = options_descriptor; 43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = NULL; 43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*> intermediate_fields; 43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string debug_msg_name = ""; 43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { 43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& name_part = uninterpreted_option_->name(i).name_part(); 43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (debug_msg_name.size() > 0) { 43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_msg_name += "."; 43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->name(i).is_extension()) { 43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_msg_name += "(" + name_part + ")"; 43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for the extension's descriptor as an extension in the builder's 43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pool. Note that we use DescriptorBuilder::LookupSymbol(), not 43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows 43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // relative lookups, and 2) because we're already holding the pool's 43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // mutex, and the latter method locks it again. 4367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch symbol = builder_->LookupSymbol(name_part, 4368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch options_to_interpret_->name_scope); 43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!symbol.IsNull() && symbol.type == Symbol::FIELD) { 43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = symbol.field_descriptor; 43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't find the field then the field's descriptor was not in the 43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // builder's pool, but there's no point in looking in the generated 43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pool. We require that you import the file that defines any extensions 43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // you use, so they must be present in the builder's pool. 43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) debug_msg_name += name_part; 43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for the field's descriptor as a regular field. 43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field = descriptor->FindFieldByName(name_part); 43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field == NULL) { 43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (get_allow_unknown(builder_->pool_)) { 43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't find the option, but AllowUnknownDependencies() is enabled, 43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so we will just leave it as uninterpreted. 43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddWithoutInterpreting(*uninterpreted_option_, options); 43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option \"" + debug_msg_name + "\" unknown."); 43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (field->containing_type() != descriptor) { 43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (get_is_placeholder(field->containing_type())) { 43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The field is an extension of a placeholder type, so we can't 43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reliably verify whether it is a valid extension to use here (e.g. 43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we don't know if it is an extension of the correct *Options message, 43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or if it has a valid field number, etc.). Just leave it as 43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uninterpreted instead. 43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddWithoutInterpreting(*uninterpreted_option_, options); 43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can only happen if, due to some insane misconfiguration of the 44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pools, we find the options message in one pool but the field in 44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // another. This would probably imply a hefty bug somewhere. 44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option field \"" + debug_msg_name + 44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" is not a field or extension of message \"" + 44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor->name() + "\"."); 44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (field->is_repeated()) { 44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option field \"" + debug_msg_name + 44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" is repeated. Repeated options are not " 44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "supported."); 44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (i < uninterpreted_option_->name_size() - 1) { 44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option \"" + debug_msg_name + 44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" is an atomic type, not a message."); 44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drill down into the submessage. 44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_fields.push_back(field); 44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor = field->message_type(); 44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've found the leaf field. Now we use UnknownFieldSets to set its value 44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on the options message. We do so because the message may not yet know 44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // about its extension fields, so we may not be able to set the fields 44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // directly. But the UnknownFieldSets will serialize to the same wire-format 44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message, so reading that message back in once the extension fields are 44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // known will populate them correctly. 44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First see if the option is already set. 44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ExamineIfOptionIsSet( 44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_fields.begin(), 44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_fields.end(), 44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) field, debug_msg_name, 44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetReflection()->GetUnknownFields(*options))) { 44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // ExamineIfOptionIsSet() already added the error. 44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First set the value on the UnknownFieldSet corresponding to the 44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // innermost message. 44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet()); 44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SetOptionValue(field, unknown_fields.get())) { 44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // SetOptionValue() already added the error. 44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all 44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the intermediate messages. 44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (vector<const FieldDescriptor*>::reverse_iterator iter = 44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_fields.rbegin(); 44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != intermediate_fields.rend(); ++iter) { 44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<UnknownFieldSet> parent_unknown_fields(new UnknownFieldSet()); 44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch ((*iter)->type()) { 44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_MESSAGE: { 44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::StringOutputStream outstr( 44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_unknown_fields->AddLengthDelimited((*iter)->number())); 44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io::CodedOutputStream out(&outstr); 44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::WireFormatLite::SerializeUnknownFields(*unknown_fields, &out); 44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(!out.HadError()) 44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Unexpected failure while serializing option submessage " 44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << debug_msg_name << "\"."; 44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_GROUP: { 44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_unknown_fields->AddGroup((*iter)->number()) 44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ->MergeFrom(*unknown_fields); 44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " 44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (*iter)->type(); 44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields.reset(parent_unknown_fields.release()); 44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now merge the UnknownFieldSet corresponding to the top-level message into 44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the options message. 44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetReflection()->MutableUnknownFields(options)->MergeFrom( 44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *unknown_fields); 44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( 44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UninterpretedOption& uninterpreted_option, Message* options) { 44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* field = 44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetDescriptor()->FindFieldByName("uninterpreted_option"); 44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(field != NULL); 44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options->GetReflection()->AddMessage(options, field) 44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ->CopyFrom(uninterpreted_option); 44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( 44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, 45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, 45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* innermost_field, const string& debug_msg_name, 45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownFieldSet& unknown_fields) { 45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do linear searches of the UnknownFieldSet and its sub-groups. This 45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should be fine since it's unlikely that any one options structure will 45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // contain more than a handful of options. 45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (intermediate_fields_iter == intermediate_fields_end) { 45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're at the innermost submessage. 45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < unknown_fields.field_count(); i++) { 45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unknown_fields.field(i).number() == innermost_field->number()) { 45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNameError("Option \"" + debug_msg_name + 45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" was already set."); 45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < unknown_fields.field_count(); i++) { 45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unknown_fields.field(i).number() == 45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*intermediate_fields_iter)->number()) { 45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const UnknownField* unknown_field = &unknown_fields.field(i); 45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); 45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recurse into the next submessage. 45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_MESSAGE: 45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { 45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet intermediate_unknown_fields; 45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (intermediate_unknown_fields.ParseFromString( 45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_field->length_delimited()) && 45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !ExamineIfOptionIsSet(intermediate_fields_iter + 1, 45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_fields_end, 45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) innermost_field, debug_msg_name, 45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_unknown_fields)) { 45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Error already added. 45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_GROUP: 45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (unknown_field->type() == UnknownField::TYPE_GROUP) { 45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, 45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) intermediate_fields_end, 45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) innermost_field, debug_msg_name, 45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_field->group())) { 45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Error already added. 45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; 45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::OptionInterpreter::SetOptionValue( 45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* option_field, 45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields) { 45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We switch on the CppType to validate. 45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (option_field->cpp_type()) { 45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT32: 45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->has_positive_int_value()) { 45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->positive_int_value() > 45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<uint64>(kint32max)) { 45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value out of range for int32 option \"" + 45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInt32(option_field->number(), 45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->positive_int_value(), 45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->type(), unknown_fields); 45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->has_negative_int_value()) { 45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->negative_int_value() < 45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int64>(kint32min)) { 45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value out of range for int32 option \"" + 45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInt32(option_field->number(), 45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->negative_int_value(), 45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->type(), unknown_fields); 45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be integer for int32 option \"" + 45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_INT64: 45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->has_positive_int_value()) { 45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->positive_int_value() > 45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<uint64>(kint64max)) { 45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value out of range for int64 option \"" + 45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInt64(option_field->number(), 46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->positive_int_value(), 46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->type(), unknown_fields); 46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->has_negative_int_value()) { 46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInt64(option_field->number(), 46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->negative_int_value(), 46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->type(), unknown_fields); 46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be integer for int64 option \"" + 46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT32: 46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->has_positive_int_value()) { 46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->positive_int_value() > kuint32max) { 46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value out of range for uint32 option \"" + 46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->name() + "\"."); 46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetUInt32(option_field->number(), 46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->positive_int_value(), 46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->type(), unknown_fields); 46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be non-negative integer for uint32 " 46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "option \"" + option_field->full_name() + "\"."); 46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_UINT64: 46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->has_positive_int_value()) { 46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetUInt64(option_field->number(), 46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->positive_int_value(), 46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->type(), unknown_fields); 46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be non-negative integer for uint64 " 46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "option \"" + option_field->full_name() + "\"."); 46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_FLOAT: { 46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float value; 46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->has_double_value()) { 46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = uninterpreted_option_->double_value(); 46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->has_positive_int_value()) { 46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = uninterpreted_option_->positive_int_value(); 46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->has_negative_int_value()) { 46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = uninterpreted_option_->negative_int_value(); 46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be number for float option \"" + 46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddFixed32(option_field->number(), 46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::internal::WireFormatLite::EncodeFloat(value)); 46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_DOUBLE: { 46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double value; 46595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->has_double_value()) { 46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = uninterpreted_option_->double_value(); 46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->has_positive_int_value()) { 46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = uninterpreted_option_->positive_int_value(); 46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->has_negative_int_value()) { 46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = uninterpreted_option_->negative_int_value(); 46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be number for double option \"" + 46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + "\"."); 46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddFixed64(option_field->number(), 46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::internal::WireFormatLite::EncodeDouble(value)); 46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_BOOL: 46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 value; 46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!uninterpreted_option_->has_identifier_value()) { 46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be identifier for boolean option " 46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + option_field->full_name() + "\"."); 46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uninterpreted_option_->identifier_value() == "true") { 46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = 1; 46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (uninterpreted_option_->identifier_value() == "false") { 46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = 0; 46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be \"true\" or \"false\" for boolean " 46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "option \"" + option_field->full_name() + "\"."); 46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(option_field->number(), value); 46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_ENUM: { 46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!uninterpreted_option_->has_identifier_value()) { 46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be identifier for enum-valued option " 46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + option_field->full_name() + "\"."); 46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumDescriptor* enum_type = option_field->enum_type(); 46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string& value_name = uninterpreted_option_->identifier_value(); 46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnumValueDescriptor* enum_value = NULL; 46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { 47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the enum value's fully-qualified name is a sibling of the 47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enum's name, not a child of it. 47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string fully_qualified_name = enum_type->full_name(); 47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fully_qualified_name.resize(fully_qualified_name.size() - 47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_type->name().size()); 47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fully_qualified_name += value_name; 47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Search for the enum value's descriptor in the builder's pool. Note 47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not 47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DescriptorPool::FindEnumValueByName() because we're already holding 47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the pool's mutex, and the latter method locks it again. 47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol symbol = 47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); 47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) { 47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symbol.enum_value_descriptor->type() != enum_type) { 47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Enum type \"" + enum_type->full_name() + 47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" has no value named \"" + value_name + "\" for option \"" + 47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->full_name() + 47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\". This appears to be a value from a sibling type."); 47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_value = symbol.enum_value_descriptor; 47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The enum type is in the generated pool, so we can search for the 47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // value there. 47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum_value = enum_type->FindValueByName(value_name); 47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enum_value == NULL) { 47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Enum type \"" + 47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->enum_type()->full_name() + 47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" has no value named \"" + value_name + "\" for " 47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "option \"" + option_field->full_name() + "\"."); 47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sign-extension is not a problem, since we cast directly from int32 to 47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // uint64, without first going through uint32. 47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(option_field->number(), 47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<uint64>(static_cast<int64>(enum_value->number()))); 47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_STRING: 47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!uninterpreted_option_->has_string_value()) { 47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Value must be quoted string for string option " 47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"" + option_field->full_name() + "\"."); 47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string has already been unquoted and unescaped by the parser. 47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddLengthDelimited(option_field->number(), 47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uninterpreted_option_->string_value()); 47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::CPPTYPE_MESSAGE: 47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SetAggregateOption(option_field, unknown_fields)) { 47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder 47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public TextFormat::Finder { 47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DescriptorBuilder* builder_; 47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const FieldDescriptor* FindExtension( 47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* message, const string& name) const { 47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert_mutex_held(builder_->pool_); 4772ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Descriptor* descriptor = message->GetDescriptor(); 47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Symbol result = builder_->LookupSymbolNoPlaceholder( 4774ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch name, descriptor->full_name()); 47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.type == Symbol::FIELD && 47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.field_descriptor->is_extension()) { 47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result.field_descriptor; 4778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else if (result.type == Symbol::MESSAGE && 4779ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch descriptor->options().message_set_wire_format()) { 4780ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Descriptor* foreign_type = result.descriptor; 4781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // The text format allows MessageSet items to be specified using 4782ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // the type name, rather than the extension identifier. If the symbol 4783ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // lookup returned a Message, and the enclosing Message has 4784ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // message_set_wire_format = true, then return the message set 4785ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // extension, if one exists. 4786ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch for (int i = 0; i < foreign_type->extension_count(); i++) { 4787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const FieldDescriptor* extension = foreign_type->extension(i); 4788ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (extension->containing_type() == descriptor && 4789ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extension->type() == FieldDescriptor::TYPE_MESSAGE && 4790ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extension->is_optional() && 4791ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extension->message_type() == foreign_type) { 4792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Found it. 4793ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return extension; 4794ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 4795ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4797ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return NULL; 47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A custom error collector to record any text-format parsing errors 48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AggregateErrorCollector : public io::ErrorCollector { 48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string error_; 48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddError(int line, int column, const string& message) { 48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!error_.empty()) { 48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ += "; "; 48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ += message; 48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AddWarning(int line, int column, const string& message) { 48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ignore warnings 48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We construct a dynamic message of the type corresponding to 48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// option_field, parse the supplied text-format string into this 48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message, and serialize the resulting message to produce the value. 48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DescriptorBuilder::OptionInterpreter::SetAggregateOption( 48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FieldDescriptor* option_field, 48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnknownFieldSet* unknown_fields) { 48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!uninterpreted_option_->has_aggregate_value()) { 48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddValueError("Option \"" + option_field->full_name() + 48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\" is a message. To set the entire message, use " 48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syntax like \"" + option_field->name() + 48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " = { <proto text format> }\". " 48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "To set fields within it, use " 48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "syntax like \"" + option_field->name() + 48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".foo = value\"."); 48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Descriptor* type = option_field->message_type(); 48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New()); 48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_CHECK(dynamic.get() != NULL) 48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Could not create an instance of " << option_field->DebugString(); 48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AggregateErrorCollector collector; 48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AggregateOptionFinder finder; 48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finder.builder_ = builder_; 48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TextFormat::Parser parser; 48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.RecordErrorsTo(&collector); 48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.SetFinder(&finder); 48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), 48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dynamic.get())) { 48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddValueError("Error while parsing option value for \"" + 48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) option_field->name() + "\": " + collector.error_); 48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string serial; 48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dynamic->SerializeToString(&serial); // Never fails 4855ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { 4856ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch unknown_fields->AddLengthDelimited(option_field->number(), serial); 4857ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } else { 4858ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); 4859ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); 4860ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch group->ParseFromString(serial); 4861ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, 48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_INT32: 48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(number, 48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<uint64>(static_cast<int64>(value))); 48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_SFIXED32: 48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddFixed32(number, static_cast<uint32>(value)); 48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_SINT32: 48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(number, 48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::internal::WireFormatLite::ZigZagEncode32(value)); 48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; 48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value, 48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_INT64: 48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(number, static_cast<uint64>(value)); 48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_SFIXED64: 48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddFixed64(number, static_cast<uint64>(value)); 48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_SINT64: 49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(number, 49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) google::protobuf::internal::WireFormatLite::ZigZagEncode64(value)); 49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; 49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value, 49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_UINT32: 49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(number, static_cast<uint64>(value)); 49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_FIXED32: 49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddFixed32(number, static_cast<uint32>(value)); 49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; 49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value, 49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_UINT64: 49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddVarint(number, value); 49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FieldDescriptor::TYPE_FIXED64: 49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unknown_fields->AddFixed64(number, value); 49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; 49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 4947