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