1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/hash.h> 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <map> 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <set> 38a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <string> 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <vector> 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <algorithm> 41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <limits> 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.h> 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor_database.h> 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/descriptor.pb.h> 46a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/dynamic_message.h> 47a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/generated_message_util.h> 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/text_format.h> 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/unknown_field_set.h> 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/wire_format.h> 51a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/io/strtod.h> 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/coded_stream.h> 53a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/io/tokenizer.h> 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h> 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/once.h> 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/strutil.h> 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/substitute.h> 59a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/stubs/map_util.h> 60a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#include <google/protobuf/stubs/stl_util.h> 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef PACKAGE // autoheader #defines this. :( 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor::CppType 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<CppType>(0), // 0 is reserved for errors 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_DOUBLE, // TYPE_DOUBLE 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_FLOAT, // TYPE_FLOAT 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_INT64, // TYPE_INT64 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_UINT64, // TYPE_UINT64 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_INT32, // TYPE_INT32 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_UINT64, // TYPE_FIXED64 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_UINT32, // TYPE_FIXED32 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_BOOL, // TYPE_BOOL 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_STRING, // TYPE_STRING 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_MESSAGE, // TYPE_GROUP 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_MESSAGE, // TYPE_MESSAGE 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_STRING, // TYPE_BYTES 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_UINT32, // TYPE_UINT32 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_ENUM, // TYPE_ENUM 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_INT32, // TYPE_SFIXED32 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_INT64, // TYPE_SFIXED64 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_INT32, // TYPE_SINT32 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CPPTYPE_INT64, // TYPE_SINT64 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char * const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "ERROR", // 0 is reserved for errors 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "double", // TYPE_DOUBLE 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "float", // TYPE_FLOAT 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "int64", // TYPE_INT64 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "uint64", // TYPE_UINT64 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "int32", // TYPE_INT32 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "fixed64", // TYPE_FIXED64 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "fixed32", // TYPE_FIXED32 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "bool", // TYPE_BOOL 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "string", // TYPE_STRING 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "group", // TYPE_GROUP 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "message", // TYPE_MESSAGE 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "bytes", // TYPE_BYTES 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "uint32", // TYPE_UINT32 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "enum", // TYPE_ENUM 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "sfixed32", // TYPE_SFIXED32 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "sfixed64", // TYPE_SFIXED64 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "sint32", // TYPE_SINT32 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "sint64", // TYPE_SINT64 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 114a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonconst char * const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = { 115a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "ERROR", // 0 is reserved for errors 116a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 117a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "int32", // CPPTYPE_INT32 118a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "int64", // CPPTYPE_INT64 119a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "uint32", // CPPTYPE_UINT32 120a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "uint64", // CPPTYPE_UINT64 121a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "double", // CPPTYPE_DOUBLE 122a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "float", // CPPTYPE_FLOAT 123a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "bool", // CPPTYPE_BOOL 124a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "enum", // CPPTYPE_ENUM 125a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "string", // CPPTYPE_STRING 126a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "message", // CPPTYPE_MESSAGE 127a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}; 128a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = { 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "ERROR", // 0 is reserved for errors 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "optional", // LABEL_OPTIONAL 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "required", // LABEL_REQUIRED 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "repeated", // LABEL_REPEATED 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstatic const char * const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty"; 138a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef _MSC_VER // MSVC doesn't need these and won't even accept them. 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst int FieldDescriptor::kMaxNumber; 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst int FieldDescriptor::kFirstReservedNumber; 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst int FieldDescriptor::kLastReservedNumber; 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ToCamelCase(const string& input) { 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool capitalize_next = false; 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.reserve(input.size()); 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < input.size(); i++) { 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (input[i] == '_') { 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville capitalize_next = true; 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (capitalize_next) { 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: I distrust ctype.h due to locales. 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if ('a' <= input[i] && input[i] <= 'z') { 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.push_back(input[i] - 'a' + 'A'); 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.push_back(input[i]); 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville capitalize_next = false; 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.push_back(input[i]); 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Lower-case the first letter. 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') { 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result[0] = result[0] - 'A' + 'a'; 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A DescriptorPool contains a bunch of hash_maps to implement the 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// various Find*By*() methods. Since hashtable lookups are O(1), it's 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// most efficient to construct a fixed set of large hash_maps used by 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// all objects in the pool rather than construct one or more small 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// hash_maps for each object. 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// The keys to these hash_maps are (parent, name) or (parent, number) 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// pairs. Unfortunately STL doesn't provide hash functions for pair<>, 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// so we must invent our own. 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(kenton): Use StringPiece rather than const char* in keys? It would 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// be a lot cleaner but we'd just have to convert it back to const char* 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// for the open source release. 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef pair<const void*, const char*> PointerStringPair; 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct PointerStringPairEqual { 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline bool operator()(const PointerStringPair& a, 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const PointerStringPair& b) const { 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return a.first == b.first && strcmp(a.second, b.second) == 0; 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<typename PairType> 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct PointerIntegerPairHash { 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size_t operator()(const PairType& p) const { 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FIXME(kenton): What is the best way to compute this hash? I have 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // no idea! This seems a bit better than an XOR. 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + p.second; 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#ifdef _MSC_VER 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Used only by MSVC and platforms where hash_map is not available. 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const size_t bucket_size = 4; 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const size_t min_buckets = 8; 211a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#endif 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline bool operator()(const PairType& a, const PairType& b) const { 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return a.first < b.first || 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (a.first == b.first && a.second < b.second); 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef pair<const Descriptor*, int> DescriptorIntPair; 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef pair<const EnumDescriptor*, int> EnumIntPair; 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct PointerStringPairHash { 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size_t operator()(const PointerStringPair& p) const { 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FIXME(kenton): What is the best way to compute this hash? I have 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // no idea! This seems a bit better than an XOR. 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash<const char*> cstring_hash; 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return reinterpret_cast<intptr_t>(p.first) * ((1 << 16) - 1) + 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville cstring_hash(p.second); 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#ifdef _MSC_VER 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Used only by MSVC and platforms where hash_map is not available. 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const size_t bucket_size = 4; 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const size_t min_buckets = 8; 234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson#endif 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline bool operator()(const PointerStringPair& a, 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const PointerStringPair& b) const { 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (a.first < b.first) return true; 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (a.first > b.first) return false; 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return strcmp(a.second, b.second) < 0; 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct Symbol { 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum Type { 246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD, 247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson PACKAGE 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Type type; 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville union { 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* descriptor; 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field_descriptor; 253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const OneofDescriptor* oneof_descriptor; 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* enum_descriptor; 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* enum_value_descriptor; 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ServiceDescriptor* service_descriptor; 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const MethodDescriptor* method_descriptor; 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* package_file_descriptor; 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline bool IsNull() const { return type == NULL_SYMBOL; } 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline bool IsType() const { 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return type == MESSAGE || type == ENUM; 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline bool IsAggregate() const { 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return type == MESSAGE || type == PACKAGE 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville || type == ENUM || type == SERVICE; 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline explicit Symbol(const TYPE* value) { \ 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type = TYPE_CONSTANT; \ 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville this->FIELD = value; \ 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) 279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson CONSTRUCTOR(OneofDescriptor , ONEOF , oneof_descriptor ) 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef CONSTRUCTOR 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* GetFile() const { 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type) { 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case NULL_SYMBOL: return NULL; 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case MESSAGE : return descriptor ->file(); 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FIELD : return field_descriptor ->file(); 292a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson case ONEOF : return oneof_descriptor ->containing_type()->file(); 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ENUM : return enum_descriptor ->file(); 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case ENUM_VALUE : return enum_value_descriptor->type()->file(); 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case SERVICE : return service_descriptor ->file(); 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case METHOD : return method_descriptor ->service()->file(); 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case PACKAGE : return package_file_descriptor; 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst Symbol kNullSymbol; 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<const char*, Symbol, 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash<const char*>, streq> 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SymbolsByNameMap; 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<PointerStringPair, Symbol, 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPairHash, PointerStringPairEqual> 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SymbolsByParentMap; 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<const char*, const FileDescriptor*, 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash<const char*>, streq> 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FilesByNameMap; 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<PointerStringPair, const FieldDescriptor*, 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPairHash, PointerStringPairEqual> 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldsByNameMap; 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<DescriptorIntPair, const FieldDescriptor*, 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerIntegerPairHash<DescriptorIntPair> > 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldsByNumberMap; 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef hash_map<EnumIntPair, const EnumValueDescriptor*, 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerIntegerPairHash<EnumIntPair> > 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumValuesByNumberMap; 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This is a map rather than a hash_map, since we use it to iterate 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// through all the extensions that extend a given Descriptor, and an 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ordered data structure that implements lower_bound is convenient 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// for that. 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletypedef map<DescriptorIntPair, const FieldDescriptor*> 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExtensionsGroupedByDescriptorMap; 329a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsontypedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap; 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // anonymous namespace 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DescriptorPool::Tables 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass DescriptorPool::Tables { 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Tables(); 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~Tables(); 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 340a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Record the current state of the tables to the stack of checkpoints. 341a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Each call to AddCheckpoint() must be paired with exactly one call to either 342a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // ClearLastCheckpoint() or RollbackToLastCheckpoint(). 343a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // 344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // This is used when building files, since some kinds of validation errors 345a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // cannot be detected until the file's descriptors have already been added to 346a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the tables. 347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // 348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // This supports recursive checkpoints, since building a file may trigger 349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // recursive building of other files. Note that recursive checkpoints are not 350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // normally necessary; explicit dependencies are built prior to checkpointing. 351a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // So although we recursively build transitive imports, there is at most one 352a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // checkpoint in the stack during dependency building. 353a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // 354a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Recursive checkpoints only arise during cross-linking of the descriptors. 355a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and 356a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // friends. If the pending file references an unknown symbol 357a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // (e.g., it is not defined in the pending file's explicit dependencies), and 358a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the pool is using a fallback database, and that database contains a file 359a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // defining that symbol, and that file has not yet been built by the pool, 360a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the pool builds the file during cross-linking, leading to another 361a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // checkpoint. 362a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void AddCheckpoint(); 363a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 364a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Mark the last checkpoint as having cleared successfully, removing it from 365a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the stack. If the stack is empty, all pending symbols will be committed. 366a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // 367a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Note that this does not guarantee that the symbols added since the last 368a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // checkpoint won't be rolled back: if a checkpoint gets rolled back, 369a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // everything past that point gets rolled back, including symbols added after 370a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // checkpoints that were pushed onto the stack after it and marked as cleared. 371a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void ClearLastCheckpoint(); 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 373a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Roll back the Tables to the state of the checkpoint at the top of the 374a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // stack, removing everything that was added after that point. 375a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void RollbackToLastCheckpoint(); 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The stack of files which are currently being built. Used to detect 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // cyclic dependencies when loading files from a DescriptorDatabase. Not 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // used when fallback_database_ == NULL. 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> pending_files_; 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A set of files which we have tried to load from the fallback database 383a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // and encountered errors. We will not attempt to load them again during 384a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // execution of the current public API call, but for compatibility with 385a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // legacy clients, this is cleared at the beginning of each public API call. 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Not used when fallback_database_ == NULL. 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash_set<string> known_bad_files_; 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 389a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // A set of symbols which we have tried to load from the fallback database 390a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // and encountered errors. We will not attempt to load them again during 391a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // execution of the current public API call, but for compatibility with 392a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // legacy clients, this is cleared at the beginning of each public API call. 393a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson hash_set<string> known_bad_symbols_; 394a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The set of descriptors for which we've already loaded the full 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // set of extensions numbers from fallback_database_. 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville hash_set<const Descriptor*> extensions_loaded_from_db_; 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Finding items. 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find symbols. This returns a null Symbol (symbol.IsNull() is true) 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // if not found. 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline Symbol FindSymbol(const string& key) const; 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This implements the body of DescriptorPool::Find*ByName(). It should 407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // really be a private method of DescriptorPool, but that would require 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // declaring Symbol in descriptor.h, which would drag all kinds of other 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // stuff into the header. Yay C++. 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol FindByNameHelper( 411a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const DescriptorPool* pool, const string& name); 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These return NULL if not found. 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const FileDescriptor* FindFile(const string& key) const; 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const FieldDescriptor* FindExtension(const Descriptor* extendee, 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int number); 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline void FindAllExtensions(const Descriptor* extendee, 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*>* out) const; 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Adding items. 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These add items to the corresponding tables. They return false if 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the key already exists in the table. For AddSymbol(), the string passed 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // in must be one that was constructed using AllocateString(), as it will 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // be used as a key in the symbols_by_name_ map without copying. 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddSymbol(const string& full_name, Symbol symbol); 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddFile(const FileDescriptor* file); 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddExtension(const FieldDescriptor* field); 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocating memory. 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocate an object which will be reclaimed when the pool is 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // destroyed. Note that the object's destructor will never be called, 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // so its fields must be plain old data (primitive data types and 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pointers). All of the descriptor types are such objects. 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville template<typename Type> Type* Allocate(); 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocate an array of objects which will be reclaimed when the 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pool in destroyed. Again, destructors are never called. 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville template<typename Type> Type* AllocateArray(int count); 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocate a string which will be destroyed when the pool is destroyed. 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The string is initialized to the given value for convenience. 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* AllocateString(const string& value); 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocate a protocol message object. Some older versions of GCC have 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // trouble understanding explicit template instantiations in some cases, so 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // in those cases we have to pass a dummy pointer of the right type as the 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // parameter instead of specifying the type explicitly. 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville template<typename Type> Type* AllocateMessage(Type* dummy = NULL); 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocate a FileDescriptorTables object. 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorTables* AllocateFileTables(); 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string*> strings_; // All strings in the pool. 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<Message*> messages_; // All messages in the pool. 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<FileDescriptorTables*> file_tables_; // All file tables in the pool. 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<void*> allocations_; // All other memory allocated in the pool. 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SymbolsByNameMap symbols_by_name_; 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FilesByNameMap files_by_name_; 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExtensionsGroupedByDescriptorMap extensions_; 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 467a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson struct CheckPoint { 468a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson explicit CheckPoint(const Tables* tables) 469a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson : strings_before_checkpoint(tables->strings_.size()), 470a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson messages_before_checkpoint(tables->messages_.size()), 471a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson file_tables_before_checkpoint(tables->file_tables_.size()), 472a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson allocations_before_checkpoint(tables->allocations_.size()), 473a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pending_symbols_before_checkpoint( 474a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables->symbols_after_checkpoint_.size()), 475a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pending_files_before_checkpoint( 476a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables->files_after_checkpoint_.size()), 477a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pending_extensions_before_checkpoint( 478a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables->extensions_after_checkpoint_.size()) { 479a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 480a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int strings_before_checkpoint; 481a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int messages_before_checkpoint; 482a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int file_tables_before_checkpoint; 483a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int allocations_before_checkpoint; 484a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int pending_symbols_before_checkpoint; 485a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int pending_files_before_checkpoint; 486a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int pending_extensions_before_checkpoint; 487a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson }; 488a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<CheckPoint> checkpoints_; 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const char* > symbols_after_checkpoint_; 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const char* > files_after_checkpoint_; 491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<DescriptorIntPair> extensions_after_checkpoint_; 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocate some bytes which will be reclaimed when the pool is 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // destroyed. 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* AllocateBytes(int size); 496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Contains tables specific to a particular file. These tables are not 499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modified once the file has been constructed, so they need not be 500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// protected by a mutex. This makes operations that depend only on the 501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contents of a single file -- e.g. Descriptor::FindFieldByName() -- 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// lock-free. 503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// For historical reasons, the definitions of the methods of 505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FileDescriptorTables and DescriptorPool::Tables are interleaved below. 506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// These used to be a single class. 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass FileDescriptorTables { 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorTables(); 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~FileDescriptorTables(); 511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Empty table, used with placeholder files. 513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const FileDescriptorTables kEmpty; 514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Finding items. 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find symbols. These return a null Symbol (symbol.IsNull() is true) 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // if not found. 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline Symbol FindNestedSymbol(const void* parent, 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const; 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline Symbol FindNestedSymbolOfType(const void* parent, 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name, 524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Symbol::Type type) const; 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These return NULL if not found. 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const FieldDescriptor* FindFieldByNumber( 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, int number) const; 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const FieldDescriptor* FindFieldByLowercaseName( 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& lowercase_name) const; 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const FieldDescriptor* FindFieldByCamelcaseName( 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& camelcase_name) const; 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline const EnumValueDescriptor* FindEnumValueByNumber( 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* parent, int number) const; 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ----------------------------------------------------------------- 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Adding items. 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These add items to the corresponding tables. They return false if 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the key already exists in the table. For AddAliasUnderParent(), the 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // string passed in must be one that was constructed using AllocateString(), 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // as it will be used as a key in the symbols_by_parent_ map without copying. 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddAliasUnderParent(const void* parent, const string& name, 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol symbol); 545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddFieldByNumber(const FieldDescriptor* field); 546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddEnumValueByNumber(const EnumValueDescriptor* value); 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Adds the field to the lowercase_name and camelcase_name maps. Never 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // fails because we allow duplicates; the first field by the name wins. 550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddFieldByStylizedNames(const FieldDescriptor* field); 551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 552a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Populates p->first->locations_by_path_ from p->second. 553a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Unusual signature dictated by GoogleOnceDynamic. 554a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson static void BuildLocationsByPath( 555a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pair<const FileDescriptorTables*, const SourceCodeInfo*>* p); 556a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 557a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Returns the location denoted by the specified path through info, 558a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // or NULL if not found. 559a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // The value of info must be that of the corresponding FileDescriptor. 560a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // (Conceptually a pure function, but stateful as an optimisation.) 561a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const SourceCodeInfo_Location* GetSourceLocation( 562a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const vector<int>& path, const SourceCodeInfo* info) const; 563a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SymbolsByParentMap symbols_by_parent_; 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldsByNameMap fields_by_lowercase_name_; 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldsByNameMap fields_by_camelcase_name_; 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldsByNumberMap fields_by_number_; // Not including extensions. 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumValuesByNumberMap enum_values_by_number_; 570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Populated on first request to save space, hence constness games. 572a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson mutable GoogleOnceDynamic locations_by_path_once_; 573a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson mutable LocationsByPathMap locations_by_path_; 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::Tables::Tables() 577a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Start some hash_map and hash_set objects with a small # of buckets 578a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson : known_bad_files_(3), 579a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson known_bad_symbols_(3), 580a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extensions_loaded_from_db_(3), 581a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson symbols_by_name_(3), 582a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson files_by_name_(3) {} 583a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::Tables::~Tables() { 586a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_DCHECK(checkpoints_.empty()); 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that the deletion order is important, since the destructors of some 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // messages may refer to objects in allocations_. 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLDeleteElements(&messages_); 590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < allocations_.size(); i++) { 591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville operator delete(allocations_[i]); 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLDeleteElements(&strings_); 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLDeleteElements(&file_tables_); 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 597a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonFileDescriptorTables::FileDescriptorTables() 598a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Initialize all the hash tables to start out with a small # of buckets 599a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson : symbols_by_parent_(3), 600a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fields_by_lowercase_name_(3), 601a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fields_by_camelcase_name_(3), 602a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fields_by_number_(3), 603a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson enum_values_by_number_(3) { 604a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 605a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptorTables::~FileDescriptorTables() {} 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptorTables FileDescriptorTables::kEmpty; 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 610a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorPool::Tables::AddCheckpoint() { 611a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson checkpoints_.push_back(CheckPoint(this)); 612a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 614a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorPool::Tables::ClearLastCheckpoint() { 615a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_DCHECK(!checkpoints_.empty()); 616a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson checkpoints_.pop_back(); 617a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (checkpoints_.empty()) { 618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // All checkpoints have been cleared: we can now commit all of the pending 619a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // data. 620a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson symbols_after_checkpoint_.clear(); 621a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson files_after_checkpoint_.clear(); 622a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extensions_after_checkpoint_.clear(); 623a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 626a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorPool::Tables::RollbackToLastCheckpoint() { 627a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_DCHECK(!checkpoints_.empty()); 628a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const CheckPoint& checkpoint = checkpoints_.back(); 629a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 630a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = checkpoint.pending_symbols_before_checkpoint; 631a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i < symbols_after_checkpoint_.size(); 632a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i++) { 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville symbols_by_name_.erase(symbols_after_checkpoint_[i]); 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 635a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = checkpoint.pending_files_before_checkpoint; 636a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i < files_after_checkpoint_.size(); 637a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i++) { 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville files_by_name_.erase(files_after_checkpoint_[i]); 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 640a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = checkpoint.pending_extensions_before_checkpoint; 641a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i < extensions_after_checkpoint_.size(); 642a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i++) { 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extensions_.erase(extensions_after_checkpoint_[i]); 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 646a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson symbols_after_checkpoint_.resize( 647a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson checkpoint.pending_symbols_before_checkpoint); 648a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint); 649a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extensions_after_checkpoint_.resize( 650a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson checkpoint.pending_extensions_before_checkpoint); 651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLDeleteContainerPointers( 653a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end()); 654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLDeleteContainerPointers( 655a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson messages_.begin() + checkpoint.messages_before_checkpoint, 656a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson messages_.end()); 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville STLDeleteContainerPointers( 658a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson file_tables_.begin() + checkpoint.file_tables_before_checkpoint, 659a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson file_tables_.end()); 660a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = checkpoint.allocations_before_checkpoint; 661a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i < allocations_.size(); 662a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson i++) { 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville operator delete(allocations_[i]); 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 666a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings_.resize(checkpoint.strings_before_checkpoint); 667a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson messages_.resize(checkpoint.messages_before_checkpoint); 668a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson file_tables_.resize(checkpoint.file_tables_before_checkpoint); 669a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson allocations_.resize(checkpoint.allocations_before_checkpoint); 670a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson checkpoints_.pop_back(); 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline Symbol DescriptorPool::Tables::FindSymbol(const string& key) const { 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Symbol* result = FindOrNull(symbols_by_name_, key.c_str()); 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL) { 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kNullSymbol; 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return *result; 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline Symbol FileDescriptorTables::FindNestedSymbol( 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& name) const { 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Symbol* result = 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FindOrNull(symbols_by_parent_, PointerStringPair(parent, name.c_str())); 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL) { 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kNullSymbol; 690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return *result; 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline Symbol FileDescriptorTables::FindNestedSymbolOfType( 696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& name, const Symbol::Type type) const { 697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = FindNestedSymbol(parent, name); 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.type != type) return kNullSymbol; 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSymbol DescriptorPool::Tables::FindByNameHelper( 703a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const DescriptorPool* pool, const string& name) { 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLockMaybe lock(pool->mutex_); 705a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson known_bad_symbols_.clear(); 706a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson known_bad_files_.clear(); 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = FindSymbol(name); 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.IsNull() && pool->underlay_ != NULL) { 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Symbol not found; check the underlay. 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result = 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name); 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.IsNull()) { 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Symbol still not found, so check fallback database. 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (pool->TryFindSymbolInFallbackDatabase(name)) { 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result = FindSymbol(name); 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline const FileDescriptor* DescriptorPool::Tables::FindFile( 726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& key) const { 727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindPtrOrNull(files_by_name_, key.c_str()); 728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber( 731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, int number) const { 732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindPtrOrNull(fields_by_number_, make_pair(parent, number)); 733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName( 736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& lowercase_name) const { 737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindPtrOrNull(fields_by_lowercase_name_, 738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPair(parent, lowercase_name.c_str())); 739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName( 742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& camelcase_name) const { 743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindPtrOrNull(fields_by_camelcase_name_, 744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPair(parent, camelcase_name.c_str())); 745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber( 748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* parent, int number) const { 749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number)); 750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline const FieldDescriptor* DescriptorPool::Tables::FindExtension( 753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* extendee, int number) { 754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindPtrOrNull(extensions_, make_pair(extendee, number)); 755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline void DescriptorPool::Tables::FindAllExtensions( 758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { 759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ExtensionsGroupedByDescriptorMap::const_iterator it = 760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extensions_.lower_bound(make_pair(extendee, 0)); 761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (; it != extensions_.end() && it->first.first == extendee; ++it) { 762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville out->push_back(it->second); 763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::Tables::AddSymbol( 769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& full_name, Symbol symbol) { 770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) { 771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville symbols_after_checkpoint_.push_back(full_name.c_str()); 772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileDescriptorTables::AddAliasUnderParent( 779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& name, Symbol symbol) { 780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPair by_parent_key(parent, name.c_str()); 781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol); 782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::Tables::AddFile(const FileDescriptor* file) { 785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) { 786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville files_after_checkpoint_.push_back(file->name().c_str()); 787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileDescriptorTables::AddFieldByStylizedNames( 794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field) { 795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent; 796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_extension()) { 797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->extension_scope() == NULL) { 798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parent = field->file(); 799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parent = field->extension_scope(); 801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parent = field->containing_type(); 804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPair lowercase_key(parent, field->lowercase_name().c_str()); 807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field); 808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PointerStringPair camelcase_key(parent, field->camelcase_name().c_str()); 810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field); 811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) { 814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorIntPair key(field->containing_type(), field->number()); 815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InsertIfNotPresent(&fields_by_number_, key, field); 816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 818fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FileDescriptorTables::AddEnumValueByNumber( 819fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* value) { 820fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumIntPair key(value->type(), value->number()); 821fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return InsertIfNotPresent(&enum_values_by_number_, key, value); 822fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 824fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) { 825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorIntPair key(field->containing_type(), field->number()); 826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (InsertIfNotPresent(&extensions_, key, field)) { 827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extensions_after_checkpoint_.push_back(key); 828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<typename Type> 837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleType* DescriptorPool::Tables::Allocate() { 838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type))); 839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<typename Type> 842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleType* DescriptorPool::Tables::AllocateArray(int count) { 843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count)); 844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring* DescriptorPool::Tables::AllocateString(const string& value) { 847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* result = new string(value); 848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings_.push_back(result); 849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<typename Type> 853a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonType* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) { 854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Type* result = new Type; 855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville messages_.push_back(result); 856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() { 860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorTables* result = new FileDescriptorTables; 861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_tables_.push_back(result); 862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid* DescriptorPool::Tables::AllocateBytes(int size) { 866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // TODO(kenton): Would it be worthwhile to implement this in some more 867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // sophisticated way? Probably not for the open source release, but for 868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // internal use we could easily plug in one of our existing memory pool 869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // allocators... 870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (size == 0) return NULL; 871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* result = operator new(size); 873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville allocations_.push_back(result); 874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 877a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid FileDescriptorTables::BuildLocationsByPath( 878a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) { 879a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0, len = p->second->location_size(); i < len; ++i) { 880a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const SourceCodeInfo_Location* loc = &p->second->location().Get(i); 881a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson p->first->locations_by_path_[Join(loc->path(), ",")] = loc; 882a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 883a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 884a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 885a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonconst SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation( 886a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const vector<int>& path, const SourceCodeInfo* info) const { 887a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pair<const FileDescriptorTables*, const SourceCodeInfo*> p( 888a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson make_pair(this, info)); 889a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p); 890a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return FindPtrOrNull(locations_by_path_, Join(path, ",")); 891a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 892a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DescriptorPool 895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::ErrorCollector::~ErrorCollector() {} 897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::DescriptorPool() 899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : mutex_(NULL), 900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fallback_database_(NULL), 901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default_error_collector_(NULL), 902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville underlay_(NULL), 903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_(new Tables), 904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enforce_dependencies_(true), 905a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson allow_unknown_(false), 906a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson enforce_weak_(false) {} 907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, 909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ErrorCollector* error_collector) 910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : mutex_(new Mutex), 911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fallback_database_(fallback_database), 912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default_error_collector_(error_collector), 913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville underlay_(NULL), 914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_(new Tables), 915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enforce_dependencies_(true), 916a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson allow_unknown_(false), 917a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson enforce_weak_(false) { 918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::DescriptorPool(const DescriptorPool* underlay) 921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : mutex_(NULL), 922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fallback_database_(NULL), 923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default_error_collector_(NULL), 924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville underlay_(underlay), 925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_(new Tables), 926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enforce_dependencies_(true), 927a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson allow_unknown_(false), 928a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson enforce_weak_(false) {} 929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool::~DescriptorPool() { 931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (mutex_ != NULL) delete mutex_; 932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DescriptorPool::BuildFile() defined later. 935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DescriptorPool::BuildFileCollectingErrors() defined later. 936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorPool::InternalDontEnforceDependencies() { 938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enforce_dependencies_ = false; 939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 941a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorPool::AddUnusedImportTrackFile(const string& file_name) { 942a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unused_import_track_files_.insert(file_name); 943a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 944a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 945a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorPool::ClearUnusedImportTrackFiles() { 946a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unused_import_track_files_.clear(); 947a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 948a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::InternalIsFileLoaded(const string& filename) const { 950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLockMaybe lock(mutex_); 951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return tables_->FindFile(filename) != NULL; 952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// generated_pool ==================================================== 955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 958d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleEncodedDescriptorDatabase* generated_database_ = NULL; 960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool* generated_pool_ = NULL; 961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleGOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_); 962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DeleteGeneratedPool() { 964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete generated_database_; 965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generated_database_ = NULL; 966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete generated_pool_; 967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generated_pool_ = NULL; 968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 970a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstatic void InitGeneratedPool() { 971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generated_database_ = new EncodedDescriptorDatabase; 972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville generated_pool_ = new DescriptorPool(generated_database_); 973d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville 974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::OnShutdown(&DeleteGeneratedPool); 975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleinline void InitGeneratedPoolOnce() { 978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool); 979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // anonymous namespace 982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst DescriptorPool* DescriptorPool::generated_pool() { 984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InitGeneratedPoolOnce(); 985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return generated_pool_; 986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorPool* DescriptorPool::internal_generated_pool() { 989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InitGeneratedPoolOnce(); 990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return generated_pool_; 991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorPool::InternalAddGeneratedFile( 994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* encoded_file_descriptor, int size) { 995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // So, this function is called in the process of initializing the 996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptors for generated proto classes. Each generated .pb.cc file 997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // has an internal procedure called AddDescriptors() which is called at 998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // process startup, and that function calls this one in order to register 999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the raw bytes of the FileDescriptorProto representing the file. 1000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 1001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We do not actually construct the descriptor objects right away. We just 1002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // hang on to the bytes until they are actually needed. We actually construct 1003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the descriptor the first time one of the following things happens: 1004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // * Someone calls a method like descriptor(), GetDescriptor(), or 1005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // GetReflection() on the generated types, which requires returning the 1006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptor or an object based on it. 1007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // * Someone looks up the descriptor in DescriptorPool::generated_pool(). 1008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 1009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Once one of these happens, the DescriptorPool actually parses the 1010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FileDescriptorProto and generates a FileDescriptor (and all its children) 1011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // based on it. 1012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 1013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that FileDescriptorProto is itself a generated protocol message. 1014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Therefore, when we parse one, we have to be very careful to avoid using 1015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // any descriptor-based operations, since this might cause infinite recursion 1016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // or deadlock. 1017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville InitGeneratedPoolOnce(); 1018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size)); 1019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Find*By* methods ================================================== 1023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(kenton): There's a lot of repeated code here, but I'm not sure if 1025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// there's any good way to factor it out. Think about this some time when 1026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// there's nothing more important to do (read: never). 1027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorPool::FindFileByName(const string& name) const { 1029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLockMaybe lock(mutex_); 1030a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.clear(); 1031a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.clear(); 1032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* result = tables_->FindFile(name); 1033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != NULL) return result; 1034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (underlay_ != NULL) { 1035a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = underlay_->FindFileByName(name); 1036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != NULL) return result; 1037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryFindFileInFallbackDatabase(name)) { 1039a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = tables_->FindFile(name); 1040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != NULL) return result; 1041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorPool::FindFileContainingSymbol( 1046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& symbol_name) const { 1047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLockMaybe lock(mutex_); 1048a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.clear(); 1049a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.clear(); 1050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindSymbol(symbol_name); 1051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) return result.GetFile(); 1052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (underlay_ != NULL) { 1053a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FileDescriptor* file_result = 1054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville underlay_->FindFileContainingSymbol(symbol_name); 1055a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (file_result != NULL) return file_result; 1056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryFindSymbolInFallbackDatabase(symbol_name)) { 1058a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = tables_->FindSymbol(symbol_name); 1059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) return result.GetFile(); 1060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst Descriptor* DescriptorPool::FindMessageTypeByName( 1065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL; 1068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* DescriptorPool::FindFieldByName( 1071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.type == Symbol::FIELD && 1074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville !result.field_descriptor->is_extension()) { 1075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.field_descriptor; 1076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* DescriptorPool::FindExtensionByName( 1082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.type == Symbol::FIELD && 1085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.field_descriptor->is_extension()) { 1086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.field_descriptor; 1087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1092a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonconst OneofDescriptor* DescriptorPool::FindOneofByName( 1093a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& name) const { 1094a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol result = tables_->FindByNameHelper(this, name); 1095a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : NULL; 1096a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 1097a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumDescriptor* DescriptorPool::FindEnumTypeByName( 1099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL; 1102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumValueDescriptor* DescriptorPool::FindEnumValueByName( 1105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (result.type == Symbol::ENUM_VALUE) ? 1108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.enum_value_descriptor : NULL; 1109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst ServiceDescriptor* DescriptorPool::FindServiceByName( 1112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL; 1115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst MethodDescriptor* DescriptorPool::FindMethodByName( 1118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) const { 1119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindByNameHelper(this, name); 1120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL; 1121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* DescriptorPool::FindExtensionByNumber( 1124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* extendee, int number) const { 1125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLockMaybe lock(mutex_); 1126a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.clear(); 1127a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.clear(); 1128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = tables_->FindExtension(extendee, number); 1129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != NULL) { 1130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (underlay_ != NULL) { 1133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = underlay_->FindExtensionByNumber(extendee, number); 1134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != NULL) return result; 1135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (TryFindExtensionInFallbackDatabase(extendee, number)) { 1137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = tables_->FindExtension(extendee, number); 1138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result != NULL) { 1139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorPool::FindAllExtensions( 1146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* extendee, vector<const FieldDescriptor*>* out) const { 1147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MutexLockMaybe lock(mutex_); 1148a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.clear(); 1149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.clear(); 1150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Initialize tables_->extensions_ from the fallback database first 1152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // (but do this only once per descriptor). 1153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fallback_database_ != NULL && 1154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->extensions_loaded_from_db_.count(extendee) == 0) { 1155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<int> numbers; 1156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(), 1157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &numbers)) { 1158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < numbers.size(); ++i) { 1159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int number = numbers[i]; 1160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->FindExtension(extendee, number) == NULL) { 1161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville TryFindExtensionInFallbackDatabase(extendee, number); 1162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->extensions_loaded_from_db_.insert(extendee); 1165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->FindAllExtensions(extendee, out); 1169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (underlay_ != NULL) { 1170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville underlay_->FindAllExtensions(extendee, out); 1171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 1176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindFieldByNumber(int key) const { 1179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = 1180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindFieldByNumber(this, key); 1181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || result->is_extension()) { 1182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindFieldByLowercaseName(const string& key) const { 1190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = 1191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindFieldByLowercaseName(this, key); 1192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || result->is_extension()) { 1193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindFieldByCamelcaseName(const string& key) const { 1201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = 1202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindFieldByCamelcaseName(this, key); 1203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || result->is_extension()) { 1204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindFieldByName(const string& key) const { 1212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 1214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull() && !result.field_descriptor->is_extension()) { 1215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.field_descriptor; 1216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonconst OneofDescriptor* 1222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonDescriptor::FindOneofByName(const string& key) const { 1223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol result = 1224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF); 1225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!result.IsNull()) { 1226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return result.oneof_descriptor; 1227a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 1228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return NULL; 1229a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 1231a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindExtensionByName(const string& key) const { 1234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 1236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull() && result.field_descriptor->is_extension()) { 1237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.field_descriptor; 1238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindExtensionByLowercaseName(const string& key) const { 1245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = 1246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindFieldByLowercaseName(this, key); 1247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || !result->is_extension()) { 1248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindExtensionByCamelcaseName(const string& key) const { 1256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = 1257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindFieldByCamelcaseName(this, key); 1258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || !result->is_extension()) { 1259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst Descriptor* 1266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindNestedTypeByName(const string& key) const { 1267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); 1269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.descriptor; 1271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumDescriptor* 1277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindEnumTypeByName(const string& key) const { 1278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); 1280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.enum_descriptor; 1282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumValueDescriptor* 1288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptor::FindEnumValueByName(const string& key) const { 1289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 1291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.enum_value_descriptor; 1293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumValueDescriptor* 1299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleEnumDescriptor::FindValueByName(const string& key) const { 1300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 1302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.enum_value_descriptor; 1304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumValueDescriptor* 1310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleEnumDescriptor::FindValueByNumber(int key) const { 1311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return file()->tables_->FindEnumValueByNumber(this, key); 1312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst MethodDescriptor* 1315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleServiceDescriptor::FindMethodByName(const string& key) const { 1316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD); 1318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.method_descriptor; 1320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst Descriptor* 1326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindMessageTypeByName(const string& key) const { 1327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE); 1328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.descriptor; 1330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumDescriptor* 1336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindEnumTypeByName(const string& key) const { 1337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM); 1338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.enum_descriptor; 1340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst EnumValueDescriptor* 1346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindEnumValueByName(const string& key) const { 1347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = 1348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM_VALUE); 1349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.enum_value_descriptor; 1351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst ServiceDescriptor* 1357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindServiceByName(const string& key) const { 1358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE); 1359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 1360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.service_descriptor; 1361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindExtensionByName(const string& key) const { 1368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD); 1369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull() && result.field_descriptor->is_extension()) { 1370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result.field_descriptor; 1371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindExtensionByLowercaseName(const string& key) const { 1378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key); 1379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || !result->is_extension()) { 1380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FieldDescriptor* 1387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleFileDescriptor::FindExtensionByCamelcaseName(const string& key) const { 1388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key); 1389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result == NULL || !result->is_extension()) { 1390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 1391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 1393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1396a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonconst Descriptor::ExtensionRange* 1397a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonDescriptor::FindExtensionRangeContainingNumber(int number) const { 1398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Linear search should be fine because we don't expect a message to have 1399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // more than a couple extension ranges. 1400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_range_count(); i++) { 1401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (number >= extension_range(i)->start && 1402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville number < extension_range(i)->end) { 1403a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return extension_range(i); 1404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1406a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return NULL; 1407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 1410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { 1412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fallback_database_ == NULL) return false; 1413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->known_bad_files_.count(name) > 0) return false; 1415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorProto file_proto; 1417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!fallback_database_->FindFileByName(name, &file_proto) || 1418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BuildFileFromDatabase(file_proto) == NULL) { 1419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->known_bad_files_.insert(name); 1420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 1421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 1423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1425a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool DescriptorPool::IsSubSymbolOfBuiltType(const string& name) const { 1426a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string prefix = name; 1427a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (;;) { 1428a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string::size_type dot_pos = prefix.find_last_of('.'); 1429a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (dot_pos == string::npos) { 1430a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson break; 1431a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1432a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson prefix = prefix.substr(0, dot_pos); 1433a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol symbol = tables_->FindSymbol(prefix); 1434a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // If the symbol type is anything other than PACKAGE, then its complete 1435a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // definition is already known. 1436a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) { 1437a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return true; 1438a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1439a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1440a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (underlay_ != NULL) { 1441a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Check to see if any prefix of this symbol exists in the underlay. 1442a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return underlay_->IsSubSymbolOfBuiltType(name); 1443a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1444a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return false; 1445a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 1446a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const { 1448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fallback_database_ == NULL) return false; 1449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1450a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (tables_->known_bad_symbols_.count(name) > 0) return false; 1451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1452a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson FileDescriptorProto file_proto; 1453a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (// We skip looking in the fallback database if the name is a sub-symbol 1454a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // of any descriptor that already exists in the descriptor pool (except 1455a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // for package descriptors). This is valid because all symbols except 1456a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // for packages are defined in a single file, so if the symbol exists 1457a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // then we should already have its definition. 1458a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // 1459a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // The other reason to do this is to support "overriding" type 1460a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // definitions by merging two databases that define the same type. (Yes, 1461a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // people do this.) The main difficulty with making this work is that 1462a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // FindFileContainingSymbol() is allowed to return both false positives 1463a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false 1464a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase). 1465a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // When two such databases are merged, looking up a non-existent 1466a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // sub-symbol of a type that already exists in the descriptor pool can 1467a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // result in an attempt to load multiple definitions of the same type. 1468a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // The check below avoids this. 1469a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson IsSubSymbolOfBuiltType(name) 1470a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1471a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Look up file containing this symbol in fallback database. 1472a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson || !fallback_database_->FindFileContainingSymbol(name, &file_proto) 1473a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1474a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Check if we've already built this file. If so, it apparently doesn't 1475a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // contain the symbol we're looking for. Some DescriptorDatabases 1476a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // return false positives. 1477a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson || tables_->FindFile(file_proto.name()) != NULL 1478a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1479a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Build the file. 1480a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson || BuildFileFromDatabase(file_proto) == NULL) { 1481a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.insert(name); 1482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 1483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 1486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorPool::TryFindExtensionInFallbackDatabase( 1489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* containing_type, int field_number) const { 1490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fallback_database_ == NULL) return false; 1491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorProto file_proto; 1493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!fallback_database_->FindFileContainingExtension( 1494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville containing_type->full_name(), field_number, &file_proto)) { 1495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 1496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->FindFile(file_proto.name()) != NULL) { 1499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We've already loaded this file, and it apparently doesn't contain the 1500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // extension we're looking for. Some DescriptorDatabases return false 1501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // positives. 1502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 1503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (BuildFileFromDatabase(file_proto) == NULL) { 1506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 1507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 1510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 1513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FieldDescriptor::DefaultValueAsString(bool quote_string_type) const { 1515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(has_default_value()) << "No default value"; 1516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (cpp_type()) { 1517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_INT32: 1518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SimpleItoa(default_value_int32()); 1519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_INT64: 1521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SimpleItoa(default_value_int64()); 1522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_UINT32: 1524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SimpleItoa(default_value_uint32()); 1525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_UINT64: 1527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SimpleItoa(default_value_uint64()); 1528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_FLOAT: 1530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SimpleFtoa(default_value_float()); 1531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_DOUBLE: 1533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return SimpleDtoa(default_value_double()); 1534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_BOOL: 1536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return default_value_bool() ? "true" : "false"; 1537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_STRING: 1539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (quote_string_type) { 1540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return "\"" + CEscape(default_value_string()) + "\""; 1541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (type() == TYPE_BYTES) { 1543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return CEscape(default_value_string()); 1544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 1545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return default_value_string(); 1546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_ENUM: 1550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return default_value_enum()->name(); 1551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case CPPTYPE_MESSAGE: 1553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(DFATAL) << "Messages can't have default values!"; 1554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string"; 1557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return ""; 1558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// CopyTo methods ==================================================== 1561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FileDescriptor::CopyTo(FileDescriptorProto* proto) const { 1563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!package().empty()) proto->set_package(package()); 1565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < dependency_count(); i++) { 1567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->add_dependency(dependency(i)->name()); 1568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < public_dependency_count(); i++) { 1571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto->add_public_dependency(public_dependencies_[i]); 1572a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1573a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1574a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < weak_dependency_count(); i++) { 1575a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto->add_weak_dependency(weak_dependencies_[i]); 1576a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1577a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < message_type_count(); i++) { 1579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_type(i)->CopyTo(proto->add_message_type()); 1580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < enum_type_count(); i++) { 1582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_type(i)->CopyTo(proto->add_enum_type()); 1583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < service_count(); i++) { 1585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville service(i)->CopyTo(proto->add_service()); 1586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_count(); i++) { 1588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension(i)->CopyTo(proto->add_extension()); 1589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &FileOptions::default_instance()) { 1592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1596a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const { 1597a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (source_code_info_ != &SourceCodeInfo::default_instance()) { 1598a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto->mutable_source_code_info()->CopyFrom(*source_code_info_); 1599a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1600a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 1601a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Descriptor::CopyTo(DescriptorProto* proto) const { 1603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < field_count(); i++) { 1606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field(i)->CopyTo(proto->add_field()); 1607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1608a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < oneof_decl_count(); i++) { 1609a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson oneof_decl(i)->CopyTo(proto->add_oneof_decl()); 1610a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < nested_type_count(); i++) { 1612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville nested_type(i)->CopyTo(proto->add_nested_type()); 1613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < enum_type_count(); i++) { 1615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_type(i)->CopyTo(proto->add_enum_type()); 1616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_range_count(); i++) { 1618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorProto::ExtensionRange* range = proto->add_extension_range(); 1619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville range->set_start(extension_range(i)->start); 1620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville range->set_end(extension_range(i)->end); 1621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_count(); i++) { 1623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension(i)->CopyTo(proto->add_extension()); 1624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &MessageOptions::default_instance()) { 1627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { 1632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_number(number()); 1634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Some compilers do not allow static_cast directly between two enum types, 1636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // so we must cast to int first. 1637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_label(static_cast<FieldDescriptorProto::Label>( 1638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville implicit_cast<int>(label()))); 1639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_type(static_cast<FieldDescriptorProto::Type>( 1640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville implicit_cast<int>(type()))); 1641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (is_extension()) { 1643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!containing_type()->is_unqualified_placeholder_) { 1644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_extendee("."); 1645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_extendee()->append(containing_type()->full_name()); 1647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (cpp_type() == CPPTYPE_MESSAGE) { 1650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (message_type()->is_placeholder_) { 1651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We don't actually know if the type is a message type. It could be 1652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // an enum. 1653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->clear_type(); 1654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!message_type()->is_unqualified_placeholder_) { 1657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_type_name("."); 1658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_type_name()->append(message_type()->full_name()); 1660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (cpp_type() == CPPTYPE_ENUM) { 1661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!enum_type()->is_unqualified_placeholder_) { 1662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_type_name("."); 1663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_type_name()->append(enum_type()->full_name()); 1665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (has_default_value()) { 1668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_default_value(DefaultValueAsString(false)); 1669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1671a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (containing_oneof() != NULL && !is_extension()) { 1672a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto->set_oneof_index(containing_oneof()->index()); 1673a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1674a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &FieldOptions::default_instance()) { 1676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1680a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const { 1681a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto->set_name(name()); 1682a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 1683a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const { 1685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < value_count(); i++) { 1688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value(i)->CopyTo(proto->add_value()); 1689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &EnumOptions::default_instance()) { 1692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const { 1697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_number(number()); 1699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &EnumValueOptions::default_instance()) { 1701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const { 1706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < method_count(); i++) { 1709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville method(i)->CopyTo(proto->add_method()); 1710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &ServiceOptions::default_instance()) { 1713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const { 1718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_name(name()); 1719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!input_type()->is_unqualified_placeholder_) { 1721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_input_type("."); 1722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_input_type()->append(input_type()->full_name()); 1724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!output_type()->is_unqualified_placeholder_) { 1726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->set_output_type("."); 1727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_output_type()->append(output_type()->full_name()); 1729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (&options() != &MethodOptions::default_instance()) { 1731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto->mutable_options()->CopyFrom(options()); 1732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DebugString methods =============================================== 1736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 1738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Used by each of the option formatters. 1740a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool RetrieveOptions(int depth, 1741a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Message &options, 1742a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<string> *option_entries) { 1743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_entries->clear(); 1744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Reflection* reflection = options.GetReflection(); 1745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> fields; 1746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville reflection->ListFields(options, &fields); 1747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < fields.size(); i++) { 1748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int count = 1; 1749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool repeated = false; 1750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (fields[i]->is_repeated()) { 1751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville count = reflection->FieldSize(options, fields[i]); 1752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville repeated = true; 1753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < count; j++) { 1755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string fieldval; 1756a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 1757a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string tmp; 1758a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson TextFormat::Printer printer; 1759a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson printer.SetInitialIndentLevel(depth + 1); 1760a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson printer.PrintFieldValueToString(options, fields[i], 1761a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson repeated ? j : -1, &tmp); 1762a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fieldval.append("{\n"); 1763a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fieldval.append(tmp); 1764a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fieldval.append(depth * 2, ' '); 1765a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson fieldval.append("}"); 1766a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 1767a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson TextFormat::PrintFieldValueToString(options, fields[i], 1768a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson repeated ? j : -1, &fieldval); 1769a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1770a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string name; 1771a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (fields[i]->is_extension()) { 1772a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson name = "(." + fields[i]->full_name() + ")"; 1773a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 1774a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson name = fields[i]->name(); 1775a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1776a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson option_entries->push_back(name + " = " + fieldval); 1777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !option_entries->empty(); 1780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Formats options that all appear together in brackets. Does not include 1783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// brackets. 1784a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool FormatBracketedOptions(int depth, const Message &options, string *output) { 1785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> all_options; 1786a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (RetrieveOptions(depth, options, &all_options)) { 1787a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->append(Join(all_options, ", ")); 1788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !all_options.empty(); 1790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Formats options one per line 1793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool FormatLineOptions(int depth, const Message &options, string *output) { 1794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix(depth * 2, ' '); 1795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<string> all_options; 1796a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (RetrieveOptions(depth, options, &all_options)) { 1797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < all_options.size(); i++) { 1798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(output, "$0option $1;\n", 1799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, all_options[i]); 1800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !all_options.empty(); 1803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // anonymous namespace 1806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FileDescriptor::DebugString() const { 1808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents = "syntax = \"proto2\";\n\n"; 1809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1810a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson set<int> public_dependencies; 1811a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson set<int> weak_dependencies; 1812a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson public_dependencies.insert(public_dependencies_, 1813a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson public_dependencies_ + public_dependency_count_); 1814a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson weak_dependencies.insert(weak_dependencies_, 1815a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson weak_dependencies_ + weak_dependency_count_); 1816a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1817fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < dependency_count(); i++) { 1818a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (public_dependencies.count(i) > 0) { 1819a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::SubstituteAndAppend(&contents, "import public \"$0\";\n", 1820a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson dependency(i)->name()); 1821a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else if (weak_dependencies.count(i) > 0) { 1822a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n", 1823a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson dependency(i)->name()); 1824a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 1825a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::SubstituteAndAppend(&contents, "import \"$0\";\n", 1826a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson dependency(i)->name()); 1827a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!package().empty()) { 1831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(&contents, "package $0;\n\n", package()); 1832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (FormatLineOptions(0, options(), &contents)) { 1835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents.append("\n"); // add some space if we had options 1836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < enum_type_count(); i++) { 1839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_type(i)->DebugString(0, &contents); 1840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents.append("\n"); 1841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find all the 'group' type extensions; we will not output their nested 1844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // definitions (those will be done with their group field descriptor). 1845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville set<const Descriptor*> groups; 1846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_count(); i++) { 1847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { 1848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville groups.insert(extension(i)->message_type()); 1849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < message_type_count(); i++) { 1853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (groups.count(message_type(i)) == 0) { 1854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(&contents, "message $0", 1855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_type(i)->name()); 1856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_type(i)->DebugString(0, &contents); 1857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents.append("\n"); 1858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < service_count(); i++) { 1862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville service(i)->DebugString(&contents); 1863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents.append("\n"); 1864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* containing_type = NULL; 1867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_count(); i++) { 1868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extension(i)->containing_type() != containing_type) { 1869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i > 0) contents.append("}\n\n"); 1870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville containing_type = extension(i)->containing_type(); 1871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(&contents, "extend .$0 {\n", 1872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville containing_type->full_name()); 1873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1874a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extension(i)->DebugString(1, FieldDescriptor::PRINT_LABEL, &contents); 1875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extension_count() > 0) contents.append("}\n\n"); 1877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 1879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring Descriptor::DebugString() const { 1882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents; 1883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(&contents, "message $0", name()); 1884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DebugString(0, &contents); 1885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 1886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid Descriptor::DebugString(int depth, string *contents) const { 1889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix(depth * 2, ' '); 1890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++depth; 1891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append(" {\n"); 1892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FormatLineOptions(depth, options(), contents); 1894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find all the 'group' types for fields and extensions; we will not output 1896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // their nested definitions (those will be done with their group field 1897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptor). 1898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville set<const Descriptor*> groups; 1899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < field_count(); i++) { 1900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field(i)->type() == FieldDescriptor::TYPE_GROUP) { 1901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville groups.insert(field(i)->message_type()); 1902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_count(); i++) { 1905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extension(i)->type() == FieldDescriptor::TYPE_GROUP) { 1906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville groups.insert(extension(i)->message_type()); 1907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < nested_type_count(); i++) { 1911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (groups.count(nested_type(i)) == 0) { 1912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0 message $1", 1913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, nested_type(i)->name()); 1914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville nested_type(i)->DebugString(depth, contents); 1915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < enum_type_count(); i++) { 1918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_type(i)->DebugString(depth, contents); 1919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < field_count(); i++) { 1921a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (field(i)->containing_oneof() == NULL) { 1922a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents); 1923a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else if (field(i)->containing_oneof()->field(0) == field(i)) { 1924a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // This is the first field in this oneof, so print the whole oneof. 1925a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field(i)->containing_oneof()->DebugString(depth, contents); 1926a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_range_count(); i++) { 1930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", 1931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, 1932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension_range(i)->start, 1933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville extension_range(i)->end - 1); 1934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Group extensions by what they extend, so they can be printed out together. 1937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* containing_type = NULL; 1938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < extension_count(); i++) { 1939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extension(i)->containing_type() != containing_type) { 1940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix); 1941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville containing_type = extension(i)->containing_type(); 1942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", 1943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, containing_type->full_name()); 1944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1945a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extension(i)->DebugString( 1946a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson depth + 1, FieldDescriptor::PRINT_LABEL, contents); 1947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extension_count() > 0) 1949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0 }\n", prefix); 1950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0}\n", prefix); 1952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring FieldDescriptor::DebugString() const { 1955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents; 1956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int depth = 0; 1957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (is_extension()) { 1958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(&contents, "extend .$0 {\n", 1959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville containing_type()->full_name()); 1960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville depth = 1; 1961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1962a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DebugString(depth, PRINT_LABEL, &contents); 1963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (is_extension()) { 1964a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson contents.append("}\n"); 1965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 1967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 1968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1969a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid FieldDescriptor::DebugString(int depth, 1970a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson PrintLabelFlag print_label_flag, 1971a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string *contents) const { 1972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix(depth * 2, ' '); 1973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string field_type; 1974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type()) { 1975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case TYPE_MESSAGE: 1976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_type = "." + message_type()->full_name(); 1977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case TYPE_ENUM: 1979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_type = "." + enum_type()->full_name(); 1980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 1981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 1982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_type = kTypeToName[type()]; 1983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 1984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1985a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string label; 1986a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (print_label_flag == PRINT_LABEL) { 1987a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson label = kLabelToName[this->label()]; 1988a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson label.push_back(' '); 1989a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 1990a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 1991a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4", 1992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, 1993a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson label, 1994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field_type, 1995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville type() == TYPE_GROUP ? message_type()->name() : 1996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name(), 1997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville number()); 1998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 1999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool bracketed = false; 2000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (has_default_value()) { 2001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bracketed = true; 2002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, " [default = $0", 2003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DefaultValueAsString(true)); 2004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string formatted_options; 2007a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (FormatBracketedOptions(depth, options(), &formatted_options)) { 2008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append(bracketed ? ", " : " ["); 2009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bracketed = true; 2010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append(formatted_options); 2011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (bracketed) { 2014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append("]"); 2015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (type() == TYPE_GROUP) { 2018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message_type()->DebugString(depth, contents); 2019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append(";\n"); 2021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2024a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstring OneofDescriptor::DebugString() const { 2025a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string contents; 2026a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DebugString(0, &contents); 2027a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return contents; 2028a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2029a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2030a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid OneofDescriptor::DebugString(int depth, string* contents) const { 2031a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string prefix(depth * 2, ' '); 2032a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ++depth; 2033a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::SubstituteAndAppend( 2034a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson contents, "$0 oneof $1 {\n", prefix, name()); 2035a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < field_count(); i++) { 2036a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents); 2037a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2038a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::SubstituteAndAppend(contents, "$0}\n", prefix); 2039a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2040a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring EnumDescriptor::DebugString() const { 2042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents; 2043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DebugString(0, &contents); 2044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 2045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumDescriptor::DebugString(int depth, string *contents) const { 2048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix(depth * 2, ' '); 2049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++depth; 2050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0enum $1 {\n", 2051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, name()); 2052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FormatLineOptions(depth, options(), contents); 2054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < value_count(); i++) { 2056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value(i)->DebugString(depth, contents); 2057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0}\n", prefix); 2059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring EnumValueDescriptor::DebugString() const { 2062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents; 2063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DebugString(0, &contents); 2064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 2065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid EnumValueDescriptor::DebugString(int depth, string *contents) const { 2068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix(depth * 2, ' '); 2069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0$1 = $2", 2070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, name(), number()); 2071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string formatted_options; 2073a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (FormatBracketedOptions(depth, options(), &formatted_options)) { 2074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, " [$0]", formatted_options); 2075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append(";\n"); 2077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring ServiceDescriptor::DebugString() const { 2080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents; 2081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DebugString(&contents); 2082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 2083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid ServiceDescriptor::DebugString(string *contents) const { 2086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "service $0 {\n", name()); 2087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FormatLineOptions(1, options(), contents); 2089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < method_count(); i++) { 2091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville method(i)->DebugString(1, contents); 2092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append("}\n"); 2095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring MethodDescriptor::DebugString() const { 2098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string contents; 2099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DebugString(0, &contents); 2100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return contents; 2101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid MethodDescriptor::DebugString(int depth, string *contents) const { 2104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string prefix(depth * 2, ' '); 2105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ++depth; 2106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, "$0rpc $1(.$2) returns (.$3)", 2107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville prefix, name(), 2108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input_type()->full_name(), 2109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output_type()->full_name()); 2110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string formatted_options; 2112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (FormatLineOptions(depth, options(), &formatted_options)) { 2113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::SubstituteAndAppend(contents, " {\n$0$1}\n", 2114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville formatted_options, prefix); 2115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville contents->append(";\n"); 2117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2119a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2120a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2121a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// Location methods =============================================== 2122a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2123a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool FileDescriptor::GetSourceLocation(const vector<int>& path, 2124a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson SourceLocation* out_location) const { 2125a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK_NOTNULL(out_location); 2126a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (source_code_info_) { 2127a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (const SourceCodeInfo_Location* loc = 2128a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->GetSourceLocation(path, source_code_info_)) { 2129a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const RepeatedField<int32>& span = loc->span(); 2130a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (span.size() == 3 || span.size() == 4) { 2131a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson out_location->start_line = span.Get(0); 2132a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson out_location->start_column = span.Get(1); 2133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson out_location->end_line = span.Get(span.size() == 3 ? 0 : 2); 2134a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson out_location->end_column = span.Get(span.size() - 1); 2135a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2136a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson out_location->leading_comments = loc->leading_comments(); 2137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson out_location->trailing_comments = loc->trailing_comments(); 2138a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return true; 2139a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2140a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2141a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2142a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return false; 2143a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2144a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2145a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool FieldDescriptor::is_packed() const { 2146a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return is_packable() && (options_ != NULL) && options_->packed(); 2147a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2148a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool Descriptor::GetSourceLocation(SourceLocation* out_location) const { 2150a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2151a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return file()->GetSourceLocation(path, out_location); 2153a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2154a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2155a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2156a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2157a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2158a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return file()->GetSourceLocation(path, out_location); 2159a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2160a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2161a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2162a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2163a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2164a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return containing_type()->file()->GetSourceLocation(path, out_location); 2165a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2166a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2167a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2168a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2169a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2170a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return file()->GetSourceLocation(path, out_location); 2171a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2172a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2173a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2174a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2175a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2176a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return service()->file()->GetSourceLocation(path, out_location); 2177a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2178a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2179a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const { 2180a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2181a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2182a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return file()->GetSourceLocation(path, out_location); 2183a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2184a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2185a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool EnumValueDescriptor::GetSourceLocation( 2186a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson SourceLocation* out_location) const { 2187a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson vector<int> path; 2188a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GetLocationPath(&path); 2189a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return type()->file()->GetSourceLocation(path, out_location); 2190a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2191a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2192a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid Descriptor::GetLocationPath(vector<int>* output) const { 2193a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (containing_type()) { 2194a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson containing_type()->GetLocationPath(output); 2195a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(DescriptorProto::kNestedTypeFieldNumber); 2196a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2197a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 2198a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(FileDescriptorProto::kMessageTypeFieldNumber); 2199a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2200a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid FieldDescriptor::GetLocationPath(vector<int>* output) const { 2204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (is_extension()) { 2205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (extension_scope() == NULL) { 2206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(FileDescriptorProto::kExtensionFieldNumber); 2207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2208a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 2209a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extension_scope()->GetLocationPath(output); 2210a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(DescriptorProto::kExtensionFieldNumber); 2211a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2212a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2213a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 2214a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson containing_type()->GetLocationPath(output); 2215a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(DescriptorProto::kFieldFieldNumber); 2216a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2217a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2218a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2219a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid OneofDescriptor::GetLocationPath(vector<int>* output) const { 2221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson containing_type()->GetLocationPath(output); 2222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(DescriptorProto::kOneofDeclFieldNumber); 2223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid EnumDescriptor::GetLocationPath(vector<int>* output) const { 2227a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (containing_type()) { 2228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson containing_type()->GetLocationPath(output); 2229a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(DescriptorProto::kEnumTypeFieldNumber); 2230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2231a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 2232a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(FileDescriptorProto::kEnumTypeFieldNumber); 2233a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2235a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid EnumValueDescriptor::GetLocationPath(vector<int>* output) const { 2238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson type()->GetLocationPath(output); 2239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(EnumDescriptorProto::kValueFieldNumber); 2240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2242a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2243a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid ServiceDescriptor::GetLocationPath(vector<int>* output) const { 2244a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(FileDescriptorProto::kServiceFieldNumber); 2245a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid MethodDescriptor::GetLocationPath(vector<int>* output) const { 2249a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson service()->GetLocationPath(output); 2250a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(ServiceDescriptorProto::kMethodFieldNumber); 2251a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson output->push_back(index()); 2252a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 2255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 2257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Represents an options message to interpret. Extension names in the option 2259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// name are respolved relative to name_scope. element_name and orig_opt are 2260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// used only for error reporting (since the parser records locations against 2261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// pointers in the original options, not the mutable copy). The Message must be 2262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// one of the Options messages in descriptor.proto. 2263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestruct OptionsToInterpret { 2264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OptionsToInterpret(const string& ns, 2265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& el, 2266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message* orig_opt, 2267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* opt) 2268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : name_scope(ns), 2269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville element_name(el), 2270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville original_options(orig_opt), 2271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options(opt) { 2272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string name_scope; 2274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string element_name; 2275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message* original_options; 2276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* options; 2277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 2278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 2280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass DescriptorBuilder { 2282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 2283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorBuilder(const DescriptorPool* pool, 2284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::Tables* tables, 2285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector* error_collector); 2286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~DescriptorBuilder(); 2287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* BuildFile(const FileDescriptorProto& proto); 2289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 2291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville friend class OptionInterpreter; 2292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const DescriptorPool* pool_; 2294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::Tables* tables_; // for convenience 2295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector* error_collector_; 2296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // As we build descriptors we store copies of the options messages in 2298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // them. We put pointers to those copies in this vector, as we build, so we 2299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // can later (after cross-linking) interpret those options. 2300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<OptionsToInterpret> options_to_interpret_; 2301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool had_errors_; 2303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string filename_; 2304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* file_; 2305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptorTables* file_tables_; 2306a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson set<const FileDescriptor*> dependencies_; 2307a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2308a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // unused_dependency_ is used to record the unused imported files. 2309a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Note: public import is not considered. 2310a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson set<const FileDescriptor*> unused_dependency_; 2311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If LookupSymbol() finds a symbol that is in a file which is not a declared 2313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // dependency of this file, it will fail, but will set 2314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // possible_undeclared_dependency_ to point at that file. This is only used 2315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // by AddNotDefinedError() to report a more useful error message. 2316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // possible_undeclared_dependency_name_ is the name of the symbol that was 2317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // actually found in possible_undeclared_dependency_, which may be a parent 2318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // of the symbol actually looked for. 2319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* possible_undeclared_dependency_; 2320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string possible_undeclared_dependency_name_; 2321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2322a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // If LookupSymbol() could resolve a symbol which is not defined, 2323a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // record the resolved name. This is only used by AddNotDefinedError() 2324a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // to report a more useful error message. 2325a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string undefine_resolved_name_; 2326a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddError(const string& element_name, 2328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& descriptor, 2329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::ErrorLocation location, 2330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& error); 2331a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void AddError(const string& element_name, 2332a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Message& descriptor, 2333a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::ErrorLocation location, 2334a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const char* error); 2335a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here); 2336a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void AddTwiceListedError(const FileDescriptorProto& proto, int index); 2337a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void AddImportError(const FileDescriptorProto& proto, int index); 2338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Adds an error indicating that undefined_symbol was not defined. Must 2340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // only be called after LookupSymbol() fails. 2341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddNotDefinedError( 2342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& element_name, 2343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& descriptor, 2344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::ErrorLocation location, 2345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& undefined_symbol); 2346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void AddWarning(const string& element_name, const Message& descriptor, 2348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::ErrorLocation location, 2349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& error); 2350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Silly helper which determines if the given file is in the given package. 2352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // I.e., either file->package() == package_name or file->package() is a 2353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // nested package within package_name. 2354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool IsInPackage(const FileDescriptor* file, const string& package_name); 2355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2356a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Helper function which finds all public dependencies of the given file, and 2357a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // stores the them in the dependencies_ set in the builder. 2358a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void RecordPublicDependencies(const FileDescriptor* file); 2359a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Like tables_->FindSymbol(), but additionally: 2361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // - Search the pool's underlay if not found in tables_. 2362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // - Insure that the resulting Symbol is from one of the file's declared 2363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // dependencies. 2364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol FindSymbol(const string& name); 2365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Like FindSymbol() but does not require that the symbol is in one of the 2367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // file's declared dependencies. 2368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol FindSymbolNotEnforcingDeps(const string& name); 2369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2370a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // This implements the body of FindSymbolNotEnforcingDeps(). 2371a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool, 2372a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& name); 2373a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Like FindSymbol(), but looks up the name relative to some other symbol 2375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // name. This first searches siblings of relative_to, then siblings of its 2376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes 2377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the following calls, returning the first non-null result: 2378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"), 2379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called 2380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // on the DescriptorPool, this will generate a placeholder type if 2381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the name is not found (unless the name itself is malformed). The 2382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // placeholder_type parameter indicates what kind of placeholder should be 2383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // constructed in this case. The resolve_mode parameter determines whether 2384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // any symbol is returned, or only symbols that are types. Note, however, 2385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, 2386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // if it believes that's all it could refer to. The caller should always 2387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // check that it receives the type of symbol it was expecting. 2388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum PlaceholderType { 2389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PLACEHOLDER_MESSAGE, 2390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PLACEHOLDER_ENUM, 2391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PLACEHOLDER_EXTENDABLE_MESSAGE 2392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 2393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum ResolveMode { 2394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOOKUP_ALL, LOOKUP_TYPES 2395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 2396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol LookupSymbol(const string& name, const string& relative_to, 2397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE, 2398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ResolveMode resolve_mode = LOOKUP_ALL); 2399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Like LookupSymbol() but will not return a placeholder even if 2401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // AllowUnknownDependencies() has been used. 2402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol LookupSymbolNoPlaceholder(const string& name, 2403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& relative_to, 2404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ResolveMode resolve_mode = LOOKUP_ALL); 2405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Creates a placeholder type suitable for return from LookupSymbol(). May 2407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // return kNullSymbol if the name is not a valid type name. 2408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type); 2409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Creates a placeholder file. Never returns NULL. This is used when an 2411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // import is not found and AllowUnknownDependencies() is enabled. 2412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* NewPlaceholderFile(const string& name); 2413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Calls tables_->AddSymbol() and records an error if it fails. Returns 2415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // true if successful or false if failed, though most callers can ignore 2416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the return value since an error has already been recorded. 2417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddSymbol(const string& full_name, 2418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* parent, const string& name, 2419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& proto, Symbol symbol); 2420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Like AddSymbol(), but succeeds if the symbol is already defined as long 2422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // as the existing definition is also a package (because it's OK to define 2423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the same package in two different files). Also adds all parents of the 2424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add 2425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // "foo.bar" and "foo" to the table). 2426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddPackage(const string& name, const Message& proto, 2427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* file); 2428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Checks that the symbol name contains only alphanumeric characters and 2430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // underscores. Records an error otherwise. 2431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateSymbolName(const string& name, const string& full_name, 2432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& proto); 2433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Like ValidateSymbolName(), but the name is allowed to contain periods and 2435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // an error is indicated by returning false (not recording the error). 2436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ValidateQualifiedName(const string& name); 2437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Used by BUILD_ARRAY macro (below) to avoid having to have the type 2439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // specified as a macro parameter. 2440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville template <typename Type> 2441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville inline void AllocateArray(int size, Type** output) { 2442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *output = tables_->AllocateArray<Type>(size); 2443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Allocates a copy of orig_options in tables_ and stores it in the 2446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptor. Remembers its uninterpreted options, to be interpreted 2447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // later. DescriptorT must be one of the Descriptor messages from 2448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptor.proto. 2449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville template<class DescriptorT> void AllocateOptions( 2450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const typename DescriptorT::OptionsType& orig_options, 2451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorT* descriptor); 2452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Specialization for FileOptions. 2453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AllocateOptions(const FileOptions& orig_options, 2454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* descriptor); 2455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Implementation for AllocateOptions(). Don't call this directly. 2457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville template<class DescriptorT> void AllocateOptionsImpl( 2458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name_scope, 2459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& element_name, 2460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const typename DescriptorT::OptionsType& orig_options, 2461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorT* descriptor); 2462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These methods all have the same signature for the sake of the BUILD_ARRAY 2464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // macro, below. 2465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildMessage(const DescriptorProto& proto, 2466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 2467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Descriptor* result); 2468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildFieldOrExtension(const FieldDescriptorProto& proto, 2469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 2470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor* result, 2471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool is_extension); 2472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildField(const FieldDescriptorProto& proto, 2473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 2474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor* result) { 2475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BuildFieldOrExtension(proto, parent, result, false); 2476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildExtension(const FieldDescriptorProto& proto, 2478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 2479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor* result) { 2480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BuildFieldOrExtension(proto, parent, result, true); 2481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto, 2483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 2484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Descriptor::ExtensionRange* result); 2485a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void BuildOneof(const OneofDescriptorProto& proto, 2486a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Descriptor* parent, 2487a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson OneofDescriptor* result); 2488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildEnum(const EnumDescriptorProto& proto, 2489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 2490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumDescriptor* result); 2491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildEnumValue(const EnumValueDescriptorProto& proto, 2492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* parent, 2493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumValueDescriptor* result); 2494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildService(const ServiceDescriptorProto& proto, 2495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* dummy, 2496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ServiceDescriptor* result); 2497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void BuildMethod(const MethodDescriptorProto& proto, 2498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ServiceDescriptor* parent, 2499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MethodDescriptor* result); 2500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2501a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson void LogUnusedDependency(const FileDescriptor* result); 2502a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Must be run only after building. 2504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 2505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // NOTE: Options will not be available during cross-linking, as they 2506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // have not yet been interpreted. Defer any handling of options to the 2507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Validate*Options methods. 2508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto); 2509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto); 2510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkField(FieldDescriptor* field, 2511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptorProto& proto); 2512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkEnum(EnumDescriptor* enum_type, 2513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptorProto& proto); 2514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkEnumValue(EnumValueDescriptor* enum_value, 2515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptorProto& proto); 2516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkService(ServiceDescriptor* service, 2517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ServiceDescriptorProto& proto); 2518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void CrossLinkMethod(MethodDescriptor* method, 2519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const MethodDescriptorProto& proto); 2520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Must be run only after cross-linking. 2522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void InterpretOptions(); 2523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A helper class for interpreting options. 2525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville class OptionInterpreter { 2526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 2527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Creates an interpreter that operates in the context of the pool of the 2528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // specified builder, which must not be NULL. We don't take ownership of the 2529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // builder. 2530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville explicit OptionInterpreter(DescriptorBuilder* builder); 2531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~OptionInterpreter(); 2533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Interprets the uninterpreted options in the specified Options message. 2535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // On error, calls AddError() on the underlying builder and returns false. 2536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Otherwise returns true. 2537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool InterpretOptions(OptionsToInterpret* options_to_interpret); 2538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2539a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson class AggregateOptionFinder; 2540a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville private: 2542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Interprets uninterpreted_option_ on the specified message, which 2543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // must be the mutable copy of the original options message to which 2544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // uninterpreted_option_ belongs. 2545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool InterpretSingleOption(Message* options); 2546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Adds the uninterpreted_option to the given options message verbatim. 2548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Used when AllowUnknownDependencies() is in effect and we can't find 2549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the option's definition. 2550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, 2551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* options); 2552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A recursive helper function that drills into the intermediate fields 2554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // in unknown_fields to check if field innermost_field is set on the 2555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // innermost message. Returns false and sets an error if so. 2556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool ExamineIfOptionIsSet( 2557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, 2558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, 2559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* innermost_field, const string& debug_msg_name, 2560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields); 2561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Validates the value for the option field of the currently interpreted 2563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // option and then sets it on the unknown_field. 2564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool SetOptionValue(const FieldDescriptor* option_field, 2565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet* unknown_fields); 2566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2567a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Parses an aggregate value for a CPPTYPE_MESSAGE option and 2568a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // saves it into *unknown_fields. 2569a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson bool SetAggregateOption(const FieldDescriptor* option_field, 2570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson UnknownFieldSet* unknown_fields); 2571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Convenience functions to set an int field the right way, depending on 2573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // its wire type (a single int CppType can represent multiple wire types). 2574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void SetInt32(int number, int32 value, FieldDescriptor::Type type, 2575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet* unknown_fields); 2576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void SetInt64(int number, int64 value, FieldDescriptor::Type type, 2577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet* unknown_fields); 2578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, 2579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet* unknown_fields); 2580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, 2581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet* unknown_fields); 2582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A helper function that adds an error at the specified location of the 2584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // option we're currently interpreting, and returns false. 2585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, 2586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& msg) { 2587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville builder_->AddError(options_to_interpret_->element_name, 2588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *uninterpreted_option_, location, msg); 2589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 2590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A helper function that adds an error at the location of the option name 2593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // and returns false. 2594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddNameError(const string& msg) { 2595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg); 2596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // A helper function that adds an error at the location of the option name 2599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // and returns false. 2600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool AddValueError(const string& msg) { 2601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg); 2602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We interpret against this builder's pool. Is never NULL. We don't own 2605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // this pointer. 2606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorBuilder* builder_; 2607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The options we're currently interpreting, or NULL if we're not in a call 2609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to InterpretOptions. 2610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const OptionsToInterpret* options_to_interpret_; 2611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The option we're currently interpreting within options_to_interpret_, or 2613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // NULL if we're not in a call to InterpretOptions(). This points to a 2614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // submessage of the original option, not the mutable copy. Therefore we 2615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // can use it to find locations recorded by the parser. 2616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UninterpretedOption* uninterpreted_option_; 2617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2618a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Factory used to create the dynamic messages we need to parse 2619a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // any aggregate option values we encounter. 2620a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DynamicMessageFactory dynamic_factory_; 2621a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter); 2623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville }; 2624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Work-around for broken compilers: According to the C++ standard, 2626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // OptionInterpreter should have access to the private members of any class 2627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // which has declared DescriptorBuilder as a friend. Unfortunately some old 2628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // versions of GCC and other compilers do not implement this correctly. So, 2629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we have to have these intermediate methods to provide access. We also 2630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // redundantly declare OptionInterpreter a friend just to make things extra 2631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // clear for these bad compilers. 2632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville friend class OptionInterpreter; 2633a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson friend class OptionInterpreter::AggregateOptionFinder; 2634a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static inline bool get_allow_unknown(const DescriptorPool* pool) { 2636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return pool->allow_unknown_; 2637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2638a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson static inline bool get_enforce_weak(const DescriptorPool* pool) { 2639a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return pool->enforce_weak_; 2640a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static inline bool get_is_placeholder(const Descriptor* descriptor) { 2642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return descriptor->is_placeholder_; 2643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2644a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson static inline void assert_mutex_held(const DescriptorPool* pool) { 2645a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (pool->mutex_ != NULL) { 2646a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pool->mutex_->AssertHeld(); 2647a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2648a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Must be run only after options have been interpreted. 2651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // 2652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // NOTE: Validation code must only reference the options in the mutable 2653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptors, which are the ones that have been interpreted. The const 2654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // proto references are passed in only so they can be provided to calls to 2655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // AddError(). Do not look at their options, which have not been interpreted. 2656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateFileOptions(FileDescriptor* file, 2657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptorProto& proto); 2658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateMessageOptions(Descriptor* message, 2659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const DescriptorProto& proto); 2660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateFieldOptions(FieldDescriptor* field, 2661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptorProto& proto); 2662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateEnumOptions(EnumDescriptor* enm, 2663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptorProto& proto); 2664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateEnumValueOptions(EnumValueDescriptor* enum_value, 2665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptorProto& proto); 2666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateServiceOptions(ServiceDescriptor* service, 2667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ServiceDescriptorProto& proto); 2668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateMethodOptions(MethodDescriptor* method, 2669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const MethodDescriptorProto& proto); 2670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ValidateMapKey(FieldDescriptor* field, 2672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptorProto& proto); 2673a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 2675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorPool::BuildFile( 2677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptorProto& proto) { 2678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(fallback_database_ == NULL) 2679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Cannot call BuildFile on a DescriptorPool that uses a " 2680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "DescriptorDatabase. You must instead find a way to get your file " 2681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "into the underlying database."; 2682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. 2683a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.clear(); 2684a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.clear(); 2685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DescriptorBuilder(this, tables_.get(), NULL).BuildFile(proto); 2686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorPool::BuildFileCollectingErrors( 2689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptorProto& proto, 2690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ErrorCollector* error_collector) { 2691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(fallback_database_ == NULL) 2692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Cannot call BuildFile on a DescriptorPool that uses a " 2693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "DescriptorDatabase. You must instead find a way to get your file " 2694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "into the underlying database."; 2695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(mutex_ == NULL); // Implied by the above GOOGLE_CHECK. 2696a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_symbols_.clear(); 2697a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.clear(); 2698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return DescriptorBuilder(this, tables_.get(), 2699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector).BuildFile(proto); 2700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorPool::BuildFileFromDatabase( 2703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptorProto& proto) const { 2704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville mutex_->AssertHeld(); 2705a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (tables_->known_bad_files_.count(proto.name()) > 0) { 2706a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return NULL; 2707a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2708a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FileDescriptor* result = 2709a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorBuilder(this, tables_.get(), 2710a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson default_error_collector_).BuildFile(proto); 2711a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result == NULL) { 2712a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->known_bad_files_.insert(proto.name()); 2713a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2714a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return result; 2715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorBuilder::DescriptorBuilder( 2718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const DescriptorPool* pool, 2719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::Tables* tables, 2720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector* error_collector) 2721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville : pool_(pool), 2722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_(tables), 2723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector_(error_collector), 2724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville had_errors_(false), 2725a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson possible_undeclared_dependency_(NULL), 2726a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson undefine_resolved_name_("") {} 2727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorBuilder::~DescriptorBuilder() {} 2729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::AddError( 2731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& element_name, 2732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& descriptor, 2733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::ErrorLocation location, 2734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& error) { 2735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (error_collector_ == NULL) { 2736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!had_errors_) { 2737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ 2738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "\":"; 2739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(ERROR) << " " << element_name << ": " << error; 2741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville error_collector_->AddError(filename_, element_name, 2743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &descriptor, location, error); 2744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville had_errors_ = true; 2746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2748a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::AddError( 2749a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& element_name, 2750a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Message& descriptor, 2751a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::ErrorLocation location, 2752a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const char* error) { 2753a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(element_name, descriptor, location, string(error)); 2754a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2755a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::AddNotDefinedError( 2757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& element_name, 2758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& descriptor, 2759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::ErrorLocation location, 2760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& undefined_symbol) { 2761a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (possible_undeclared_dependency_ == NULL && 2762a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson undefine_resolved_name_.empty()) { 2763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(element_name, descriptor, location, 2764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + undefined_symbol + "\" is not defined."); 2765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2766a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (possible_undeclared_dependency_ != NULL) { 2767a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(element_name, descriptor, location, 2768a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\"" + possible_undeclared_dependency_name_ + 2769a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" seems to be defined in \"" + 2770a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson possible_undeclared_dependency_->name() + "\", which is not " 2771a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "imported by \"" + filename_ + "\". To use it here, please " 2772a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "add the necessary import."); 2773a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2774a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!undefine_resolved_name_.empty()) { 2775a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(element_name, descriptor, location, 2776a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\"" + undefined_symbol + "\" is resolved to \"" + 2777a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson undefine_resolved_name_ + "\", which is not defined. " 2778a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "The innermost scope is searched first in name resolution. " 2779a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Consider using a leading '.'(i.e., \"." 2780a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson + undefined_symbol + 2781a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\") to start from the outermost scope."); 2782a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2783a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2784a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2785a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2786a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::AddWarning( 2787a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& element_name, const Message& descriptor, 2788a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::ErrorLocation location, 2789a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& error) { 2790a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (error_collector_ == NULL) { 2791a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error; 2792a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 2793a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_collector_->AddWarning(filename_, element_name, &descriptor, location, 2794a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error); 2795fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::IsInPackage(const FileDescriptor* file, 2799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& package_name) { 2800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return HasPrefixString(file->package(), package_name) && 2801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (file->package().size() == package_name.size() || 2802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file->package()[package_name.size()] == '.'); 2803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2805a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { 2806a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (file == NULL || !dependencies_.insert(file).second) return; 2807a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) { 2808a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson RecordPublicDependencies(file->public_dependency(i)); 2809a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2810a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2812a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonSymbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( 2813a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const DescriptorPool* pool, const string& name) { 2814a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // If we are looking at an underlay, we must lock its mutex_, since we are 2815a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // accessing the underlay's tables_ directly. 2816a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); 2817a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2818a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol result = pool->tables_->FindSymbol(name); 2819a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result.IsNull() && pool->underlay_ != NULL) { 2820a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Symbol not found; check the underlay. 2821a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name); 2822a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2823fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2824a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result.IsNull()) { 2825a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // In theory, we shouldn't need to check fallback_database_ because the 2826a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // symbol should be in one of its file's direct dependencies, and we have 2827a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // already loaded those by the time we get here. But we check anyway so 2828a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // that we can generate better error message when dependencies are missing 2829a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // (i.e., "missing dependency" rather than "type is not defined"). 2830a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (pool->TryFindSymbolInFallbackDatabase(name)) { 2831a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = pool->tables_->FindSymbol(name); 2832a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 2836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2838a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff DavidsonSymbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) { 2839a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return FindSymbolNotEnforcingDepsHelper(pool_, name); 2840a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 2841a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSymbol DescriptorBuilder::FindSymbol(const string& name) { 2843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = FindSymbolNotEnforcingDeps(name); 2844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2845a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result.IsNull()) return result; 2846a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 2847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!pool_->enforce_dependencies_) { 2848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Hack for CompilerUpgrader. 2849fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 2850fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2851fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Only find symbols which were defined in this file or one of its 2853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // dependencies. 2854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* file = result.GetFile(); 2855a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (file == file_ || dependencies_.count(file) > 0) { 2856a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unused_dependency_.erase(file); 2857a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return result; 2858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.type == Symbol::PACKAGE) { 2861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Arg, this is overcomplicated. The symbol is a package name. It could 2862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // be that the package was defined in multiple files. result.GetFile() 2863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // returns the first file we saw that used this package. We've determined 2864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that that file is not a direct dependency of the file we are currently 2865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // building, but it could be that some other file which *is* a direct 2866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // dependency also defines the same package. We can't really rule out this 2867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // symbol unless none of the dependencies define it. 2868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (IsInPackage(file_, name)) return result; 2869a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (set<const FileDescriptor*>::const_iterator it = dependencies_.begin(); 2870a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson it != dependencies_.end(); ++it) { 2871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: A dependency may be NULL if it was not found or had errors. 2872a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (*it != NULL && IsInPackage(*it, name)) return result; 2873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville possible_undeclared_dependency_ = file; 2877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville possible_undeclared_dependency_name_ = name; 2878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return kNullSymbol; 2879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSymbol DescriptorBuilder::LookupSymbolNoPlaceholder( 2882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name, const string& relative_to, ResolveMode resolve_mode) { 2883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville possible_undeclared_dependency_ = NULL; 2884a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson undefine_resolved_name_.clear(); 2885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (name.size() > 0 && name[0] == '.') { 2887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fully-qualified name. 2888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindSymbol(name.substr(1)); 2889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If name is something like "Foo.Bar.baz", and symbols named "Foo" are 2892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // defined in multiple parent scopes, we only want to find "Bar.baz" in the 2893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // innermost one. E.g., the following should produce an error: 2894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // message Bar { message Baz {} } 2895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // message Foo { 2896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // message Bar { 2897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // } 2898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // optional Bar.Baz baz = 1; 2899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // } 2900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // So, we look for just "Foo" first, then look for "Bar.baz" within it if 2901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // found. 2902a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string::size_type name_dot_pos = name.find_first_of('.'); 2903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string first_part_of_name; 2904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (name_dot_pos == string::npos) { 2905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville first_part_of_name = name; 2906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville first_part_of_name = name.substr(0, name_dot_pos); 2908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string scope_to_try(relative_to); 2911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (true) { 2913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Chop off the last component of the scope. 2914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type dot_pos = scope_to_try.find_last_of('.'); 2915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dot_pos == string::npos) { 2916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return FindSymbol(name); 2917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scope_to_try.erase(dot_pos); 2919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Append ".first_part_of_name" and try to find. 2922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type old_size = scope_to_try.size(); 2923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scope_to_try.append(1, '.'); 2924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scope_to_try.append(first_part_of_name); 2925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = FindSymbol(scope_to_try); 2926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result.IsNull()) { 2927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (first_part_of_name.size() < name.size()) { 2928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // name is a compound symbol, of which we only found the first part. 2929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Now try to look up the rest of it. 2930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.IsAggregate()) { 2931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scope_to_try.append(name, first_part_of_name.size(), 2932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name.size() - first_part_of_name.size()); 2933a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result = FindSymbol(scope_to_try); 2934a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result.IsNull()) { 2935a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson undefine_resolved_name_ = scope_to_try; 2936a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 2937a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return result; 2938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We found a symbol but it's not an aggregate. Continue the loop. 2940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (resolve_mode == LOOKUP_TYPES && !result.IsType()) { 2943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We found a symbol but it's not a type. Continue the loop. 2944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 2946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Not found. Remove the name so we can try again. 2951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scope_to_try.erase(old_size); 2952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSymbol DescriptorBuilder::LookupSymbol( 2956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name, const string& relative_to, 2957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PlaceholderType placeholder_type, ResolveMode resolve_mode) { 2958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol result = LookupSymbolNoPlaceholder( 2959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville name, relative_to, resolve_mode); 2960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result.IsNull() && pool_->allow_unknown_) { 2961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Not found, but AllowUnknownDependencies() is enabled. Return a 2962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // placeholder instead. 2963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result = NewPlaceholder(name, placeholder_type); 2964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 2966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 2967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleSymbol DescriptorBuilder::NewPlaceholder(const string& name, 2969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PlaceholderType placeholder_type) { 2970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Compute names. 2971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string* placeholder_full_name; 2972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string* placeholder_name; 2973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string* placeholder_package; 2974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ValidateQualifiedName(name)) return kNullSymbol; 2976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (name[0] == '.') { 2977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fully-qualified. 2978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_full_name = tables_->AllocateString(name.substr(1)); 2979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_full_name = tables_->AllocateString(name); 2981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type dotpos = placeholder_full_name->find_last_of('.'); 2984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dotpos != string::npos) { 2985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_package = tables_->AllocateString( 2986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_full_name->substr(0, dotpos)); 2987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_name = tables_->AllocateString( 2988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_full_name->substr(dotpos + 1)); 2989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 2990a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson placeholder_package = &internal::GetEmptyString(); 2991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_name = placeholder_full_name; 2992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 2993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create the placeholders. 2995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* placeholder_file = tables_->Allocate<FileDescriptor>(); 2996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memset(placeholder_file, 0, sizeof(*placeholder_file)); 2997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 2998a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance(); 2999a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->name_ = 3001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->AllocateString(*placeholder_full_name + ".placeholder.proto"); 3002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->package_ = placeholder_package; 3003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->pool_ = pool_; 3004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->options_ = &FileOptions::default_instance(); 3005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->tables_ = &FileDescriptorTables::kEmpty; 3006a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson placeholder_file->is_placeholder_ = true; 3007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // All other fields are zero or NULL. 3008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (placeholder_type == PLACEHOLDER_ENUM) { 3010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->enum_type_count_ = 1; 3011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->enum_types_ = 3012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->AllocateArray<EnumDescriptor>(1); 3013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; 3015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memset(placeholder_enum, 0, sizeof(*placeholder_enum)); 3016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->full_name_ = placeholder_full_name; 3018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->name_ = placeholder_name; 3019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->file_ = placeholder_file; 3020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->options_ = &EnumOptions::default_instance(); 3021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->is_placeholder_ = true; 3022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.'); 3023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Enums must have at least one value. 3025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->value_count_ = 1; 3026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1); 3027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0]; 3029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memset(placeholder_value, 0, sizeof(*placeholder_value)); 3030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE"); 3032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that enum value names are siblings of their type, not children. 3033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_value->full_name_ = 3034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_package->empty() ? placeholder_value->name_ : 3035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE"); 3036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_value->number_ = 0; 3038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_value->type_ = placeholder_enum; 3039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_value->options_ = &EnumValueOptions::default_instance(); 3040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Symbol(placeholder_enum); 3042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->message_type_count_ = 1; 3044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_file->message_types_ = 3045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->AllocateArray<Descriptor>(1); 3046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Descriptor* placeholder_message = &placeholder_file->message_types_[0]; 3048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memset(placeholder_message, 0, sizeof(*placeholder_message)); 3049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->full_name_ = placeholder_full_name; 3051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->name_ = placeholder_name; 3052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->file_ = placeholder_file; 3053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->options_ = &MessageOptions::default_instance(); 3054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->is_placeholder_ = true; 3055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->is_unqualified_placeholder_ = (name[0] != '.'); 3056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) { 3058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->extension_range_count_ = 1; 3059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->extension_ranges_ = 3060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->AllocateArray<Descriptor::ExtensionRange>(1); 3061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->extension_ranges_->start = 1; 3062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // kMaxNumber + 1 because ExtensionRange::end is exclusive. 3063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder_message->extension_ranges_->end = 3064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::kMaxNumber + 1; 3065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return Symbol(placeholder_message); 3068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorBuilder::NewPlaceholderFile( 3072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name) { 3073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>(); 3074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memset(placeholder, 0, sizeof(*placeholder)); 3075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder->name_ = tables_->AllocateString(name); 3077a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson placeholder->package_ = &internal::GetEmptyString(); 3078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder->pool_ = pool_; 3079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder->options_ = &FileOptions::default_instance(); 3080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville placeholder->tables_ = &FileDescriptorTables::kEmpty; 3081a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson placeholder->is_placeholder_ = true; 3082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // All other fields are zero or NULL. 3083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return placeholder; 3085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::AddSymbol( 3088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& full_name, const void* parent, const string& name, 3089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message& proto, Symbol symbol) { 3090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If the caller passed NULL for the parent, the symbol is at file scope. 3091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Use its file as the parent instead. 3092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (parent == NULL) parent = file_; 3093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->AddSymbol(full_name, symbol)) { 3095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { 3096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(DFATAL) << "\"" << full_name << "\" not previously defined in " 3097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "symbols_by_name_, but was defined in symbols_by_parent_; " 3098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "this shouldn't be possible."; 3099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 3100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 3102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile(); 3104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (other_file == file_) { 3105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type dot_pos = full_name.find_last_of('.'); 3106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dot_pos == string::npos) { 3107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + full_name + "\" is already defined."); 3109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + full_name.substr(dot_pos + 1) + 3112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" is already defined in \"" + 3113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name.substr(0, dot_pos) + "\"."); 3114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Symbol seems to have been defined in a different file. 3117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + full_name + "\" is already defined in file \"" + 3119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville other_file->name() + "\"."); 3120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 3122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::AddPackage( 3126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name, const Message& proto, const FileDescriptor* file) { 3127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->AddSymbol(name, Symbol(file))) { 3128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Success. Also add parent package, if any. 3129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string::size_type dot_pos = name.find_last_of('.'); 3130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dot_pos == string::npos) { 3131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // No parents. 3132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(name, name, proto); 3133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Has parent. 3135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* parent_name = tables_->AllocateString(name.substr(0, dot_pos)); 3136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddPackage(*parent_name, proto, file); 3137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(name.substr(dot_pos + 1), name, proto); 3138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol existing_symbol = tables_->FindSymbol(name); 3141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // It's OK to redefine a package. 3142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (existing_symbol.type != Symbol::PACKAGE) { 3143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Symbol seems to have been defined in a different file. 3144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(name, proto, DescriptorPool::ErrorCollector::NAME, 3145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + name + "\" is already defined (as something other than " 3146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "a package) in file \"" + existing_symbol.GetFile()->name() + 3147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"."); 3148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateSymbolName( 3153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name, const string& full_name, const Message& proto) { 3154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (name.empty()) { 3155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Missing name."); 3157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < name.size(); i++) { 3159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // I don't trust isalnum() due to locales. :( 3160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if ((name[i] < 'a' || 'z' < name[i]) && 3161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (name[i] < 'A' || 'Z' < name[i]) && 3162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (name[i] < '0' || '9' < name[i]) && 3163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (name[i] != '_')) { 3164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, 3165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + name + "\" is not a valid identifier."); 3166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::ValidateQualifiedName(const string& name) { 3172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool last_was_period = false; 3173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < name.size(); i++) { 3175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // I don't trust isalnum() due to locales. :( 3176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (('a' <= name[i] && name[i] <= 'z') || 3177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ('A' <= name[i] && name[i] <= 'Z') || 3178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ('0' <= name[i] && name[i] <= '9') || 3179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (name[i] == '_')) { 3180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville last_was_period = false; 3181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (name[i] == '.') { 3182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (last_was_period) return false; 3183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville last_was_period = true; 3184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 3186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !name.empty() && !last_was_period; 3190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 3193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// This generic implementation is good for all descriptors except 3195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// FileDescriptor. 3196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<class DescriptorT> void DescriptorBuilder::AllocateOptions( 3197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const typename DescriptorT::OptionsType& orig_options, 3198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorT* descriptor) { 3199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(), 3200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville orig_options, descriptor); 3201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// We specialize for FileDescriptor. 3204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::AllocateOptions(const FileOptions& orig_options, 3205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* descriptor) { 3206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We add the dummy token so that LookupSymbol does the right thing. 3207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(), 3208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville orig_options, descriptor); 3209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilletemplate<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl( 3212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name_scope, 3213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& element_name, 3214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const typename DescriptorT::OptionsType& orig_options, 3215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorT* descriptor) { 3216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We need to use a dummy pointer to work around a bug in older versions of 3217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // GCC. Otherwise, the following two lines could be replaced with: 3218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // typename DescriptorT::OptionsType* options = 3219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // tables_->AllocateMessage<typename DescriptorT::OptionsType>(); 3220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville typename DescriptorT::OptionsType* const dummy = NULL; 3221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy); 3222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti 3223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the 3224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // reflection based method, which requires the Descriptor. However, we are in 3225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the middle of building the descriptors, thus the deadlock. 3226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson options->ParseFromString(orig_options.SerializeAsString()); 3227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor->options_ = options; 3228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Don't add to options_to_interpret_ unless there were uninterpreted 3230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // options. This not only avoids unnecessary work, but prevents a 3231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // bootstrapping problem when building descriptors for descriptor.proto. 3232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptor.proto does not contain any uninterpreted options, but 3233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // attempting to interpret options anyway will cause 3234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // OptionsType::GetDescriptor() to be called which may then deadlock since 3235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we're still trying to build it. 3236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (options->uninterpreted_option_size() > 0) { 3237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_to_interpret_.push_back( 3238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OptionsToInterpret(name_scope, element_name, &orig_options, options)); 3239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A common pattern: We want to convert a repeated field in the descriptor 3244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// to an array of values, calling some method to build each value. 3245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ 3246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ 3247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \ 3248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < INPUT.NAME##_size(); i++) { \ 3249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \ 3250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3252a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::AddRecursiveImportError( 3253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FileDescriptorProto& proto, int from_here) { 3254a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string error_message("File recursively imports itself: "); 3255a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = from_here; i < tables_->pending_files_.size(); i++) { 3256a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_message.append(tables_->pending_files_[i]); 3257a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_message.append(" -> "); 3258a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_message.append(proto.name()); 3260a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3261a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_message); 3263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 3264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto, 3266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int index) { 3267a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3268a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Import \"" + proto.dependency(index) + "\" was listed twice."); 3269a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 3270a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3271a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::AddImportError(const FileDescriptorProto& proto, 3272a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int index) { 3273a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string message; 3274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (pool_->fallback_database_ == NULL) { 3275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson message = "Import \"" + proto.dependency(index) + 3276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" has not been loaded."; 3277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson message = "Import \"" + proto.dependency(index) + 3279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" was not found or had errors."; 3280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, message); 3282a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 3283a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonstatic bool ExistingFileMatchesProto(const FileDescriptor* existing_file, 3285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FileDescriptorProto& proto) { 3286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson FileDescriptorProto existing_proto; 3287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson existing_file->CopyTo(&existing_proto); 3288a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return existing_proto.SerializeAsString() == proto.SerializeAsString(); 3289a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 3290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst FileDescriptor* DescriptorBuilder::BuildFile( 3292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptorProto& proto) { 3293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville filename_ = proto.name(); 3294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check if the file already exists and is identical to the one being built. 3296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: This only works if the input is canonical -- that is, it 3297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // fully-qualifies all type names, has no UninterpretedOptions, etc. 3298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This is fine, because this idempotency "feature" really only exists to 3299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // accomodate one hack in the proto1->proto2 migration layer. 3300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* existing_file = tables_->FindFile(filename_); 3301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (existing_file != NULL) { 3302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // File already in pool. Compare the existing one to the input. 3303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (ExistingFileMatchesProto(existing_file, proto)) { 3304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // They're identical. Return the existing descriptor. 3305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return existing_file; 3306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Not a match. The error will be detected and handled later. 3309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check to see if this file is already on the pending files list. 3312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // TODO(kenton): Allow recursive imports? It may not work with some 3313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // (most?) programming languages. E.g., in C++, a forward declaration 3314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // of a type is not sufficient to allow it to be used even in a 3315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // generated header file due to inlining. This could perhaps be 3316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // worked around using tricks involving inserting #include statements 3317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // mid-file, but that's pretty ugly, and I'm pretty sure there are 3318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // some languages out there that do not allow recursive dependencies 3319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // at all. 3320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < tables_->pending_files_.size(); i++) { 3321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->pending_files_[i] == proto.name()) { 3322a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddRecursiveImportError(proto, i); 3323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 3324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we have a fallback_database_, attempt to load all dependencies now, 3328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // before checkpointing tables_. This avoids confusion with recursive 3329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // checkpoints. 3330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (pool_->fallback_database_ != NULL) { 3331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->pending_files_.push_back(proto.name()); 3332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < proto.dependency_size(); i++) { 3333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (tables_->FindFile(proto.dependency(i)) == NULL && 3334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (pool_->underlay_ == NULL || 3335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { 3336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We don't care what this returns since we'll find out below anyway. 3337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); 3338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->pending_files_.pop_back(); 3341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Checkpoint the tables so that we can roll back if something goes wrong. 3344a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->AddCheckpoint(); 3345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* result = tables_->Allocate<FileDescriptor>(); 3347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_ = result; 3348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->is_placeholder_ = false; 3350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (proto.has_source_code_info()) { 3351a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>(); 3352a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson info->CopyFrom(proto.source_code_info()); 3353a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->source_code_info_ = info; 3354a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3355a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->source_code_info_ = &SourceCodeInfo::default_instance(); 3356a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3357a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_tables_ = tables_->AllocateFileTables(); 3359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_->tables_ = file_tables_; 3360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_name()) { 3362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError("", proto, DescriptorPool::ErrorCollector::OTHER, 3363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Missing field: FileDescriptorProto.name."); 3364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 3367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_package()) { 3368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->package_ = tables_->AllocateString(proto.package()); 3369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We cannot rely on proto.package() returning a valid string if 3371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // proto.has_package() is false, because we might be running at static 3372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // initialization time, in which case default values have not yet been 3373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // initialized. 3374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->package_ = tables_->AllocateString(""); 3375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->pool_ = pool_; 3377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Add to tables. 3379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!tables_->AddFile(result)) { 3380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, 3381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "A file with this name is already in the pool."); 3382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Bail out early so that if this is actually the exact same file, we 3383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // don't end up reporting that every single symbol is already defined. 3384a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->RollbackToLastCheckpoint(); 3385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 3386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!result->package().empty()) { 3388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddPackage(result->package(), proto, result); 3389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make sure all dependencies are loaded. 3392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville set<string> seen_dependencies; 3393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->dependency_count_ = proto.dependency_size(); 3394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->dependencies_ = 3395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size()); 3396a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unused_dependency_.clear(); 3397a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson set<int> weak_deps; 3398a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < proto.weak_dependency_size(); ++i) { 3399a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson weak_deps.insert(proto.weak_dependency(i)); 3400a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < proto.dependency_size(); i++) { 3402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!seen_dependencies.insert(proto.dependency(i)).second) { 3403a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddTwiceListedError(proto, i); 3404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i)); 3407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dependency == NULL && pool_->underlay_ != NULL) { 3408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dependency = pool_->underlay_->FindFileByName(proto.dependency(i)); 3409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (dependency == NULL) { 3412a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (pool_->allow_unknown_ || 3413a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) { 3414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville dependency = NewPlaceholderFile(proto.dependency(i)); 3415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3416a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddImportError(proto, i); 3417a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3418a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3419a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Add to unused_dependency_ to track unused imported files. 3420a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Note: do not track unused imported files for public import. 3421a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (pool_->enforce_dependencies_ && 3422a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (pool_->unused_import_track_files_.find(proto.name()) != 3423a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson pool_->unused_import_track_files_.end()) && 3424a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (dependency->public_dependency_count() == 0)) { 3425a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unused_dependency_.insert(dependency); 3426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->dependencies_[i] = dependency; 3430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3432a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Check public dependencies. 3433a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int public_dependency_count = 0; 3434a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->public_dependencies_ = tables_->AllocateArray<int>( 3435a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto.public_dependency_size()); 3436a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < proto.public_dependency_size(); i++) { 3437a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Only put valid public dependency indexes. 3438a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int index = proto.public_dependency(i); 3439a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (index >= 0 && index < proto.dependency_size()) { 3440a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->public_dependencies_[public_dependency_count++] = index; 3441a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Do not track unused imported files for public import. 3442a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unused_dependency_.erase(result->dependency(index)); 3443a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3444a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(proto.name(), proto, 3445a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::OTHER, 3446a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Invalid public dependency index."); 3447a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3448a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3449a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->public_dependency_count_ = public_dependency_count; 3450a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3451a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Build dependency set 3452a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson dependencies_.clear(); 3453a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < result->dependency_count(); i++) { 3454a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson RecordPublicDependencies(result->dependency(i)); 3455a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3456a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3457a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Check weak dependencies. 3458a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int weak_dependency_count = 0; 3459a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->weak_dependencies_ = tables_->AllocateArray<int>( 3460a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto.weak_dependency_size()); 3461a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < proto.weak_dependency_size(); i++) { 3462a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int index = proto.weak_dependency(i); 3463a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (index >= 0 && index < proto.dependency_size()) { 3464a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->weak_dependencies_[weak_dependency_count++] = index; 3465a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3466a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(proto.name(), proto, 3467a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::OTHER, 3468a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Invalid weak dependency index."); 3469a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3470a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3471a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->weak_dependency_count_ = weak_dependency_count; 3472a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Convert children. 3474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, message_type, BuildMessage , NULL); 3475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, enum_type , BuildEnum , NULL); 3476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, service , BuildService , NULL); 3477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, extension , BuildExtension, NULL); 3478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 3480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 3481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 3482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 3484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that the following steps must occur in exactly the specified order. 3487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Cross-link. 3489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkFile(result, proto); 3490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Interpret any remaining uninterpreted options gathered into 3492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // options_to_interpret_ during descriptor building. Cross-linking has made 3493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // extension options known, so all interpretations should now succeed. 3494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!had_errors_) { 3495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OptionInterpreter option_interpreter(this); 3496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (vector<OptionsToInterpret>::iterator iter = 3497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_to_interpret_.begin(); 3498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville iter != options_to_interpret_.end(); ++iter) { 3499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_interpreter.InterpretOptions(&(*iter)); 3500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_to_interpret_.clear(); 3502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Validate options. 3505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!had_errors_) { 3506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateFileOptions(result, proto); 3507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3509a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3510a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!unused_dependency_.empty()) { 3511a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson LogUnusedDependency(result); 3512a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3513a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (had_errors_) { 3515a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->RollbackToLastCheckpoint(); 3516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return NULL; 3517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3518a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->ClearLastCheckpoint(); 3519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 3520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildMessage(const DescriptorProto& proto, 3524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 3525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Descriptor* result) { 3526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& scope = (parent == NULL) ? 3527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_->package() : parent->full_name(); 3528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* full_name = tables_->AllocateString(scope); 3529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!full_name->empty()) full_name->append(1, '.'); 3530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(proto.name()); 3531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(proto.name(), *full_name, proto); 3533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 3535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->full_name_ = full_name; 3536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->file_ = file_; 3537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->containing_type_ = parent; 3538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->is_placeholder_ = false; 3539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->is_unqualified_placeholder_ = false; 3540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3541a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Build oneofs first so that fields and extension ranges can refer to them. 3542a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson BUILD_ARRAY(proto, result, oneof_decl , BuildOneof , result); 3543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, field , BuildField , result); 3544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, nested_type , BuildMessage , result); 3545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, enum_type , BuildEnum , result); 3546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result); 3547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, extension , BuildExtension , result); 3548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 3550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 3551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 3552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 3554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSymbol(result->full_name(), parent, result->name(), 3557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto, Symbol(result)); 3558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check that no fields have numbers in extension ranges. 3560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < result->field_count(); i++) { 3561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = result->field(i); 3562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < result->extension_range_count(); j++) { 3563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor::ExtensionRange* range = result->extension_range(j); 3564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (range->start <= field->number() && field->number() < range->end) { 3565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto.extension_range(j), 3566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 3567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute( 3568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Extension range $0 to $1 includes field \"$2\" ($3).", 3569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville range->start, range->end - 1, 3570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->name(), field->number())); 3571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Check that extension ranges don't overlap. 3576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < result->extension_range_count(); i++) { 3577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor::ExtensionRange* range1 = result->extension_range(i); 3578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = i + 1; j < result->extension_range_count(); j++) { 3579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor::ExtensionRange* range2 = result->extension_range(j); 3580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (range1->end > range2->start && range2->end > range1->start) { 3581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto.extension_range(j), 3582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 3583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute("Extension range $0 to $1 overlaps with " 3584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "already-defined range $2 to $3.", 3585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville range2->start, range2->end - 1, 3586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville range1->start, range1->end - 1)); 3587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, 3593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 3594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor* result, 3595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool is_extension) { 3596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& scope = (parent == NULL) ? 3597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_->package() : parent->full_name(); 3598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* full_name = tables_->AllocateString(scope); 3599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!full_name->empty()) full_name->append(1, '.'); 3600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(proto.name()); 3601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(proto.name(), *full_name, proto); 3603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 3605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->full_name_ = full_name; 3606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->file_ = file_; 3607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->number_ = proto.number(); 3608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->is_extension_ = is_extension; 3609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If .proto files follow the style guide then the name should already be 3611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // lower-cased. If that's the case we can just reuse the string we already 3612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // allocated rather than allocate a new one. 3613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string lowercase_name(proto.name()); 3614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LowerString(&lowercase_name); 3615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (lowercase_name == proto.name()) { 3616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->lowercase_name_ = result->name_; 3617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->lowercase_name_ = tables_->AllocateString(lowercase_name); 3619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Don't bother with the above optimization for camel-case names since 3622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // .proto files that follow the guide shouldn't be using names in this 3623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // format, so the optimization wouldn't help much. 3624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name())); 3625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Some compilers do not allow static_cast directly between two enum types, 3627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // so we must cast to int first. 3628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->type_ = static_cast<FieldDescriptor::Type>( 3629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville implicit_cast<int>(proto.type())); 3630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->label_ = static_cast<FieldDescriptor::Label>( 3631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville implicit_cast<int>(proto.label())); 3632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3633a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // An extension cannot have a required field (b/13365836). 3634a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result->is_extension_ && 3635a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->label_ == FieldDescriptor::LABEL_REQUIRED) { 3636a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(result->full_name(), proto, 3637a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Error location `TYPE`: we would really like to indicate 3638a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // `LABEL`, but the `ErrorLocation` enum has no entry for this, and 3639a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // we don't necessarily know about all implementations of the 3640a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // `ErrorCollector` interface to extend them to handle the new 3641a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // error location type properly. 3642a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::TYPE, 3643a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Message extensions cannot have required fields."); 3644a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3645a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Some of these may be filled in when cross-linking. 3647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->containing_type_ = NULL; 3648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->extension_scope_ = NULL; 3649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->experimental_map_key_ = NULL; 3650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->message_type_ = NULL; 3651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->enum_type_ = NULL; 3652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->has_default_value_ = proto.has_default_value(); 3654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_default_value() && result->is_repeated()) { 3655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::DEFAULT_VALUE, 3657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Repeated fields can't have default values."); 3658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_type()) { 3661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_default_value()) { 3662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville char* end_pos = NULL; 3663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (result->cpp_type()) { 3664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT32: 3665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_int32_ = 3666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strtol(proto.default_value().c_str(), &end_pos, 0); 3667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT64: 3669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_int64_ = 3670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strto64(proto.default_value().c_str(), &end_pos, 0); 3671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT32: 3673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_uint32_ = 3674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strtoul(proto.default_value().c_str(), &end_pos, 0); 3675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT64: 3677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_uint64_ = 3678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strtou64(proto.default_value().c_str(), &end_pos, 0); 3679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_FLOAT: 3681d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (proto.default_value() == "inf") { 3682d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_float_ = numeric_limits<float>::infinity(); 3683d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else if (proto.default_value() == "-inf") { 3684d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_float_ = -numeric_limits<float>::infinity(); 3685d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else if (proto.default_value() == "nan") { 3686d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_float_ = numeric_limits<float>::quiet_NaN(); 3687d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 3688d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_float_ = 3689a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos); 3690d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 3691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_DOUBLE: 3693d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (proto.default_value() == "inf") { 3694d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_double_ = numeric_limits<double>::infinity(); 3695d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else if (proto.default_value() == "-inf") { 3696d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_double_ = -numeric_limits<double>::infinity(); 3697d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else if (proto.default_value() == "nan") { 3698d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_double_ = numeric_limits<double>::quiet_NaN(); 3699d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } else { 3700d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville result->default_value_double_ = 3701a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos); 3702d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville } 3703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_BOOL: 3705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.default_value() == "true") { 3706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_bool_ = true; 3707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (proto.default_value() == "false") { 3708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_bool_ = false; 3709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::DEFAULT_VALUE, 3712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Boolean default must be true or false."); 3713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_ENUM: 3716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This will be filled in when cross-linking. 3717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_enum_ = NULL; 3718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_STRING: 3720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result->type() == FieldDescriptor::TYPE_BYTES) { 3721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_string_ = tables_->AllocateString( 3722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnescapeCEscapeString(proto.default_value())); 3723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_string_ = 3725a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->AllocateString(proto.default_value()); 3726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 3729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::DEFAULT_VALUE, 3731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Messages can't have default values."); 3732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->has_default_value_ = false; 3733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (end_pos != NULL) { 3737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // end_pos is only set non-NULL by the parsers for numeric types, above. 3738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This checks that the default was non-empty and had no extra junk 3739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // after the end of the number. 3740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.default_value().empty() || *end_pos != '\0') { 3741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::DEFAULT_VALUE, 3743a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Couldn't parse default value \"" + proto.default_value() + 3744a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\"."); 3745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // No explicit default value 3749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (result->cpp_type()) { 3750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT32: 3751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_int32_ = 0; 3752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT64: 3754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_int64_ = 0; 3755fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT32: 3757fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_uint32_ = 0; 3758fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3759fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT64: 3760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_uint64_ = 0; 3761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_FLOAT: 3763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_float_ = 0.0f; 3764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_DOUBLE: 3766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_double_ = 0.0; 3767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_BOOL: 3769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_bool_ = false; 3770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_ENUM: 3772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This will be filled in when cross-linking. 3773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->default_value_enum_ = NULL; 3774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_STRING: 3776a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->default_value_string_ = &internal::GetEmptyString(); 3777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 3779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 3780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result->number() <= 0) { 3785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 3786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Field numbers must be positive integers."); 3787a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) { 3788a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Only validate that the number is within the valid field range if it is 3789a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // not an extension. Since extension numbers are validated with the 3790a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // extendee's valid set of extension numbers, and those are in turn 3791a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // validated against the max allowed number, the check is unnecessary for 3792a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // extension fields. 3793a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // This avoids cross-linking issues that arise when attempting to check if 3794a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the extendee is a message_set_wire_format message, which has a higher max 3795a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // on extension numbers. 3796fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 3797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute("Field numbers cannot be greater than $0.", 3798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::kMaxNumber)); 3799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (result->number() >= FieldDescriptor::kFirstReservedNumber && 3800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->number() <= FieldDescriptor::kLastReservedNumber) { 3801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER, 3802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute( 3803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Field numbers $0 through $1 are reserved for the protocol " 3804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "buffer library implementation.", 3805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::kFirstReservedNumber, 3806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::kLastReservedNumber)); 3807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (is_extension) { 3810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_extendee()) { 3811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::EXTENDEE, 3813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "FieldDescriptorProto.extendee not set for extension field."); 3814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3816fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->extension_scope_ = parent; 3817a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3818a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (proto.has_oneof_index()) { 3819a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(result->full_name(), proto, 3820a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::OTHER, 3821a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "FieldDescriptorProto.oneof_index should not be set for " 3822a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "extensions."); 3823a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3824a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3825a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Fill in later (maybe). 3826a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->containing_oneof_ = NULL; 3827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_extendee()) { 3829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::EXTENDEE, 3831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "FieldDescriptorProto.extendee set for non-extension field."); 3832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->containing_type_ = parent; 3835a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3836a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (proto.has_oneof_index()) { 3837a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (proto.oneof_index() < 0 || 3838a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto.oneof_index() >= parent->oneof_decl_count()) { 3839a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(result->full_name(), proto, 3840a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::OTHER, 3841a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::Substitute("FieldDescriptorProto.oneof_index $0 is " 3842a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "out of range for type \"$1\".", 3843a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto.oneof_index(), 3844a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson parent->name())); 3845a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->containing_oneof_ = NULL; 3846a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3847a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->containing_oneof_ = parent->oneof_decl(proto.oneof_index()); 3848a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3849a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 3850a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->containing_oneof_ = NULL; 3851a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 3852fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3853fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 3855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 3856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 3857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 3859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSymbol(result->full_name(), parent, result->name(), 3862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto, Symbol(result)); 3863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildExtensionRange( 3866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const DescriptorProto::ExtensionRange& proto, 3867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 3868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Descriptor::ExtensionRange* result) { 3869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->start = proto.start(); 3870fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->end = proto.end(); 3871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result->start <= 0) { 3872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(parent->full_name(), proto, 3873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 3874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Extension numbers must be positive integers."); 3875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3877a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Checking of the upper bound of the extension range is deferred until after 3878a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // options interpreting. This allows messages with message_set_wire_format to 3879a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // have extensions beyond FieldDescriptor::kMaxNumber, since the extension 3880a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // numbers are actually used as int32s in the message_set_wire_format. 3881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (result->start >= result->end) { 3883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(parent->full_name(), proto, 3884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 3885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Extension range end number must be greater than start number."); 3886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3889a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto, 3890a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Descriptor* parent, 3891a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson OneofDescriptor* result) { 3892a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string* full_name = tables_->AllocateString(parent->full_name()); 3893a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson full_name->append(1, '.'); 3894a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson full_name->append(proto.name()); 3895a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3896a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ValidateSymbolName(proto.name(), *full_name, proto); 3897a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3898a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->name_ = tables_->AllocateString(proto.name()); 3899a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->full_name_ = full_name; 3900a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3901a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->containing_type_ = parent; 3902a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3903a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // We need to fill these in later. 3904a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->field_count_ = 0; 3905a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result->fields_ = NULL; 3906a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3907a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddSymbol(result->full_name(), parent, result->name(), 3908a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto, Symbol(result)); 3909a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 3910a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 3911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, 3912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* parent, 3913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumDescriptor* result) { 3914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& scope = (parent == NULL) ? 3915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_->package() : parent->full_name(); 3916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* full_name = tables_->AllocateString(scope); 3917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!full_name->empty()) full_name->append(1, '.'); 3918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(proto.name()); 3919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(proto.name(), *full_name, proto); 3921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 3923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->full_name_ = full_name; 3924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->file_ = file_; 3925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->containing_type_ = parent; 3926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->is_placeholder_ = false; 3927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->is_unqualified_placeholder_ = false; 3928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.value_size() == 0) { 3930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We cannot allow enums with no values because this would mean there 3931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // would be no valid default value for fields of this type. 3932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 3933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NAME, 3934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Enums must contain at least one value."); 3935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, value, BuildEnumValue, result); 3938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 3940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 3941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 3942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 3944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSymbol(result->full_name(), parent, result->name(), 3947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto, Symbol(result)); 3948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 3949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto, 3951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* parent, 3952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumValueDescriptor* result) { 3953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 3954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->number_ = proto.number(); 3955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->type_ = parent; 3956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: full_name for enum values is a sibling to the parent's name, not a 3958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // child of it. 3959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* full_name = tables_->AllocateString(*parent->full_name_); 3960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->resize(full_name->size() - parent->name_->size()); 3961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(*result->name_); 3962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->full_name_ = full_name; 3963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(proto.name(), *full_name, proto); 3965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 3967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 3968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 3969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 3971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Again, enum values are weird because we makes them appear as siblings 3974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // of the enum type instead of children of it. So, we use 3975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // parent->containing_type() as the value's parent. 3976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool added_to_outer_scope = 3977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSymbol(result->full_name(), parent->containing_type(), result->name(), 3978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto, Symbol(result)); 3979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // However, we also want to be able to search for values within a single 3981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // enum type, so we add it as a child of the enum type itself, too. 3982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: This could fail, but if it does, the error has already been 3983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // reported by the above AddSymbol() call, so we ignore the return code. 3984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool added_to_inner_scope = 3985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result)); 3986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (added_to_inner_scope && !added_to_outer_scope) { 3988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This value did not conflict with any values defined in the same enum, 3989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // but it did conflict with some other symbol defined in the enum type's 3990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // scope. Let's print an additional error to explain this. 3991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string outer_scope; 3992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (parent->containing_type() == NULL) { 3993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville outer_scope = file_->package(); 3994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 3995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville outer_scope = parent->containing_type()->full_name(); 3996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 3997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 3998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (outer_scope.empty()) { 3999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville outer_scope = "the global scope"; 4000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville outer_scope = "\"" + outer_scope + "\""; 4002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(result->full_name(), proto, 4005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NAME, 4006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Note that enum values use C++ scoping rules, meaning that " 4007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "enum values are siblings of their type, not children of it. " 4008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Therefore, \"" + result->name() + "\" must be unique within " 4009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville + outer_scope + ", not just within \"" + parent->name() + "\"."); 4010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // An enum is allowed to define two numbers that refer to the same value. 4013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // FindValueByNumber() should return the first such value, so we simply 4014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ignore AddEnumValueByNumber()'s return code. 4015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_tables_->AddEnumValueByNumber(result); 4016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto, 4019a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const void* /* dummy */, 4020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ServiceDescriptor* result) { 4021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* full_name = tables_->AllocateString(file_->package()); 4022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!full_name->empty()) full_name->append(1, '.'); 4023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(proto.name()); 4024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(proto.name(), *full_name, proto); 4026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 4028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->full_name_ = full_name; 4029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->file_ = file_; 4030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville BUILD_ARRAY(proto, result, method, BuildMethod, result); 4032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 4034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 4035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 4036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 4038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSymbol(result->full_name(), NULL, result->name(), 4041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto, Symbol(result)); 4042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, 4045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ServiceDescriptor* parent, 4046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MethodDescriptor* result) { 4047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->name_ = tables_->AllocateString(proto.name()); 4048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->service_ = parent; 4049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string* full_name = tables_->AllocateString(parent->full_name()); 4051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(1, '.'); 4052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville full_name->append(*result->name_); 4053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->full_name_ = full_name; 4054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateSymbolName(proto.name(), *full_name, proto); 4056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // These will be filled in when cross-linking. 4058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->input_type_ = NULL; 4059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->output_type_ = NULL; 4060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Copy options. 4062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_options()) { 4063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result->options_ = NULL; // Will set to default_instance later. 4064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AllocateOptions(proto.options(), result); 4066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddSymbol(result->full_name(), parent, result->name(), 4069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto, Symbol(result)); 4070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef BUILD_ARRAY 4073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 4075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkFile( 4077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileDescriptor* file, const FileDescriptorProto& proto) { 4078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (file->options_ == NULL) { 4079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file->options_ = &FileOptions::default_instance(); 4080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < file->message_type_count(); i++) { 4083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkMessage(&file->message_types_[i], proto.message_type(i)); 4084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < file->extension_count(); i++) { 4087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkField(&file->extensions_[i], proto.extension(i)); 4088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < file->enum_type_count(); i++) { 4091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i)); 4092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < file->service_count(); i++) { 4095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkService(&file->services_[i], proto.service(i)); 4096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkMessage( 4100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Descriptor* message, const DescriptorProto& proto) { 4101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (message->options_ == NULL) { 4102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville message->options_ = &MessageOptions::default_instance(); 4103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < message->nested_type_count(); i++) { 4106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i)); 4107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < message->enum_type_count(); i++) { 4110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i)); 4111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < message->field_count(); i++) { 4114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkField(&message->fields_[i], proto.field(i)); 4115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < message->extension_count(); i++) { 4118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkField(&message->extensions_[i], proto.extension(i)); 4119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4120a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4121a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Set up field array for each oneof. 4122a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4123a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // First count the number of fields per oneof. 4124a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < message->field_count(); i++) { 4125a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); 4126a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (oneof_decl != NULL) { 4127a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Must go through oneof_decls_ array to get a non-const version of the 4128a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // OneofDescriptor. 4129a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ++message->oneof_decls_[oneof_decl->index()].field_count_; 4130a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4131a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4132a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4133a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Then allocate the arrays. 4134a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < message->oneof_decl_count(); i++) { 4135a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson OneofDescriptor* oneof_decl = &message->oneof_decls_[i]; 4136a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4137a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (oneof_decl->field_count() == 0) { 4138a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(message->full_name() + "." + oneof_decl->name(), 4139a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson proto.oneof_decl(i), 4140a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::NAME, 4141a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Oneof must have at least one field."); 4142a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4143a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4144a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson oneof_decl->fields_ = 4145a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_); 4146a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson oneof_decl->field_count_ = 0; 4147a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4148a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4149a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Then fill them in. 4150a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < message->field_count(); i++) { 4151a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); 4152a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (oneof_decl != NULL) { 4153a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson OneofDescriptor* mutable_oneof_decl = 4154a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson &message->oneof_decls_[oneof_decl->index()]; 4155a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_; 4156a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] = 4157a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson message->field(i); 4158a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4159a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkField( 4163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor* field, const FieldDescriptorProto& proto) { 4164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->options_ == NULL) { 4165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->options_ = &FieldOptions::default_instance(); 4166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_extendee()) { 4169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(), 4170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville PLACEHOLDER_EXTENDABLE_MESSAGE); 4171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (extendee.IsNull()) { 4172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddNotDefinedError(field->full_name(), proto, 4173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::EXTENDEE, 4174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto.extendee()); 4175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (extendee.type != Symbol::MESSAGE) { 4177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::EXTENDEE, 4179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + proto.extendee() + "\" is not a message type."); 4180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->containing_type_ = extendee.descriptor; 4183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4184a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Descriptor::ExtensionRange* extension_range = field->containing_type() 4185a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ->FindExtensionRangeContainingNumber(field->number()); 4186a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4187a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (extension_range == NULL) { 4188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 4190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute("\"$0\" does not declare $1 as an " 4191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "extension number.", 4192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->containing_type()->full_name(), 4193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->number())); 4194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4197a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (field->containing_oneof() != NULL) { 4198a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (field->label() != FieldDescriptor::LABEL_OPTIONAL) { 4199a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Note that this error will never happen when parsing .proto files. 4200a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // It can only happen if you manually construct a FileDescriptorProto 4201a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // that is incorrect. 4202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(field->full_name(), proto, 4203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::NAME, 4204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Fields of oneofs must themselves have label LABEL_OPTIONAL."); 4205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (proto.has_type_name()) { 4209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Assume we are expecting a message type unless the proto contains some 4210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // evidence that it expects an enum type. This only makes a difference if 4211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we end up creating a placeholder. 4212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) || 4213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto.has_default_value(); 4214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol type = 4216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LookupSymbol(proto.type_name(), field->full_name(), 4217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE, 4218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LOOKUP_TYPES); 4219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // If the type is a weak type, we change the type to a google.protobuf.Empty field. 4221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) { 4222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson type = FindSymbol(kNonLinkedWeakMessageReplacementName); 4223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (type.IsNull()) { 4226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddNotDefinedError(field->full_name(), proto, 4227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::TYPE, 4228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto.type_name()); 4229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!proto.has_type()) { 4233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Choose field type based on symbol. 4234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (type.type == Symbol::MESSAGE) { 4235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->type_ = FieldDescriptor::TYPE_MESSAGE; 4236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (type.type == Symbol::ENUM) { 4237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->type_ = FieldDescriptor::TYPE_ENUM; 4238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::TYPE, 4241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + proto.type_name() + "\" is not a type."); 4242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 4247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (type.type != Symbol::MESSAGE) { 4248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::TYPE, 4250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + proto.type_name() + "\" is not a message type."); 4251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->message_type_ = type.descriptor; 4254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->has_default_value()) { 4256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Messages can't have default values."); 4259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { 4261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (type.type != Symbol::ENUM) { 4262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::TYPE, 4264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + proto.type_name() + "\" is not an enum type."); 4265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->enum_type_ = type.enum_descriptor; 4268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->enum_type()->is_placeholder_) { 4270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We can't look up default values for placeholder types. We'll have 4271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to just drop them. 4272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->has_default_value_ = false; 4273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->has_default_value()) { 4276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Ensure that the default value is an identifier. Parser cannot always 4277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // verify this because it does not have complete type information. 4278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // N.B. that this check yields better error messages but is not 4279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // necessary for correctness (an enum symbol must be a valid identifier 4280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // anyway), only for better errors. 4281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!io::Tokenizer::IsIdentifier(proto.default_value())) { 4282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Default value for an enum field must be an identifier."); 4285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 4286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // We can't just use field->enum_type()->FindValueByName() here 4287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // because that locks the pool's mutex, which we have already locked 4288a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // at this point. 4289a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol default_value = 4290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson LookupSymbolNoPlaceholder(proto.default_value(), 4291a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field->enum_type()->full_name()); 4292a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4293a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (default_value.type == Symbol::ENUM_VALUE && 4294a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson default_value.enum_value_descriptor->type() == 4295a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field->enum_type()) { 4296a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field->default_value_enum_ = default_value.enum_value_descriptor; 4297a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 4298a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(field->full_name(), proto, 4299a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::DEFAULT_VALUE, 4300a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Enum type \"" + field->enum_type()->full_name() + 4301a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" has no value named \"" + proto.default_value() + 4302a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\"."); 4303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (field->enum_type()->value_count() > 0) { 4306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // All enums must have at least one value, or we would have reported 4307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // an error elsewhere. We use the first defined value as the default 4308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // if a default is not explicitly defined. 4309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->default_value_enum_ = field->enum_type()->value(0); 4310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Field with primitive type has type_name."); 4314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE || 4317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { 4318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Field with message or enum type missing type_name."); 4320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Add the field to the fields-by-number table. 4324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: We have to do this *after* cross-linking because extensions do not 4325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // know their containing type until now. 4326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!file_tables_->AddFieldByNumber(field)) { 4327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* conflicting_field = 4328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_tables_->FindFieldByNumber(field->containing_type(), 4329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->number()); 4330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_extension()) { 4331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 4333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute("Extension number $0 has already been used " 4334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "in \"$1\" by extension \"$2\".", 4335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->number(), 4336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->containing_type()->full_name(), 4337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville conflicting_field->full_name())); 4338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NUMBER, 4341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville strings::Substitute("Field number $0 has already been used in " 4342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"$1\" by field \"$2\".", 4343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->number(), 4344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->containing_type()->full_name(), 4345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville conflicting_field->name())); 4346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4347a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 4348a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (field->is_extension()) { 4349a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!tables_->AddExtension(field)) { 4350a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FieldDescriptor* conflicting_field = 4351a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson tables_->FindExtension(field->containing_type(), field->number()); 4352a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string error_msg = strings::Substitute( 4353a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Extension number $0 has already been used in \"$1\" by extension " 4354a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\"$2\" defined in $3.", 4355a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field->number(), 4356a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson field->containing_type()->full_name(), 4357a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson conflicting_field->full_name(), 4358a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson conflicting_field->file()->name()); 4359a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Conflicting extension numbers should be an error. However, before 4360a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // turning this into an error we need to fix all existing broken 4361a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // protos first. 4362a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // TODO(xiaofeng): Change this to an error. 4363a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddWarning(field->full_name(), proto, 4364a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::NUMBER, error_msg); 4365a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4366a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Add the field to the lowercase-name and camelcase-name tables. 4370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file_tables_->AddFieldByStylizedNames(field); 4371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkEnum( 4374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EnumDescriptor* enum_type, const EnumDescriptorProto& proto) { 4375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (enum_type->options_ == NULL) { 4376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_type->options_ = &EnumOptions::default_instance(); 4377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < enum_type->value_count(); i++) { 4380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkEnumValue(&enum_type->values_[i], proto.value(i)); 4381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkEnumValue( 4385a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson EnumValueDescriptor* enum_value, 4386a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const EnumValueDescriptorProto& /* proto */) { 4387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (enum_value->options_ == NULL) { 4388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_value->options_ = &EnumValueOptions::default_instance(); 4389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkService( 4393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ServiceDescriptor* service, const ServiceDescriptorProto& proto) { 4394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (service->options_ == NULL) { 4395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville service->options_ = &ServiceOptions::default_instance(); 4396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < service->method_count(); i++) { 4399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville CrossLinkMethod(&service->methods_[i], proto.method(i)); 4400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::CrossLinkMethod( 4404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MethodDescriptor* method, const MethodDescriptorProto& proto) { 4405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (method->options_ == NULL) { 4406fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville method->options_ = &MethodOptions::default_instance(); 4407fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); 4410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (input_type.IsNull()) { 4411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddNotDefinedError(method->full_name(), proto, 4412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::INPUT_TYPE, 4413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto.input_type()); 4414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (input_type.type != Symbol::MESSAGE) { 4415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(method->full_name(), proto, 4416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::INPUT_TYPE, 4417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + proto.input_type() + "\" is not a message type."); 4418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville method->input_type_ = input_type.descriptor; 4420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); 4423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (output_type.IsNull()) { 4424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddNotDefinedError(method->full_name(), proto, 4425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::OUTPUT_TYPE, 4426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto.output_type()); 4427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (output_type.type != Symbol::MESSAGE) { 4428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(method->full_name(), proto, 4429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::OUTPUT_TYPE, 4430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + proto.output_type() + "\" is not a message type."); 4431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville method->output_type_ = output_type.descriptor; 4433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 4437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \ 4439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < descriptor->array_name##_count(); ++i) { \ 4440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Validate##type##Options(descriptor->array_name##s_ + i, \ 4441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville proto.array_name(i)); \ 4442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to 4445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// avoid problems that exist at init time. 4446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestatic bool IsLite(const FileDescriptor* file) { 4447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // TODO(kenton): I don't even remember how many of these conditions are 4448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // actually possible. I'm just being super-safe. 4449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return file != NULL && 4450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &file->options() != &FileOptions::default_instance() && 4451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file->options().optimize_for() == FileOptions::LITE_RUNTIME; 4452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateFileOptions(FileDescriptor* file, 4455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FileDescriptorProto& proto) { 4456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message); 4457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum); 4458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service); 4459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field); 4460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Lite files can only be imported by other Lite files. 4462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!IsLite(file)) { 4463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < file->dependency_count(); i++) { 4464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (IsLite(file->dependency(i))) { 4465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError( 4466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville file->name(), proto, 4467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::OTHER, 4468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Files that do not use optimize_for = LITE_RUNTIME cannot import " 4469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "files which do use this option. This file is not lite, but it " 4470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "imports \"" + file->dependency(i)->name() + "\" which is."); 4471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 4472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4477a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateMessageOptions(Descriptor* message, 4479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const DescriptorProto& proto) { 4480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field); 4481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message); 4482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum); 4483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field); 4484a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4485a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const int64 max_extension_range = 4486a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson static_cast<int64>(message->options().message_set_wire_format() ? 4487a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson kint32max : 4488a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson FieldDescriptor::kMaxNumber); 4489a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < message->extension_range_count(); ++i) { 4490a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (message->extension_range(i)->end > max_extension_range + 1) { 4491a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError( 4492a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson message->full_name(), proto.extension_range(i), 4493a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::NUMBER, 4494a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson strings::Substitute("Extension numbers cannot be greater than $0.", 4495a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson max_extension_range)); 4496a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4497a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, 4501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptorProto& proto) { 4502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->options().has_experimental_map_key()) { 4503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ValidateMapKey(field, proto); 4504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4506a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Only message type fields may be lazy. 4507a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (field->options().lazy()) { 4508a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (field->type() != FieldDescriptor::TYPE_MESSAGE) { 4509a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(field->full_name(), proto, 4510a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::TYPE, 4511a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "[lazy = true] can only be specified for submessage fields."); 4512a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4513a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4514a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Only repeated primitive fields may be packed. 4516d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville if (field->options().packed() && !field->is_packable()) { 4517d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville AddError( 4518d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville field->full_name(), proto, 4519d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville DescriptorPool::ErrorCollector::TYPE, 4520d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville "[packed = true] can only be specified for repeated primitive fields."); 4521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: Default instance may not yet be initialized here, so we have to 4524fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // avoid reading from it. 4525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->containing_type_ != NULL && 4526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &field->containing_type()->options() != 4527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &MessageOptions::default_instance() && 4528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->containing_type()->options().message_set_wire_format()) { 4529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->is_extension()) { 4530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!field->is_optional() || 4531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->type() != FieldDescriptor::TYPE_MESSAGE) { 4532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::TYPE, 4534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Extensions of MessageSets must be optional messages."); 4535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NAME, 4539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "MessageSets cannot have fields, only extensions."); 4540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Lite extensions can only be of Lite types. 4544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (IsLite(field->file()) && 4545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->containing_type_ != NULL && 4546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville !IsLite(field->containing_type()->file())) { 4547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, 4548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::EXTENDEE, 4549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Extensions to non-lite types can only be declared in non-lite " 4550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "files. Note that you cannot extend a non-lite type to contain " 4551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "a lite type, but the reverse is allowed."); 4552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4553a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm, 4557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptorProto& proto) { 4558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue); 4559a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) { 4560a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson map<int, string> used_values; 4561a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < enm->value_count(); ++i) { 4562a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const EnumValueDescriptor* enum_value = enm->value(i); 4563a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (used_values.find(enum_value->number()) != used_values.end()) { 4564a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string error = 4565a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\"" + enum_value->full_name() + 4566a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" uses the same enum value as \"" + 4567a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson used_values[enum_value->number()] + "\". If this is intended, set " 4568a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "'option allow_alias = true;' to the enum definition."; 4569a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!enm->options().allow_alias()) { 4570a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Generate error if duplicated enum values are explicitly disallowed. 4571a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddError(enm->full_name(), proto, 4572a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorPool::ErrorCollector::NUMBER, 4573a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error); 4574a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 4575a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Generate warning if duplicated values are found but the option 4576a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // isn't set. 4577a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_LOG(ERROR) << error; 4578a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4579a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 4580a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson used_values[enum_value->number()] = enum_value->full_name(); 4581a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4582a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4583a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 4584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateEnumValueOptions( 4587a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson EnumValueDescriptor* /* enum_value */, 4588a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const EnumValueDescriptorProto& /* proto */) { 4589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Nothing to do so far. 4590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service, 4592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const ServiceDescriptorProto& proto) { 4593a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (IsLite(service->file()) && 4594a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (service->file()->options().cc_generic_services() || 4595a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson service->file()->options().java_generic_services())) { 4596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(service->full_name(), proto, 4597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorPool::ErrorCollector::NAME, 4598a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Files with optimize_for = LITE_RUNTIME cannot define services " 4599a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "unless you set both options cc_generic_services and " 4600a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "java_generic_sevices to false."); 4601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method); 4604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4606a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* /* method */, 4607a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const MethodDescriptorProto& /* proto */) { 4608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Nothing to do so far. 4609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::ValidateMapKey(FieldDescriptor* field, 4612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptorProto& proto) { 4613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!field->is_repeated()) { 4614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "map type is only allowed for repeated fields."); 4616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 4620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "map type is only allowed for fields with a message type."); 4622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* item_type = field->message_type(); 4626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (item_type == NULL) { 4627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Could not find field type."); 4629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find the field in item_type named by "experimental_map_key" 4633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& key_name = field->options().experimental_map_key(); 4634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Symbol key_symbol = LookupSymbol( 4635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville key_name, 4636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We append ".key_name" to the containing type's name since 4637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // LookupSymbol() searches for peers of the supplied name, not 4638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // children of the supplied name. 4639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville item_type->full_name() + "." + key_name); 4640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (key_symbol.IsNull() || key_symbol.field_descriptor->is_extension()) { 4642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "Could not find field named \"" + key_name + "\" in type \"" + 4644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville item_type->full_name() + "\"."); 4645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* key_field = key_symbol.field_descriptor; 4648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (key_field->is_repeated()) { 4650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "map_key must not name a repeated field."); 4652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (key_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { 4656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, 4657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "map key must name a scalar or string field."); 4658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return; 4659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field->experimental_map_key_ = key_field; 4662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4664a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 4665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#undef VALIDATE_OPTIONS_FROM_ARRAY 4666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ------------------------------------------------------------------- 4668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorBuilder::OptionInterpreter::OptionInterpreter( 4670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville DescriptorBuilder* builder) : builder_(builder) { 4671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(builder_); 4672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleDescriptorBuilder::OptionInterpreter::~OptionInterpreter() { 4675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::OptionInterpreter::InterpretOptions( 4678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OptionsToInterpret* options_to_interpret) { 4679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that these may be in different pools, so we can't use the same 4680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // descriptor and reflection objects on both. 4681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* options = options_to_interpret->options; 4682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Message* original_options = options_to_interpret->original_options; 4683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool failed = false; 4685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_to_interpret_ = options_to_interpret; 4686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find the uninterpreted_option field in the mutable copy of the options 4688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // and clear them, since we're about to interpret them. 4689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* uninterpreted_options_field = 4690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetDescriptor()->FindFieldByName("uninterpreted_option"); 4691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(uninterpreted_options_field != NULL) 4692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "No field named \"uninterpreted_option\" in the Options proto."; 4693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetReflection()->ClearField(options, uninterpreted_options_field); 4694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Find the uninterpreted_option field in the original options. 4696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* original_uninterpreted_options_field = 4697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville original_options->GetDescriptor()-> 4698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FindFieldByName("uninterpreted_option"); 4699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(original_uninterpreted_options_field != NULL) 4700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "No field named \"uninterpreted_option\" in the Options proto."; 4701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int num_uninterpreted_options = original_options->GetReflection()-> 4703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldSize(*original_options, original_uninterpreted_options_field); 4704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < num_uninterpreted_options; ++i) { 4705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_ = down_cast<const UninterpretedOption*>( 4706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &original_options->GetReflection()->GetRepeatedMessage( 4707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *original_options, original_uninterpreted_options_field, i)); 4708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!InterpretSingleOption(options)) { 4709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Error already added by InterpretSingleOption(). 4710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville failed = true; 4711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 4712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Reset these, so we don't have any dangling pointers. 4715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_ = NULL; 4716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_to_interpret_ = NULL; 4717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!failed) { 4719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // InterpretSingleOption() added the interpreted options in the 4720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // UnknownFieldSet, in case the option isn't yet known to us. Now we 4721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // serialize the options message and deserialize it back. That way, any 4722fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // option fields that we do happen to know about will get moved from the 4723fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // UnknownFieldSet into the real fields, and thus be available right away. 4724fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If they are not known, that's OK too. They will get reparsed into the 4725fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // UnknownFieldSet and wait there until the message is parsed by something 4726fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that does know about the options. 4727fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string buf; 4728fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->AppendToString(&buf); 4729fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(options->ParseFromString(buf)) 4730fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Protocol message serialized itself in invalid fashion."; 4731fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4732fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4733fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return !failed; 4734fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4735fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4736fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::OptionInterpreter::InterpretSingleOption( 4737fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Message* options) { 4738fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // First do some basic validation. 4739fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->name_size() == 0) { 4740fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This should never happen unless the parser has gone seriously awry or 4741fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // someone has manually created the uninterpreted option badly. 4742fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddNameError("Option must have a name."); 4743fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4744fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { 4745fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddNameError("Option must not use reserved name " 4746fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"uninterpreted_option\"."); 4747fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4748fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4749fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* options_descriptor = NULL; 4750fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Get the options message's descriptor from the builder's pool, so that we 4751fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // get the version that knows about any extension options declared in the 4752fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // file we're currently building. The descriptor should be there as long as 4753fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the file we're building imported "google/protobuf/descriptors.proto". 4754fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4755a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not 4756fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // DescriptorPool::FindMessageTypeByName() because we're already holding the 4757a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // pool's mutex, and the latter method locks it again. We don't use 4758a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // FindSymbol() because files that use custom options only need to depend on 4759a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the file that defines the option, not descriptor.proto itself. 4760fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol symbol = builder_->FindSymbolNotEnforcingDeps( 4761fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetDescriptor()->full_name()); 4762fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) { 4763fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_descriptor = symbol.descriptor; 4764fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4765fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The options message's descriptor was not in the builder's pool, so use 4766fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the standard version from the generated pool. We're not holding the 4767fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // generated pool's mutex, so we can search it the straightforward way. 4768fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options_descriptor = options->GetDescriptor(); 4769fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4770fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(options_descriptor); 4771fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4772fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We iterate over the name parts to drill into the submessages until we find 4773fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the leaf field for the option. As we drill down we remember the current 4774fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // submessage's descriptor in |descriptor| and the next field in that 4775fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // submessage in |field|. We also track the fields we're drilling down 4776fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // through in |intermediate_fields|. As we go, we reconstruct the full option 4777fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // name in |debug_msg_name|, for use in error messages. 4778fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const Descriptor* descriptor = options_descriptor; 4779fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = NULL; 4780fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*> intermediate_fields; 4781fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string debug_msg_name = ""; 4782fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4783fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { 4784fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& name_part = uninterpreted_option_->name(i).name_part(); 4785fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (debug_msg_name.size() > 0) { 4786fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville debug_msg_name += "."; 4787fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4788fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->name(i).is_extension()) { 4789fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville debug_msg_name += "(" + name_part + ")"; 4790fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Search for the extension's descriptor as an extension in the builder's 4791fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pool. Note that we use DescriptorBuilder::LookupSymbol(), not 4792fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows 4793fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // relative lookups, and 2) because we're already holding the pool's 4794fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // mutex, and the latter method locks it again. 4795a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson symbol = builder_->LookupSymbol(name_part, 4796a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson options_to_interpret_->name_scope); 4797fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!symbol.IsNull() && symbol.type == Symbol::FIELD) { 4798fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = symbol.field_descriptor; 4799fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4800fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // If we don't find the field then the field's descriptor was not in the 4801fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // builder's pool, but there's no point in looking in the generated 4802fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pool. We require that you import the file that defines any extensions 4803fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // you use, so they must be present in the builder's pool. 4804fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4805fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville debug_msg_name += name_part; 4806fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Search for the field's descriptor as a regular field. 4807fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field = descriptor->FindFieldByName(name_part); 4808fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4809fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4810fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field == NULL) { 4811fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (get_allow_unknown(builder_->pool_)) { 4812fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We can't find the option, but AllowUnknownDependencies() is enabled, 4813fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // so we will just leave it as uninterpreted. 4814fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddWithoutInterpreting(*uninterpreted_option_, options); 4815fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 4816a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else if (!(builder_->undefine_resolved_name_).empty()) { 4817a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Option is resolved to a name which is not defined. 4818a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return AddNameError( 4819a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "Option \"" + debug_msg_name + "\" is resolved to \"(" + 4820a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson builder_->undefine_resolved_name_ + 4821a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ")\", which is not defined. The innermost scope is searched first " 4822a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "in name resolution. Consider using a leading '.'(i.e., \"(." + 4823a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson debug_msg_name.substr(1) + 4824a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\") to start from the outermost scope."); 4825fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4826fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddNameError("Option \"" + debug_msg_name + "\" unknown."); 4827fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4828fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (field->containing_type() != descriptor) { 4829fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (get_is_placeholder(field->containing_type())) { 4830fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The field is an extension of a placeholder type, so we can't 4831fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // reliably verify whether it is a valid extension to use here (e.g. 4832fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // we don't know if it is an extension of the correct *Options message, 4833fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // or if it has a valid field number, etc.). Just leave it as 4834fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // uninterpreted instead. 4835fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville AddWithoutInterpreting(*uninterpreted_option_, options); 4836fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 4837fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4838fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // This can only happen if, due to some insane misconfiguration of the 4839fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // pools, we find the options message in one pool but the field in 4840fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // another. This would probably imply a hefty bug somewhere. 4841fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddNameError("Option field \"" + debug_msg_name + 4842fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" is not a field or extension of message \"" + 4843fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor->name() + "\"."); 4844fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4845fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (i < uninterpreted_option_->name_size() - 1) { 4846fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { 4847fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddNameError("Option \"" + debug_msg_name + 4848fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" is an atomic type, not a message."); 4849a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else if (field->is_repeated()) { 4850a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return AddNameError("Option field \"" + debug_msg_name + 4851a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" is a repeated message. Repeated message " 4852a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "options must be initialized using an " 4853a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "aggregate value."); 4854fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 4855fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Drill down into the submessage. 4856fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_fields.push_back(field); 4857fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville descriptor = field->message_type(); 4858fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4859fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4860fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4861fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4862fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We've found the leaf field. Now we use UnknownFieldSets to set its value 4863fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // on the options message. We do so because the message may not yet know 4864fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // about its extension fields, so we may not be able to set the fields 4865fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // directly. But the UnknownFieldSets will serialize to the same wire-format 4866fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // message, so reading that message back in once the extension fields are 4867fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // known will populate them correctly. 4868fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4869fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // First see if the option is already set. 4870a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!field->is_repeated() && !ExamineIfOptionIsSet( 4871fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_fields.begin(), 4872fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_fields.end(), 4873fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville field, debug_msg_name, 4874fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetReflection()->GetUnknownFields(*options))) { 4875fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; // ExamineIfOptionIsSet() already added the error. 4876fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4877fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4878fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4879fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // First set the value on the UnknownFieldSet corresponding to the 4880fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // innermost message. 4881fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet()); 4882fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!SetOptionValue(field, unknown_fields.get())) { 4883fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; // SetOptionValue() already added the error. 4884fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4885fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4886fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all 4887fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the intermediate messages. 4888fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (vector<const FieldDescriptor*>::reverse_iterator iter = 4889fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_fields.rbegin(); 4890fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville iter != intermediate_fields.rend(); ++iter) { 4891fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_ptr<UnknownFieldSet> parent_unknown_fields(new UnknownFieldSet()); 4892fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch ((*iter)->type()) { 4893fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_MESSAGE: { 4894fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::StringOutputStream outstr( 4895fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parent_unknown_fields->AddLengthDelimited((*iter)->number())); 4896fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville io::CodedOutputStream out(&outstr); 4897fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out); 4898fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(!out.HadError()) 4899fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << "Unexpected failure while serializing option submessage " 4900fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << debug_msg_name << "\"."; 4901fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 4902fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4903fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4904fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_GROUP: { 4905fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville parent_unknown_fields->AddGroup((*iter)->number()) 4906fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ->MergeFrom(*unknown_fields); 4907fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 4908fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4909fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4910fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 4911fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " 4912fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville << (*iter)->type(); 4913fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 4914fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4915fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields.reset(parent_unknown_fields.release()); 4916fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4917fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4918fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Now merge the UnknownFieldSet corresponding to the top-level message into 4919fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the options message. 4920fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetReflection()->MutableUnknownFields(options)->MergeFrom( 4921fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville *unknown_fields); 4922fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4923fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 4924fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4925fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4926fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( 4927fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UninterpretedOption& uninterpreted_option, Message* options) { 4928fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* field = 4929fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetDescriptor()->FindFieldByName("uninterpreted_option"); 4930fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_CHECK(field != NULL); 4931fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4932fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options->GetReflection()->AddMessage(options, field) 4933fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ->CopyFrom(uninterpreted_option); 4934fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4935fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4936fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( 4937fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter, 4938fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville vector<const FieldDescriptor*>::const_iterator intermediate_fields_end, 4939fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* innermost_field, const string& debug_msg_name, 4940fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownFieldSet& unknown_fields) { 4941fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We do linear searches of the UnknownFieldSet and its sub-groups. This 4942fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // should be fine since it's unlikely that any one options structure will 4943fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // contain more than a handful of options. 4944fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4945fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (intermediate_fields_iter == intermediate_fields_end) { 4946fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We're at the innermost submessage. 4947fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < unknown_fields.field_count(); i++) { 4948fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (unknown_fields.field(i).number() == innermost_field->number()) { 4949fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddNameError("Option \"" + debug_msg_name + 4950fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" was already set."); 4951fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4952fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4953fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 4954fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4955fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4956fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < unknown_fields.field_count(); i++) { 4957fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (unknown_fields.field(i).number() == 4958fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville (*intermediate_fields_iter)->number()) { 4959fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const UnknownField* unknown_field = &unknown_fields.field(i); 4960fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); 4961fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Recurse into the next submessage. 4962fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type) { 4963fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_MESSAGE: 4964fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { 4965fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet intermediate_unknown_fields; 4966fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (intermediate_unknown_fields.ParseFromString( 4967fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_field->length_delimited()) && 4968fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville !ExamineIfOptionIsSet(intermediate_fields_iter + 1, 4969fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_fields_end, 4970fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville innermost_field, debug_msg_name, 4971fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_unknown_fields)) { 4972fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; // Error already added. 4973fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4974fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4975fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 4976fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4977fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_GROUP: 4978fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (unknown_field->type() == UnknownField::TYPE_GROUP) { 4979fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, 4980fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville intermediate_fields_end, 4981fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville innermost_field, debug_msg_name, 4982fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_field->group())) { 4983fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; // Error already added. 4984fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4985fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4986fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 4987fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4988fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 4989fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; 4990fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 4991fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4992fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4993fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 4994fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 4995fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 4996fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 4997fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool DescriptorBuilder::OptionInterpreter::SetOptionValue( 4998fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const FieldDescriptor* option_field, 4999fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville UnknownFieldSet* unknown_fields) { 5000fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // We switch on the CppType to validate. 5001fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (option_field->cpp_type()) { 5002fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5003fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT32: 5004fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->has_positive_int_value()) { 5005fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->positive_int_value() > 5006fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<uint64>(kint32max)) { 5007fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value out of range for int32 option \"" + 5008fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5009fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5010fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInt32(option_field->number(), 5011fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->positive_int_value(), 5012fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->type(), unknown_fields); 5013fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5014fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->has_negative_int_value()) { 5015fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->negative_int_value() < 5016fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<int64>(kint32min)) { 5017fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value out of range for int32 option \"" + 5018fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5019fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5020fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInt32(option_field->number(), 5021fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->negative_int_value(), 5022fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->type(), unknown_fields); 5023fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5024fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5025fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be integer for int32 option \"" + 5026fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5027fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5028fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5029fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5030fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_INT64: 5031fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->has_positive_int_value()) { 5032fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->positive_int_value() > 5033fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<uint64>(kint64max)) { 5034fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value out of range for int64 option \"" + 5035fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5036fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5037fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInt64(option_field->number(), 5038fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->positive_int_value(), 5039fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->type(), unknown_fields); 5040fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5041fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->has_negative_int_value()) { 5042fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetInt64(option_field->number(), 5043fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->negative_int_value(), 5044fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->type(), unknown_fields); 5045fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5046fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be integer for int64 option \"" + 5047fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5048fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5049fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5050fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5051fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT32: 5052fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->has_positive_int_value()) { 5053fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->positive_int_value() > kuint32max) { 5054fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value out of range for uint32 option \"" + 5055fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->name() + "\"."); 5056fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5057fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetUInt32(option_field->number(), 5058fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->positive_int_value(), 5059fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->type(), unknown_fields); 5060fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5061fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5062fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be non-negative integer for uint32 " 5063fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "option \"" + option_field->full_name() + "\"."); 5064fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5065fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5066fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5067fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_UINT64: 5068fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->has_positive_int_value()) { 5069fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville SetUInt64(option_field->number(), 5070fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->positive_int_value(), 5071fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->type(), unknown_fields); 5072fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5073fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be non-negative integer for uint64 " 5074fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "option \"" + option_field->full_name() + "\"."); 5075fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5076fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5077fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5078fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_FLOAT: { 5079fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville float value; 5080fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->has_double_value()) { 5081fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = uninterpreted_option_->double_value(); 5082fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->has_positive_int_value()) { 5083fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = uninterpreted_option_->positive_int_value(); 5084fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->has_negative_int_value()) { 5085fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = uninterpreted_option_->negative_int_value(); 5086fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5087fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be number for float option \"" + 5088fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5089fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5090fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddFixed32(option_field->number(), 5091fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville google::protobuf::internal::WireFormatLite::EncodeFloat(value)); 5092fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5093fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5094fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5095fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_DOUBLE: { 5096fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville double value; 5097fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->has_double_value()) { 5098fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = uninterpreted_option_->double_value(); 5099fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->has_positive_int_value()) { 5100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = uninterpreted_option_->positive_int_value(); 5101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->has_negative_int_value()) { 5102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = uninterpreted_option_->negative_int_value(); 5103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be number for double option \"" + 5105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + "\"."); 5106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddFixed64(option_field->number(), 5108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville google::protobuf::internal::WireFormatLite::EncodeDouble(value)); 5109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_BOOL: 5113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint64 value; 5114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!uninterpreted_option_->has_identifier_value()) { 5115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be identifier for boolean option " 5116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + option_field->full_name() + "\"."); 5117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (uninterpreted_option_->identifier_value() == "true") { 5119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = 1; 5120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else if (uninterpreted_option_->identifier_value() == "false") { 5121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville value = 0; 5122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be \"true\" or \"false\" for boolean " 5124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "option \"" + option_field->full_name() + "\"."); 5125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(option_field->number(), value); 5127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_ENUM: { 5130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!uninterpreted_option_->has_identifier_value()) { 5131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be identifier for enum-valued option " 5132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + option_field->full_name() + "\"."); 5133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumDescriptor* enum_type = option_field->enum_type(); 5135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const string& value_name = uninterpreted_option_->identifier_value(); 5136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const EnumValueDescriptor* enum_value = NULL; 5137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { 5139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note that the enum value's fully-qualified name is a sibling of the 5140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // enum's name, not a child of it. 5141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string fully_qualified_name = enum_type->full_name(); 5142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fully_qualified_name.resize(fully_qualified_name.size() - 5143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_type->name().size()); 5144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville fully_qualified_name += value_name; 5145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Search for the enum value's descriptor in the builder's pool. Note 5147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not 5148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // DescriptorPool::FindEnumValueByName() because we're already holding 5149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the pool's mutex, and the latter method locks it again. 5150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville Symbol symbol = 5151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); 5152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) { 5153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (symbol.enum_value_descriptor->type() != enum_type) { 5154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Enum type \"" + enum_type->full_name() + 5155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" has no value named \"" + value_name + "\" for option \"" + 5156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->full_name() + 5157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\". This appears to be a value from a sibling type."); 5158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_value = symbol.enum_value_descriptor; 5160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The enum type is in the generated pool, so we can search for the 5164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // value there. 5165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville enum_value = enum_type->FindValueByName(value_name); 5166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (enum_value == NULL) { 5169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Enum type \"" + 5170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville option_field->enum_type()->full_name() + 5171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\" has no value named \"" + value_name + "\" for " 5172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "option \"" + option_field->full_name() + "\"."); 5173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 5174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Sign-extension is not a problem, since we cast directly from int32 to 5175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // uint64, without first going through uint32. 5176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(option_field->number(), 5177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<uint64>(static_cast<int64>(enum_value->number()))); 5178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_STRING: 5183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!uninterpreted_option_->has_string_value()) { 5184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return AddValueError("Value must be quoted string for string option " 5185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville "\"" + option_field->full_name() + "\"."); 5186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The string has already been unquoted and unescaped by the parser. 5188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddLengthDelimited(option_field->number(), 5189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uninterpreted_option_->string_value()); 5190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 5193a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!SetAggregateOption(option_field, unknown_fields)) { 5194a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return false; 5195a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 5200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 5201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5202a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass DescriptorBuilder::OptionInterpreter::AggregateOptionFinder 5203a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson : public TextFormat::Finder { 5204a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson public: 5205a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson DescriptorBuilder* builder_; 5206a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5207a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson virtual const FieldDescriptor* FindExtension( 5208a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Message* message, const string& name) const { 5209a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson assert_mutex_held(builder_->pool_); 5210a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Descriptor* descriptor = message->GetDescriptor(); 5211a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson Symbol result = builder_->LookupSymbolNoPlaceholder( 5212a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson name, descriptor->full_name()); 5213a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (result.type == Symbol::FIELD && 5214a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson result.field_descriptor->is_extension()) { 5215a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return result.field_descriptor; 5216a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else if (result.type == Symbol::MESSAGE && 5217a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson descriptor->options().message_set_wire_format()) { 5218a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Descriptor* foreign_type = result.descriptor; 5219a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // The text format allows MessageSet items to be specified using 5220a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // the type name, rather than the extension identifier. If the symbol 5221a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // lookup returned a Message, and the enclosing Message has 5222a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // message_set_wire_format = true, then return the message set 5223a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // extension, if one exists. 5224a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (int i = 0; i < foreign_type->extension_count(); i++) { 5225a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FieldDescriptor* extension = foreign_type->extension(i); 5226a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (extension->containing_type() == descriptor && 5227a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extension->type() == FieldDescriptor::TYPE_MESSAGE && 5228a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extension->is_optional() && 5229a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson extension->message_type() == foreign_type) { 5230a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Found it. 5231a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return extension; 5232a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5233a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5234a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5235a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return NULL; 5236a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5237a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}; 5238a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5239a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// A custom error collector to record any text-format parsing errors 5240a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonnamespace { 5241a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonclass AggregateErrorCollector : public io::ErrorCollector { 5242a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson public: 5243a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string error_; 5244a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5245a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson virtual void AddError(int /* line */, int /* column */, 5246a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& message) { 5247a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!error_.empty()) { 5248a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_ += "; "; 5249a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5250a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson error_ += message; 5251a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5252a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5253a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson virtual void AddWarning(int /* line */, int /* column */, 5254a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const string& /* message */) { 5255a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Ignore warnings 5256a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5257a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson}; 5258a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 5259a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5260a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// We construct a dynamic message of the type corresponding to 5261a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// option_field, parse the supplied text-format string into this 5262a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson// message, and serialize the resulting message to produce the value. 5263a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonbool DescriptorBuilder::OptionInterpreter::SetAggregateOption( 5264a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const FieldDescriptor* option_field, 5265a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson UnknownFieldSet* unknown_fields) { 5266a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!uninterpreted_option_->has_aggregate_value()) { 5267a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return AddValueError("Option \"" + option_field->full_name() + 5268a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "\" is a message. To set the entire message, use " 5269a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "syntax like \"" + option_field->name() + 5270a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson " = { <proto text format> }\". " 5271a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "To set fields within it, use " 5272a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson "syntax like \"" + option_field->name() + 5273a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson ".foo = value\"."); 5274a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5275a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5276a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson const Descriptor* type = option_field->message_type(); 5277a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New()); 5278a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK(dynamic.get() != NULL) 5279a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson << "Could not create an instance of " << option_field->DebugString(); 5280a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5281a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AggregateErrorCollector collector; 5282a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AggregateOptionFinder finder; 5283a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson finder.builder_ = builder_; 5284a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson TextFormat::Parser parser; 5285a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson parser.RecordErrorsTo(&collector); 5286a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson parser.SetFinder(&finder); 5287a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), 5288a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson dynamic.get())) { 5289a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson AddValueError("Error while parsing option value for \"" + 5290a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson option_field->name() + "\": " + collector.error_); 5291a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return false; 5292a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 5293a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson string serial; 5294a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson dynamic->SerializeToString(&serial); // Never fails 5295a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { 5296a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson unknown_fields->AddLengthDelimited(option_field->number(), serial); 5297a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } else { 5298a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); 5299a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); 5300a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson group->ParseFromString(serial); 5301a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5302a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson return true; 5303a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5304a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 5305a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value, 5307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 5308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type) { 5309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_INT32: 5310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(number, 5311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static_cast<uint64>(static_cast<int64>(value))); 5312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_SFIXED32: 5315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddFixed32(number, static_cast<uint32>(value)); 5316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_SINT32: 5319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(number, 5320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville google::protobuf::internal::WireFormatLite::ZigZagEncode32(value)); 5321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 5324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; 5325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 5328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value, 5330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 5331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type) { 5332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_INT64: 5333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(number, static_cast<uint64>(value)); 5334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_SFIXED64: 5337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddFixed64(number, static_cast<uint64>(value)); 5338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_SINT64: 5341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(number, 5342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville google::protobuf::internal::WireFormatLite::ZigZagEncode64(value)); 5343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 5346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; 5347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 5350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value, 5352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 5353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type) { 5354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_UINT32: 5355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(number, static_cast<uint64>(value)); 5356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_FIXED32: 5359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddFixed32(number, static_cast<uint32>(value)); 5360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 5363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; 5364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 5367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value, 5369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) { 5370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville switch (type) { 5371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_UINT64: 5372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddVarint(number, value); 5373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville case FieldDescriptor::TYPE_FIXED64: 5376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unknown_fields->AddFixed64(number, value); 5377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville default: 5380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; 5381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville break; 5382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 5383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 5384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 5385a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidsonvoid DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) { 5386a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5387a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (!unused_dependency_.empty()) { 5388a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson std::set<string> annotation_extensions; 5389a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.MessageOptions"); 5390a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.FileOptions"); 5391a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.FieldOptions"); 5392a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.EnumOptions"); 5393a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.EnumValueOptions"); 5394a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.ServiceOptions"); 5395a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.MethodOptions"); 5396a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson annotation_extensions.insert("google.protobuf.StreamOptions"); 5397a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (set<const FileDescriptor*>::const_iterator 5398a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson it = unused_dependency_.begin(); 5399a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson it != unused_dependency_.end(); ++it) { 5400a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Do not log warnings for proto files which extend annotations. 5401a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson int i; 5402a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson for (i = 0 ; i < (*it)->extension_count(); ++i) { 5403a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (annotation_extensions.find( 5404a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson (*it)->extension(i)->containing_type()->full_name()) 5405a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson != annotation_extensions.end()) { 5406a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson break; 5407a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5408a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5409a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson // Log warnings for unused imported files. 5410a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson if (i == (*it)->extension_count()) { 5411a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson GOOGLE_LOG(WARNING) << "Warning: Unused import: \"" << result->name() 5412a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson << "\" imports \"" << (*it)->name() 5413a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson << "\" which is not used."; 5414a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5415a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5416a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson } 5417a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson} 5418a3b2a6da25a76f17c73d31def3952feb0fd2296eJeff Davidson 5419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 5420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 5421