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