LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - descriptor.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 1351 2513 53.8 %
Date: 2015-10-10 Functions: 139 254 54.7 %

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

Generated by: LCOV version 1.10