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