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