LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf - descriptor.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 26 2426 1.1 %
Date: 2017-07-14 16:53:18 Functions: 7 272 2.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13