src/google/protobuf/descriptor.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <algorithm>
36 #include <functional>
37 #include <limits>
38 #include <map>
39 #include <memory>
40 #include <set>
41 #include <string>
42 #include <unordered_map>
43 #include <unordered_set>
44 #include <vector>
45 
64 
65 
66 
70 
71 #undef PACKAGE // autoheader #defines this. :(
72 
73 
74 #include <google/protobuf/port_def.inc>
75 
76 namespace google {
77 namespace protobuf {
78 
79 struct Symbol {
80  enum Type {
90  };
92  union {
101  };
102 
103  inline Symbol() : type(NULL_SYMBOL) { descriptor = nullptr; }
104  inline bool IsNull() const { return type == NULL_SYMBOL; }
105  inline bool IsType() const { return type == MESSAGE || type == ENUM; }
106  inline bool IsAggregate() const {
107  return type == MESSAGE || type == PACKAGE || type == ENUM ||
108  type == SERVICE;
109  }
110 
111 #define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \
112  inline explicit Symbol(const TYPE* value) { \
113  type = TYPE_CONSTANT; \
114  this->FIELD = value; \
115  }
116 
122  CONSTRUCTOR(ServiceDescriptor, SERVICE, service_descriptor)
123  CONSTRUCTOR(MethodDescriptor, METHOD, method_descriptor)
125 #undef CONSTRUCTOR
126 
127  const FileDescriptor* GetFile() const {
128  switch (type) {
129  case NULL_SYMBOL:
130  return nullptr;
131  case MESSAGE:
132  return descriptor->file();
133  case FIELD:
134  return field_descriptor->file();
135  case ONEOF:
137  case ENUM:
138  return enum_descriptor->file();
139  case ENUM_VALUE:
140  return enum_value_descriptor->type()->file();
141  case SERVICE:
142  return service_descriptor->file();
143  case METHOD:
144  return method_descriptor->service()->file();
145  case PACKAGE:
147  }
148  return nullptr;
149  }
150 };
151 
153  FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
154  static_cast<CppType>(0), // 0 is reserved for errors
155 
156  CPPTYPE_DOUBLE, // TYPE_DOUBLE
157  CPPTYPE_FLOAT, // TYPE_FLOAT
158  CPPTYPE_INT64, // TYPE_INT64
159  CPPTYPE_UINT64, // TYPE_UINT64
160  CPPTYPE_INT32, // TYPE_INT32
161  CPPTYPE_UINT64, // TYPE_FIXED64
162  CPPTYPE_UINT32, // TYPE_FIXED32
163  CPPTYPE_BOOL, // TYPE_BOOL
164  CPPTYPE_STRING, // TYPE_STRING
165  CPPTYPE_MESSAGE, // TYPE_GROUP
166  CPPTYPE_MESSAGE, // TYPE_MESSAGE
167  CPPTYPE_STRING, // TYPE_BYTES
168  CPPTYPE_UINT32, // TYPE_UINT32
169  CPPTYPE_ENUM, // TYPE_ENUM
170  CPPTYPE_INT32, // TYPE_SFIXED32
171  CPPTYPE_INT64, // TYPE_SFIXED64
172  CPPTYPE_INT32, // TYPE_SINT32
173  CPPTYPE_INT64, // TYPE_SINT64
174 };
175 
176 const char* const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
177  "ERROR", // 0 is reserved for errors
178 
179  "double", // TYPE_DOUBLE
180  "float", // TYPE_FLOAT
181  "int64", // TYPE_INT64
182  "uint64", // TYPE_UINT64
183  "int32", // TYPE_INT32
184  "fixed64", // TYPE_FIXED64
185  "fixed32", // TYPE_FIXED32
186  "bool", // TYPE_BOOL
187  "string", // TYPE_STRING
188  "group", // TYPE_GROUP
189  "message", // TYPE_MESSAGE
190  "bytes", // TYPE_BYTES
191  "uint32", // TYPE_UINT32
192  "enum", // TYPE_ENUM
193  "sfixed32", // TYPE_SFIXED32
194  "sfixed64", // TYPE_SFIXED64
195  "sint32", // TYPE_SINT32
196  "sint64", // TYPE_SINT64
197 };
198 
199 const char* const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = {
200  "ERROR", // 0 is reserved for errors
201 
202  "int32", // CPPTYPE_INT32
203  "int64", // CPPTYPE_INT64
204  "uint32", // CPPTYPE_UINT32
205  "uint64", // CPPTYPE_UINT64
206  "double", // CPPTYPE_DOUBLE
207  "float", // CPPTYPE_FLOAT
208  "bool", // CPPTYPE_BOOL
209  "enum", // CPPTYPE_ENUM
210  "string", // CPPTYPE_STRING
211  "message", // CPPTYPE_MESSAGE
212 };
213 
214 const char* const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
215  "ERROR", // 0 is reserved for errors
216 
217  "optional", // LABEL_OPTIONAL
218  "required", // LABEL_REQUIRED
219  "repeated", // LABEL_REPEATED
220 };
221 
223  switch (syntax) {
224  case SYNTAX_PROTO2:
225  return "proto2";
226  case SYNTAX_PROTO3:
227  return "proto3";
228  case SYNTAX_UNKNOWN:
229  return "unknown";
230  }
231  GOOGLE_LOG(FATAL) << "can't reach here.";
232  return nullptr;
233 }
234 
235 static const char* const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
236 
237 #if !defined(_MSC_VER) || _MSC_VER >= 1900
241 #endif
242 
243 namespace {
244 
245 // Note: I distrust ctype.h due to locales.
246 char ToUpper(char ch) {
247  return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch;
248 }
249 
250 char ToLower(char ch) {
251  return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
252 }
253 
254 std::string ToCamelCase(const std::string& input, bool lower_first) {
255  bool capitalize_next = !lower_first;
256  std::string result;
257  result.reserve(input.size());
258 
259  for (int i = 0; i < input.size(); i++) {
260  if (input[i] == '_') {
261  capitalize_next = true;
262  } else if (capitalize_next) {
263  result.push_back(ToUpper(input[i]));
264  capitalize_next = false;
265  } else {
266  result.push_back(input[i]);
267  }
268  }
269 
270  // Lower-case the first letter.
271  if (lower_first && !result.empty()) {
272  result[0] = ToLower(result[0]);
273  }
274 
275  return result;
276 }
277 
278 std::string ToJsonName(const std::string& input) {
279  bool capitalize_next = false;
280  std::string result;
281  result.reserve(input.size());
282 
283  for (int i = 0; i < input.size(); i++) {
284  if (input[i] == '_') {
285  capitalize_next = true;
286  } else if (capitalize_next) {
287  result.push_back(ToUpper(input[i]));
288  capitalize_next = false;
289  } else {
290  result.push_back(input[i]);
291  }
292  }
293 
294  return result;
295 }
296 
297 std::string EnumValueToPascalCase(const std::string& input) {
298  bool next_upper = true;
299  std::string result;
300  result.reserve(input.size());
301 
302  for (int i = 0; i < input.size(); i++) {
303  if (input[i] == '_') {
304  next_upper = true;
305  } else {
306  if (next_upper) {
307  result.push_back(ToUpper(input[i]));
308  } else {
309  result.push_back(ToLower(input[i]));
310  }
311  next_upper = false;
312  }
313  }
314 
315  return result;
316 }
317 
318 // Class to remove an enum prefix from enum values.
319 class PrefixRemover {
320  public:
321  PrefixRemover(StringPiece prefix) {
322  // Strip underscores and lower-case the prefix.
323  for (int i = 0; i < prefix.size(); i++) {
324  if (prefix[i] != '_') {
326  }
327  }
328  }
329 
330  // Tries to remove the enum prefix from this enum value.
331  // If this is not possible, returns the input verbatim.
332  std::string MaybeRemove(StringPiece str) {
333  // We can't just lowercase and strip str and look for a prefix.
334  // We need to properly recognize the difference between:
335  //
336  // enum Foo {
337  // FOO_BAR_BAZ = 0;
338  // FOO_BARBAZ = 1;
339  // }
340  //
341  // This is acceptable (though perhaps not advisable) because even when
342  // we PascalCase, these two will still be distinct (BarBaz vs. Barbaz).
343  size_t i, j;
344 
345  // Skip past prefix_ in str if we can.
346  for (i = 0, j = 0; i < str.size() && j < prefix_.size(); i++) {
347  if (str[i] == '_') {
348  continue;
349  }
350 
351  if (ascii_tolower(str[i]) != prefix_[j++]) {
352  return std::string(str);
353  }
354  }
355 
356  // If we didn't make it through the prefix, we've failed to strip the
357  // prefix.
358  if (j < prefix_.size()) {
359  return std::string(str);
360  }
361 
362  // Skip underscores between prefix and further characters.
363  while (i < str.size() && str[i] == '_') {
364  i++;
365  }
366 
367  // Enum label can't be the empty string.
368  if (i == str.size()) {
369  return std::string(str);
370  }
371 
372  // We successfully stripped the prefix.
373  str.remove_prefix(i);
374  return std::string(str);
375  }
376 
377  private:
379 };
380 
381 // A DescriptorPool contains a bunch of hash-maps to implement the
382 // various Find*By*() methods. Since hashtable lookups are O(1), it's
383 // most efficient to construct a fixed set of large hash-maps used by
384 // all objects in the pool rather than construct one or more small
385 // hash-maps for each object.
386 //
387 // The keys to these hash-maps are (parent, name) or (parent, number) pairs.
388 //
389 // TODO(kenton): Use StringPiece rather than const char* in keys? It would
390 // be a lot cleaner but we'd just have to convert it back to const char*
391 // for the open source release.
392 
393 typedef std::pair<const void*, const char*> PointerStringPair;
394 
395 struct PointerStringPairEqual {
396  inline bool operator()(const PointerStringPair& a,
397  const PointerStringPair& b) const {
398  return a.first == b.first && strcmp(a.second, b.second) == 0;
399  }
400 };
401 
402 typedef std::pair<const Descriptor*, int> DescriptorIntPair;
403 typedef std::pair<const EnumDescriptor*, int> EnumIntPair;
404 
405 #define HASH_MAP std::unordered_map
406 #define HASH_SET std::unordered_set
407 #define HASH_FXN hash
408 
409 template <typename PairType>
410 struct PointerIntegerPairHash {
411  size_t operator()(const PairType& p) const {
412  static const size_t prime1 = 16777499;
413  static const size_t prime2 = 16777619;
414  return reinterpret_cast<size_t>(p.first) * prime1 ^
415  static_cast<size_t>(p.second) * prime2;
416  }
417 
418 #ifdef _MSC_VER
419  // Used only by MSVC and platforms where hash_map is not available.
420  static const size_t bucket_size = 4;
421  static const size_t min_buckets = 8;
422 #endif
423  inline bool operator()(const PairType& a, const PairType& b) const {
424  return a.first < b.first || (a.first == b.first && a.second < b.second);
425  }
426 };
427 
428 struct PointerStringPairHash {
429  size_t operator()(const PointerStringPair& p) const {
430  static const size_t prime = 16777619;
431  hash<const char*> cstring_hash;
432  return reinterpret_cast<size_t>(p.first) * prime ^
433  static_cast<size_t>(cstring_hash(p.second));
434  }
435 
436 #ifdef _MSC_VER
437  // Used only by MSVC and platforms where hash_map is not available.
438  static const size_t bucket_size = 4;
439  static const size_t min_buckets = 8;
440 #endif
441  inline bool operator()(const PointerStringPair& a,
442  const PointerStringPair& b) const {
443  if (a.first < b.first) return true;
444  if (a.first > b.first) return false;
445  return strcmp(a.second, b.second) < 0;
446  }
447 };
448 
449 
450 const Symbol kNullSymbol;
451 
452 typedef HASH_MAP<const char*, Symbol, HASH_FXN<const char*>, streq>
453  SymbolsByNameMap;
454 
455 typedef HASH_MAP<PointerStringPair, Symbol, PointerStringPairHash,
456  PointerStringPairEqual>
457  SymbolsByParentMap;
458 
459 typedef HASH_MAP<const char*, const FileDescriptor*, HASH_FXN<const char*>,
460  streq>
461  FilesByNameMap;
462 
463 typedef HASH_MAP<PointerStringPair, const FieldDescriptor*,
464  PointerStringPairHash, PointerStringPairEqual>
465  FieldsByNameMap;
466 
467 typedef HASH_MAP<DescriptorIntPair, const FieldDescriptor*,
468  PointerIntegerPairHash<DescriptorIntPair>,
469  std::equal_to<DescriptorIntPair>>
470  FieldsByNumberMap;
471 
472 typedef HASH_MAP<EnumIntPair, const EnumValueDescriptor*,
473  PointerIntegerPairHash<EnumIntPair>,
474  std::equal_to<EnumIntPair>>
475  EnumValuesByNumberMap;
476 // This is a map rather than a hash-map, since we use it to iterate
477 // through all the extensions that extend a given Descriptor, and an
478 // ordered data structure that implements lower_bound is convenient
479 // for that.
480 typedef std::map<DescriptorIntPair, const FieldDescriptor*>
481  ExtensionsGroupedByDescriptorMap;
482 typedef HASH_MAP<std::string, const SourceCodeInfo_Location*>
483  LocationsByPathMap;
484 
485 std::set<std::string>* NewAllowedProto3Extendee() {
486  auto allowed_proto3_extendees = new std::set<std::string>;
487  const char* kOptionNames[] = {
488  "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions",
489  "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"};
490  for (int i = 0; i < GOOGLE_ARRAYSIZE(kOptionNames); ++i) {
491  // descriptor.proto has a different package name in opensource. We allow
492  // both so the opensource protocol compiler can also compile internal
493  // proto3 files with custom options. See: b/27567912
494  allowed_proto3_extendees->insert(std::string("google.protobuf.") +
495  kOptionNames[i]);
496  // Split the word to trick the opensource processing scripts so they
497  // will keep the origial package name.
498  allowed_proto3_extendees->insert(std::string("proto") + "2." +
499  kOptionNames[i]);
500  }
501  return allowed_proto3_extendees;
502 }
503 
504 // Checks whether the extendee type is allowed in proto3.
505 // Only extensions to descriptor options are allowed. We use name comparison
506 // instead of comparing the descriptor directly because the extensions may be
507 // defined in a different pool.
508 bool AllowedExtendeeInProto3(const std::string& name) {
509  static auto allowed_proto3_extendees =
510  internal::OnShutdownDelete(NewAllowedProto3Extendee());
511  return allowed_proto3_extendees->find(name) !=
512  allowed_proto3_extendees->end();
513 }
514 
515 } // anonymous namespace
516 
517 // ===================================================================
518 // DescriptorPool::Tables
519 
520 class DescriptorPool::Tables {
521  public:
522  Tables();
523  ~Tables();
524 
525  // Record the current state of the tables to the stack of checkpoints.
526  // Each call to AddCheckpoint() must be paired with exactly one call to either
527  // ClearLastCheckpoint() or RollbackToLastCheckpoint().
528  //
529  // This is used when building files, since some kinds of validation errors
530  // cannot be detected until the file's descriptors have already been added to
531  // the tables.
532  //
533  // This supports recursive checkpoints, since building a file may trigger
534  // recursive building of other files. Note that recursive checkpoints are not
535  // normally necessary; explicit dependencies are built prior to checkpointing.
536  // So although we recursively build transitive imports, there is at most one
537  // checkpoint in the stack during dependency building.
538  //
539  // Recursive checkpoints only arise during cross-linking of the descriptors.
540  // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
541  // friends. If the pending file references an unknown symbol
542  // (e.g., it is not defined in the pending file's explicit dependencies), and
543  // the pool is using a fallback database, and that database contains a file
544  // defining that symbol, and that file has not yet been built by the pool,
545  // the pool builds the file during cross-linking, leading to another
546  // checkpoint.
547  void AddCheckpoint();
548 
549  // Mark the last checkpoint as having cleared successfully, removing it from
550  // the stack. If the stack is empty, all pending symbols will be committed.
551  //
552  // Note that this does not guarantee that the symbols added since the last
553  // checkpoint won't be rolled back: if a checkpoint gets rolled back,
554  // everything past that point gets rolled back, including symbols added after
555  // checkpoints that were pushed onto the stack after it and marked as cleared.
556  void ClearLastCheckpoint();
557 
558  // Roll back the Tables to the state of the checkpoint at the top of the
559  // stack, removing everything that was added after that point.
561 
562  // The stack of files which are currently being built. Used to detect
563  // cyclic dependencies when loading files from a DescriptorDatabase. Not
564  // used when fallback_database_ == nullptr.
565  std::vector<std::string> pending_files_;
566 
567  // A set of files which we have tried to load from the fallback database
568  // and encountered errors. We will not attempt to load them again during
569  // execution of the current public API call, but for compatibility with
570  // legacy clients, this is cleared at the beginning of each public API call.
571  // Not used when fallback_database_ == nullptr.
572  HASH_SET<std::string> known_bad_files_;
573 
574  // A set of symbols which we have tried to load from the fallback database
575  // and encountered errors. We will not attempt to load them again during
576  // execution of the current public API call, but for compatibility with
577  // legacy clients, this is cleared at the beginning of each public API call.
578  HASH_SET<std::string> known_bad_symbols_;
579 
580  // The set of descriptors for which we've already loaded the full
581  // set of extensions numbers from fallback_database_.
582  HASH_SET<const Descriptor*> extensions_loaded_from_db_;
583 
584  // -----------------------------------------------------------------
585  // Finding items.
586 
587  // Find symbols. This returns a null Symbol (symbol.IsNull() is true)
588  // if not found.
589  inline Symbol FindSymbol(const std::string& key) const;
590 
591  // This implements the body of DescriptorPool::Find*ByName(). It should
592  // really be a private method of DescriptorPool, but that would require
593  // declaring Symbol in descriptor.h, which would drag all kinds of other
594  // stuff into the header. Yay C++.
596 
597  // These return nullptr if not found.
598  inline const FileDescriptor* FindFile(const std::string& key) const;
599  inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
600  int number) const;
601  inline void FindAllExtensions(const Descriptor* extendee,
602  std::vector<const FieldDescriptor*>* out) const;
603 
604  // -----------------------------------------------------------------
605  // Adding items.
606 
607  // These add items to the corresponding tables. They return false if
608  // the key already exists in the table. For AddSymbol(), the string passed
609  // in must be one that was constructed using AllocateString(), as it will
610  // be used as a key in the symbols_by_name_ map without copying.
611  bool AddSymbol(const std::string& full_name, Symbol symbol);
612  bool AddFile(const FileDescriptor* file);
613  bool AddExtension(const FieldDescriptor* field);
614 
615  // -----------------------------------------------------------------
616  // Allocating memory.
617 
618  // Allocate an object which will be reclaimed when the pool is
619  // destroyed. Note that the object's destructor will never be called,
620  // so its fields must be plain old data (primitive data types and
621  // pointers). All of the descriptor types are such objects.
622  template <typename Type>
623  Type* Allocate();
624 
625  // Allocate an array of objects which will be reclaimed when the
626  // pool in destroyed. Again, destructors are never called.
627  template <typename Type>
628  Type* AllocateArray(int count);
629 
630  // Allocate a string which will be destroyed when the pool is destroyed.
631  // The string is initialized to the given value for convenience.
633 
634  // Allocate empty string which will be destroyed when the pool is destroyed.
636 
637  // Allocate a internal::call_once which will be destroyed when the pool is
638  // destroyed.
640 
641  // Allocate a protocol message object. Some older versions of GCC have
642  // trouble understanding explicit template instantiations in some cases, so
643  // in those cases we have to pass a dummy pointer of the right type as the
644  // parameter instead of specifying the type explicitly.
645  template <typename Type>
646  Type* AllocateMessage(Type* dummy = nullptr);
647 
648  // Allocate a FileDescriptorTables object.
650 
651  private:
652  std::vector<std::string*> strings_; // All strings in the pool.
653  std::vector<Message*> messages_; // All messages in the pool.
654  std::vector<internal::once_flag*>
655  once_dynamics_; // All internal::call_onces in the pool.
656  std::vector<FileDescriptorTables*>
657  file_tables_; // All file tables in the pool.
658  std::vector<void*> allocations_; // All other memory allocated in the pool.
659 
660  SymbolsByNameMap symbols_by_name_;
661  FilesByNameMap files_by_name_;
662  ExtensionsGroupedByDescriptorMap extensions_;
663 
664  struct CheckPoint {
665  explicit CheckPoint(const Tables* tables)
672  tables->symbols_after_checkpoint_.size()),
674  tables->files_after_checkpoint_.size()),
676  tables->extensions_after_checkpoint_.size()) {}
685  };
686  std::vector<CheckPoint> checkpoints_;
687  std::vector<const char*> symbols_after_checkpoint_;
688  std::vector<const char*> files_after_checkpoint_;
689  std::vector<DescriptorIntPair> extensions_after_checkpoint_;
690 
691  // Allocate some bytes which will be reclaimed when the pool is
692  // destroyed.
693  void* AllocateBytes(int size);
694 };
695 
696 // Contains tables specific to a particular file. These tables are not
697 // modified once the file has been constructed, so they need not be
698 // protected by a mutex. This makes operations that depend only on the
699 // contents of a single file -- e.g. Descriptor::FindFieldByName() --
700 // lock-free.
701 //
702 // For historical reasons, the definitions of the methods of
703 // FileDescriptorTables and DescriptorPool::Tables are interleaved below.
704 // These used to be a single class.
706  public:
709 
710  // Empty table, used with placeholder files.
711  inline static const FileDescriptorTables& GetEmptyInstance();
712 
713  // -----------------------------------------------------------------
714  // Finding items.
715 
716  // Find symbols. These return a null Symbol (symbol.IsNull() is true)
717  // if not found.
718  inline Symbol FindNestedSymbol(const void* parent,
719  const std::string& name) const;
720  inline Symbol FindNestedSymbolOfType(const void* parent,
721  const std::string& name,
722  const Symbol::Type type) const;
723 
724  // These return nullptr if not found.
725  inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent,
726  int number) const;
728  const void* parent, const std::string& lowercase_name) const;
730  const void* parent, const std::string& camelcase_name) const;
732  const EnumDescriptor* parent, int number) const;
733  // This creates a new EnumValueDescriptor if not found, in a thread-safe way.
735  const EnumDescriptor* parent, int number) const;
736 
737  // -----------------------------------------------------------------
738  // Adding items.
739 
740  // These add items to the corresponding tables. They return false if
741  // the key already exists in the table. For AddAliasUnderParent(), the
742  // string passed in must be one that was constructed using AllocateString(),
743  // as it will be used as a key in the symbols_by_parent_ map without copying.
744  bool AddAliasUnderParent(const void* parent, const std::string& name,
745  Symbol symbol);
748 
749  // Adds the field to the lowercase_name and camelcase_name maps. Never
750  // fails because we allow duplicates; the first field by the name wins.
752 
753  // Populates p->first->locations_by_path_ from p->second.
754  // Unusual signature dictated by internal::call_once.
755  static void BuildLocationsByPath(
756  std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
757 
758  // Returns the location denoted by the specified path through info,
759  // or nullptr if not found.
760  // The value of info must be that of the corresponding FileDescriptor.
761  // (Conceptually a pure function, but stateful as an optimisation.)
763  const std::vector<int>& path, const SourceCodeInfo* info) const;
764 
765  // Must be called after BuildFileImpl(), even if the build failed and
766  // we are going to roll back to the last checkpoint.
767  void FinalizeTables();
768 
769  private:
770  const void* FindParentForFieldsByMap(const FieldDescriptor* field) const;
772  const FileDescriptorTables* tables);
775  const FileDescriptorTables* tables);
777 
778  SymbolsByParentMap symbols_by_parent_;
779  mutable FieldsByNameMap fields_by_lowercase_name_;
780  std::unique_ptr<FieldsByNameMap> fields_by_lowercase_name_tmp_;
782  mutable FieldsByNameMap fields_by_camelcase_name_;
783  std::unique_ptr<FieldsByNameMap> fields_by_camelcase_name_tmp_;
785  FieldsByNumberMap fields_by_number_; // Not including extensions.
786  EnumValuesByNumberMap enum_values_by_number_;
787  mutable EnumValuesByNumberMap unknown_enum_values_by_number_
789 
790  // Populated on first request to save space, hence constness games.
792  mutable LocationsByPathMap locations_by_path_;
793 
794  // Mutex to protect the unknown-enum-value map due to dynamic
795  // EnumValueDescriptor creation on unknown values.
796  mutable internal::WrappedMutex unknown_enum_values_mu_;
797 };
798 
800  // Start some hash-map and hash-set objects with a small # of buckets
801  : known_bad_files_(3),
802  known_bad_symbols_(3),
803  extensions_loaded_from_db_(3),
804  symbols_by_name_(3),
805  files_by_name_(3) {}
806 
808  GOOGLE_DCHECK(checkpoints_.empty());
809  // Note that the deletion order is important, since the destructors of some
810  // messages may refer to objects in allocations_.
811  STLDeleteElements(&messages_);
812  for (int i = 0; i < allocations_.size(); i++) {
813  operator delete(allocations_[i]);
814  }
815  STLDeleteElements(&strings_);
816  STLDeleteElements(&file_tables_);
817  STLDeleteElements(&once_dynamics_);
818 }
819 
821  // Initialize all the hash tables to start out with a small # of buckets.
822  : symbols_by_parent_(3),
823  fields_by_lowercase_name_(3),
824  fields_by_lowercase_name_tmp_(new FieldsByNameMap()),
825  fields_by_camelcase_name_(3),
826  fields_by_camelcase_name_tmp_(new FieldsByNameMap()),
827  fields_by_number_(3),
828  enum_values_by_number_(3),
829  unknown_enum_values_by_number_(3),
830  locations_by_path_(3) {}
831 
833 
835  static auto file_descriptor_tables =
837  return *file_descriptor_tables;
838 }
839 
841  checkpoints_.push_back(CheckPoint(this));
842 }
843 
845  GOOGLE_DCHECK(!checkpoints_.empty());
846  checkpoints_.pop_back();
847  if (checkpoints_.empty()) {
848  // All checkpoints have been cleared: we can now commit all of the pending
849  // data.
850  symbols_after_checkpoint_.clear();
851  files_after_checkpoint_.clear();
852  extensions_after_checkpoint_.clear();
853  }
854 }
855 
857  GOOGLE_DCHECK(!checkpoints_.empty());
858  const CheckPoint& checkpoint = checkpoints_.back();
859 
860  for (int i = checkpoint.pending_symbols_before_checkpoint;
861  i < symbols_after_checkpoint_.size(); i++) {
862  symbols_by_name_.erase(symbols_after_checkpoint_[i]);
863  }
864  for (int i = checkpoint.pending_files_before_checkpoint;
865  i < files_after_checkpoint_.size(); i++) {
866  files_by_name_.erase(files_after_checkpoint_[i]);
867  }
868  for (int i = checkpoint.pending_extensions_before_checkpoint;
869  i < extensions_after_checkpoint_.size(); i++) {
870  extensions_.erase(extensions_after_checkpoint_[i]);
871  }
872 
873  symbols_after_checkpoint_.resize(
874  checkpoint.pending_symbols_before_checkpoint);
875  files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
876  extensions_after_checkpoint_.resize(
877  checkpoint.pending_extensions_before_checkpoint);
878 
880  strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end());
882  messages_.begin() + checkpoint.messages_before_checkpoint,
883  messages_.end());
885  once_dynamics_.begin() + checkpoint.once_dynamics_before_checkpoint,
886  once_dynamics_.end());
888  file_tables_.begin() + checkpoint.file_tables_before_checkpoint,
889  file_tables_.end());
890  for (int i = checkpoint.allocations_before_checkpoint;
891  i < allocations_.size(); i++) {
892  operator delete(allocations_[i]);
893  }
894 
895  strings_.resize(checkpoint.strings_before_checkpoint);
896  messages_.resize(checkpoint.messages_before_checkpoint);
897  once_dynamics_.resize(checkpoint.once_dynamics_before_checkpoint);
898  file_tables_.resize(checkpoint.file_tables_before_checkpoint);
899  allocations_.resize(checkpoint.allocations_before_checkpoint);
900  checkpoints_.pop_back();
901 }
902 
903 // -------------------------------------------------------------------
904 
906  const Symbol* result = FindOrNull(symbols_by_name_, key.c_str());
907  if (result == nullptr) {
908  return kNullSymbol;
909  } else {
910  return *result;
911  }
912 }
913 
915  const void* parent, const std::string& name) const {
916  const Symbol* result = FindOrNull(
917  symbols_by_parent_, PointerStringPair(parent, name.c_str()));
918  if (result == nullptr) {
919  return kNullSymbol;
920  } else {
921  return *result;
922  }
923 }
924 
926  const void* parent, const std::string& name,
927  const Symbol::Type type) const {
928  Symbol result = FindNestedSymbol(parent, name);
929  if (result.type != type) return kNullSymbol;
930  return result;
931 }
932 
934  const std::string& name) {
935  MutexLockMaybe lock(pool->mutex_);
936  if (pool->fallback_database_ != nullptr) {
937  known_bad_symbols_.clear();
938  known_bad_files_.clear();
939  }
940  Symbol result = FindSymbol(name);
941 
942  if (result.IsNull() && pool->underlay_ != nullptr) {
943  // Symbol not found; check the underlay.
944  result = pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
945  }
946 
947  if (result.IsNull()) {
948  // Symbol still not found, so check fallback database.
949  if (pool->TryFindSymbolInFallbackDatabase(name)) {
950  result = FindSymbol(name);
951  }
952  }
953 
954  return result;
955 }
956 
958  const std::string& key) const {
959  return FindPtrOrNull(files_by_name_, key.c_str());
960 }
961 
963  const Descriptor* parent, int number) const {
964  return FindPtrOrNull(fields_by_number_, std::make_pair(parent, number));
965 }
966 
968  const FieldDescriptor* field) const {
969  if (field->is_extension()) {
970  if (field->extension_scope() == nullptr) {
971  return field->file();
972  } else {
973  return field->extension_scope();
974  }
975  } else {
976  return field->containing_type();
977  }
978 }
979 
981  const FileDescriptorTables* tables) {
983 }
984 
986  for (FieldsByNumberMap::const_iterator it = fields_by_number_.begin();
987  it != fields_by_number_.end(); it++) {
988  PointerStringPair lowercase_key(FindParentForFieldsByMap(it->second),
989  it->second->lowercase_name().c_str());
990  InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key,
991  it->second);
992  }
993 }
994 
996  const void* parent, const std::string& lowercase_name) const {
998  fields_by_lowercase_name_once_,
1000  return FindPtrOrNull(fields_by_lowercase_name_,
1001  PointerStringPair(parent, lowercase_name.c_str()));
1002 }
1003 
1005  const FileDescriptorTables* tables) {
1007 }
1008 
1010  for (FieldsByNumberMap::const_iterator it = fields_by_number_.begin();
1011  it != fields_by_number_.end(); it++) {
1012  PointerStringPair camelcase_key(FindParentForFieldsByMap(it->second),
1013  it->second->camelcase_name().c_str());
1014  InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key,
1015  it->second);
1016  }
1017 }
1018 
1020  const void* parent, const std::string& camelcase_name) const {
1022  fields_by_camelcase_name_once_,
1024  return FindPtrOrNull(fields_by_camelcase_name_,
1025  PointerStringPair(parent, camelcase_name.c_str()));
1026 }
1027 
1029  const EnumDescriptor* parent, int number) const {
1030  return FindPtrOrNull(enum_values_by_number_,
1031  std::make_pair(parent, number));
1032 }
1033 
1034 inline const EnumValueDescriptor*
1036  const EnumDescriptor* parent, int number) const {
1037  // First try, with map of compiled-in values.
1038  {
1040  enum_values_by_number_, std::make_pair(parent, number));
1041  if (desc != nullptr) {
1042  return desc;
1043  }
1044  }
1045  // Second try, with reader lock held on unknown enum values: common case.
1046  {
1047  ReaderMutexLock l(&unknown_enum_values_mu_);
1049  unknown_enum_values_by_number_, std::make_pair(parent, number));
1050  if (desc != nullptr) {
1051  return desc;
1052  }
1053  }
1054  // If not found, try again with writer lock held, and create new descriptor if
1055  // necessary.
1056  {
1057  WriterMutexLock l(&unknown_enum_values_mu_);
1059  unknown_enum_values_by_number_, std::make_pair(parent, number));
1060  if (desc != nullptr) {
1061  return desc;
1062  }
1063 
1064  // Create an EnumValueDescriptor dynamically. We don't insert it into the
1065  // EnumDescriptor (it's not a part of the enum as originally defined), but
1066  // we do insert it into the table so that we can return the same pointer
1067  // later.
1068  std::string enum_value_name = StringPrintf("UNKNOWN_ENUM_VALUE_%s_%d",
1069  parent->name().c_str(), number);
1070  DescriptorPool::Tables* tables = const_cast<DescriptorPool::Tables*>(
1072  EnumValueDescriptor* result = tables->Allocate<EnumValueDescriptor>();
1073  result->name_ = tables->AllocateString(enum_value_name);
1074  result->full_name_ =
1075  tables->AllocateString(parent->full_name() + "." + enum_value_name);
1076  result->number_ = number;
1077  result->type_ = parent;
1079  InsertIfNotPresent(&unknown_enum_values_by_number_,
1080  std::make_pair(parent, number), result);
1081  return result;
1082  }
1083 }
1084 
1086  const Descriptor* extendee, int number) const {
1087  return FindPtrOrNull(extensions_, std::make_pair(extendee, number));
1088 }
1089 
1091  const Descriptor* extendee,
1092  std::vector<const FieldDescriptor*>* out) const {
1093  ExtensionsGroupedByDescriptorMap::const_iterator it =
1094  extensions_.lower_bound(std::make_pair(extendee, 0));
1095  for (; it != extensions_.end() && it->first.first == extendee; ++it) {
1096  out->push_back(it->second);
1097  }
1098 }
1099 
1100 // -------------------------------------------------------------------
1101 
1103  Symbol symbol) {
1104  if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) {
1105  symbols_after_checkpoint_.push_back(full_name.c_str());
1106  return true;
1107  } else {
1108  return false;
1109  }
1110 }
1111 
1113  const std::string& name,
1114  Symbol symbol) {
1115  PointerStringPair by_parent_key(parent, name.c_str());
1116  return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol);
1117 }
1118 
1120  if (InsertIfNotPresent(&files_by_name_, file->name().c_str(), file)) {
1121  files_after_checkpoint_.push_back(file->name().c_str());
1122  return true;
1123  } else {
1124  return false;
1125  }
1126 }
1127 
1129  // Clean up the temporary maps used by AddFieldByStylizedNames().
1130  fields_by_lowercase_name_tmp_ = nullptr;
1131  fields_by_camelcase_name_tmp_ = nullptr;
1132 }
1133 
1135  const FieldDescriptor* field) {
1136  const void* parent = FindParentForFieldsByMap(field);
1137 
1138  // We want fields_by_{lower,camel}case_name_ to be lazily built, but
1139  // cross-link order determines which entry will be present in the case of a
1140  // conflict. So we use the temporary maps that get destroyed after
1141  // BuildFileImpl() to detect the conflicts, and only store the conflicts in
1142  // the map that will persist. We will then lazily populate the rest of the
1143  // entries from fields_by_number_.
1144 
1145  PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
1146  if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(),
1147  lowercase_key, field)) {
1149  &fields_by_lowercase_name_, lowercase_key,
1150  FindPtrOrNull(*fields_by_lowercase_name_tmp_, lowercase_key));
1151  }
1152 
1153  PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
1154  if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(),
1155  camelcase_key, field)) {
1157  &fields_by_camelcase_name_, camelcase_key,
1158  FindPtrOrNull(*fields_by_camelcase_name_tmp_, camelcase_key));
1159  }
1160 }
1161 
1163  DescriptorIntPair key(field->containing_type(), field->number());
1164  return InsertIfNotPresent(&fields_by_number_, key, field);
1165 }
1166 
1168  const EnumValueDescriptor* value) {
1169  EnumIntPair key(value->type(), value->number());
1170  return InsertIfNotPresent(&enum_values_by_number_, key, value);
1171 }
1172 
1174  DescriptorIntPair key(field->containing_type(), field->number());
1175  if (InsertIfNotPresent(&extensions_, key, field)) {
1176  extensions_after_checkpoint_.push_back(key);
1177  return true;
1178  } else {
1179  return false;
1180  }
1181 }
1182 
1183 // -------------------------------------------------------------------
1184 
1185 template <typename Type>
1187  return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type)));
1188 }
1189 
1190 template <typename Type>
1192  return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count));
1193 }
1194 
1196  std::string* result = new std::string(value);
1197  strings_.push_back(result);
1198  return result;
1199 }
1200 
1202  std::string* result = new std::string();
1203  strings_.push_back(result);
1204  return result;
1205 }
1206 
1208  internal::once_flag* result = new internal::once_flag();
1209  once_dynamics_.push_back(result);
1210  return result;
1211 }
1212 
1213 template <typename Type>
1215  Type* result = new Type;
1216  messages_.push_back(result);
1217  return result;
1218 }
1219 
1222  file_tables_.push_back(result);
1223  return result;
1224 }
1225 
1227  // TODO(kenton): Would it be worthwhile to implement this in some more
1228  // sophisticated way? Probably not for the open source release, but for
1229  // internal use we could easily plug in one of our existing memory pool
1230  // allocators...
1231  if (size == 0) return nullptr;
1232 
1233  void* result = operator new(size);
1234  allocations_.push_back(result);
1235  return result;
1236 }
1237 
1239  std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
1240  for (int i = 0, len = p->second->location_size(); i < len; ++i) {
1241  const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
1242  p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
1243  }
1244 }
1245 
1247  const std::vector<int>& path, const SourceCodeInfo* info) const {
1248  std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
1249  std::make_pair(this, info));
1250  internal::call_once(locations_by_path_once_,
1252  return FindPtrOrNull(locations_by_path_, Join(path, ","));
1253 }
1254 
1255 // ===================================================================
1256 // DescriptorPool
1257 
1259 
1261  : mutex_(nullptr),
1262  fallback_database_(nullptr),
1263  default_error_collector_(nullptr),
1264  underlay_(nullptr),
1265  tables_(new Tables),
1271 
1273  ErrorCollector* error_collector)
1274  : mutex_(new internal::WrappedMutex),
1275  fallback_database_(fallback_database),
1276  default_error_collector_(error_collector),
1277  underlay_(nullptr),
1278  tables_(new Tables),
1279  enforce_dependencies_(true),
1280  lazily_build_dependencies_(false),
1281  allow_unknown_(false),
1282  enforce_weak_(false),
1283  disallow_enforce_utf8_(false) {}
1284 
1286  : mutex_(nullptr),
1287  fallback_database_(nullptr),
1288  default_error_collector_(nullptr),
1289  underlay_(underlay),
1290  tables_(new Tables),
1291  enforce_dependencies_(true),
1292  lazily_build_dependencies_(false),
1293  allow_unknown_(false),
1294  enforce_weak_(false),
1295  disallow_enforce_utf8_(false) {}
1296 
1298  if (mutex_ != nullptr) delete mutex_;
1299 }
1300 
1301 // DescriptorPool::BuildFile() defined later.
1302 // DescriptorPool::BuildFileCollectingErrors() defined later.
1303 
1305  enforce_dependencies_ = false;
1306 }
1307 
1309  unused_import_track_files_.insert(file_name);
1310 }
1311 
1314 }
1315 
1317  MutexLockMaybe lock(mutex_);
1318  return tables_->FindFile(filename) != nullptr;
1319 }
1320 
1321 // generated_pool ====================================================
1322 
1323 namespace {
1324 
1325 
1326 EncodedDescriptorDatabase* GeneratedDatabase() {
1327  static auto generated_database =
1329  return generated_database;
1330 }
1331 
1332 DescriptorPool* NewGeneratedPool() {
1333  auto generated_pool = new DescriptorPool(GeneratedDatabase());
1334  generated_pool->InternalSetLazilyBuildDependencies();
1335  return generated_pool;
1336 }
1337 
1338 } // anonymous namespace
1339 
1341  static DescriptorPool* generated_pool =
1342  internal::OnShutdownDelete(NewGeneratedPool());
1343  return generated_pool;
1344 }
1345 
1348  // Ensure that descriptor.proto has been registered in the generated pool.
1350  return pool;
1351 }
1352 
1353 
1354 
1356  const void* encoded_file_descriptor, int size) {
1357  // So, this function is called in the process of initializing the
1358  // descriptors for generated proto classes. Each generated .pb.cc file
1359  // has an internal procedure called AddDescriptors() which is called at
1360  // process startup, and that function calls this one in order to register
1361  // the raw bytes of the FileDescriptorProto representing the file.
1362  //
1363  // We do not actually construct the descriptor objects right away. We just
1364  // hang on to the bytes until they are actually needed. We actually construct
1365  // the descriptor the first time one of the following things happens:
1366  // * Someone calls a method like descriptor(), GetDescriptor(), or
1367  // GetReflection() on the generated types, which requires returning the
1368  // descriptor or an object based on it.
1369  // * Someone looks up the descriptor in DescriptorPool::generated_pool().
1370  //
1371  // Once one of these happens, the DescriptorPool actually parses the
1372  // FileDescriptorProto and generates a FileDescriptor (and all its children)
1373  // based on it.
1374  //
1375  // Note that FileDescriptorProto is itself a generated protocol message.
1376  // Therefore, when we parse one, we have to be very careful to avoid using
1377  // any descriptor-based operations, since this might cause infinite recursion
1378  // or deadlock.
1379  GOOGLE_CHECK(GeneratedDatabase()->Add(encoded_file_descriptor, size));
1380 }
1381 
1382 
1383 // Find*By* methods ==================================================
1384 
1385 // TODO(kenton): There's a lot of repeated code here, but I'm not sure if
1386 // there's any good way to factor it out. Think about this some time when
1387 // there's nothing more important to do (read: never).
1388 
1390  const std::string& name) const {
1391  MutexLockMaybe lock(mutex_);
1392  if (fallback_database_ != nullptr) {
1393  tables_->known_bad_symbols_.clear();
1394  tables_->known_bad_files_.clear();
1395  }
1396  const FileDescriptor* result = tables_->FindFile(name);
1397  if (result != nullptr) return result;
1398  if (underlay_ != nullptr) {
1399  result = underlay_->FindFileByName(name);
1400  if (result != nullptr) return result;
1401  }
1403  result = tables_->FindFile(name);
1404  if (result != nullptr) return result;
1405  }
1406  return nullptr;
1407 }
1408 
1410  const std::string& symbol_name) const {
1411  MutexLockMaybe lock(mutex_);
1412  if (fallback_database_ != nullptr) {
1413  tables_->known_bad_symbols_.clear();
1414  tables_->known_bad_files_.clear();
1415  }
1416  Symbol result = tables_->FindSymbol(symbol_name);
1417  if (!result.IsNull()) return result.GetFile();
1418  if (underlay_ != nullptr) {
1419  const FileDescriptor* file_result =
1420  underlay_->FindFileContainingSymbol(symbol_name);
1421  if (file_result != nullptr) return file_result;
1422  }
1423  if (TryFindSymbolInFallbackDatabase(symbol_name)) {
1424  result = tables_->FindSymbol(symbol_name);
1425  if (!result.IsNull()) return result.GetFile();
1426  }
1427  return nullptr;
1428 }
1429 
1431  const std::string& name) const {
1432  Symbol result = tables_->FindByNameHelper(this, name);
1433  return (result.type == Symbol::MESSAGE) ? result.descriptor : nullptr;
1434 }
1435 
1437  const std::string& name) const {
1438  Symbol result = tables_->FindByNameHelper(this, name);
1439  if (result.type == Symbol::FIELD &&
1440  !result.field_descriptor->is_extension()) {
1441  return result.field_descriptor;
1442  } else {
1443  return nullptr;
1444  }
1445 }
1446 
1448  const std::string& name) const {
1449  Symbol result = tables_->FindByNameHelper(this, name);
1450  if (result.type == Symbol::FIELD && result.field_descriptor->is_extension()) {
1451  return result.field_descriptor;
1452  } else {
1453  return nullptr;
1454  }
1455 }
1456 
1458  const std::string& name) const {
1459  Symbol result = tables_->FindByNameHelper(this, name);
1460  return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : nullptr;
1461 }
1462 
1464  const std::string& name) const {
1465  Symbol result = tables_->FindByNameHelper(this, name);
1466  return (result.type == Symbol::ENUM) ? result.enum_descriptor : nullptr;
1467 }
1468 
1470  const std::string& name) const {
1471  Symbol result = tables_->FindByNameHelper(this, name);
1472  return (result.type == Symbol::ENUM_VALUE) ? result.enum_value_descriptor
1473  : nullptr;
1474 }
1475 
1477  const std::string& name) const {
1478  Symbol result = tables_->FindByNameHelper(this, name);
1479  return (result.type == Symbol::SERVICE) ? result.service_descriptor : nullptr;
1480 }
1481 
1483  const std::string& name) const {
1484  Symbol result = tables_->FindByNameHelper(this, name);
1485  return (result.type == Symbol::METHOD) ? result.method_descriptor : nullptr;
1486 }
1487 
1489  const Descriptor* extendee, int number) const {
1490  if (extendee->extension_range_count() == 0) return nullptr;
1491  // A faster path to reduce lock contention in finding extensions, assuming
1492  // most extensions will be cache hit.
1493  if (mutex_ != nullptr) {
1494  ReaderMutexLock lock(mutex_);
1495  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
1496  if (result != nullptr) {
1497  return result;
1498  }
1499  }
1500  MutexLockMaybe lock(mutex_);
1501  if (fallback_database_ != nullptr) {
1502  tables_->known_bad_symbols_.clear();
1503  tables_->known_bad_files_.clear();
1504  }
1505  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
1506  if (result != nullptr) {
1507  return result;
1508  }
1509  if (underlay_ != nullptr) {
1510  result = underlay_->FindExtensionByNumber(extendee, number);
1511  if (result != nullptr) return result;
1512  }
1513  if (TryFindExtensionInFallbackDatabase(extendee, number)) {
1514  result = tables_->FindExtension(extendee, number);
1515  if (result != nullptr) {
1516  return result;
1517  }
1518  }
1519  return nullptr;
1520 }
1521 
1523  const Descriptor* extendee, const std::string& printable_name) const {
1524  if (extendee->extension_range_count() == 0) return nullptr;
1525  const FieldDescriptor* result = FindExtensionByName(printable_name);
1526  if (result != nullptr && result->containing_type() == extendee) {
1527  return result;
1528  }
1529  if (extendee->options().message_set_wire_format()) {
1530  // MessageSet extensions may be identified by type name.
1531  const Descriptor* type = FindMessageTypeByName(printable_name);
1532  if (type != nullptr) {
1533  // Look for a matching extension in the foreign type's scope.
1534  const int type_extension_count = type->extension_count();
1535  for (int i = 0; i < type_extension_count; i++) {
1536  const FieldDescriptor* extension = type->extension(i);
1537  if (extension->containing_type() == extendee &&
1539  extension->is_optional() && extension->message_type() == type) {
1540  // Found it.
1541  return extension;
1542  }
1543  }
1544  }
1545  }
1546  return nullptr;
1547 }
1548 
1550  const Descriptor* extendee,
1551  std::vector<const FieldDescriptor*>* out) const {
1552  MutexLockMaybe lock(mutex_);
1553  if (fallback_database_ != nullptr) {
1554  tables_->known_bad_symbols_.clear();
1555  tables_->known_bad_files_.clear();
1556  }
1557 
1558  // Initialize tables_->extensions_ from the fallback database first
1559  // (but do this only once per descriptor).
1560  if (fallback_database_ != nullptr &&
1561  tables_->extensions_loaded_from_db_.count(extendee) == 0) {
1562  std::vector<int> numbers;
1564  &numbers)) {
1565  for (int i = 0; i < numbers.size(); ++i) {
1566  int number = numbers[i];
1567  if (tables_->FindExtension(extendee, number) == nullptr) {
1569  }
1570  }
1571  tables_->extensions_loaded_from_db_.insert(extendee);
1572  }
1573  }
1574 
1575  tables_->FindAllExtensions(extendee, out);
1576  if (underlay_ != nullptr) {
1577  underlay_->FindAllExtensions(extendee, out);
1578  }
1579 }
1580 
1581 
1582 // -------------------------------------------------------------------
1583 
1585  const FieldDescriptor* result = file()->tables_->FindFieldByNumber(this, key);
1586  if (result == nullptr || result->is_extension()) {
1587  return nullptr;
1588  } else {
1589  return result;
1590  }
1591 }
1592 
1594  const std::string& key) const {
1595  const FieldDescriptor* result =
1597  if (result == nullptr || result->is_extension()) {
1598  return nullptr;
1599  } else {
1600  return result;
1601  }
1602 }
1603 
1605  const std::string& key) const {
1606  const FieldDescriptor* result =
1608  if (result == nullptr || result->is_extension()) {
1609  return nullptr;
1610  } else {
1611  return result;
1612  }
1613 }
1614 
1616  const std::string& key) const {
1617  Symbol result =
1619  if (!result.IsNull() && !result.field_descriptor->is_extension()) {
1620  return result.field_descriptor;
1621  } else {
1622  return nullptr;
1623  }
1624 }
1625 
1627  const std::string& key) const {
1628  Symbol result =
1630  if (!result.IsNull()) {
1631  return result.oneof_descriptor;
1632  } else {
1633  return nullptr;
1634  }
1635 }
1636 
1638  const std::string& key) const {
1639  Symbol result =
1641  if (!result.IsNull() && result.field_descriptor->is_extension()) {
1642  return result.field_descriptor;
1643  } else {
1644  return nullptr;
1645  }
1646 }
1647 
1649  const std::string& key) const {
1650  const FieldDescriptor* result =
1652  if (result == nullptr || !result->is_extension()) {
1653  return nullptr;
1654  } else {
1655  return result;
1656  }
1657 }
1658 
1660  const std::string& key) const {
1661  const FieldDescriptor* result =
1663  if (result == nullptr || !result->is_extension()) {
1664  return nullptr;
1665  } else {
1666  return result;
1667  }
1668 }
1669 
1671  const std::string& key) const {
1672  Symbol result =
1674  if (!result.IsNull()) {
1675  return result.descriptor;
1676  } else {
1677  return nullptr;
1678  }
1679 }
1680 
1682  const std::string& key) const {
1683  Symbol result =
1685  if (!result.IsNull()) {
1686  return result.enum_descriptor;
1687  } else {
1688  return nullptr;
1689  }
1690 }
1691 
1693  const std::string& key) const {
1694  Symbol result =
1696  if (!result.IsNull()) {
1697  return result.enum_value_descriptor;
1698  } else {
1699  return nullptr;
1700  }
1701 }
1702 
1704  const std::string& key) const {
1705  Symbol result =
1707  if (!result.IsNull()) {
1708  return result.enum_value_descriptor;
1709  } else {
1710  return nullptr;
1711  }
1712 }
1713 
1715  return file()->tables_->FindEnumValueByNumber(this, key);
1716 }
1717 
1719  int key) const {
1721 }
1722 
1724  const std::string& key) const {
1725  Symbol result =
1727  if (!result.IsNull()) {
1728  return result.method_descriptor;
1729  } else {
1730  return nullptr;
1731  }
1732 }
1733 
1735  const std::string& key) const {
1737  if (!result.IsNull()) {
1738  return result.descriptor;
1739  } else {
1740  return nullptr;
1741  }
1742 }
1743 
1745  const std::string& key) const {
1747  if (!result.IsNull()) {
1748  return result.enum_descriptor;
1749  } else {
1750  return nullptr;
1751  }
1752 }
1753 
1755  const std::string& key) const {
1756  Symbol result =
1758  if (!result.IsNull()) {
1759  return result.enum_value_descriptor;
1760  } else {
1761  return nullptr;
1762  }
1763 }
1764 
1766  const std::string& key) const {
1768  if (!result.IsNull()) {
1769  return result.service_descriptor;
1770  } else {
1771  return nullptr;
1772  }
1773 }
1774 
1776  const std::string& key) const {
1778  if (!result.IsNull() && result.field_descriptor->is_extension()) {
1779  return result.field_descriptor;
1780  } else {
1781  return nullptr;
1782  }
1783 }
1784 
1786  const std::string& key) const {
1787  const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
1788  if (result == nullptr || !result->is_extension()) {
1789  return nullptr;
1790  } else {
1791  return result;
1792  }
1793 }
1794 
1796  const std::string& key) const {
1797  const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
1798  if (result == nullptr || !result->is_extension()) {
1799  return nullptr;
1800  } else {
1801  return result;
1802  }
1803 }
1804 
1806  DescriptorProto_ExtensionRange* proto) const {
1807  proto->set_start(this->start);
1808  proto->set_end(this->end);
1810  *proto->mutable_options() = *options_;
1811  }
1812 }
1813 
1814 const Descriptor::ExtensionRange*
1816  // Linear search should be fine because we don't expect a message to have
1817  // more than a couple extension ranges.
1818  for (int i = 0; i < extension_range_count(); i++) {
1819  if (number >= extension_range(i)->start &&
1820  number < extension_range(i)->end) {
1821  return extension_range(i);
1822  }
1823  }
1824  return nullptr;
1825 }
1826 
1827 const Descriptor::ReservedRange* Descriptor::FindReservedRangeContainingNumber(
1828  int number) const {
1829  // TODO(chrisn): Consider a non-linear search.
1830  for (int i = 0; i < reserved_range_count(); i++) {
1831  if (number >= reserved_range(i)->start && number < reserved_range(i)->end) {
1832  return reserved_range(i);
1833  }
1834  }
1835  return nullptr;
1836 }
1837 
1838 const EnumDescriptor::ReservedRange*
1840  // TODO(chrisn): Consider a non-linear search.
1841  for (int i = 0; i < reserved_range_count(); i++) {
1842  if (number >= reserved_range(i)->start &&
1843  number <= reserved_range(i)->end) {
1844  return reserved_range(i);
1845  }
1846  }
1847  return nullptr;
1848 }
1849 
1850 // -------------------------------------------------------------------
1851 
1853  const std::string& name) const {
1854  if (fallback_database_ == nullptr) return false;
1855 
1856  if (tables_->known_bad_files_.count(name) > 0) return false;
1857 
1858  FileDescriptorProto file_proto;
1859  if (!fallback_database_->FindFileByName(name, &file_proto) ||
1860  BuildFileFromDatabase(file_proto) == nullptr) {
1861  tables_->known_bad_files_.insert(name);
1862  return false;
1863  }
1864  return true;
1865 }
1866 
1869  for (;;) {
1870  std::string::size_type dot_pos = prefix.find_last_of('.');
1871  if (dot_pos == std::string::npos) {
1872  break;
1873  }
1874  prefix = prefix.substr(0, dot_pos);
1875  Symbol symbol = tables_->FindSymbol(prefix);
1876  // If the symbol type is anything other than PACKAGE, then its complete
1877  // definition is already known.
1878  if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) {
1879  return true;
1880  }
1881  }
1882  if (underlay_ != nullptr) {
1883  // Check to see if any prefix of this symbol exists in the underlay.
1884  return underlay_->IsSubSymbolOfBuiltType(name);
1885  }
1886  return false;
1887 }
1888 
1890  const std::string& name) const {
1891  if (fallback_database_ == nullptr) return false;
1892 
1893  if (tables_->known_bad_symbols_.count(name) > 0) return false;
1894 
1895  FileDescriptorProto file_proto;
1896  if ( // We skip looking in the fallback database if the name is a sub-symbol
1897  // of any descriptor that already exists in the descriptor pool (except
1898  // for package descriptors). This is valid because all symbols except
1899  // for packages are defined in a single file, so if the symbol exists
1900  // then we should already have its definition.
1901  //
1902  // The other reason to do this is to support "overriding" type
1903  // definitions by merging two databases that define the same type. (Yes,
1904  // people do this.) The main difficulty with making this work is that
1905  // FindFileContainingSymbol() is allowed to return both false positives
1906  // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and
1907  // false negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
1908  // When two such databases are merged, looking up a non-existent
1909  // sub-symbol of a type that already exists in the descriptor pool can
1910  // result in an attempt to load multiple definitions of the same type.
1911  // The check below avoids this.
1912  IsSubSymbolOfBuiltType(name)
1913 
1914  // Look up file containing this symbol in fallback database.
1915  || !fallback_database_->FindFileContainingSymbol(name, &file_proto)
1916 
1917  // Check if we've already built this file. If so, it apparently doesn't
1918  // contain the symbol we're looking for. Some DescriptorDatabases
1919  // return false positives.
1920  || tables_->FindFile(file_proto.name()) != nullptr
1921 
1922  // Build the file.
1923  || BuildFileFromDatabase(file_proto) == nullptr) {
1924  tables_->known_bad_symbols_.insert(name);
1925  return false;
1926  }
1927 
1928  return true;
1929 }
1930 
1932  const Descriptor* containing_type, int field_number) const {
1933  if (fallback_database_ == nullptr) return false;
1934 
1935  FileDescriptorProto file_proto;
1936  if (!fallback_database_->FindFileContainingExtension(
1937  containing_type->full_name(), field_number, &file_proto)) {
1938  return false;
1939  }
1940 
1941  if (tables_->FindFile(file_proto.name()) != nullptr) {
1942  // We've already loaded this file, and it apparently doesn't contain the
1943  // extension we're looking for. Some DescriptorDatabases return false
1944  // positives.
1945  return false;
1946  }
1947 
1948  if (BuildFileFromDatabase(file_proto) == nullptr) {
1949  return false;
1950  }
1951 
1952  return true;
1953 }
1954 
1955 // ===================================================================
1956 
1958  return message_type_->options().map_entry();
1959 }
1960 
1962  bool quote_string_type) const {
1963  GOOGLE_CHECK(has_default_value()) << "No default value";
1964  switch (cpp_type()) {
1965  case CPPTYPE_INT32:
1966  return StrCat(default_value_int32());
1967  break;
1968  case CPPTYPE_INT64:
1969  return StrCat(default_value_int64());
1970  break;
1971  case CPPTYPE_UINT32:
1972  return StrCat(default_value_uint32());
1973  break;
1974  case CPPTYPE_UINT64:
1975  return StrCat(default_value_uint64());
1976  break;
1977  case CPPTYPE_FLOAT:
1978  return SimpleFtoa(default_value_float());
1979  break;
1980  case CPPTYPE_DOUBLE:
1981  return SimpleDtoa(default_value_double());
1982  break;
1983  case CPPTYPE_BOOL:
1984  return default_value_bool() ? "true" : "false";
1985  break;
1986  case CPPTYPE_STRING:
1987  if (quote_string_type) {
1988  return "\"" + CEscape(default_value_string()) + "\"";
1989  } else {
1990  if (type() == TYPE_BYTES) {
1991  return CEscape(default_value_string());
1992  } else {
1993  return default_value_string();
1994  }
1995  }
1996  break;
1997  case CPPTYPE_ENUM:
1998  return default_value_enum()->name();
1999  break;
2000  case CPPTYPE_MESSAGE:
2001  GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
2002  break;
2003  }
2004  GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string";
2005  return "";
2006 }
2007 
2008 // CopyTo methods ====================================================
2009 
2011  proto->set_name(name());
2012  if (!package().empty()) proto->set_package(package());
2013  // TODO(liujisi): Also populate when syntax="proto2".
2014  if (syntax() == SYNTAX_PROTO3) proto->set_syntax(SyntaxName(syntax()));
2015 
2016  for (int i = 0; i < dependency_count(); i++) {
2017  proto->add_dependency(dependency(i)->name());
2018  }
2019 
2020  for (int i = 0; i < public_dependency_count(); i++) {
2021  proto->add_public_dependency(public_dependencies_[i]);
2022  }
2023 
2024  for (int i = 0; i < weak_dependency_count(); i++) {
2025  proto->add_weak_dependency(weak_dependencies_[i]);
2026  }
2027 
2028  for (int i = 0; i < message_type_count(); i++) {
2029  message_type(i)->CopyTo(proto->add_message_type());
2030  }
2031  for (int i = 0; i < enum_type_count(); i++) {
2032  enum_type(i)->CopyTo(proto->add_enum_type());
2033  }
2034  for (int i = 0; i < service_count(); i++) {
2035  service(i)->CopyTo(proto->add_service());
2036  }
2037  for (int i = 0; i < extension_count(); i++) {
2038  extension(i)->CopyTo(proto->add_extension());
2039  }
2040 
2041  if (&options() != &FileOptions::default_instance()) {
2042  proto->mutable_options()->CopyFrom(options());
2043  }
2044 }
2045 
2047  if (message_type_count() != proto->message_type_size() ||
2048  extension_count() != proto->extension_size()) {
2049  GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size.";
2050  return;
2051  }
2052  for (int i = 0; i < message_type_count(); i++) {
2053  message_type(i)->CopyJsonNameTo(proto->mutable_message_type(i));
2054  }
2055  for (int i = 0; i < extension_count(); i++) {
2057  }
2058 }
2059 
2061  if (source_code_info_ &&
2062  source_code_info_ != &SourceCodeInfo::default_instance()) {
2063  proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
2064  }
2065 }
2066 
2068  proto->set_name(name());
2069 
2070  for (int i = 0; i < field_count(); i++) {
2071  field(i)->CopyTo(proto->add_field());
2072  }
2073  for (int i = 0; i < oneof_decl_count(); i++) {
2074  oneof_decl(i)->CopyTo(proto->add_oneof_decl());
2075  }
2076  for (int i = 0; i < nested_type_count(); i++) {
2077  nested_type(i)->CopyTo(proto->add_nested_type());
2078  }
2079  for (int i = 0; i < enum_type_count(); i++) {
2080  enum_type(i)->CopyTo(proto->add_enum_type());
2081  }
2082  for (int i = 0; i < extension_range_count(); i++) {
2084  }
2085  for (int i = 0; i < extension_count(); i++) {
2086  extension(i)->CopyTo(proto->add_extension());
2087  }
2088  for (int i = 0; i < reserved_range_count(); i++) {
2090  range->set_start(reserved_range(i)->start);
2091  range->set_end(reserved_range(i)->end);
2092  }
2093  for (int i = 0; i < reserved_name_count(); i++) {
2095  }
2096 
2098  proto->mutable_options()->CopyFrom(options());
2099  }
2100 }
2101 
2103  if (field_count() != proto->field_size() ||
2104  nested_type_count() != proto->nested_type_size() ||
2105  extension_count() != proto->extension_size()) {
2106  GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size.";
2107  return;
2108  }
2109  for (int i = 0; i < field_count(); i++) {
2110  field(i)->CopyJsonNameTo(proto->mutable_field(i));
2111  }
2112  for (int i = 0; i < nested_type_count(); i++) {
2114  }
2115  for (int i = 0; i < extension_count(); i++) {
2117  }
2118 }
2119 
2121  proto->set_name(name());
2122  proto->set_number(number());
2123  if (has_json_name_) {
2124  proto->set_json_name(json_name());
2125  }
2126 
2127  // Some compilers do not allow static_cast directly between two enum types,
2128  // so we must cast to int first.
2129  proto->set_label(static_cast<FieldDescriptorProto::Label>(
2130  implicit_cast<int>(label())));
2131  proto->set_type(static_cast<FieldDescriptorProto::Type>(
2132  implicit_cast<int>(type())));
2133 
2134  if (is_extension()) {
2136  proto->set_extendee(".");
2137  }
2138  proto->mutable_extendee()->append(containing_type()->full_name());
2139  }
2140 
2141  if (cpp_type() == CPPTYPE_MESSAGE) {
2142  if (message_type()->is_placeholder_) {
2143  // We don't actually know if the type is a message type. It could be
2144  // an enum.
2145  proto->clear_type();
2146  }
2147 
2149  proto->set_type_name(".");
2150  }
2151  proto->mutable_type_name()->append(message_type()->full_name());
2152  } else if (cpp_type() == CPPTYPE_ENUM) {
2154  proto->set_type_name(".");
2155  }
2156  proto->mutable_type_name()->append(enum_type()->full_name());
2157  }
2158 
2159  if (has_default_value()) {
2160  proto->set_default_value(DefaultValueAsString(false));
2161  }
2162 
2163  if (containing_oneof() != nullptr && !is_extension()) {
2164  proto->set_oneof_index(containing_oneof()->index());
2165  }
2166 
2167  if (&options() != &FieldOptions::default_instance()) {
2168  proto->mutable_options()->CopyFrom(options());
2169  }
2170 }
2171 
2173  proto->set_json_name(json_name());
2174 }
2175 
2177  proto->set_name(name());
2178  if (&options() != &OneofOptions::default_instance()) {
2179  proto->mutable_options()->CopyFrom(options());
2180  }
2181 }
2182 
2184  proto->set_name(name());
2185 
2186  for (int i = 0; i < value_count(); i++) {
2187  value(i)->CopyTo(proto->add_value());
2188  }
2189  for (int i = 0; i < reserved_range_count(); i++) {
2191  range->set_start(reserved_range(i)->start);
2192  range->set_end(reserved_range(i)->end);
2193  }
2194  for (int i = 0; i < reserved_name_count(); i++) {
2196  }
2197 
2198  if (&options() != &EnumOptions::default_instance()) {
2199  proto->mutable_options()->CopyFrom(options());
2200  }
2201 }
2202 
2204  proto->set_name(name());
2205  proto->set_number(number());
2206 
2208  proto->mutable_options()->CopyFrom(options());
2209  }
2210 }
2211 
2213  proto->set_name(name());
2214 
2215  for (int i = 0; i < method_count(); i++) {
2216  method(i)->CopyTo(proto->add_method());
2217  }
2218 
2220  proto->mutable_options()->CopyFrom(options());
2221  }
2222 }
2223 
2225  proto->set_name(name());
2226 
2227  if (!input_type()->is_unqualified_placeholder_) {
2228  proto->set_input_type(".");
2229  }
2230  proto->mutable_input_type()->append(input_type()->full_name());
2231 
2232  if (!output_type()->is_unqualified_placeholder_) {
2233  proto->set_output_type(".");
2234  }
2235  proto->mutable_output_type()->append(output_type()->full_name());
2236 
2238  proto->mutable_options()->CopyFrom(options());
2239  }
2240 
2241  if (client_streaming_) {
2242  proto->set_client_streaming(true);
2243  }
2244  if (server_streaming_) {
2245  proto->set_server_streaming(true);
2246  }
2247 }
2248 
2249 // DebugString methods ===============================================
2250 
2251 namespace {
2252 
2253 bool RetrieveOptionsAssumingRightPool(
2254  int depth, const Message& options,
2255  std::vector<std::string>* option_entries) {
2256  option_entries->clear();
2257  const Reflection* reflection = options.GetReflection();
2258  std::vector<const FieldDescriptor*> fields;
2259  reflection->ListFields(options, &fields);
2260  for (int i = 0; i < fields.size(); i++) {
2261  int count = 1;
2262  bool repeated = false;
2263  if (fields[i]->is_repeated()) {
2264  count = reflection->FieldSize(options, fields[i]);
2265  repeated = true;
2266  }
2267  for (int j = 0; j < count; j++) {
2268  std::string fieldval;
2270  std::string tmp;
2271  TextFormat::Printer printer;
2272  printer.SetInitialIndentLevel(depth + 1);
2273  printer.PrintFieldValueToString(options, fields[i], repeated ? j : -1,
2274  &tmp);
2275  fieldval.append("{\n");
2276  fieldval.append(tmp);
2277  fieldval.append(depth * 2, ' ');
2278  fieldval.append("}");
2279  } else {
2281  repeated ? j : -1, &fieldval);
2282  }
2283  std::string name;
2284  if (fields[i]->is_extension()) {
2285  name = "(." + fields[i]->full_name() + ")";
2286  } else {
2287  name = fields[i]->name();
2288  }
2289  option_entries->push_back(name + " = " + fieldval);
2290  }
2291  }
2292  return !option_entries->empty();
2293 }
2294 
2295 // Used by each of the option formatters.
2296 bool RetrieveOptions(int depth, const Message& options,
2297  const DescriptorPool* pool,
2298  std::vector<std::string>* option_entries) {
2299  // When printing custom options for a descriptor, we must use an options
2300  // message built on top of the same DescriptorPool where the descriptor
2301  // is coming from. This is to ensure we are interpreting custom options
2302  // against the right pool.
2303  if (options.GetDescriptor()->file()->pool() == pool) {
2304  return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
2305  } else {
2306  const Descriptor* option_descriptor =
2307  pool->FindMessageTypeByName(options.GetDescriptor()->full_name());
2308  if (option_descriptor == nullptr) {
2309  // descriptor.proto is not in the pool. This means no custom options are
2310  // used so we are safe to proceed with the compiled options message type.
2311  return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
2312  }
2313  DynamicMessageFactory factory;
2314  std::unique_ptr<Message> dynamic_options(
2315  factory.GetPrototype(option_descriptor)->New());
2316  if (dynamic_options->ParseFromString(options.SerializeAsString())) {
2317  return RetrieveOptionsAssumingRightPool(depth, *dynamic_options,
2318  option_entries);
2319  } else {
2320  GOOGLE_LOG(ERROR) << "Found invalid proto option data for: "
2321  << options.GetDescriptor()->full_name();
2322  return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
2323  }
2324  }
2325 }
2326 
2327 // Formats options that all appear together in brackets. Does not include
2328 // brackets.
2329 bool FormatBracketedOptions(int depth, const Message& options,
2331  std::vector<std::string> all_options;
2332  if (RetrieveOptions(depth, options, pool, &all_options)) {
2333  output->append(Join(all_options, ", "));
2334  }
2335  return !all_options.empty();
2336 }
2337 
2338 // Formats options one per line
2339 bool FormatLineOptions(int depth, const Message& options,
2341  std::string prefix(depth * 2, ' ');
2342  std::vector<std::string> all_options;
2343  if (RetrieveOptions(depth, options, pool, &all_options)) {
2344  for (int i = 0; i < all_options.size(); i++) {
2345  strings::SubstituteAndAppend(output, "$0option $1;\n", prefix,
2346  all_options[i]);
2347  }
2348  }
2349  return !all_options.empty();
2350 }
2351 
2352 class SourceLocationCommentPrinter {
2353  public:
2354  template <typename DescType>
2355  SourceLocationCommentPrinter(const DescType* desc, const std::string& prefix,
2356  const DebugStringOptions& options)
2358  // Perform the SourceLocation lookup only if we're including user comments,
2359  // because the lookup is fairly expensive.
2361  options.include_comments && desc->GetSourceLocation(&source_loc_);
2362  }
2363  SourceLocationCommentPrinter(const FileDescriptor* file,
2364  const std::vector<int>& path,
2365  const std::string& prefix,
2366  const DebugStringOptions& options)
2368  // Perform the SourceLocation lookup only if we're including user comments,
2369  // because the lookup is fairly expensive.
2371  options.include_comments && file->GetSourceLocation(path, &source_loc_);
2372  }
2373  void AddPreComment(std::string* output) {
2374  if (have_source_loc_) {
2375  // Detached leading comments.
2376  for (int i = 0; i < source_loc_.leading_detached_comments.size(); ++i) {
2377  *output += FormatComment(source_loc_.leading_detached_comments[i]);
2378  *output += "\n";
2379  }
2380  // Attached leading comments.
2381  if (!source_loc_.leading_comments.empty()) {
2382  *output += FormatComment(source_loc_.leading_comments);
2383  }
2384  }
2385  }
2386  void AddPostComment(std::string* output) {
2387  if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) {
2388  *output += FormatComment(source_loc_.trailing_comments);
2389  }
2390  }
2391 
2392  // Format comment such that each line becomes a full-line C++-style comment in
2393  // the DebugString() output.
2394  std::string FormatComment(const std::string& comment_text) {
2395  std::string stripped_comment = comment_text;
2396  StripWhitespace(&stripped_comment);
2397  std::vector<std::string> lines = Split(stripped_comment, "\n");
2399  for (int i = 0; i < lines.size(); ++i) {
2400  const std::string& line = lines[i];
2401  strings::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line);
2402  }
2403  return output;
2404  }
2405 
2406  private:
2407 
2409  SourceLocation source_loc_;
2410  DebugStringOptions options_;
2412 };
2413 
2414 } // anonymous namespace
2415 
2417  DebugStringOptions options; // default options
2419 }
2420 
2422  const DebugStringOptions& debug_string_options) const {
2423  std::string contents;
2424  {
2425  std::vector<int> path;
2427  SourceLocationCommentPrinter syntax_comment(this, path, "",
2428  debug_string_options);
2429  syntax_comment.AddPreComment(&contents);
2430  strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
2431  SyntaxName(syntax()));
2432  syntax_comment.AddPostComment(&contents);
2433  }
2434 
2435  SourceLocationCommentPrinter comment_printer(this, "", debug_string_options);
2436  comment_printer.AddPreComment(&contents);
2437 
2438  std::set<int> public_dependencies;
2439  std::set<int> weak_dependencies;
2440  public_dependencies.insert(public_dependencies_,
2441  public_dependencies_ + public_dependency_count_);
2442  weak_dependencies.insert(weak_dependencies_,
2443  weak_dependencies_ + weak_dependency_count_);
2444 
2445  for (int i = 0; i < dependency_count(); i++) {
2446  if (public_dependencies.count(i) > 0) {
2447  strings::SubstituteAndAppend(&contents, "import public \"$0\";\n",
2448  dependency(i)->name());
2449  } else if (weak_dependencies.count(i) > 0) {
2450  strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n",
2451  dependency(i)->name());
2452  } else {
2453  strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
2454  dependency(i)->name());
2455  }
2456  }
2457 
2458  if (!package().empty()) {
2459  std::vector<int> path;
2461  SourceLocationCommentPrinter package_comment(this, path, "",
2462  debug_string_options);
2463  package_comment.AddPreComment(&contents);
2464  strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
2465  package_comment.AddPostComment(&contents);
2466  }
2467 
2468  if (FormatLineOptions(0, options(), pool(), &contents)) {
2469  contents.append("\n"); // add some space if we had options
2470  }
2471 
2472  for (int i = 0; i < enum_type_count(); i++) {
2473  enum_type(i)->DebugString(0, &contents, debug_string_options);
2474  contents.append("\n");
2475  }
2476 
2477  // Find all the 'group' type extensions; we will not output their nested
2478  // definitions (those will be done with their group field descriptor).
2479  std::set<const Descriptor*> groups;
2480  for (int i = 0; i < extension_count(); i++) {
2482  groups.insert(extension(i)->message_type());
2483  }
2484  }
2485 
2486  for (int i = 0; i < message_type_count(); i++) {
2487  if (groups.count(message_type(i)) == 0) {
2488  message_type(i)->DebugString(0, &contents, debug_string_options,
2489  /* include_opening_clause */ true);
2490  contents.append("\n");
2491  }
2492  }
2493 
2494  for (int i = 0; i < service_count(); i++) {
2495  service(i)->DebugString(&contents, debug_string_options);
2496  contents.append("\n");
2497  }
2498 
2499  const Descriptor* containing_type = nullptr;
2500  for (int i = 0; i < extension_count(); i++) {
2502  if (i > 0) contents.append("}\n\n");
2504  strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
2506  }
2508  debug_string_options);
2509  }
2510  if (extension_count() > 0) contents.append("}\n\n");
2511 
2512  comment_printer.AddPostComment(&contents);
2513 
2514  return contents;
2515 }
2516 
2518  DebugStringOptions options; // default options
2520 }
2521 
2523  const DebugStringOptions& options) const {
2524  std::string contents;
2525  DebugString(0, &contents, options, /* include_opening_clause */ true);
2526  return contents;
2527 }
2528 
2530  const DebugStringOptions& debug_string_options,
2531  bool include_opening_clause) const {
2532  if (options().map_entry()) {
2533  // Do not generate debug string for auto-generated map-entry type.
2534  return;
2535  }
2536  std::string prefix(depth * 2, ' ');
2537  ++depth;
2538 
2539  SourceLocationCommentPrinter comment_printer(this, prefix,
2540  debug_string_options);
2541  comment_printer.AddPreComment(contents);
2542 
2543  if (include_opening_clause) {
2544  strings::SubstituteAndAppend(contents, "$0message $1", prefix, name());
2545  }
2546  contents->append(" {\n");
2547 
2548  FormatLineOptions(depth, options(), file()->pool(), contents);
2549 
2550  // Find all the 'group' types for fields and extensions; we will not output
2551  // their nested definitions (those will be done with their group field
2552  // descriptor).
2553  std::set<const Descriptor*> groups;
2554  for (int i = 0; i < field_count(); i++) {
2555  if (field(i)->type() == FieldDescriptor::TYPE_GROUP) {
2556  groups.insert(field(i)->message_type());
2557  }
2558  }
2559  for (int i = 0; i < extension_count(); i++) {
2561  groups.insert(extension(i)->message_type());
2562  }
2563  }
2564 
2565  for (int i = 0; i < nested_type_count(); i++) {
2566  if (groups.count(nested_type(i)) == 0) {
2567  nested_type(i)->DebugString(depth, contents, debug_string_options,
2568  /* include_opening_clause */ true);
2569  }
2570  }
2571  for (int i = 0; i < enum_type_count(); i++) {
2572  enum_type(i)->DebugString(depth, contents, debug_string_options);
2573  }
2574  for (int i = 0; i < field_count(); i++) {
2575  if (field(i)->containing_oneof() == nullptr) {
2577  debug_string_options);
2578  } else if (field(i)->containing_oneof()->field(0) == field(i)) {
2579  // This is the first field in this oneof, so print the whole oneof.
2580  field(i)->containing_oneof()->DebugString(depth, contents,
2581  debug_string_options);
2582  }
2583  }
2584 
2585  for (int i = 0; i < extension_range_count(); i++) {
2586  strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", prefix,
2588  extension_range(i)->end - 1);
2589  }
2590 
2591  // Group extensions by what they extend, so they can be printed out together.
2592  const Descriptor* containing_type = nullptr;
2593  for (int i = 0; i < extension_count(); i++) {
2595  if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
2597  strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", prefix,
2599  }
2601  debug_string_options);
2602  }
2603  if (extension_count() > 0)
2604  strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
2605 
2606  if (reserved_range_count() > 0) {
2607  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
2608  for (int i = 0; i < reserved_range_count(); i++) {
2609  const Descriptor::ReservedRange* range = reserved_range(i);
2610  if (range->end == range->start + 1) {
2611  strings::SubstituteAndAppend(contents, "$0, ", range->start);
2612  } else {
2613  strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start,
2614  range->end - 1);
2615  }
2616  }
2617  contents->replace(contents->size() - 2, 2, ";\n");
2618  }
2619 
2620  if (reserved_name_count() > 0) {
2621  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
2622  for (int i = 0; i < reserved_name_count(); i++) {
2623  strings::SubstituteAndAppend(contents, "\"$0\", ",
2624  CEscape(reserved_name(i)));
2625  }
2626  contents->replace(contents->size() - 2, 2, ";\n");
2627  }
2628 
2629  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
2630  comment_printer.AddPostComment(contents);
2631 }
2632 
2634  DebugStringOptions options; // default options
2636 }
2637 
2639  const DebugStringOptions& debug_string_options) const {
2640  std::string contents;
2641  int depth = 0;
2642  if (is_extension()) {
2643  strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
2644  containing_type()->full_name());
2645  depth = 1;
2646  }
2647  DebugString(depth, PRINT_LABEL, &contents, debug_string_options);
2648  if (is_extension()) {
2649  contents.append("}\n");
2650  }
2651  return contents;
2652 }
2653 
2654 // The field type string used in FieldDescriptor::DebugString()
2656  switch (type()) {
2657  case TYPE_MESSAGE:
2658  return "." + message_type()->full_name();
2659  case TYPE_ENUM:
2660  return "." + enum_type()->full_name();
2661  default:
2662  return kTypeToName[type()];
2663  }
2664 }
2665 
2667  int depth, PrintLabelFlag print_label_flag, std::string* contents,
2668  const DebugStringOptions& debug_string_options) const {
2669  std::string prefix(depth * 2, ' ');
2671 
2672  // Special case map fields.
2673  if (is_map()) {
2675  &field_type, "map<$0, $1>",
2676  message_type()->field(0)->FieldTypeNameDebugString(),
2677  message_type()->field(1)->FieldTypeNameDebugString());
2678  } else {
2679  field_type = FieldTypeNameDebugString();
2680  }
2681 
2682  bool print_label = true;
2683  // Determine whether to omit label:
2684  // 1. For an optional field, omit label if it's in oneof or in proto3.
2685  // 2. For a repeated field, omit label if it's a map.
2686  if (is_optional() && (print_label_flag == OMIT_LABEL ||
2687  file()->syntax() == FileDescriptor::SYNTAX_PROTO3)) {
2688  print_label = false;
2689  } else if (is_map()) {
2690  print_label = false;
2691  }
2693  if (print_label) {
2694  label = kLabelToName[this->label()];
2695  label.push_back(' ');
2696  }
2697 
2698  SourceLocationCommentPrinter comment_printer(this, prefix,
2699  debug_string_options);
2700  comment_printer.AddPreComment(contents);
2701 
2703  contents, "$0$1$2 $3 = $4", prefix, label, field_type,
2704  type() == TYPE_GROUP ? message_type()->name() : name(), number());
2705 
2706  bool bracketed = false;
2707  if (has_default_value()) {
2708  bracketed = true;
2709  strings::SubstituteAndAppend(contents, " [default = $0",
2710  DefaultValueAsString(true));
2711  }
2712  if (has_json_name_) {
2713  if (!bracketed) {
2714  bracketed = true;
2715  contents->append("[");
2716  } else {
2717  contents->append(", ");
2718  }
2719  contents->append("json_name = \"");
2720  contents->append(CEscape(json_name()));
2721  contents->append("\"");
2722  }
2723 
2724  std::string formatted_options;
2725  if (FormatBracketedOptions(depth, options(), file()->pool(),
2726  &formatted_options)) {
2727  contents->append(bracketed ? ", " : " [");
2728  bracketed = true;
2729  contents->append(formatted_options);
2730  }
2731 
2732  if (bracketed) {
2733  contents->append("]");
2734  }
2735 
2736  if (type() == TYPE_GROUP) {
2737  if (debug_string_options.elide_group_body) {
2738  contents->append(" { ... };\n");
2739  } else {
2740  message_type()->DebugString(depth, contents, debug_string_options,
2741  /* include_opening_clause */ false);
2742  }
2743  } else {
2744  contents->append(";\n");
2745  }
2746 
2747  comment_printer.AddPostComment(contents);
2748 }
2749 
2751  DebugStringOptions options; // default values
2753 }
2754 
2756  const DebugStringOptions& options) const {
2757  std::string contents;
2758  DebugString(0, &contents, options);
2759  return contents;
2760 }
2761 
2763  int depth, std::string* contents,
2764  const DebugStringOptions& debug_string_options) const {
2765  std::string prefix(depth * 2, ' ');
2766  ++depth;
2767  SourceLocationCommentPrinter comment_printer(this, prefix,
2768  debug_string_options);
2769  comment_printer.AddPreComment(contents);
2770  strings::SubstituteAndAppend(contents, "$0oneof $1 {", prefix, name());
2771 
2772  FormatLineOptions(depth, options(), containing_type()->file()->pool(),
2773  contents);
2774 
2775  if (debug_string_options.elide_oneof_body) {
2776  contents->append(" ... }\n");
2777  } else {
2778  contents->append("\n");
2779  for (int i = 0; i < field_count(); i++) {
2781  debug_string_options);
2782  }
2783  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
2784  }
2785  comment_printer.AddPostComment(contents);
2786 }
2787 
2789  DebugStringOptions options; // default values
2791 }
2792 
2794  const DebugStringOptions& options) const {
2795  std::string contents;
2796  DebugString(0, &contents, options);
2797  return contents;
2798 }
2799 
2801  int depth, std::string* contents,
2802  const DebugStringOptions& debug_string_options) const {
2803  std::string prefix(depth * 2, ' ');
2804  ++depth;
2805 
2806  SourceLocationCommentPrinter comment_printer(this, prefix,
2807  debug_string_options);
2808  comment_printer.AddPreComment(contents);
2809 
2810  strings::SubstituteAndAppend(contents, "$0enum $1 {\n", prefix, name());
2811 
2812  FormatLineOptions(depth, options(), file()->pool(), contents);
2813 
2814  for (int i = 0; i < value_count(); i++) {
2815  value(i)->DebugString(depth, contents, debug_string_options);
2816  }
2817 
2818  if (reserved_range_count() > 0) {
2819  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
2820  for (int i = 0; i < reserved_range_count(); i++) {
2821  const EnumDescriptor::ReservedRange* range = reserved_range(i);
2822  if (range->end == range->start) {
2823  strings::SubstituteAndAppend(contents, "$0, ", range->start);
2824  } else {
2825  strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start,
2826  range->end);
2827  }
2828  }
2829  contents->replace(contents->size() - 2, 2, ";\n");
2830  }
2831 
2832  if (reserved_name_count() > 0) {
2833  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
2834  for (int i = 0; i < reserved_name_count(); i++) {
2835  strings::SubstituteAndAppend(contents, "\"$0\", ",
2836  CEscape(reserved_name(i)));
2837  }
2838  contents->replace(contents->size() - 2, 2, ";\n");
2839  }
2840 
2841  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
2842 
2843  comment_printer.AddPostComment(contents);
2844 }
2845 
2847  DebugStringOptions options; // default values
2849 }
2850 
2852  const DebugStringOptions& options) const {
2853  std::string contents;
2854  DebugString(0, &contents, options);
2855  return contents;
2856 }
2857 
2859  int depth, std::string* contents,
2860  const DebugStringOptions& debug_string_options) const {
2861  std::string prefix(depth * 2, ' ');
2862 
2863  SourceLocationCommentPrinter comment_printer(this, prefix,
2864  debug_string_options);
2865  comment_printer.AddPreComment(contents);
2866 
2867  strings::SubstituteAndAppend(contents, "$0$1 = $2", prefix, name(), number());
2868 
2869  std::string formatted_options;
2870  if (FormatBracketedOptions(depth, options(), type()->file()->pool(),
2871  &formatted_options)) {
2872  strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
2873  }
2874  contents->append(";\n");
2875 
2876  comment_printer.AddPostComment(contents);
2877 }
2878 
2880  DebugStringOptions options; // default values
2882 }
2883 
2885  const DebugStringOptions& options) const {
2886  std::string contents;
2887  DebugString(&contents, options);
2888  return contents;
2889 }
2890 
2892  std::string* contents,
2893  const DebugStringOptions& debug_string_options) const {
2894  SourceLocationCommentPrinter comment_printer(this, /* prefix */ "",
2895  debug_string_options);
2896  comment_printer.AddPreComment(contents);
2897 
2898  strings::SubstituteAndAppend(contents, "service $0 {\n", name());
2899 
2900  FormatLineOptions(1, options(), file()->pool(), contents);
2901 
2902  for (int i = 0; i < method_count(); i++) {
2903  method(i)->DebugString(1, contents, debug_string_options);
2904  }
2905 
2906  contents->append("}\n");
2907 
2908  comment_printer.AddPostComment(contents);
2909 }
2910 
2912  DebugStringOptions options; // default values
2914 }
2915 
2917  const DebugStringOptions& options) const {
2918  std::string contents;
2919  DebugString(0, &contents, options);
2920  return contents;
2921 }
2922 
2924  int depth, std::string* contents,
2925  const DebugStringOptions& debug_string_options) const {
2926  std::string prefix(depth * 2, ' ');
2927  ++depth;
2928 
2929  SourceLocationCommentPrinter comment_printer(this, prefix,
2930  debug_string_options);
2931  comment_printer.AddPreComment(contents);
2932 
2934  contents, "$0rpc $1($4.$2) returns ($5.$3)", prefix, name(),
2935  input_type()->full_name(), output_type()->full_name(),
2936  client_streaming() ? "stream " : "", server_streaming() ? "stream " : "");
2937 
2938  std::string formatted_options;
2939  if (FormatLineOptions(depth, options(), service()->file()->pool(),
2940  &formatted_options)) {
2941  strings::SubstituteAndAppend(contents, " {\n$0$1}\n", formatted_options,
2942  prefix);
2943  } else {
2944  contents->append(";\n");
2945  }
2946 
2947  comment_printer.AddPostComment(contents);
2948 }
2949 
2950 
2951 // Location methods ===============================================
2952 
2953 bool FileDescriptor::GetSourceLocation(const std::vector<int>& path,
2954  SourceLocation* out_location) const {
2955  GOOGLE_CHECK(out_location != nullptr);
2956  if (source_code_info_) {
2957  if (const SourceCodeInfo_Location* loc =
2958  tables_->GetSourceLocation(path, source_code_info_)) {
2959  const RepeatedField<int32>& span = loc->span();
2960  if (span.size() == 3 || span.size() == 4) {
2961  out_location->start_line = span.Get(0);
2962  out_location->start_column = span.Get(1);
2963  out_location->end_line = span.Get(span.size() == 3 ? 0 : 2);
2964  out_location->end_column = span.Get(span.size() - 1);
2965 
2966  out_location->leading_comments = loc->leading_comments();
2967  out_location->trailing_comments = loc->trailing_comments();
2968  out_location->leading_detached_comments.assign(
2969  loc->leading_detached_comments().begin(),
2970  loc->leading_detached_comments().end());
2971  return true;
2972  }
2973  }
2974  }
2975  return false;
2976 }
2977 
2979  std::vector<int> path; // empty path for root FileDescriptor
2980  return GetSourceLocation(path, out_location);
2981 }
2982 
2984  if (!is_packable()) return false;
2986  return (options_ != nullptr) && options_->packed();
2987  } else {
2988  return options_ == nullptr || !options_->has_packed() || options_->packed();
2989  }
2990 }
2991 
2993  std::vector<int> path;
2995  return file()->GetSourceLocation(path, out_location);
2996 }
2997 
2999  std::vector<int> path;
3001  return file()->GetSourceLocation(path, out_location);
3002 }
3003 
3005  std::vector<int> path;
3007  return containing_type()->file()->GetSourceLocation(path, out_location);
3008 }
3009 
3011  std::vector<int> path;
3013  return file()->GetSourceLocation(path, out_location);
3014 }
3015 
3017  std::vector<int> path;
3019  return service()->file()->GetSourceLocation(path, out_location);
3020 }
3021 
3023  std::vector<int> path;
3025  return file()->GetSourceLocation(path, out_location);
3026 }
3027 
3029  SourceLocation* out_location) const {
3030  std::vector<int> path;
3032  return type()->file()->GetSourceLocation(path, out_location);
3033 }
3034 
3035 void Descriptor::GetLocationPath(std::vector<int>* output) const {
3036  if (containing_type()) {
3039  output->push_back(index());
3040  } else {
3042  output->push_back(index());
3043  }
3044 }
3045 
3046 void FieldDescriptor::GetLocationPath(std::vector<int>* output) const {
3047  if (is_extension()) {
3048  if (extension_scope() == nullptr) {
3050  output->push_back(index());
3051  } else {
3052  extension_scope()->GetLocationPath(output);
3054  output->push_back(index());
3055  }
3056  } else {
3059  output->push_back(index());
3060  }
3061 }
3062 
3063 void OneofDescriptor::GetLocationPath(std::vector<int>* output) const {
3066  output->push_back(index());
3067 }
3068 
3069 void EnumDescriptor::GetLocationPath(std::vector<int>* output) const {
3070  if (containing_type()) {
3073  output->push_back(index());
3074  } else {
3076  output->push_back(index());
3077  }
3078 }
3079 
3080 void EnumValueDescriptor::GetLocationPath(std::vector<int>* output) const {
3081  type()->GetLocationPath(output);
3083  output->push_back(index());
3084 }
3085 
3086 void ServiceDescriptor::GetLocationPath(std::vector<int>* output) const {
3088  output->push_back(index());
3089 }
3090 
3091 void MethodDescriptor::GetLocationPath(std::vector<int>* output) const {
3092  service()->GetLocationPath(output);
3094  output->push_back(index());
3095 }
3096 
3097 // ===================================================================
3098 
3099 namespace {
3100 
3101 // Represents an options message to interpret. Extension names in the option
3102 // name are resolved relative to name_scope. element_name and orig_opt are
3103 // used only for error reporting (since the parser records locations against
3104 // pointers in the original options, not the mutable copy). The Message must be
3105 // one of the Options messages in descriptor.proto.
3106 struct OptionsToInterpret {
3107  OptionsToInterpret(const std::string& ns, const std::string& el,
3108  const std::vector<int>& path, const Message* orig_opt,
3109  Message* opt)
3110  : name_scope(ns),
3111  element_name(el),
3112  element_path(path),
3113  original_options(orig_opt),
3114  options(opt) {}
3117  std::vector<int> element_path;
3118  const Message* original_options;
3119  Message* options;
3120 };
3121 
3122 } // namespace
3123 
3125  public:
3126  DescriptorBuilder(const DescriptorPool* pool, DescriptorPool::Tables* tables,
3127  DescriptorPool::ErrorCollector* error_collector);
3128  ~DescriptorBuilder();
3129 
3130  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
3131 
3132  private:
3133  friend class OptionInterpreter;
3134 
3135  // Non-recursive part of BuildFile functionality.
3136  FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto);
3137 
3139  DescriptorPool::Tables* tables_; // for convenience
3140  DescriptorPool::ErrorCollector* error_collector_;
3141 
3142  // As we build descriptors we store copies of the options messages in
3143  // them. We put pointers to those copies in this vector, as we build, so we
3144  // can later (after cross-linking) interpret those options.
3145  std::vector<OptionsToInterpret> options_to_interpret_;
3146 
3151  std::set<const FileDescriptor*> dependencies_;
3152 
3153  // unused_dependency_ is used to record the unused imported files.
3154  // Note: public import is not considered.
3155  std::set<const FileDescriptor*> unused_dependency_;
3156 
3157  // If LookupSymbol() finds a symbol that is in a file which is not a declared
3158  // dependency of this file, it will fail, but will set
3159  // possible_undeclared_dependency_ to point at that file. This is only used
3160  // by AddNotDefinedError() to report a more useful error message.
3161  // possible_undeclared_dependency_name_ is the name of the symbol that was
3162  // actually found in possible_undeclared_dependency_, which may be a parent
3163  // of the symbol actually looked for.
3166 
3167  // If LookupSymbol() could resolve a symbol which is not defined,
3168  // record the resolved name. This is only used by AddNotDefinedError()
3169  // to report a more useful error message.
3171 
3172  void AddError(const std::string& element_name, const Message& descriptor,
3174  const std::string& error);
3175  void AddError(const std::string& element_name, const Message& descriptor,
3177  const char* error);
3178  void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
3179  void AddTwiceListedError(const FileDescriptorProto& proto, int index);
3180  void AddImportError(const FileDescriptorProto& proto, int index);
3181 
3182  // Adds an error indicating that undefined_symbol was not defined. Must
3183  // only be called after LookupSymbol() fails.
3184  void AddNotDefinedError(
3185  const std::string& element_name, const Message& descriptor,
3187  const std::string& undefined_symbol);
3188 
3189  void AddWarning(const std::string& element_name, const Message& descriptor,
3191  const std::string& error);
3192 
3193  // Silly helper which determines if the given file is in the given package.
3194  // I.e., either file->package() == package_name or file->package() is a
3195  // nested package within package_name.
3196  bool IsInPackage(const FileDescriptor* file, const std::string& package_name);
3197 
3198  // Helper function which finds all public dependencies of the given file, and
3199  // stores the them in the dependencies_ set in the builder.
3200  void RecordPublicDependencies(const FileDescriptor* file);
3201 
3202  // Like tables_->FindSymbol(), but additionally:
3203  // - Search the pool's underlay if not found in tables_.
3204  // - Insure that the resulting Symbol is from one of the file's declared
3205  // dependencies.
3206  Symbol FindSymbol(const std::string& name, bool build_it = true);
3207 
3208  // Like FindSymbol() but does not require that the symbol is in one of the
3209  // file's declared dependencies.
3210  Symbol FindSymbolNotEnforcingDeps(const std::string& name,
3211  bool build_it = true);
3212 
3213  // This implements the body of FindSymbolNotEnforcingDeps().
3214  Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
3215  const std::string& name,
3216  bool build_it = true);
3217 
3218  // Like FindSymbol(), but looks up the name relative to some other symbol
3219  // name. This first searches siblings of relative_to, then siblings of its
3220  // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
3221  // the following calls, returning the first non-null result:
3222  // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
3223  // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called
3224  // on the DescriptorPool, this will generate a placeholder type if
3225  // the name is not found (unless the name itself is malformed). The
3226  // placeholder_type parameter indicates what kind of placeholder should be
3227  // constructed in this case. The resolve_mode parameter determines whether
3228  // any symbol is returned, or only symbols that are types. Note, however,
3229  // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
3230  // if it believes that's all it could refer to. The caller should always
3231  // check that it receives the type of symbol it was expecting.
3232  enum ResolveMode { LOOKUP_ALL, LOOKUP_TYPES };
3233  Symbol LookupSymbol(const std::string& name, const std::string& relative_to,
3234  DescriptorPool::PlaceholderType placeholder_type =
3236  ResolveMode resolve_mode = LOOKUP_ALL,
3237  bool build_it = true);
3238 
3239  // Like LookupSymbol() but will not return a placeholder even if
3240  // AllowUnknownDependencies() has been used.
3241  Symbol LookupSymbolNoPlaceholder(const std::string& name,
3242  const std::string& relative_to,
3243  ResolveMode resolve_mode = LOOKUP_ALL,
3244  bool build_it = true);
3245 
3246  // Calls tables_->AddSymbol() and records an error if it fails. Returns
3247  // true if successful or false if failed, though most callers can ignore
3248  // the return value since an error has already been recorded.
3249  bool AddSymbol(const std::string& full_name, const void* parent,
3250  const std::string& name, const Message& proto, Symbol symbol);
3251 
3252  // Like AddSymbol(), but succeeds if the symbol is already defined as long
3253  // as the existing definition is also a package (because it's OK to define
3254  // the same package in two different files). Also adds all parents of the
3255  // packgae to the symbol table (e.g. AddPackage("foo.bar", ...) will add
3256  // "foo.bar" and "foo" to the table).
3257  void AddPackage(const std::string& name, const Message& proto,
3258  const FileDescriptor* file);
3259 
3260  // Checks that the symbol name contains only alphanumeric characters and
3261  // underscores. Records an error otherwise.
3262  void ValidateSymbolName(const std::string& name, const std::string& full_name,
3263  const Message& proto);
3264 
3265  // Used by BUILD_ARRAY macro (below) to avoid having to have the type
3266  // specified as a macro parameter.
3267  template <typename Type>
3268  inline void AllocateArray(int size, Type** output) {
3269  *output = tables_->AllocateArray<Type>(size);
3270  }
3271 
3272  // Allocates a copy of orig_options in tables_ and stores it in the
3273  // descriptor. Remembers its uninterpreted options, to be interpreted
3274  // later. DescriptorT must be one of the Descriptor messages from
3275  // descriptor.proto.
3276  template <class DescriptorT>
3277  void AllocateOptions(const typename DescriptorT::OptionsType& orig_options,
3278  DescriptorT* descriptor, int options_field_tag);
3279  // Specialization for FileOptions.
3280  void AllocateOptions(const FileOptions& orig_options,
3282 
3283  // Implementation for AllocateOptions(). Don't call this directly.
3284  template <class DescriptorT>
3285  void AllocateOptionsImpl(
3287  const typename DescriptorT::OptionsType& orig_options,
3288  DescriptorT* descriptor, const std::vector<int>& options_path);
3289 
3290  // Allocate string on the string pool and initialize it to full proto name.
3291  // Full proto name is "scope.proto_name" if scope is non-empty and
3292  // "proto_name" otherwise.
3293  std::string* AllocateNameString(const std::string& scope,
3294  const std::string& proto_name);
3295 
3296  // These methods all have the same signature for the sake of the BUILD_ARRAY
3297  // macro, below.
3298  void BuildMessage(const DescriptorProto& proto, const Descriptor* parent,
3299  Descriptor* result);
3300  void BuildFieldOrExtension(const FieldDescriptorProto& proto,
3301  const Descriptor* parent, FieldDescriptor* result,
3302  bool is_extension);
3303  void BuildField(const FieldDescriptorProto& proto, const Descriptor* parent,
3304  FieldDescriptor* result) {
3305  BuildFieldOrExtension(proto, parent, result, false);
3306  }
3308  const Descriptor* parent, FieldDescriptor* result) {
3309  BuildFieldOrExtension(proto, parent, result, true);
3310  }
3311  void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
3312  const Descriptor* parent,
3313  Descriptor::ExtensionRange* result);
3314  void BuildReservedRange(const DescriptorProto::ReservedRange& proto,
3315  const Descriptor* parent,
3316  Descriptor::ReservedRange* result);
3317  void BuildReservedRange(const EnumDescriptorProto::EnumReservedRange& proto,
3318  const EnumDescriptor* parent,
3319  EnumDescriptor::ReservedRange* result);
3320  void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent,
3321  OneofDescriptor* result);
3322  void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
3323  const EnumDescriptor* result);
3324  void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent,
3325  EnumDescriptor* result);
3326  void BuildEnumValue(const EnumValueDescriptorProto& proto,
3327  const EnumDescriptor* parent,
3328  EnumValueDescriptor* result);
3329  void BuildService(const ServiceDescriptorProto& proto, const void* dummy,
3330  ServiceDescriptor* result);
3331  void BuildMethod(const MethodDescriptorProto& proto,
3332  const ServiceDescriptor* parent, MethodDescriptor* result);
3333 
3334  void LogUnusedDependency(const FileDescriptorProto& proto,
3335  const FileDescriptor* result);
3336 
3337  // Must be run only after building.
3338  //
3339  // NOTE: Options will not be available during cross-linking, as they
3340  // have not yet been interpreted. Defer any handling of options to the
3341  // Validate*Options methods.
3342  void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
3343  void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
3344  void CrossLinkField(FieldDescriptor* field,
3345  const FieldDescriptorProto& proto);
3346  void CrossLinkExtensionRange(Descriptor::ExtensionRange* range,
3347  const DescriptorProto::ExtensionRange& proto);
3348  void CrossLinkEnum(EnumDescriptor* enum_type,
3349  const EnumDescriptorProto& proto);
3350  void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
3351  const EnumValueDescriptorProto& proto);
3352  void CrossLinkService(ServiceDescriptor* service,
3353  const ServiceDescriptorProto& proto);
3354  void CrossLinkMethod(MethodDescriptor* method,
3355  const MethodDescriptorProto& proto);
3356 
3357  // Must be run only after cross-linking.
3358  void InterpretOptions();
3359 
3360  // A helper class for interpreting options.
3362  public:
3363  // Creates an interpreter that operates in the context of the pool of the
3364  // specified builder, which must not be nullptr. We don't take ownership of
3365  // the builder.
3366  explicit OptionInterpreter(DescriptorBuilder* builder);
3367 
3368  ~OptionInterpreter();
3369 
3370  // Interprets the uninterpreted options in the specified Options message.
3371  // On error, calls AddError() on the underlying builder and returns false.
3372  // Otherwise returns true.
3373  bool InterpretOptions(OptionsToInterpret* options_to_interpret);
3374 
3375  // Updates the given source code info by re-writing uninterpreted option
3376  // locations to refer to the corresponding interpreted option.
3377  void UpdateSourceCodeInfo(SourceCodeInfo* info);
3378 
3379  class AggregateOptionFinder;
3380 
3381  private:
3382  // Interprets uninterpreted_option_ on the specified message, which
3383  // must be the mutable copy of the original options message to which
3384  // uninterpreted_option_ belongs. The given src_path is the source
3385  // location path to the uninterpreted option, and options_path is the
3386  // source location path to the options message. The location paths are
3387  // recorded and then used in UpdateSourceCodeInfo.
3388  bool InterpretSingleOption(Message* options,
3389  const std::vector<int>& src_path,
3390  const std::vector<int>& options_path);
3391 
3392  // Adds the uninterpreted_option to the given options message verbatim.
3393  // Used when AllowUnknownDependencies() is in effect and we can't find
3394  // the option's definition.
3395  void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
3396  Message* options);
3397 
3398  // A recursive helper function that drills into the intermediate fields
3399  // in unknown_fields to check if field innermost_field is set on the
3400  // innermost message. Returns false and sets an error if so.
3401  bool ExamineIfOptionIsSet(
3402  std::vector<const FieldDescriptor*>::const_iterator
3403  intermediate_fields_iter,
3404  std::vector<const FieldDescriptor*>::const_iterator
3405  intermediate_fields_end,
3406  const FieldDescriptor* innermost_field,
3407  const std::string& debug_msg_name,
3408  const UnknownFieldSet& unknown_fields);
3409 
3410  // Validates the value for the option field of the currently interpreted
3411  // option and then sets it on the unknown_field.
3412  bool SetOptionValue(const FieldDescriptor* option_field,
3413  UnknownFieldSet* unknown_fields);
3414 
3415  // Parses an aggregate value for a CPPTYPE_MESSAGE option and
3416  // saves it into *unknown_fields.
3417  bool SetAggregateOption(const FieldDescriptor* option_field,
3418  UnknownFieldSet* unknown_fields);
3419 
3420  // Convenience functions to set an int field the right way, depending on
3421  // its wire type (a single int CppType can represent multiple wire types).
3422  void SetInt32(int number, int32 value, FieldDescriptor::Type type,
3423  UnknownFieldSet* unknown_fields);
3424  void SetInt64(int number, int64 value, FieldDescriptor::Type type,
3425  UnknownFieldSet* unknown_fields);
3426  void SetUInt32(int number, uint32 value, FieldDescriptor::Type type,
3427  UnknownFieldSet* unknown_fields);
3428  void SetUInt64(int number, uint64 value, FieldDescriptor::Type type,
3429  UnknownFieldSet* unknown_fields);
3430 
3431  // A helper function that adds an error at the specified location of the
3432  // option we're currently interpreting, and returns false.
3434  const std::string& msg) {
3435  builder_->AddError(options_to_interpret_->element_name,
3436  *uninterpreted_option_, location, msg);
3437  return false;
3438  }
3439 
3440  // A helper function that adds an error at the location of the option name
3441  // and returns false.
3442  bool AddNameError(const std::string& msg) {
3443  return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg);
3444  }
3445 
3446  // A helper function that adds an error at the location of the option name
3447  // and returns false.
3448  bool AddValueError(const std::string& msg) {
3449  return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg);
3450  }
3451 
3452  // We interpret against this builder's pool. Is never nullptr. We don't own
3453  // this pointer.
3455 
3456  // The options we're currently interpreting, or nullptr if we're not in a
3457  // call to InterpretOptions.
3458  const OptionsToInterpret* options_to_interpret_;
3459 
3460  // The option we're currently interpreting within options_to_interpret_, or
3461  // nullptr if we're not in a call to InterpretOptions(). This points to a
3462  // submessage of the original option, not the mutable copy. Therefore we
3463  // can use it to find locations recorded by the parser.
3465 
3466  // This maps the element path of uninterpreted options to the element path
3467  // of the resulting interpreted option. This is used to modify a file's
3468  // source code info to account for option interpretation.
3469  std::map<std::vector<int>, std::vector<int>> interpreted_paths_;
3470 
3471  // This maps the path to a repeated option field to the known number of
3472  // elements the field contains. This is used to track the compute the
3473  // index portion of the element path when interpreting a single option.
3474  std::map<std::vector<int>, int> repeated_option_counts_;
3475 
3476  // Factory used to create the dynamic messages we need to parse
3477  // any aggregate option values we encounter.
3479 
3481  };
3482 
3483  // Work-around for broken compilers: According to the C++ standard,
3484  // OptionInterpreter should have access to the private members of any class
3485  // which has declared DescriptorBuilder as a friend. Unfortunately some old
3486  // versions of GCC and other compilers do not implement this correctly. So,
3487  // we have to have these intermediate methods to provide access. We also
3488  // redundantly declare OptionInterpreter a friend just to make things extra
3489  // clear for these bad compilers.
3490  friend class OptionInterpreter;
3492 
3493  static inline bool get_allow_unknown(const DescriptorPool* pool) {
3494  return pool->allow_unknown_;
3495  }
3496  static inline bool get_enforce_weak(const DescriptorPool* pool) {
3497  return pool->enforce_weak_;
3498  }
3499  static inline bool get_is_placeholder(const Descriptor* descriptor) {
3500  return descriptor->is_placeholder_;
3501  }
3502  static inline void assert_mutex_held(const DescriptorPool* pool) {
3503  if (pool->mutex_ != nullptr) {
3504  pool->mutex_->AssertHeld();
3505  }
3506  }
3507 
3508  // Must be run only after options have been interpreted.
3509  //
3510  // NOTE: Validation code must only reference the options in the mutable
3511  // descriptors, which are the ones that have been interpreted. The const
3512  // proto references are passed in only so they can be provided to calls to
3513  // AddError(). Do not look at their options, which have not been interpreted.
3514  void ValidateFileOptions(FileDescriptor* file,
3515  const FileDescriptorProto& proto);
3516  void ValidateMessageOptions(Descriptor* message,
3517  const DescriptorProto& proto);
3518  void ValidateFieldOptions(FieldDescriptor* field,
3519  const FieldDescriptorProto& proto);
3520  void ValidateEnumOptions(EnumDescriptor* enm,
3521  const EnumDescriptorProto& proto);
3522  void ValidateEnumValueOptions(EnumValueDescriptor* enum_value,
3523  const EnumValueDescriptorProto& proto);
3524  void ValidateServiceOptions(ServiceDescriptor* service,
3525  const ServiceDescriptorProto& proto);
3526  void ValidateMethodOptions(MethodDescriptor* method,
3527  const MethodDescriptorProto& proto);
3528  void ValidateProto3(FileDescriptor* file, const FileDescriptorProto& proto);
3529  void ValidateProto3Message(Descriptor* message, const DescriptorProto& proto);
3530  void ValidateProto3Field(FieldDescriptor* field,
3531  const FieldDescriptorProto& proto);
3532  void ValidateProto3Enum(EnumDescriptor* enm,
3533  const EnumDescriptorProto& proto);
3534 
3535  // Returns true if the map entry message is compatible with the
3536  // auto-generated entry message from map fields syntax.
3537  bool ValidateMapEntry(FieldDescriptor* field,
3538  const FieldDescriptorProto& proto);
3539 
3540  // Recursively detects naming conflicts with map entry types for a
3541  // better error message.
3542  void DetectMapConflicts(const Descriptor* message,
3543  const DescriptorProto& proto);
3544 
3545  void ValidateJSType(FieldDescriptor* field,
3546  const FieldDescriptorProto& proto);
3547 };
3548 
3550  const FileDescriptorProto& proto) {
3551  GOOGLE_CHECK(fallback_database_ == nullptr)
3552  << "Cannot call BuildFile on a DescriptorPool that uses a "
3553  "DescriptorDatabase. You must instead find a way to get your file "
3554  "into the underlying database.";
3555  GOOGLE_CHECK(mutex_ == nullptr); // Implied by the above GOOGLE_CHECK.
3556  tables_->known_bad_symbols_.clear();
3557  tables_->known_bad_files_.clear();
3558  return DescriptorBuilder(this, tables_.get(), nullptr).BuildFile(proto);
3559 }
3560 
3562  const FileDescriptorProto& proto, ErrorCollector* error_collector) {
3563  GOOGLE_CHECK(fallback_database_ == nullptr)
3564  << "Cannot call BuildFile on a DescriptorPool that uses a "
3565  "DescriptorDatabase. You must instead find a way to get your file "
3566  "into the underlying database.";
3567  GOOGLE_CHECK(mutex_ == nullptr); // Implied by the above GOOGLE_CHECK.
3568  tables_->known_bad_symbols_.clear();
3569  tables_->known_bad_files_.clear();
3570  return DescriptorBuilder(this, tables_.get(), error_collector)
3571  .BuildFile(proto);
3572 }
3573 
3575  const FileDescriptorProto& proto) const {
3576  mutex_->AssertHeld();
3577  if (tables_->known_bad_files_.count(proto.name()) > 0) {
3578  return nullptr;
3579  }
3580  const FileDescriptor* result =
3581  DescriptorBuilder(this, tables_.get(), default_error_collector_)
3582  .BuildFile(proto);
3583  if (result == nullptr) {
3584  tables_->known_bad_files_.insert(proto.name());
3585  }
3586  return result;
3587 }
3588 
3590  const DescriptorPool* pool, DescriptorPool::Tables* tables,
3591  DescriptorPool::ErrorCollector* error_collector)
3592  : pool_(pool),
3593  tables_(tables),
3594  error_collector_(error_collector),
3595  had_errors_(false),
3596  possible_undeclared_dependency_(nullptr),
3597  undefine_resolved_name_("") {}
3598 
3600 
3602  const std::string& element_name, const Message& descriptor,
3604  const std::string& error) {
3605  if (error_collector_ == nullptr) {
3606  if (!had_errors_) {
3607  GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_
3608  << "\":";
3609  }
3610  GOOGLE_LOG(ERROR) << " " << element_name << ": " << error;
3611  } else {
3613  error);
3614  }
3615  had_errors_ = true;
3616 }
3617 
3619  const std::string& element_name, const Message& descriptor,
3622 }
3623 
3625  const std::string& element_name, const Message& descriptor,
3627  const std::string& undefined_symbol) {
3628  if (possible_undeclared_dependency_ == nullptr &&
3629  undefine_resolved_name_.empty()) {
3631  "\"" + undefined_symbol + "\" is not defined.");
3632  } else {
3633  if (possible_undeclared_dependency_ != nullptr) {
3636  "\" seems to be defined in \"" +
3638  "\", which is not "
3639  "imported by \"" +
3640  filename_ +
3641  "\". To use it here, please "
3642  "add the necessary import.");
3643  }
3644  if (!undefine_resolved_name_.empty()) {
3646  "\"" + undefined_symbol + "\" is resolved to \"" +
3648  "\", which is not defined. "
3649  "The innermost scope is searched first in name resolution. "
3650  "Consider using a leading '.'(i.e., \"." +
3651  undefined_symbol + "\") to start from the outermost scope.");
3652  }
3653  }
3654 }
3655 
3657  const std::string& element_name, const Message& descriptor,
3659  const std::string& error) {
3660  if (error_collector_ == nullptr) {
3661  GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
3662  } else {
3664  error);
3665  }
3666 }
3667 
3669  const std::string& package_name) {
3670  return HasPrefixString(file->package(), package_name) &&
3671  (file->package().size() == package_name.size() ||
3672  file->package()[package_name.size()] == '.');
3673 }
3674 
3676  if (file == nullptr || !dependencies_.insert(file).second) return;
3677  for (int i = 0; file != nullptr && i < file->public_dependency_count(); i++) {
3679  }
3680 }
3681 
3683  const DescriptorPool* pool, const std::string& name, bool build_it) {
3684  // If we are looking at an underlay, we must lock its mutex_, since we are
3685  // accessing the underlay's tables_ directly.
3686  MutexLockMaybe lock((pool == pool_) ? nullptr : pool->mutex_);
3687 
3688  Symbol result = pool->tables_->FindSymbol(name);
3689  if (result.IsNull() && pool->underlay_ != nullptr) {
3690  // Symbol not found; check the underlay.
3691  result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name);
3692  }
3693 
3694  if (result.IsNull()) {
3695  // With lazily_build_dependencies_, a symbol lookup at cross link time is
3696  // not guaranteed to be successful. In most cases, build_it will be false,
3697  // which intentionally prevents us from building an import until it's
3698  // actually needed. In some cases, like registering an extension, we want
3699  // to build the file containing the symbol, and build_it will be set.
3700  // Also, build_it will be true when !lazily_build_dependencies_, to provide
3701  // better error reporting of missing dependencies.
3702  if (build_it && pool->TryFindSymbolInFallbackDatabase(name)) {
3703  result = pool->tables_->FindSymbol(name);
3704  }
3705  }
3706 
3707  return result;
3708 }
3709 
3711  bool build_it) {
3712  return FindSymbolNotEnforcingDepsHelper(pool_, name, build_it);
3713 }
3714 
3716  Symbol result = FindSymbolNotEnforcingDeps(name, build_it);
3717 
3718  if (result.IsNull()) return result;
3719 
3720  if (!pool_->enforce_dependencies_) {
3721  // Hack for CompilerUpgrader, and also used for lazily_build_dependencies_
3722  return result;
3723  }
3724 
3725  // Only find symbols which were defined in this file or one of its
3726  // dependencies.
3727  const FileDescriptor* file = result.GetFile();
3728  if (file == file_ || dependencies_.count(file) > 0) {
3729  unused_dependency_.erase(file);
3730  return result;
3731  }
3732 
3733  if (result.type == Symbol::PACKAGE) {
3734  // Arg, this is overcomplicated. The symbol is a package name. It could
3735  // be that the package was defined in multiple files. result.GetFile()
3736  // returns the first file we saw that used this package. We've determined
3737  // that that file is not a direct dependency of the file we are currently
3738  // building, but it could be that some other file which *is* a direct
3739  // dependency also defines the same package. We can't really rule out this
3740  // symbol unless none of the dependencies define it.
3741  if (IsInPackage(file_, name)) return result;
3742  for (std::set<const FileDescriptor*>::const_iterator it =
3743  dependencies_.begin();
3744  it != dependencies_.end(); ++it) {
3745  // Note: A dependency may be nullptr if it was not found or had errors.
3746  if (*it != nullptr && IsInPackage(*it, name)) return result;
3747  }
3748  }
3749 
3752  return kNullSymbol;
3753 }
3754 
3756  const std::string& name, const std::string& relative_to,
3757  ResolveMode resolve_mode, bool build_it) {
3759  undefine_resolved_name_.clear();
3760 
3761  if (!name.empty() && name[0] == '.') {
3762  // Fully-qualified name.
3763  return FindSymbol(name.substr(1), build_it);
3764  }
3765 
3766  // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
3767  // defined in multiple parent scopes, we only want to find "Bar.baz" in the
3768  // innermost one. E.g., the following should produce an error:
3769  // message Bar { message Baz {} }
3770  // message Foo {
3771  // message Bar {
3772  // }
3773  // optional Bar.Baz baz = 1;
3774  // }
3775  // So, we look for just "Foo" first, then look for "Bar.baz" within it if
3776  // found.
3777  std::string::size_type name_dot_pos = name.find_first_of('.');
3778  std::string first_part_of_name;
3779  if (name_dot_pos == std::string::npos) {
3780  first_part_of_name = name;
3781  } else {
3782  first_part_of_name = name.substr(0, name_dot_pos);
3783  }
3784 
3785  std::string scope_to_try(relative_to);
3786 
3787  while (true) {
3788  // Chop off the last component of the scope.
3789  std::string::size_type dot_pos = scope_to_try.find_last_of('.');
3790  if (dot_pos == std::string::npos) {
3791  return FindSymbol(name, build_it);
3792  } else {
3793  scope_to_try.erase(dot_pos);
3794  }
3795 
3796  // Append ".first_part_of_name" and try to find.
3797  std::string::size_type old_size = scope_to_try.size();
3798  scope_to_try.append(1, '.');
3799  scope_to_try.append(first_part_of_name);
3800  Symbol result = FindSymbol(scope_to_try, build_it);
3801  if (!result.IsNull()) {
3802  if (first_part_of_name.size() < name.size()) {
3803  // name is a compound symbol, of which we only found the first part.
3804  // Now try to look up the rest of it.
3805  if (result.IsAggregate()) {
3806  scope_to_try.append(name, first_part_of_name.size(),
3807  name.size() - first_part_of_name.size());
3808  result = FindSymbol(scope_to_try, build_it);
3809  if (result.IsNull()) {
3810  undefine_resolved_name_ = scope_to_try;
3811  }
3812  return result;
3813  } else {
3814  // We found a symbol but it's not an aggregate. Continue the loop.
3815  }
3816  } else {
3817  if (resolve_mode == LOOKUP_TYPES && !result.IsType()) {
3818  // We found a symbol but it's not a type. Continue the loop.
3819  } else {
3820  return result;
3821  }
3822  }
3823  }
3824 
3825  // Not found. Remove the name so we can try again.
3826  scope_to_try.erase(old_size);
3827  }
3828 }
3829 
3831  const std::string& name, const std::string& relative_to,
3832  DescriptorPool::PlaceholderType placeholder_type, ResolveMode resolve_mode,
3833  bool build_it) {
3834  Symbol result =
3835  LookupSymbolNoPlaceholder(name, relative_to, resolve_mode, build_it);
3836  if (result.IsNull() && pool_->allow_unknown_) {
3837  // Not found, but AllowUnknownDependencies() is enabled. Return a
3838  // placeholder instead.
3839  result = pool_->NewPlaceholderWithMutexHeld(name, placeholder_type);
3840  }
3841  return result;
3842 }
3843 
3845  bool last_was_period = false;
3846 
3847  for (int i = 0; i < name.size(); i++) {
3848  // I don't trust isalnum() due to locales. :(
3849  if (('a' <= name[i] && name[i] <= 'z') ||
3850  ('A' <= name[i] && name[i] <= 'Z') ||
3851  ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) {
3852  last_was_period = false;
3853  } else if (name[i] == '.') {
3854  if (last_was_period) return false;
3855  last_was_period = true;
3856  } else {
3857  return false;
3858  }
3859  }
3860 
3861  return !name.empty() && !last_was_period;
3862 }
3863 
3865  PlaceholderType placeholder_type) const {
3866  MutexLockMaybe lock(mutex_);
3867  return NewPlaceholderWithMutexHeld(name, placeholder_type);
3868 }
3869 
3871  const std::string& name, PlaceholderType placeholder_type) const {
3872  if (mutex_) {
3873  mutex_->AssertHeld();
3874  }
3875  // Compute names.
3876  const std::string* placeholder_full_name;
3877  const std::string* placeholder_name;
3878  const std::string* placeholder_package;
3879 
3880  if (!ValidateQualifiedName(name)) return kNullSymbol;
3881  if (name[0] == '.') {
3882  // Fully-qualified.
3883  placeholder_full_name = tables_->AllocateString(name.substr(1));
3884  } else {
3885  placeholder_full_name = tables_->AllocateString(name);
3886  }
3887 
3888  std::string::size_type dotpos = placeholder_full_name->find_last_of('.');
3889  if (dotpos != std::string::npos) {
3890  placeholder_package =
3891  tables_->AllocateString(placeholder_full_name->substr(0, dotpos));
3892  placeholder_name =
3893  tables_->AllocateString(placeholder_full_name->substr(dotpos + 1));
3894  } else {
3895  placeholder_package = &internal::GetEmptyString();
3896  placeholder_name = placeholder_full_name;
3897  }
3898 
3899  // Create the placeholders.
3900  FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld(
3901  *placeholder_full_name + ".placeholder.proto");
3902  placeholder_file->package_ = placeholder_package;
3903 
3904  if (placeholder_type == PLACEHOLDER_ENUM) {
3905  placeholder_file->enum_type_count_ = 1;
3906  placeholder_file->enum_types_ = tables_->AllocateArray<EnumDescriptor>(1);
3907 
3908  EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
3909  memset(static_cast<void*>(placeholder_enum), 0, sizeof(*placeholder_enum));
3910 
3911  placeholder_enum->full_name_ = placeholder_full_name;
3912  placeholder_enum->name_ = placeholder_name;
3913  placeholder_enum->file_ = placeholder_file;
3914  placeholder_enum->options_ = &EnumOptions::default_instance();
3915  placeholder_enum->is_placeholder_ = true;
3916  placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
3917 
3918  // Enums must have at least one value.
3919  placeholder_enum->value_count_ = 1;
3920  placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1);
3921 
3922  EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
3923  memset(static_cast<void*>(placeholder_value), 0,
3924  sizeof(*placeholder_value));
3925 
3926  placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE");
3927  // Note that enum value names are siblings of their type, not children.
3928  placeholder_value->full_name_ =
3929  placeholder_package->empty()
3930  ? placeholder_value->name_
3931  : tables_->AllocateString(*placeholder_package +
3932  ".PLACEHOLDER_VALUE");
3933 
3934  placeholder_value->number_ = 0;
3935  placeholder_value->type_ = placeholder_enum;
3936  placeholder_value->options_ = &EnumValueOptions::default_instance();
3937 
3938  return Symbol(placeholder_enum);
3939  } else {
3940  placeholder_file->message_type_count_ = 1;
3941  placeholder_file->message_types_ = tables_->AllocateArray<Descriptor>(1);
3942 
3943  Descriptor* placeholder_message = &placeholder_file->message_types_[0];
3944  memset(static_cast<void*>(placeholder_message), 0,
3945  sizeof(*placeholder_message));
3946 
3947  placeholder_message->full_name_ = placeholder_full_name;
3948  placeholder_message->name_ = placeholder_name;
3949  placeholder_message->file_ = placeholder_file;
3950  placeholder_message->options_ = &MessageOptions::default_instance();
3951  placeholder_message->is_placeholder_ = true;
3952  placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
3953 
3954  if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
3955  placeholder_message->extension_range_count_ = 1;
3956  placeholder_message->extension_ranges_ =
3957  tables_->AllocateArray<Descriptor::ExtensionRange>(1);
3958  placeholder_message->extension_ranges_->start = 1;
3959  // kMaxNumber + 1 because ExtensionRange::end is exclusive.
3960  placeholder_message->extension_ranges_->end =
3962  }
3963 
3964  return Symbol(placeholder_message);
3965  }
3966 }
3967 
3969  const std::string& name) const {
3970  MutexLockMaybe lock(mutex_);
3972 }
3973 
3975  const std::string& name) const {
3976  if (mutex_) {
3977  mutex_->AssertHeld();
3978  }
3979  FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
3980  memset(static_cast<void*>(placeholder), 0, sizeof(*placeholder));
3981 
3982  placeholder->name_ = tables_->AllocateString(name);
3983  placeholder->package_ = &internal::GetEmptyString();
3984  placeholder->pool_ = this;
3985  placeholder->options_ = &FileOptions::default_instance();
3988  placeholder->is_placeholder_ = true;
3989  placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2;
3990  placeholder->finished_building_ = true;
3991  // All other fields are zero or nullptr.
3992 
3993  return placeholder;
3994 }
3995 
3997  const void* parent, const std::string& name,
3998  const Message& proto, Symbol symbol) {
3999  // If the caller passed nullptr for the parent, the symbol is at file scope.
4000  // Use its file as the parent instead.
4001  if (parent == nullptr) parent = file_;
4002 
4003  if (tables_->AddSymbol(full_name, symbol)) {
4004  if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) {
4005  // This is only possible if there was already an error adding something of
4006  // the same name.
4007  if (!had_errors_) {
4008  GOOGLE_LOG(DFATAL) << "\"" << full_name
4009  << "\" not previously defined in "
4010  "symbols_by_name_, but was defined in "
4011  "symbols_by_parent_; this shouldn't be possible.";
4012  }
4013  return false;
4014  }
4015  return true;
4016  } else {
4017  const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile();
4018  if (other_file == file_) {
4019  std::string::size_type dot_pos = full_name.find_last_of('.');
4020  if (dot_pos == std::string::npos) {
4022  "\"" + full_name + "\" is already defined.");
4023  } else {
4025  "\"" + full_name.substr(dot_pos + 1) +
4026  "\" is already defined in \"" +
4027  full_name.substr(0, dot_pos) + "\".");
4028  }
4029  } else {
4030  // Symbol seems to have been defined in a different file.
4032  "\"" + full_name + "\" is already defined in file \"" +
4033  other_file->name() + "\".");
4034  }
4035  return false;
4036  }
4037 }
4038 
4040  const Message& proto,
4041  const FileDescriptor* file) {
4042  if (tables_->AddSymbol(name, Symbol(file))) {
4043  // Success. Also add parent package, if any.
4044  std::string::size_type dot_pos = name.find_last_of('.');
4045  if (dot_pos == std::string::npos) {
4046  // No parents.
4047  ValidateSymbolName(name, name, proto);
4048  } else {
4049  // Has parent.
4050  std::string* parent_name =
4051  tables_->AllocateString(name.substr(0, dot_pos));
4052  AddPackage(*parent_name, proto, file);
4053  ValidateSymbolName(name.substr(dot_pos + 1), name, proto);
4054  }
4055  } else {
4056  Symbol existing_symbol = tables_->FindSymbol(name);
4057  // It's OK to redefine a package.
4058  if (existing_symbol.type != Symbol::PACKAGE) {
4059  // Symbol seems to have been defined in a different file.
4061  "\"" + name +
4062  "\" is already defined (as something other than "
4063  "a package) in file \"" +
4064  existing_symbol.GetFile()->name() + "\".");
4065  }
4066  }
4067 }
4068 
4070  const std::string& full_name,
4071  const Message& proto) {
4072  if (name.empty()) {
4074  "Missing name.");
4075  } else {
4076  for (int i = 0; i < name.size(); i++) {
4077  // I don't trust isalnum() due to locales. :(
4078  if ((name[i] < 'a' || 'z' < name[i]) &&
4079  (name[i] < 'A' || 'Z' < name[i]) &&
4080  (name[i] < '0' || '9' < name[i]) && (name[i] != '_')) {
4082  "\"" + name + "\" is not a valid identifier.");
4083  }
4084  }
4085  }
4086 }
4087 
4088 // -------------------------------------------------------------------
4089 
4090 // This generic implementation is good for all descriptors except
4091 // FileDescriptor.
4092 template <class DescriptorT>
4094  const typename DescriptorT::OptionsType& orig_options,
4095  DescriptorT* descriptor, int options_field_tag) {
4096  std::vector<int> options_path;
4097  descriptor->GetLocationPath(&options_path);
4098  options_path.push_back(options_field_tag);
4099  AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
4100  orig_options, descriptor, options_path);
4101 }
4102 
4103 // We specialize for FileDescriptor.
4106  std::vector<int> options_path;
4107  options_path.push_back(FileDescriptorProto::kOptionsFieldNumber);
4108  // We add the dummy token so that LookupSymbol does the right thing.
4109  AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(),
4110  orig_options, descriptor, options_path);
4111 }
4112 
4113 template <class DescriptorT>
4116  const typename DescriptorT::OptionsType& orig_options,
4117  DescriptorT* descriptor, const std::vector<int>& options_path) {
4118  // We need to use a dummy pointer to work around a bug in older versions of
4119  // GCC. Otherwise, the following two lines could be replaced with:
4120  // typename DescriptorT::OptionsType* options =
4121  // tables_->AllocateMessage<typename DescriptorT::OptionsType>();
4122  typename DescriptorT::OptionsType* const dummy = nullptr;
4123  typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
4124 
4125  if (!orig_options.IsInitialized()) {
4126  AddError(name_scope + "." + element_name, orig_options,
4128  "Uninterpreted option is missing name or value.");
4129  return;
4130  }
4131 
4132  // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
4133  // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
4134  // reflection based method, which requires the Descriptor. However, we are in
4135  // the middle of building the descriptors, thus the deadlock.
4136  options->ParseFromString(orig_options.SerializeAsString());
4137  descriptor->options_ = options;
4138 
4139  // Don't add to options_to_interpret_ unless there were uninterpreted
4140  // options. This not only avoids unnecessary work, but prevents a
4141  // bootstrapping problem when building descriptors for descriptor.proto.
4142  // descriptor.proto does not contain any uninterpreted options, but
4143  // attempting to interpret options anyway will cause
4144  // OptionsType::GetDescriptor() to be called which may then deadlock since
4145  // we're still trying to build it.
4146  if (options->uninterpreted_option_size() > 0) {
4147  options_to_interpret_.push_back(OptionsToInterpret(
4148  name_scope, element_name, options_path, &orig_options, options));
4149  }
4150 }
4151 
4152 // A common pattern: We want to convert a repeated field in the descriptor
4153 // to an array of values, calling some method to build each value.
4154 #define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \
4155  OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \
4156  AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \
4157  for (int i = 0; i < INPUT.NAME##_size(); i++) { \
4158  METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
4159  }
4160 
4162  const FileDescriptorProto& proto, int from_here) {
4163  std::string error_message("File recursively imports itself: ");
4164  for (int i = from_here; i < tables_->pending_files_.size(); i++) {
4165  error_message.append(tables_->pending_files_[i]);
4166  error_message.append(" -> ");
4167  }
4168  error_message.append(proto.name());
4169 
4170  if (from_here < tables_->pending_files_.size() - 1) {
4171  AddError(tables_->pending_files_[from_here + 1], proto,
4173  } else {
4175  error_message);
4176  }
4177 }
4178 
4180  int index) {
4181  AddError(proto.dependency(index), proto,
4183  "Import \"" + proto.dependency(index) + "\" was listed twice.");
4184 }
4185 
4187  int index) {
4189  if (pool_->fallback_database_ == nullptr) {
4190  message = "Import \"" + proto.dependency(index) + "\" has not been loaded.";
4191  } else {
4192  message = "Import \"" + proto.dependency(index) +
4193  "\" was not found or had errors.";
4194  }
4195  AddError(proto.dependency(index), proto,
4197 }
4198 
4199 static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
4200  const FileDescriptorProto& proto) {
4201  FileDescriptorProto existing_proto;
4202  existing_file->CopyTo(&existing_proto);
4203  // TODO(liujisi): Remove it when CopyTo supports copying syntax params when
4204  // syntax="proto2".
4205  if (existing_file->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
4206  proto.has_syntax()) {
4207  existing_proto.set_syntax(
4208  existing_file->SyntaxName(existing_file->syntax()));
4209  }
4210 
4211  return existing_proto.SerializeAsString() == proto.SerializeAsString();
4212 }
4213 
4215  const FileDescriptorProto& proto) {
4216  filename_ = proto.name();
4217 
4218  // Check if the file already exists and is identical to the one being built.
4219  // Note: This only works if the input is canonical -- that is, it
4220  // fully-qualifies all type names, has no UninterpretedOptions, etc.
4221  // This is fine, because this idempotency "feature" really only exists to
4222  // accommodate one hack in the proto1->proto2 migration layer.
4223  const FileDescriptor* existing_file = tables_->FindFile(filename_);
4224  if (existing_file != nullptr) {
4225  // File already in pool. Compare the existing one to the input.
4226  if (ExistingFileMatchesProto(existing_file, proto)) {
4227  // They're identical. Return the existing descriptor.
4228  return existing_file;
4229  }
4230 
4231  // Not a match. The error will be detected and handled later.
4232  }
4233 
4234  // Check to see if this file is already on the pending files list.
4235  // TODO(kenton): Allow recursive imports? It may not work with some
4236  // (most?) programming languages. E.g., in C++, a forward declaration
4237  // of a type is not sufficient to allow it to be used even in a
4238  // generated header file due to inlining. This could perhaps be
4239  // worked around using tricks involving inserting #include statements
4240  // mid-file, but that's pretty ugly, and I'm pretty sure there are
4241  // some languages out there that do not allow recursive dependencies
4242  // at all.
4243  for (int i = 0; i < tables_->pending_files_.size(); i++) {
4244  if (tables_->pending_files_[i] == proto.name()) {
4245  AddRecursiveImportError(proto, i);
4246  return nullptr;
4247  }
4248  }
4249 
4250  // If we have a fallback_database_, and we aren't doing lazy import building,
4251  // attempt to load all dependencies now, before checkpointing tables_. This
4252  // avoids confusion with recursive checkpoints.
4254  if (pool_->fallback_database_ != nullptr) {
4255  tables_->pending_files_.push_back(proto.name());
4256  for (int i = 0; i < proto.dependency_size(); i++) {
4257  if (tables_->FindFile(proto.dependency(i)) == nullptr &&
4258  (pool_->underlay_ == nullptr ||
4260  nullptr)) {
4261  // We don't care what this returns since we'll find out below anyway.
4263  }
4264  }
4265  tables_->pending_files_.pop_back();
4266  }
4267  }
4268 
4269  // Checkpoint the tables so that we can roll back if something goes wrong.
4270  tables_->AddCheckpoint();
4271 
4272  FileDescriptor* result = BuildFileImpl(proto);
4273 
4275  if (result) {
4276  tables_->ClearLastCheckpoint();
4277  result->finished_building_ = true;
4278  } else {
4279  tables_->RollbackToLastCheckpoint();
4280  }
4281 
4282  return result;
4283 }
4284 
4286  const FileDescriptorProto& proto) {
4287  FileDescriptor* result = tables_->Allocate<FileDescriptor>();
4288  file_ = result;
4289 
4290  result->is_placeholder_ = false;
4291  result->finished_building_ = false;
4292  SourceCodeInfo* info = nullptr;
4293  if (proto.has_source_code_info()) {
4294  info = tables_->AllocateMessage<SourceCodeInfo>();
4295  info->CopyFrom(proto.source_code_info());
4296  result->source_code_info_ = info;
4297  } else {
4299  }
4300 
4301  file_tables_ = tables_->AllocateFileTables();
4303 
4304  if (!proto.has_name()) {
4306  "Missing field: FileDescriptorProto.name.");
4307  }
4308 
4309  // TODO(liujisi): Report error when the syntax is empty after all the protos
4310  // have added the syntax statement.
4311  if (proto.syntax().empty() || proto.syntax() == "proto2") {
4313  } else if (proto.syntax() == "proto3") {
4315  } else {
4318  "Unrecognized syntax: " + proto.syntax());
4319  }
4320 
4321  result->name_ = tables_->AllocateString(proto.name());
4322  if (proto.has_package()) {
4323  result->package_ = tables_->AllocateString(proto.package());
4324  } else {
4325  // We cannot rely on proto.package() returning a valid string if
4326  // proto.has_package() is false, because we might be running at static
4327  // initialization time, in which case default values have not yet been
4328  // initialized.
4329  result->package_ = tables_->AllocateString("");
4330  }
4331  result->pool_ = pool_;
4332 
4333  // Add to tables.
4334  if (!tables_->AddFile(result)) {
4336  "A file with this name is already in the pool.");
4337  // Bail out early so that if this is actually the exact same file, we
4338  // don't end up reporting that every single symbol is already defined.
4339  return nullptr;
4340  }
4341  if (!result->package().empty()) {
4342  AddPackage(result->package(), proto, result);
4343  }
4344 
4345  // Make sure all dependencies are loaded.
4346  std::set<std::string> seen_dependencies;
4347  result->dependency_count_ = proto.dependency_size();
4348  result->dependencies_ =
4349  tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
4351  result->dependencies_once_ = tables_->AllocateOnceDynamic();
4352  result->dependencies_names_ =
4353  tables_->AllocateArray<const std::string*>(proto.dependency_size());
4354  if (proto.dependency_size() > 0) {
4355  memset(result->dependencies_names_, 0,
4356  sizeof(*result->dependencies_names_) * proto.dependency_size());
4357  }
4358  } else {
4359  result->dependencies_once_ = nullptr;
4360  result->dependencies_names_ = nullptr;
4361  }
4362  unused_dependency_.clear();
4363  std::set<int> weak_deps;
4364  for (int i = 0; i < proto.weak_dependency_size(); ++i) {
4365  weak_deps.insert(proto.weak_dependency(i));
4366  }
4367  for (int i = 0; i < proto.dependency_size(); i++) {
4368  if (!seen_dependencies.insert(proto.dependency(i)).second) {
4369  AddTwiceListedError(proto, i);
4370  }
4371 
4372  const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
4373  if (dependency == nullptr && pool_->underlay_ != nullptr) {
4374  dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
4375  }
4376 
4377  if (dependency == result) {
4378  // Recursive import. dependency/result is not fully initialized, and it's
4379  // dangerous to try to do anything with it. The recursive import error
4380  // will be detected and reported in DescriptorBuilder::BuildFile().
4381  return nullptr;
4382  }
4383 
4384  if (dependency == nullptr) {
4386  if (pool_->allow_unknown_ ||
4387  (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
4388  dependency =
4390  } else {
4391  AddImportError(proto, i);
4392  }
4393  }
4394  } else {
4395  // Add to unused_dependency_ to track unused imported files.
4396  // Note: do not track unused imported files for public import.
4398  (pool_->unused_import_track_files_.find(proto.name()) !=
4400  (dependency->public_dependency_count() == 0)) {
4401  unused_dependency_.insert(dependency);
4402  }
4403  }
4404 
4405  result->dependencies_[i] = dependency;
4406  if (pool_->lazily_build_dependencies_ && !dependency) {
4407  result->dependencies_names_[i] =
4408  tables_->AllocateString(proto.dependency(i));
4409  }
4410  }
4411 
4412  // Check public dependencies.
4413  int public_dependency_count = 0;
4414  result->public_dependencies_ =
4415  tables_->AllocateArray<int>(proto.public_dependency_size());
4416  for (int i = 0; i < proto.public_dependency_size(); i++) {
4417  // Only put valid public dependency indexes.
4418  int index = proto.public_dependency(i);
4419  if (index >= 0 && index < proto.dependency_size()) {
4420  result->public_dependencies_[public_dependency_count++] = index;
4421  // Do not track unused imported files for public import.
4422  // Calling dependency(i) builds that file when doing lazy imports,
4423  // need to avoid doing this. Unused dependency detection isn't done
4424  // when building lazily, anyways.
4426  unused_dependency_.erase(result->dependency(index));
4427  }
4428  } else {
4430  "Invalid public dependency index.");
4431  }
4432  }
4433  result->public_dependency_count_ = public_dependency_count;
4434 
4435  // Build dependency set
4436  dependencies_.clear();
4437  // We don't/can't do proper dependency error checking when
4438  // lazily_build_dependencies_, and calling dependency(i) will force
4439  // a dependency to be built, which we don't want.
4441  for (int i = 0; i < result->dependency_count(); i++) {
4443  }
4444  }
4445 
4446  // Check weak dependencies.
4447  int weak_dependency_count = 0;
4448  result->weak_dependencies_ =
4449  tables_->AllocateArray<int>(proto.weak_dependency_size());
4450  for (int i = 0; i < proto.weak_dependency_size(); i++) {
4451  int index = proto.weak_dependency(i);
4452  if (index >= 0 && index < proto.dependency_size()) {
4453  result->weak_dependencies_[weak_dependency_count++] = index;
4454  } else {
4456  "Invalid weak dependency index.");
4457  }
4458  }
4459  result->weak_dependency_count_ = weak_dependency_count;
4460 
4461  // Convert children.
4462  BUILD_ARRAY(proto, result, message_type, BuildMessage, nullptr);
4463  BUILD_ARRAY(proto, result, enum_type, BuildEnum, nullptr);
4464  BUILD_ARRAY(proto, result, service, BuildService, nullptr);
4465  BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr);
4466 
4467  // Copy options.
4468  if (!proto.has_options()) {
4469  result->options_ = nullptr; // Will set to default_instance later.
4470  } else {
4471  AllocateOptions(proto.options(), result);
4472  }
4473 
4474  // Note that the following steps must occur in exactly the specified order.
4475 
4476  // Cross-link.
4477  CrossLinkFile(result, proto);
4478 
4479  // Interpret any remaining uninterpreted options gathered into
4480  // options_to_interpret_ during descriptor building. Cross-linking has made
4481  // extension options known, so all interpretations should now succeed.
4482  if (!had_errors_) {
4483  OptionInterpreter option_interpreter(this);
4484  for (std::vector<OptionsToInterpret>::iterator iter =
4485  options_to_interpret_.begin();
4486  iter != options_to_interpret_.end(); ++iter) {
4487  option_interpreter.InterpretOptions(&(*iter));
4488  }
4489  options_to_interpret_.clear();
4490  if (info != nullptr) {
4491  option_interpreter.UpdateSourceCodeInfo(info);
4492  }
4493  }
4494 
4495  // Validate options. See comments at InternalSetLazilyBuildDependencies about
4496  // error checking and lazy import building.
4498  ValidateFileOptions(result, proto);
4499  }
4500 
4501  // Additional naming conflict check for map entry types. Only need to check
4502  // this if there are already errors.
4503  if (had_errors_) {
4504  for (int i = 0; i < proto.message_type_size(); ++i) {
4505  DetectMapConflicts(result->message_type(i), proto.message_type(i));
4506  }
4507  }
4508 
4509 
4510  // Again, see comments at InternalSetLazilyBuildDependencies about error
4511  // checking.
4513  LogUnusedDependency(proto, result);
4514  }
4515 
4516  if (had_errors_) {
4517  return nullptr;
4518  } else {
4519  return result;
4520  }
4521 }
4522 
4523 
4525  const std::string& scope, const std::string& proto_name) {
4526  std::string* full_name;
4527  if (scope.empty()) {
4528  full_name = tables_->AllocateString(proto_name);
4529  } else {
4530  full_name = tables_->AllocateEmptyString();
4531  *full_name = StrCat(scope, ".", proto_name);
4532  }
4533  return full_name;
4534 }
4535 
4537  const Descriptor* parent,
4538  Descriptor* result) {
4539  const std::string& scope =
4540  (parent == nullptr) ? file_->package() : parent->full_name();
4541  std::string* full_name = AllocateNameString(scope, proto.name());
4542  ValidateSymbolName(proto.name(), *full_name, proto);
4543 
4544  result->name_ = tables_->AllocateString(proto.name());
4545  result->full_name_ = full_name;
4546  result->file_ = file_;
4547  result->containing_type_ = parent;
4548  result->is_placeholder_ = false;
4549  result->is_unqualified_placeholder_ = false;
4550 
4551  // Build oneofs first so that fields and extension ranges can refer to them.
4552  BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result);
4553  BUILD_ARRAY(proto, result, field, BuildField, result);
4554  BUILD_ARRAY(proto, result, nested_type, BuildMessage, result);
4555  BUILD_ARRAY(proto, result, enum_type, BuildEnum, result);
4556  BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
4557  BUILD_ARRAY(proto, result, extension, BuildExtension, result);
4558  BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result);
4559 
4560  // Copy reserved names.
4561  int reserved_name_count = proto.reserved_name_size();
4562  result->reserved_name_count_ = reserved_name_count;
4563  result->reserved_names_ =
4564  tables_->AllocateArray<const std::string*>(reserved_name_count);
4565  for (int i = 0; i < reserved_name_count; ++i) {
4566  result->reserved_names_[i] =
4567  tables_->AllocateString(proto.reserved_name(i));
4568  }
4569 
4570  // Copy options.
4571  if (!proto.has_options()) {
4572  result->options_ = nullptr; // Will set to default_instance later.
4573  } else {
4574  AllocateOptions(proto.options(), result,
4576  }
4577 
4578  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
4579 
4580 
4581  for (int i = 0; i < proto.reserved_range_size(); i++) {
4582  const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i);
4583  for (int j = i + 1; j < proto.reserved_range_size(); j++) {
4584  const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j);
4585  if (range1.end() > range2.start() && range2.end() > range1.start()) {
4586  AddError(result->full_name(), proto.reserved_range(i),
4588  strings::Substitute("Reserved range $0 to $1 overlaps with "
4589  "already-defined range $2 to $3.",
4590  range2.start(), range2.end() - 1,
4591  range1.start(), range1.end() - 1));
4592  }
4593  }
4594  }
4595 
4596  HASH_SET<std::string> reserved_name_set;
4597  for (int i = 0; i < proto.reserved_name_size(); i++) {
4598  const std::string& name = proto.reserved_name(i);
4599  if (reserved_name_set.find(name) == reserved_name_set.end()) {
4600  reserved_name_set.insert(name);
4601  } else {
4604  "Field name \"$0\" is reserved multiple times.", name));
4605  }
4606  }
4607 
4608  for (int i = 0; i < result->field_count(); i++) {
4609  const FieldDescriptor* field = result->field(i);
4610  for (int j = 0; j < result->extension_range_count(); j++) {
4611  const Descriptor::ExtensionRange* range = result->extension_range(j);
4612  if (range->start <= field->number() && field->number() < range->end) {
4613  AddError(
4614  field->full_name(), proto.extension_range(j),
4617  "Extension range $0 to $1 includes field \"$2\" ($3).",
4618  range->start, range->end - 1, field->name(), field->number()));
4619  }
4620  }
4621  for (int j = 0; j < result->reserved_range_count(); j++) {
4622  const Descriptor::ReservedRange* range = result->reserved_range(j);
4623  if (range->start <= field->number() && field->number() < range->end) {
4624  AddError(field->full_name(), proto.reserved_range(j),
4626  strings::Substitute("Field \"$0\" uses reserved number $1.",
4627  field->name(), field->number()));
4628  }
4629  }
4630  if (reserved_name_set.find(field->name()) != reserved_name_set.end()) {
4631  AddError(
4632  field->full_name(), proto.field(i),
4634  strings::Substitute("Field name \"$0\" is reserved.", field->name()));
4635  }
4636  }
4637 
4638  // Check that extension ranges don't overlap and don't include
4639  // reserved field numbers.
4640  for (int i = 0; i < result->extension_range_count(); i++) {
4641  const Descriptor::ExtensionRange* range1 = result->extension_range(i);
4642  for (int j = 0; j < result->reserved_range_count(); j++) {
4643  const Descriptor::ReservedRange* range2 = result->reserved_range(j);
4644  if (range1->end > range2->start && range2->end > range1->start) {
4645  AddError(result->full_name(), proto.extension_range(i),
4647  strings::Substitute("Extension range $0 to $1 overlaps with "
4648  "reserved range $2 to $3.",
4649  range1->start, range1->end - 1,
4650  range2->start, range2->end - 1));
4651  }
4652  }
4653  for (int j = i + 1; j < result->extension_range_count(); j++) {
4654  const Descriptor::ExtensionRange* range2 = result->extension_range(j);
4655  if (range1->end > range2->start && range2->end > range1->start) {
4656  AddError(result->full_name(), proto.extension_range(i),
4658  strings::Substitute("Extension range $0 to $1 overlaps with "
4659  "already-defined range $2 to $3.",
4660  range2->start, range2->end - 1,
4661  range1->start, range1->end - 1));
4662  }
4663  }
4664  }
4665 }
4666 
4668  const Descriptor* parent,
4669  FieldDescriptor* result,
4670  bool is_extension) {
4671  const std::string& scope =
4672  (parent == nullptr) ? file_->package() : parent->full_name();
4673  std::string* full_name = AllocateNameString(scope, proto.name());
4674  ValidateSymbolName(proto.name(), *full_name, proto);
4675 
4676  result->name_ = tables_->AllocateString(proto.name());
4677  result->full_name_ = full_name;
4678  result->file_ = file_;
4679  result->number_ = proto.number();
4680  result->is_extension_ = is_extension;
4681 
4682  // If .proto files follow the style guide then the name should already be
4683  // lower-cased. If that's the case we can just reuse the string we
4684  // already allocated rather than allocate a new one.
4685  std::string lowercase_name(proto.name());
4686  LowerString(&lowercase_name);
4687  if (lowercase_name == proto.name()) {
4688  result->lowercase_name_ = result->name_;
4689  } else {
4690  result->lowercase_name_ = tables_->AllocateString(lowercase_name);
4691  }
4692 
4693  // Don't bother with the above optimization for camel-case names since
4694  // .proto files that follow the guide shouldn't be using names in this
4695  // format, so the optimization wouldn't help much.
4696  result->camelcase_name_ =
4697  tables_->AllocateString(ToCamelCase(proto.name(),
4698  /* lower_first = */ true));
4699 
4700  if (proto.has_json_name()) {
4701  result->has_json_name_ = true;
4702  result->json_name_ = tables_->AllocateString(proto.json_name());
4703  } else {
4704  result->has_json_name_ = false;
4705  result->json_name_ = tables_->AllocateString(ToJsonName(proto.name()));
4706  }
4707 
4708  // Some compilers do not allow static_cast directly between two enum types,
4709  // so we must cast to int first.
4710  result->type_ = static_cast<FieldDescriptor::Type>(
4711  implicit_cast<int>(proto.type()));
4712  result->label_ = static_cast<FieldDescriptor::Label>(
4713  implicit_cast<int>(proto.label()));
4714 
4715  // An extension cannot have a required field (b/13365836).
4716  if (result->is_extension_ &&
4718  AddError(result->full_name(), proto,
4719  // Error location `TYPE`: we would really like to indicate
4720  // `LABEL`, but the `ErrorLocation` enum has no entry for this, and
4721  // we don't necessarily know about all implementations of the
4722  // `ErrorCollector` interface to extend them to handle the new
4723  // error location type properly.
4725  "Message extensions cannot have required fields.");
4726  }
4727 
4728  // Some of these may be filled in when cross-linking.
4729  result->containing_type_ = nullptr;
4730  result->extension_scope_ = nullptr;
4731  result->message_type_ = nullptr;
4732  result->enum_type_ = nullptr;
4733  result->type_name_ = nullptr;
4734  result->type_once_ = nullptr;
4735  result->default_value_enum_ = nullptr;
4736  result->default_value_enum_name_ = nullptr;
4737 
4738  result->has_default_value_ = proto.has_default_value();
4739  if (proto.has_default_value() && result->is_repeated()) {
4740  AddError(result->full_name(), proto,
4742  "Repeated fields can't have default values.");
4743  }
4744 
4745  if (proto.has_type()) {
4746  if (proto.has_default_value()) {
4747  char* end_pos = nullptr;
4748  switch (result->cpp_type()) {
4750  result->default_value_int32_ =
4751  strtol(proto.default_value().c_str(), &end_pos, 0);
4752  break;
4754  result->default_value_int64_ =
4755  strto64(proto.default_value().c_str(), &end_pos, 0);
4756  break;
4758  result->default_value_uint32_ =
4759  strtoul(proto.default_value().c_str(), &end_pos, 0);
4760  break;
4762  result->default_value_uint64_ =
4763  strtou64(proto.default_value().c_str(), &end_pos, 0);
4764  break;
4766  if (proto.default_value() == "inf") {
4767  result->default_value_float_ =
4768  std::numeric_limits<float>::infinity();
4769  } else if (proto.default_value() == "-inf") {
4770  result->default_value_float_ =
4771  -std::numeric_limits<float>::infinity();
4772  } else if (proto.default_value() == "nan") {
4773  result->default_value_float_ =
4774  std::numeric_limits<float>::quiet_NaN();
4775  } else {
4777  io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos));
4778  }
4779  break;
4781  if (proto.default_value() == "inf") {
4782  result->default_value_double_ =
4783  std::numeric_limits<double>::infinity();
4784  } else if (proto.default_value() == "-inf") {
4785  result->default_value_double_ =
4786  -std::numeric_limits<double>::infinity();
4787  } else if (proto.default_value() == "nan") {
4788  result->default_value_double_ =
4789  std::numeric_limits<double>::quiet_NaN();
4790  } else {
4791  result->default_value_double_ =
4792  io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
4793  }
4794  break;
4796  if (proto.default_value() == "true") {
4797  result->default_value_bool_ = true;
4798  } else if (proto.default_value() == "false") {
4799  result->default_value_bool_ = false;
4800  } else {
4801  AddError(result->full_name(), proto,
4803  "Boolean default must be true or false.");
4804  }
4805  break;
4807  // This will be filled in when cross-linking.
4808  result->default_value_enum_ = nullptr;
4809  break;
4811  if (result->type() == FieldDescriptor::TYPE_BYTES) {
4812  result->default_value_string_ = tables_->AllocateString(
4814  } else {
4815  result->default_value_string_ =
4816  tables_->AllocateString(proto.default_value());
4817  }
4818  break;
4820  AddError(result->full_name(), proto,
4822  "Messages can't have default values.");
4823  result->has_default_value_ = false;
4824  break;
4825  }
4826 
4827  if (end_pos != nullptr) {
4828  // end_pos is only set non-null by the parsers for numeric types,
4829  // above. This checks that the default was non-empty and had no extra
4830  // junk after the end of the number.
4831  if (proto.default_value().empty() || *end_pos != '\0') {
4832  AddError(result->full_name(), proto,
4834  "Couldn't parse default value \"" + proto.default_value() +
4835  "\".");
4836  }
4837  }
4838  } else {
4839  // No explicit default value
4840  switch (result->cpp_type()) {
4842  result->default_value_int32_ = 0;
4843  break;
4845  result->default_value_int64_ = 0;
4846  break;
4848  result->default_value_uint32_ = 0;
4849  break;
4851  result->default_value_uint64_ = 0;
4852  break;
4854  result->default_value_float_ = 0.0f;
4855  break;
4857  result->default_value_double_ = 0.0;
4858  break;
4860  result->default_value_bool_ = false;
4861  break;
4863  // This will be filled in when cross-linking.
4864  result->default_value_enum_ = nullptr;
4865  break;
4868  break;
4870  break;
4871  }
4872  }
4873  }
4874 
4875  if (result->number() <= 0) {
4877  "Field numbers must be positive integers.");
4878  } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
4879  // Only validate that the number is within the valid field range if it is
4880  // not an extension. Since extension numbers are validated with the
4881  // extendee's valid set of extension numbers, and those are in turn
4882  // validated against the max allowed number, the check is unnecessary for
4883  // extension fields.
4884  // This avoids cross-linking issues that arise when attempting to check if
4885  // the extendee is a message_set_wire_format message, which has a higher max
4886  // on extension numbers.
4888  strings::Substitute("Field numbers cannot be greater than $0.",
4890  } else if (result->number() >= FieldDescriptor::kFirstReservedNumber &&
4894  "Field numbers $0 through $1 are reserved for the protocol "
4895  "buffer library implementation.",
4898  }
4899 
4900  if (is_extension) {
4901  if (!proto.has_extendee()) {
4902  AddError(result->full_name(), proto,
4904  "FieldDescriptorProto.extendee not set for extension field.");
4905  }
4906 
4907  result->extension_scope_ = parent;
4908 
4909  if (proto.has_oneof_index()) {
4911  "FieldDescriptorProto.oneof_index should not be set for "
4912  "extensions.");
4913  }
4914 
4915  // Fill in later (maybe).
4916  result->containing_oneof_ = nullptr;
4917  } else {
4918  if (proto.has_extendee()) {
4919  AddError(result->full_name(), proto,
4921  "FieldDescriptorProto.extendee set for non-extension field.");
4922  }
4923 
4924  result->containing_type_ = parent;
4925 
4926  if (proto.has_oneof_index()) {
4927  if (proto.oneof_index() < 0 ||
4928  proto.oneof_index() >= parent->oneof_decl_count()) {
4929  AddError(result->full_name(), proto,
4931  strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
4932  "out of range for type \"$1\".",
4933  proto.oneof_index(), parent->name()));
4934  result->containing_oneof_ = nullptr;
4935  } else {
4936  result->containing_oneof_ = parent->oneof_decl(proto.oneof_index());
4937  }
4938  } else {
4939  result->containing_oneof_ = nullptr;
4940  }
4941  }
4942 
4943  // Copy options.
4944  if (!proto.has_options()) {
4945  result->options_ = nullptr; // Will set to default_instance later.
4946  } else {
4947  AllocateOptions(proto.options(), result,
4949  }
4950 
4951 
4952  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
4953 }
4954 
4956  const DescriptorProto::ExtensionRange& proto, const Descriptor* parent,
4957  Descriptor::ExtensionRange* result) {
4958  result->start = proto.start();
4959  result->end = proto.end();
4960  if (result->start <= 0) {
4962  "Extension numbers must be positive integers.");
4963  }
4964 
4965  // Checking of the upper bound of the extension range is deferred until after
4966  // options interpreting. This allows messages with message_set_wire_format to
4967  // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
4968  // numbers are actually used as int32s in the message_set_wire_format.
4969 
4970  if (result->start >= result->end) {
4972  "Extension range end number must be greater than start number.");
4973  }
4974 
4975  if (!proto.has_options()) {
4976  result->options_ = nullptr; // Will set to default_instance later.
4977  } else {
4978  std::vector<int> options_path;
4979  parent->GetLocationPath(&options_path);
4980  options_path.push_back(DescriptorProto::kExtensionRangeFieldNumber);
4981  // find index of this extension range in order to compute path
4982  int index;
4983  for (index = 0; parent->extension_ranges_ + index != result; index++) {
4984  }
4985  options_path.push_back(index);
4987  AllocateOptionsImpl(parent->full_name(), parent->full_name(),
4988  proto.options(), result, options_path);
4989  }
4990 }
4991 
4993  const DescriptorProto::ReservedRange& proto, const Descriptor* parent,
4994  Descriptor::ReservedRange* result) {
4995  result->start = proto.start();
4996  result->end = proto.end();
4997  if (result->start <= 0) {
4999  "Reserved numbers must be positive integers.");
5000  }
5001 }
5002 
5005  const EnumDescriptor* parent, EnumDescriptor::ReservedRange* result) {
5006  result->start = proto.start();
5007  result->end = proto.end();
5008 
5009  if (result->start > result->end) {
5011  "Reserved range end number must be greater than start number.");
5012  }
5013 }
5014 
5016  Descriptor* parent,
5017  OneofDescriptor* result) {
5018  std::string* full_name =
5019  AllocateNameString(parent->full_name(), proto.name());
5020  ValidateSymbolName(proto.name(), *full_name, proto);
5021 
5022  result->name_ = tables_->AllocateString(proto.name());
5023  result->full_name_ = full_name;
5024 
5025  result->containing_type_ = parent;
5026 
5027  // We need to fill these in later.
5028  result->field_count_ = 0;
5029  result->fields_ = nullptr;
5030 
5031  // Copy options.
5032  if (!proto.has_options()) {
5033  result->options_ = nullptr; // Will set to default_instance later.
5034  } else {
5035  AllocateOptions(proto.options(), result,
5037  }
5038 
5039  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5040 }
5041 
5043  const EnumDescriptorProto& proto, const EnumDescriptor* result) {
5044 
5045  // Check that enum labels are still unique when we remove the enum prefix from
5046  // values that have it.
5047  //
5048  // This will fail for something like:
5049  //
5050  // enum MyEnum {
5051  // MY_ENUM_FOO = 0;
5052  // FOO = 1;
5053  // }
5054  //
5055  // By enforcing this reasonable constraint, we allow code generators to strip
5056  // the prefix and/or PascalCase it without creating conflicts. This can lead
5057  // to much nicer language-specific enums like:
5058  //
5059  // enum NameType {
5060  // FirstName = 1,
5061  // LastName = 2,
5062  // }
5063  //
5064  // Instead of:
5065  //
5066  // enum NameType {
5067  // NAME_TYPE_FIRST_NAME = 1,
5068  // NAME_TYPE_LAST_NAME = 2,
5069  // }
5070  PrefixRemover remover(result->name());
5071  std::map<std::string, const EnumValueDescriptor*> values;
5072  for (int i = 0; i < result->value_count(); i++) {
5073  const EnumValueDescriptor* value = result->value(i);
5074  std::string stripped =
5075  EnumValueToPascalCase(remover.MaybeRemove(value->name()));
5076  std::pair<std::map<std::string, const EnumValueDescriptor*>::iterator, bool>
5077  insert_result = values.insert(std::make_pair(stripped, value));
5078  bool inserted = insert_result.second;
5079 
5080  // We don't throw the error if the two conflicting symbols are identical, or
5081  // if they map to the same number. In the former case, the normal symbol
5082  // duplication error will fire so we don't need to (and its error message
5083  // will make more sense). We allow the latter case so users can create
5084  // aliases which add or remove the prefix (code generators that do prefix
5085  // stripping should de-dup the labels in this case).
5086  if (!inserted && insert_result.first->second->name() != value->name() &&
5087  insert_result.first->second->number() != value->number()) {
5088  std::string error_message =
5089  "Enum name " + value->name() + " has the same name as " +
5090  values[stripped]->name() +
5091  " if you ignore case and strip out the enum name prefix (if any). "
5092  "This is error-prone and can lead to undefined behavior. "
5093  "Please avoid doing this. If you are using allow_alias, please "
5094  "assign the same numeric value to both enums.";
5095  // There are proto2 enums out there with conflicting names, so to preserve
5096  // compatibility we issue only a warning for proto2.
5097  if (result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) {
5098  AddWarning(value->full_name(), proto.value(i),
5099  DescriptorPool::ErrorCollector::NAME, error_message);
5100  } else {
5101  AddError(value->full_name(), proto.value(i),
5102  DescriptorPool::ErrorCollector::NAME, error_message);
5103  }
5104  }
5105  }
5106 }
5107 
5109  const Descriptor* parent,
5110  EnumDescriptor* result) {
5111  const std::string& scope =
5112  (parent == nullptr) ? file_->package() : parent->full_name();
5113  std::string* full_name = AllocateNameString(scope, proto.name());
5114  ValidateSymbolName(proto.name(), *full_name, proto);
5115 
5116  result->name_ = tables_->AllocateString(proto.name());
5117  result->full_name_ = full_name;
5118  result->file_ = file_;
5119  result->containing_type_ = parent;
5120  result->is_placeholder_ = false;
5121  result->is_unqualified_placeholder_ = false;
5122 
5123  if (proto.value_size() == 0) {
5124  // We cannot allow enums with no values because this would mean there
5125  // would be no valid default value for fields of this type.
5127  "Enums must contain at least one value.");
5128  }
5129 
5130  BUILD_ARRAY(proto, result, value, BuildEnumValue, result);
5131  BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result);
5132 
5133  // Copy reserved names.
5134  int reserved_name_count = proto.reserved_name_size();
5135  result->reserved_name_count_ = reserved_name_count;
5136  result->reserved_names_ =
5137  tables_->AllocateArray<const std::string*>(reserved_name_count);
5138  for (int i = 0; i < reserved_name_count; ++i) {
5139  result->reserved_names_[i] =
5140  tables_->AllocateString(proto.reserved_name(i));
5141  }
5142 
5143  CheckEnumValueUniqueness(proto, result);
5144 
5145  // Copy options.
5146  if (!proto.has_options()) {
5147  result->options_ = nullptr; // Will set to default_instance later.
5148  } else {
5149  AllocateOptions(proto.options(), result,
5151  }
5152 
5153  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5154 
5155  for (int i = 0; i < proto.reserved_range_size(); i++) {
5157  proto.reserved_range(i);
5158  for (int j = i + 1; j < proto.reserved_range_size(); j++) {
5160  proto.reserved_range(j);
5161  if (range1.end() >= range2.start() && range2.end() >= range1.start()) {
5162  AddError(result->full_name(), proto.reserved_range(i),
5164  strings::Substitute("Reserved range $0 to $1 overlaps with "
5165  "already-defined range $2 to $3.",
5166  range2.start(), range2.end(),
5167  range1.start(), range1.end()));
5168  }
5169  }
5170  }
5171 
5172  HASH_SET<std::string> reserved_name_set;
5173  for (int i = 0; i < proto.reserved_name_size(); i++) {
5174  const std::string& name = proto.reserved_name(i);
5175  if (reserved_name_set.find(name) == reserved_name_set.end()) {
5176  reserved_name_set.insert(name);
5177  } else {
5180  "Enum value \"$0\" is reserved multiple times.", name));
5181  }
5182  }
5183 
5184  for (int i = 0; i < result->value_count(); i++) {
5185  const EnumValueDescriptor* value = result->value(i);
5186  for (int j = 0; j < result->reserved_range_count(); j++) {
5187  const EnumDescriptor::ReservedRange* range = result->reserved_range(j);
5188  if (range->start <= value->number() && value->number() <= range->end) {
5189  AddError(
5190  value->full_name(), proto.reserved_range(j),
5192  strings::Substitute("Enum value \"$0\" uses reserved number $1.",
5193  value->name(), value->number()));
5194  }
5195  }
5196  if (reserved_name_set.find(value->name()) != reserved_name_set.end()) {
5197  AddError(
5198  value->full_name(), proto.value(i),
5200  strings::Substitute("Enum value \"$0\" is reserved.", value->name()));
5201  }
5202  }
5203 }
5204 
5206  const EnumDescriptor* parent,
5207  EnumValueDescriptor* result) {
5208  result->name_ = tables_->AllocateString(proto.name());
5209  result->number_ = proto.number();
5210  result->type_ = parent;
5211 
5212  // Note: full_name for enum values is a sibling to the parent's name, not a
5213  // child of it.
5214  std::string* full_name = tables_->AllocateEmptyString();
5215  size_t scope_len = parent->full_name_->size() - parent->name_->size();
5216  full_name->reserve(scope_len + result->name_->size());
5217  full_name->append(parent->full_name_->data(), scope_len);
5218  full_name->append(*result->name_);
5219  result->full_name_ = full_name;
5220 
5221  ValidateSymbolName(proto.name(), *full_name, proto);
5222 
5223  // Copy options.
5224  if (!proto.has_options()) {
5225  result->options_ = nullptr; // Will set to default_instance later.
5226  } else {
5227  AllocateOptions(proto.options(), result,
5229  }
5230 
5231  // Again, enum values are weird because we makes them appear as siblings
5232  // of the enum type instead of children of it. So, we use
5233  // parent->containing_type() as the value's parent.
5234  bool added_to_outer_scope =
5235  AddSymbol(result->full_name(), parent->containing_type(), result->name(),
5236  proto, Symbol(result));
5237 
5238  // However, we also want to be able to search for values within a single
5239  // enum type, so we add it as a child of the enum type itself, too.
5240  // Note: This could fail, but if it does, the error has already been
5241  // reported by the above AddSymbol() call, so we ignore the return code.
5242  bool added_to_inner_scope =
5243  file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result));
5244 
5245  if (added_to_inner_scope && !added_to_outer_scope) {
5246  // This value did not conflict with any values defined in the same enum,
5247  // but it did conflict with some other symbol defined in the enum type's
5248  // scope. Let's print an additional error to explain this.
5249  std::string outer_scope;
5250  if (parent->containing_type() == nullptr) {
5251  outer_scope = file_->package();
5252  } else {
5253  outer_scope = parent->containing_type()->full_name();
5254  }
5255 
5256  if (outer_scope.empty()) {
5257  outer_scope = "the global scope";
5258  } else {
5259  outer_scope = "\"" + outer_scope + "\"";
5260  }
5261 
5263  "Note that enum values use C++ scoping rules, meaning that "
5264  "enum values are siblings of their type, not children of it. "
5265  "Therefore, \"" +
5266  result->name() + "\" must be unique within " + outer_scope +
5267  ", not just within \"" + parent->name() + "\".");
5268  }
5269 
5270  // An enum is allowed to define two numbers that refer to the same value.
5271  // FindValueByNumber() should return the first such value, so we simply
5272  // ignore AddEnumValueByNumber()'s return code.
5274 }
5275 
5277  const void* /* dummy */,
5278  ServiceDescriptor* result) {
5279  std::string* full_name = AllocateNameString(file_->package(), proto.name());
5280  ValidateSymbolName(proto.name(), *full_name, proto);
5281 
5282  result->name_ = tables_->AllocateString(proto.name());
5283  result->full_name_ = full_name;
5284  result->file_ = file_;
5285 
5286  BUILD_ARRAY(proto, result, method, BuildMethod, result);
5287 
5288  // Copy options.
5289  if (!proto.has_options()) {
5290  result->options_ = nullptr; // Will set to default_instance later.
5291  } else {
5292  AllocateOptions(proto.options(), result,
5294  }
5295 
5296  AddSymbol(result->full_name(), nullptr, result->name(), proto,
5297  Symbol(result));
5298 }
5299 
5301  const ServiceDescriptor* parent,
5302  MethodDescriptor* result) {
5303  result->name_ = tables_->AllocateString(proto.name());
5304  result->service_ = parent;
5305 
5306  std::string* full_name =
5307  AllocateNameString(parent->full_name(), *result->name_);
5308  result->full_name_ = full_name;
5309 
5310  ValidateSymbolName(proto.name(), *full_name, proto);
5311 
5312  // These will be filled in when cross-linking.
5313  result->input_type_.Init();
5314  result->output_type_.Init();
5315 
5316  // Copy options.
5317  if (!proto.has_options()) {
5318  result->options_ = nullptr; // Will set to default_instance later.
5319  } else {
5320  AllocateOptions(proto.options(), result,
5322  }
5323 
5324  result->client_streaming_ = proto.client_streaming();
5325  result->server_streaming_ = proto.server_streaming();
5326 
5327  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5328 }
5329 
5330 #undef BUILD_ARRAY
5331 
5332 // -------------------------------------------------------------------
5333 
5335  const FileDescriptorProto& proto) {
5336  if (file->options_ == nullptr) {
5338  }
5339 
5340  for (int i = 0; i < file->message_type_count(); i++) {
5341  CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
5342  }
5343 
5344  for (int i = 0; i < file->extension_count(); i++) {
5345  CrossLinkField(&file->extensions_[i], proto.extension(i));
5346  }
5347 
5348  for (int i = 0; i < file->enum_type_count(); i++) {
5349  CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i));
5350  }
5351 
5352  for (int i = 0; i < file->service_count(); i++) {
5353  CrossLinkService(&file->services_[i], proto.service(i));
5354  }
5355 }
5356 
5358  const DescriptorProto& proto) {
5359  if (message->options_ == nullptr) {
5361  }
5362 
5363  for (int i = 0; i < message->nested_type_count(); i++) {
5364  CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
5365  }
5366 
5367  for (int i = 0; i < message->enum_type_count(); i++) {
5368  CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i));
5369  }
5370 
5371  for (int i = 0; i < message->field_count(); i++) {
5372  CrossLinkField(&message->fields_[i], proto.field(i));
5373  }
5374 
5375  for (int i = 0; i < message->extension_count(); i++) {
5376  CrossLinkField(&message->extensions_[i], proto.extension(i));
5377  }
5378 
5379  for (int i = 0; i < message->extension_range_count(); i++) {
5380  CrossLinkExtensionRange(&message->extension_ranges_[i],
5381  proto.extension_range(i));
5382  }
5383 
5384  // Set up field array for each oneof.
5385 
5386  // First count the number of fields per oneof.
5387  for (int i = 0; i < message->field_count(); i++) {
5388  const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
5389  if (oneof_decl != nullptr) {
5390  // Make sure fields belonging to the same oneof are defined consecutively.
5391  // This enables optimizations in codegens and reflection libraries to
5392  // skip fields in the oneof group, as only one of the field can be set.
5393  // Note that field_count() returns how many fields in this oneof we have
5394  // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is
5395  // safe.
5396  if (oneof_decl->field_count() > 0 &&
5397  message->field(i - 1)->containing_oneof() != oneof_decl) {
5398  AddError(message->full_name() + "." + message->field(i - 1)->name(),
5401  "Fields in the same oneof must be defined consecutively. "
5402  "\"$0\" cannot be defined before the completion of the "
5403  "\"$1\" oneof definition.",
5404  message->field(i - 1)->name(), oneof_decl->name()));
5405  }
5406  // Must go through oneof_decls_ array to get a non-const version of the
5407  // OneofDescriptor.
5408  ++message->oneof_decls_[oneof_decl->index()].field_count_;
5409  }
5410  }
5411 
5412  // Then allocate the arrays.
5413  for (int i = 0; i < message->oneof_decl_count(); i++) {
5414  OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
5415 
5416  if (oneof_decl->field_count() == 0) {
5417  AddError(message->full_name() + "." + oneof_decl->name(),
5419  "Oneof must have at least one field.");
5420  }
5421 
5422  oneof_decl->fields_ = tables_->AllocateArray<const FieldDescriptor*>(
5423  oneof_decl->field_count_);
5424  oneof_decl->field_count_ = 0;
5425 
5426  if (oneof_decl->options_ == nullptr) {
5427  oneof_decl->options_ = &OneofOptions::default_instance();
5428  }
5429  }
5430 
5431  // Then fill them in.
5432  for (int i = 0; i < message->field_count(); i++) {
5433  const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
5434  if (oneof_decl != nullptr) {
5435  OneofDescriptor* mutable_oneof_decl =
5436  &message->oneof_decls_[oneof_decl->index()];
5437  message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_;
5438  mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] =
5439  message->field(i);
5440  }
5441  }
5442 }
5443 
5445  Descriptor::ExtensionRange* range,
5446  const DescriptorProto::ExtensionRange& proto) {
5447  if (range->options_ == nullptr) {
5449  }
5450 }
5451 
5453  const FieldDescriptorProto& proto) {
5454  if (field->options_ == nullptr) {
5455  field->options_ = &FieldOptions::default_instance();
5456  }
5457 
5458  // Add the field to the lowercase-name and camelcase-name tables.
5460 
5461  if (proto.has_extendee()) {
5462  Symbol extendee =
5463  LookupSymbol(proto.extendee(), field->full_name(),
5465  if (extendee.IsNull()) {
5466  AddNotDefinedError(field->full_name(), proto,
5468  proto.extendee());
5469  return;
5470  } else if (extendee.type != Symbol::MESSAGE) {
5471  AddError(field->full_name(), proto,
5473  "\"" + proto.extendee() + "\" is not a message type.");
5474  return;
5475  }
5476  field->containing_type_ = extendee.descriptor;
5477 
5478  const Descriptor::ExtensionRange* extension_range =
5479  field->containing_type()->FindExtensionRangeContainingNumber(
5480  field->number());
5481 
5482  if (extension_range == nullptr) {
5483  AddError(field->full_name(), proto,
5485  strings::Substitute("\"$0\" does not declare $1 as an "
5486  "extension number.",
5487  field->containing_type()->full_name(),
5488  field->number()));
5489  }
5490  }
5491 
5492  if (field->containing_oneof() != nullptr) {
5493  if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
5494  // Note that this error will never happen when parsing .proto files.
5495  // It can only happen if you manually construct a FileDescriptorProto
5496  // that is incorrect.
5498  "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
5499  }
5500  }
5501 
5502  if (proto.has_type_name()) {
5503  // Assume we are expecting a message type unless the proto contains some
5504  // evidence that it expects an enum type. This only makes a difference if
5505  // we end up creating a placeholder.
5506  bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
5507  proto.has_default_value();
5508 
5509  // In case of weak fields we force building the dependency. We need to know
5510  // if the type exist or not. If it doesnt exist we substitute Empty which
5511  // should only be done if the type can't be found in the generated pool.
5512  // TODO(gerbens) Ideally we should query the database directly to check
5513  // if weak fields exist or not so that we don't need to force building
5514  // weak dependencies. However the name lookup rules for symbols are
5515  // somewhat complicated, so I defer it too another CL.
5516  bool is_weak = !pool_->enforce_weak_ && proto.options().weak();
5517  bool is_lazy = pool_->lazily_build_dependencies_ && !is_weak;
5518 
5519  Symbol type =
5520  LookupSymbol(proto.type_name(), field->full_name(),
5521  expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM
5523  LOOKUP_TYPES, !is_lazy);
5524 
5525  if (type.IsNull()) {
5526  if (is_lazy) {
5527  // Save the symbol names for later for lookup, and allocate the once
5528  // object needed for the accessors.
5529  std::string name = proto.type_name();
5530  field->type_once_ = tables_->AllocateOnceDynamic();
5531  field->type_name_ = tables_->AllocateString(name);
5532  if (proto.has_default_value()) {
5533  field->default_value_enum_name_ =
5534  tables_->AllocateString(proto.default_value());
5535  }
5536  // AddFieldByNumber and AddExtension are done later in this function,
5537  // and can/must be done if the field type was not found. The related
5538  // error checking is not necessary when in lazily_build_dependencies_
5539  // mode, and can't be done without building the type's descriptor,
5540  // which we don't want to do.
5542  if (field->is_extension()) {
5543  tables_->AddExtension(field);
5544  }
5545  return;
5546  } else {
5547  // If the type is a weak type, we change the type to a google.protobuf.Empty
5548  // field.
5549  if (is_weak) {
5551  }
5552  if (type.IsNull()) {
5553  AddNotDefinedError(field->full_name(), proto,
5555  proto.type_name());
5556  return;
5557  }
5558  }
5559  }
5560 
5561  if (!proto.has_type()) {
5562  // Choose field type based on symbol.
5563  if (type.type == Symbol::MESSAGE) {
5565  } else if (type.type == Symbol::ENUM) {
5567  } else {
5568  AddError(field->full_name(), proto,
5570  "\"" + proto.type_name() + "\" is not a type.");
5571  return;
5572  }
5573  }
5574 
5575  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
5576  if (type.type != Symbol::MESSAGE) {
5577  AddError(field->full_name(), proto,
5579  "\"" + proto.type_name() + "\" is not a message type.");
5580  return;
5581  }
5582  field->message_type_ = type.descriptor;
5583 
5584  if (field->has_default_value()) {
5585  AddError(field->full_name(), proto,
5587  "Messages can't have default values.");
5588  }
5589  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
5590  if (type.type != Symbol::ENUM) {
5591  AddError(field->full_name(), proto,
5593  "\"" + proto.type_name() + "\" is not an enum type.");
5594  return;
5595  }
5596  field->enum_type_ = type.enum_descriptor;
5597 
5598  if (field->enum_type()->is_placeholder_) {
5599  // We can't look up default values for placeholder types. We'll have
5600  // to just drop them.
5601  field->has_default_value_ = false;
5602  }
5603 
5604  if (field->has_default_value()) {
5605  // Ensure that the default value is an identifier. Parser cannot always
5606  // verify this because it does not have complete type information.
5607  // N.B. that this check yields better error messages but is not
5608  // necessary for correctness (an enum symbol must be a valid identifier
5609  // anyway), only for better errors.
5611  AddError(field->full_name(), proto,
5613  "Default value for an enum field must be an identifier.");
5614  } else {
5615  // We can't just use field->enum_type()->FindValueByName() here
5616  // because that locks the pool's mutex, which we have already locked
5617  // at this point.
5619  proto.default_value(), field->enum_type()->full_name());
5620 
5621  if (default_value.type == Symbol::ENUM_VALUE &&
5622  default_value.enum_value_descriptor->type() ==
5623  field->enum_type()) {
5624  field->default_value_enum_ = default_value.enum_value_descriptor;
5625  } else {
5626  AddError(field->full_name(), proto,
5628  "Enum type \"" + field->enum_type()->full_name() +
5629  "\" has no value named \"" + proto.default_value() +
5630  "\".");
5631  }
5632  }
5633  } else if (field->enum_type()->value_count() > 0) {
5634  // All enums must have at least one value, or we would have reported
5635  // an error elsewhere. We use the first defined value as the default
5636  // if a default is not explicitly defined.
5637  field->default_value_enum_ = field->enum_type()->value(0);
5638  }
5639  } else {
5641  "Field with primitive type has type_name.");
5642  }
5643  } else {
5644  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
5645  field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
5647  "Field with message or enum type missing type_name.");
5648  }
5649  }
5650 
5651  // Add the field to the fields-by-number table.
5652  // Note: We have to do this *after* cross-linking because extensions do not
5653  // know their containing type until now. If we're in
5654  // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no
5655  // risk to calling containing_type() or other accessors that will build
5656  // dependencies.
5658  const FieldDescriptor* conflicting_field = file_tables_->FindFieldByNumber(
5659  field->containing_type(), field->number());
5660  std::string containing_type_name =
5661  field->containing_type() == nullptr
5662  ? "unknown"
5663  : field->containing_type()->full_name();
5664  if (field->is_extension()) {
5665  AddError(field->full_name(), proto,
5667  strings::Substitute("Extension number $0 has already been used "
5668  "in \"$1\" by extension \"$2\".",
5669  field->number(), containing_type_name,
5670  conflicting_field->full_name()));
5671  } else {
5672  AddError(field->full_name(), proto,
5674  strings::Substitute("Field number $0 has already been used in "
5675  "\"$1\" by field \"$2\".",
5676  field->number(), containing_type_name,
5677  conflicting_field->name()));
5678  }
5679  } else {
5680  if (field->is_extension()) {
5681  if (!tables_->AddExtension(field)) {
5682  const FieldDescriptor* conflicting_field =
5683  tables_->FindExtension(field->containing_type(), field->number());
5684  std::string containing_type_name =
5685  field->containing_type() == nullptr
5686  ? "unknown"
5687  : field->containing_type()->full_name();
5688  std::string error_msg = strings::Substitute(
5689  "Extension number $0 has already been used in \"$1\" by extension "
5690  "\"$2\" defined in $3.",
5691  field->number(), containing_type_name,
5692  conflicting_field->full_name(), conflicting_field->file()->name());
5693  // Conflicting extension numbers should be an error. However, before
5694  // turning this into an error we need to fix all existing broken
5695  // protos first.
5696  // TODO(xiaofeng): Change this to an error.
5697  AddWarning(field->full_name(), proto,
5699  }
5700  }
5701  }
5702 }
5703 
5705  const EnumDescriptorProto& proto) {
5706  if (enum_type->options_ == nullptr) {
5708  }
5709 
5710  for (int i = 0; i < enum_type->value_count(); i++) {
5711  CrossLinkEnumValue(&enum_type->values_[i], proto.value(i));
5712  }
5713 }
5714 
5716  EnumValueDescriptor* enum_value,
5717  const EnumValueDescriptorProto& /* proto */) {
5718  if (enum_value->options_ == nullptr) {
5720  }
5721 }
5722 
5724  const ServiceDescriptorProto& proto) {
5725  if (service->options_ == nullptr) {
5727  }
5728 
5729  for (int i = 0; i < service->method_count(); i++) {
5730  CrossLinkMethod(&service->methods_[i], proto.method(i));
5731  }
5732 }
5733 
5735  const MethodDescriptorProto& proto) {
5736  if (method->options_ == nullptr) {
5738  }
5739 
5740  Symbol input_type =
5744  if (input_type.IsNull()) {
5748  proto.input_type());
5749  } else {
5750  method->input_type_.SetLazy(proto.input_type(), file_);
5751  }
5752  } else if (input_type.type != Symbol::MESSAGE) {
5753  AddError(method->full_name(), proto,
5755  "\"" + proto.input_type() + "\" is not a message type.");
5756  } else {
5757  method->input_type_.Set(input_type.descriptor);
5758  }
5759 
5760  Symbol output_type =
5764  if (output_type.IsNull()) {
5768  proto.output_type());
5769  } else {
5770  method->output_type_.SetLazy(proto.output_type(), file_);
5771  }
5772  } else if (output_type.type != Symbol::MESSAGE) {
5773  AddError(method->full_name(), proto,
5775  "\"" + proto.output_type() + "\" is not a message type.");
5776  } else {
5777  method->output_type_.Set(output_type.descriptor);
5778  }
5779 }
5780 
5781 // -------------------------------------------------------------------
5782 
5783 #define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \
5784  for (int i = 0; i < descriptor->array_name##_count(); ++i) { \
5785  Validate##type##Options(descriptor->array_name##s_ + i, \
5786  proto.array_name(i)); \
5787  }
5788 
5789 // Determine if the file uses optimize_for = LITE_RUNTIME, being careful to
5790 // avoid problems that exist at init time.
5791 static bool IsLite(const FileDescriptor* file) {
5792  // TODO(kenton): I don't even remember how many of these conditions are
5793  // actually possible. I'm just being super-safe.
5794  return file != nullptr &&
5795  &file->options() != &FileOptions::default_instance() &&
5797 }
5798 
5800  const FileDescriptorProto& proto) {
5803  VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service);
5805 
5806  // Lite files can only be imported by other Lite files.
5807  if (!IsLite(file)) {
5808  for (int i = 0; i < file->dependency_count(); i++) {
5809  if (IsLite(file->dependency(i))) {
5810  AddError(
5811  file->dependency(i)->name(), proto,
5813  "Files that do not use optimize_for = LITE_RUNTIME cannot import "
5814  "files which do use this option. This file is not lite, but it "
5815  "imports \"" +
5816  file->dependency(i)->name() + "\" which is.");
5817  break;
5818  }
5819  }
5820  }
5821  if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) {
5822  ValidateProto3(file, proto);
5823  }
5824 }
5825 
5827  const FileDescriptorProto& proto) {
5828  for (int i = 0; i < file->extension_count(); ++i) {
5829  ValidateProto3Field(file->extensions_ + i, proto.extension(i));
5830  }
5831  for (int i = 0; i < file->message_type_count(); ++i) {
5833  }
5834  for (int i = 0; i < file->enum_type_count(); ++i) {
5835  ValidateProto3Enum(file->enum_types_ + i, proto.enum_type(i));
5836  }
5837 }
5838 
5840  std::string result;
5841  for (int i = 0; i < name.size(); ++i) {
5842  if (name[i] != '_') {
5843  if (name[i] >= 'A' && name[i] <= 'Z') {
5844  result.push_back(name[i] - 'A' + 'a');
5845  } else {
5846  result.push_back(name[i]);
5847  }
5848  }
5849  }
5850  return result;
5851 }
5852 
5854  const DescriptorProto& proto) {
5855  for (int i = 0; i < message->nested_type_count(); ++i) {
5856  ValidateProto3Message(message->nested_types_ + i, proto.nested_type(i));
5857  }
5858  for (int i = 0; i < message->enum_type_count(); ++i) {
5859  ValidateProto3Enum(message->enum_types_ + i, proto.enum_type(i));
5860  }
5861  for (int i = 0; i < message->field_count(); ++i) {
5862  ValidateProto3Field(message->fields_ + i, proto.field(i));
5863  }
5864  for (int i = 0; i < message->extension_count(); ++i) {
5865  ValidateProto3Field(message->extensions_ + i, proto.extension(i));
5866  }
5867  if (message->extension_range_count() > 0) {
5868  AddError(message->full_name(), proto.extension_range(0),
5870  "Extension ranges are not allowed in proto3.");
5871  }
5872  if (message->options().message_set_wire_format()) {
5873  // Using MessageSet doesn't make sense since we disallow extensions.
5875  "MessageSet is not supported in proto3.");
5876  }
5877 
5878  // In proto3, we reject field names if they conflict in camelCase.
5879  // Note that we currently enforce a stricter rule: Field names must be
5880  // unique after being converted to lowercase with underscores removed.
5881  std::map<std::string, const FieldDescriptor*> name_to_field;
5882  for (int i = 0; i < message->field_count(); ++i) {
5883  std::string lowercase_name =
5884  ToLowercaseWithoutUnderscores(message->field(i)->name());
5885  if (name_to_field.find(lowercase_name) != name_to_field.end()) {
5886  AddError(message->full_name(), proto.field(i),
5888  "The JSON camel-case name of field \"" +
5889  message->field(i)->name() + "\" conflicts with field \"" +
5890  name_to_field[lowercase_name]->name() + "\". This is not " +
5891  "allowed in proto3.");
5892  } else {
5893  name_to_field[lowercase_name] = message->field(i);
5894  }
5895  }
5896 }
5897 
5899  const FieldDescriptorProto& proto) {
5900  if (field->is_extension() &&
5901  !AllowedExtendeeInProto3(field->containing_type()->full_name())) {
5902  AddError(field->full_name(), proto,
5904  "Extensions in proto3 are only allowed for defining options.");
5905  }
5906  if (field->is_required()) {
5908  "Required fields are not allowed in proto3.");
5909  }
5910  if (field->has_default_value()) {
5911  AddError(field->full_name(), proto,
5913  "Explicit default values are not allowed in proto3.");
5914  }
5915  if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
5916  field->enum_type() &&
5917  field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3) {
5918  // Proto3 messages can only use Proto3 enum types; otherwise we can't
5919  // guarantee that the default value is zero.
5921  "Enum type \"" + field->enum_type()->full_name() +
5922  "\" is not a proto3 enum, but is used in \"" +
5923  field->containing_type()->full_name() +
5924  "\" which is a proto3 message type.");
5925  }
5926  if (field->type() == FieldDescriptor::TYPE_GROUP) {
5928  "Groups are not supported in proto3 syntax.");
5929  }
5930 }
5931 
5933  const EnumDescriptorProto& proto) {
5934  if (enm->value_count() > 0 && enm->value(0)->number() != 0) {
5935  AddError(enm->full_name(), proto.value(0),
5937  "The first enum value must be zero in proto3.");
5938  }
5939 }
5940 
5942  const DescriptorProto& proto) {
5947 
5948  const int64 max_extension_range =
5949  static_cast<int64>(message->options().message_set_wire_format()
5950  ? kint32max
5952  for (int i = 0; i < message->extension_range_count(); ++i) {
5953  if (message->extension_range(i)->end > max_extension_range + 1) {
5954  AddError(
5955  message->full_name(), proto.extension_range(i),
5957  strings::Substitute("Extension numbers cannot be greater than $0.",
5958  max_extension_range));
5959  }
5960  }
5961 }
5962 
5963 
5965  FieldDescriptor* field, const FieldDescriptorProto& proto) {
5966  if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) {
5967  return;
5968  }
5969  // Only message type fields may be lazy.
5970  if (field->options().lazy()) {
5971  if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
5973  "[lazy = true] can only be specified for submessage fields.");
5974  }
5975  }
5976 
5977  // Only repeated primitive fields may be packed.
5978  if (field->options().packed() && !field->is_packable()) {
5979  AddError(
5980  field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
5981  "[packed = true] can only be specified for repeated primitive fields.");
5982  }
5983 
5984  // Note: Default instance may not yet be initialized here, so we have to
5985  // avoid reading from it.
5986  if (field->containing_type_ != nullptr &&
5987  &field->containing_type()->options() !=
5989  field->containing_type()->options().message_set_wire_format()) {
5990  if (field->is_extension()) {
5991  if (!field->is_optional() ||
5992  field->type() != FieldDescriptor::TYPE_MESSAGE) {
5993  AddError(field->full_name(), proto,
5995  "Extensions of MessageSets must be optional messages.");
5996  }
5997  } else {
5999  "MessageSets cannot have fields, only extensions.");
6000  }
6001  }
6002 
6003  // Lite extensions can only be of Lite types.
6004  if (IsLite(field->file()) && field->containing_type_ != nullptr &&
6005  !IsLite(field->containing_type()->file())) {
6006  AddError(field->full_name(), proto,
6008  "Extensions to non-lite types can only be declared in non-lite "
6009  "files. Note that you cannot extend a non-lite type to contain "
6010  "a lite type, but the reverse is allowed.");
6011  }
6012 
6013  // Validate map types.
6014  if (field->is_map()) {
6015  if (!ValidateMapEntry(field, proto)) {
6017  "map_entry should not be set explicitly. Use map<KeyType, "
6018  "ValueType> instead.");
6019  }
6020  }
6021 
6022  ValidateJSType(field, proto);
6023 
6024  // json_name option is not allowed on extension fields. Note that the
6025  // json_name field in FieldDescriptorProto is always populated by protoc
6026  // when it sends descriptor data to plugins (caculated from field name if
6027  // the option is not explicitly set) so we can't rely on its presence to
6028  // determine whether the json_name option is set on the field. Here we
6029  // compare it against the default calculated json_name value and consider
6030  // the option set if they are different. This won't catch the case when
6031  // an user explicitly sets json_name to the default value, but should be
6032  // good enough to catch common misuses.
6033  if (field->is_extension() &&
6034  (field->has_json_name() &&
6035  field->json_name() != ToJsonName(field->name()))) {
6036  AddError(field->full_name(), proto,
6038  "option json_name is not allowed on extension fields.");
6039  }
6040 
6041 }
6042 
6044  const EnumDescriptorProto& proto) {
6046  if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
6047  std::map<int, std::string> used_values;
6048  for (int i = 0; i < enm->value_count(); ++i) {
6049  const EnumValueDescriptor* enum_value = enm->value(i);
6050  if (used_values.find(enum_value->number()) != used_values.end()) {
6051  std::string error =
6052  "\"" + enum_value->full_name() +
6053  "\" uses the same enum value as \"" +
6054  used_values[enum_value->number()] +
6055  "\". If this is intended, set "
6056  "'option allow_alias = true;' to the enum definition.";
6057  if (!enm->options().allow_alias()) {
6058  // Generate error if duplicated enum values are explicitly disallowed.
6059  AddError(enm->full_name(), proto.value(i),
6061  }
6062  } else {
6063  used_values[enum_value->number()] = enum_value->full_name();
6064  }
6065  }
6066  }
6067 }
6068 
6070  EnumValueDescriptor* /* enum_value */,
6071  const EnumValueDescriptorProto& /* proto */) {
6072  // Nothing to do so far.
6073 }
6075  ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
6076  if (IsLite(service->file()) &&
6077  (service->file()->options().cc_generic_services() ||
6078  service->file()->options().java_generic_services())) {
6080  "Files with optimize_for = LITE_RUNTIME cannot define services "
6081  "unless you set both options cc_generic_services and "
6082  "java_generic_services to false.");
6083  }
6084 
6086 }
6087 
6089  MethodDescriptor* /* method */, const MethodDescriptorProto& /* proto */) {
6090  // Nothing to do so far.
6091 }
6092 
6094  const FieldDescriptorProto& proto) {
6095  const Descriptor* message = field->message_type();
6096  if ( // Must not contain extensions, extension range or nested message or
6097  // enums
6098  message->extension_count() != 0 ||
6099  field->label() != FieldDescriptor::LABEL_REPEATED ||
6100  message->extension_range_count() != 0 ||
6101  message->nested_type_count() != 0 || message->enum_type_count() != 0 ||
6102  // Must contain exactly two fields
6103  message->field_count() != 2 ||
6104  // Field name and message name must match
6105  message->name() != ToCamelCase(field->name(), false) + "Entry" ||
6106  // Entry message must be in the same containing type of the field.
6107  field->containing_type() != message->containing_type()) {
6108  return false;
6109  }
6110 
6111  const FieldDescriptor* key = message->field(0);
6112  const FieldDescriptor* value = message->field(1);
6113  if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 ||
6114  key->name() != "key") {
6115  return false;
6116  }
6117  if (value->label() != FieldDescriptor::LABEL_OPTIONAL ||
6118  value->number() != 2 || value->name() != "value") {
6119  return false;
6120  }
6121 
6122  // Check key types are legal.
6123  switch (key->type()) {
6126  "Key in map fields cannot be enum types.");
6127  break;
6133  AddError(
6134  field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
6135  "Key in map fields cannot be float/double, bytes or message types.");
6136  break;
6149  // Legal cases
6150  break;
6151  // Do not add a default, so that the compiler will complain when new types
6152  // are added.
6153  }
6154 
6155  if (value->type() == FieldDescriptor::TYPE_ENUM) {
6156  if (value->enum_type()->value(0)->number() != 0) {
6158  "Enum value in map must define 0 as the first value.");
6159  }
6160  }
6161 
6162  return true;
6163 }
6164 
6166  const DescriptorProto& proto) {
6167  std::map<std::string, const Descriptor*> seen_types;
6168  for (int i = 0; i < message->nested_type_count(); ++i) {
6169  const Descriptor* nested = message->nested_type(i);
6170  std::pair<std::map<std::string, const Descriptor*>::iterator, bool> result =
6171  seen_types.insert(std::make_pair(nested->name(), nested));
6172  if (!result.second) {
6173  if (result.first->second->options().map_entry() ||
6174  nested->options().map_entry()) {
6175  AddError(message->full_name(), proto,
6177  "Expanded map entry type " + nested->name() +
6178  " conflicts with an existing nested message type.");
6179  }
6180  }
6181  // Recursively test on the nested types.
6182  DetectMapConflicts(message->nested_type(i), proto.nested_type(i));
6183  }
6184  // Check for conflicted field names.
6185  for (int i = 0; i < message->field_count(); ++i) {
6186  const FieldDescriptor* field = message->field(i);
6187  std::map<std::string, const Descriptor*>::iterator iter =
6188  seen_types.find(field->name());
6189  if (iter != seen_types.end() && iter->second->options().map_entry()) {
6190  AddError(message->full_name(), proto,
6192  "Expanded map entry type " + iter->second->name() +
6193  " conflicts with an existing field.");
6194  }
6195  }
6196  // Check for conflicted enum names.
6197  for (int i = 0; i < message->enum_type_count(); ++i) {
6198  const EnumDescriptor* enum_desc = message->enum_type(i);
6199  std::map<std::string, const Descriptor*>::iterator iter =
6200  seen_types.find(enum_desc->name());
6201  if (iter != seen_types.end() && iter->second->options().map_entry()) {
6202  AddError(message->full_name(), proto,
6204  "Expanded map entry type " + iter->second->name() +
6205  " conflicts with an existing enum type.");
6206  }
6207  }
6208  // Check for conflicted oneof names.
6209  for (int i = 0; i < message->oneof_decl_count(); ++i) {
6210  const OneofDescriptor* oneof_desc = message->oneof_decl(i);
6211  std::map<std::string, const Descriptor*>::iterator iter =
6212  seen_types.find(oneof_desc->name());
6213  if (iter != seen_types.end() && iter->second->options().map_entry()) {
6214  AddError(message->full_name(), proto,
6216  "Expanded map entry type " + iter->second->name() +
6217  " conflicts with an existing oneof type.");
6218  }
6219  }
6220 }
6221 
6223  const FieldDescriptorProto& proto) {
6224  FieldOptions::JSType jstype = field->options().jstype();
6225  // The default is always acceptable.
6226  if (jstype == FieldOptions::JS_NORMAL) {
6227  return;
6228  }
6229 
6230  switch (field->type()) {
6231  // Integral 64-bit types may be represented as JavaScript numbers or
6232  // strings.
6238  if (jstype == FieldOptions::JS_STRING ||
6239  jstype == FieldOptions::JS_NUMBER) {
6240  return;
6241  }
6243  "Illegal jstype for int64, uint64, sint64, fixed64 "
6244  "or sfixed64 field: " +
6245  FieldOptions_JSType_descriptor()->value(jstype)->name());
6246  break;
6247 
6248  // No other types permit a jstype option.
6249  default:
6251  "jstype is only allowed on int64, uint64, sint64, fixed64 "
6252  "or sfixed64 fields.");
6253  break;
6254  }
6255 }
6256 
6257 #undef VALIDATE_OPTIONS_FROM_ARRAY
6258 
6259 // -------------------------------------------------------------------
6260 
6262  DescriptorBuilder* builder)
6263  : builder_(builder) {
6265 }
6266 
6268 
6270  OptionsToInterpret* options_to_interpret) {
6271  // Note that these may be in different pools, so we can't use the same
6272  // descriptor and reflection objects on both.
6273  Message* options = options_to_interpret->options;
6274  const Message* original_options = options_to_interpret->original_options;
6275 
6276  bool failed = false;
6277  options_to_interpret_ = options_to_interpret;
6278 
6279  // Find the uninterpreted_option field in the mutable copy of the options
6280  // and clear them, since we're about to interpret them.
6281  const FieldDescriptor* uninterpreted_options_field =
6282  options->GetDescriptor()->FindFieldByName("uninterpreted_option");
6283  GOOGLE_CHECK(uninterpreted_options_field != nullptr)
6284  << "No field named \"uninterpreted_option\" in the Options proto.";
6285  options->GetReflection()->ClearField(options, uninterpreted_options_field);
6286 
6287  std::vector<int> src_path = options_to_interpret->element_path;
6288  src_path.push_back(uninterpreted_options_field->number());
6289 
6290  // Find the uninterpreted_option field in the original options.
6291  const FieldDescriptor* original_uninterpreted_options_field =
6292  original_options->GetDescriptor()->FindFieldByName(
6293  "uninterpreted_option");
6294  GOOGLE_CHECK(original_uninterpreted_options_field != nullptr)
6295  << "No field named \"uninterpreted_option\" in the Options proto.";
6296 
6297  const int num_uninterpreted_options =
6298  original_options->GetReflection()->FieldSize(
6299  *original_options, original_uninterpreted_options_field);
6300  for (int i = 0; i < num_uninterpreted_options; ++i) {
6301  src_path.push_back(i);
6302  uninterpreted_option_ = down_cast<const UninterpretedOption*>(
6303  &original_options->GetReflection()->GetRepeatedMessage(
6304  *original_options, original_uninterpreted_options_field, i));
6305  if (!InterpretSingleOption(options, src_path,
6306  options_to_interpret->element_path)) {
6307  // Error already added by InterpretSingleOption().
6308  failed = true;
6309  break;
6310  }
6311  src_path.pop_back();
6312  }
6313  // Reset these, so we don't have any dangling pointers.
6314  uninterpreted_option_ = nullptr;
6315  options_to_interpret_ = nullptr;
6316 
6317  if (!failed) {
6318  // InterpretSingleOption() added the interpreted options in the
6319  // UnknownFieldSet, in case the option isn't yet known to us. Now we
6320  // serialize the options message and deserialize it back. That way, any
6321  // option fields that we do happen to know about will get moved from the
6322  // UnknownFieldSet into the real fields, and thus be available right away.
6323  // If they are not known, that's OK too. They will get reparsed into the
6324  // UnknownFieldSet and wait there until the message is parsed by something
6325  // that does know about the options.
6326 
6327  // Keep the unparsed options around in case the reparsing fails.
6328  std::unique_ptr<Message> unparsed_options(options->New());
6329  options->GetReflection()->Swap(unparsed_options.get(), options);
6330 
6331  std::string buf;
6332  if (!unparsed_options->AppendToString(&buf) ||
6333  !options->ParseFromString(buf)) {
6334  builder_->AddError(
6335  options_to_interpret->element_name, *original_options,
6337  "Some options could not be correctly parsed using the proto "
6338  "descriptors compiled into this binary.\n"
6339  "Unparsed options: " +
6340  unparsed_options->ShortDebugString() +
6341  "\n"
6342  "Parsing attempt: " +
6343  options->ShortDebugString());
6344  // Restore the unparsed options.
6345  options->GetReflection()->Swap(unparsed_options.get(), options);
6346  }
6347  }
6348  return !failed;
6349 }
6350 
6352  Message* options, const std::vector<int>& src_path,
6353  const std::vector<int>& options_path) {
6354  // First do some basic validation.
6355  if (uninterpreted_option_->name_size() == 0) {
6356  // This should never happen unless the parser has gone seriously awry or
6357  // someone has manually created the uninterpreted option badly.
6358  return AddNameError("Option must have a name.");
6359  }
6360  if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") {
6361  return AddNameError(
6362  "Option must not use reserved name "
6363  "\"uninterpreted_option\".");
6364  }
6365 
6366  const Descriptor* options_descriptor = nullptr;
6367  // Get the options message's descriptor from the builder's pool, so that we
6368  // get the version that knows about any extension options declared in the file
6369  // we're currently building. The descriptor should be there as long as the
6370  // file we're building imported descriptor.proto.
6371 
6372  // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
6373  // DescriptorPool::FindMessageTypeByName() because we're already holding the
6374  // pool's mutex, and the latter method locks it again. We don't use
6375  // FindSymbol() because files that use custom options only need to depend on
6376  // the file that defines the option, not descriptor.proto itself.
6377  Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
6378  options->GetDescriptor()->full_name());
6379  if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) {
6380  options_descriptor = symbol.descriptor;
6381  } else {
6382  // The options message's descriptor was not in the builder's pool, so use
6383  // the standard version from the generated pool. We're not holding the
6384  // generated pool's mutex, so we can search it the straightforward way.
6385  options_descriptor = options->GetDescriptor();
6386  }
6387  GOOGLE_CHECK(options_descriptor);
6388 
6389  // We iterate over the name parts to drill into the submessages until we find
6390  // the leaf field for the option. As we drill down we remember the current
6391  // submessage's descriptor in |descriptor| and the next field in that
6392  // submessage in |field|. We also track the fields we're drilling down
6393  // through in |intermediate_fields|. As we go, we reconstruct the full option
6394  // name in |debug_msg_name|, for use in error messages.
6395  const Descriptor* descriptor = options_descriptor;
6396  const FieldDescriptor* field = nullptr;
6397  std::vector<const FieldDescriptor*> intermediate_fields;
6398  std::string debug_msg_name = "";
6399 
6400  std::vector<int> dest_path = options_path;
6401 
6402  for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
6403  const std::string& name_part = uninterpreted_option_->name(i).name_part();
6404  if (debug_msg_name.size() > 0) {
6405  debug_msg_name += ".";
6406  }
6407  if (uninterpreted_option_->name(i).is_extension()) {
6408  debug_msg_name += "(" + name_part + ")";
6409  // Search for the extension's descriptor as an extension in the builder's
6410  // pool. Note that we use DescriptorBuilder::LookupSymbol(), not
6411  // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
6412  // relative lookups, and 2) because we're already holding the pool's
6413  // mutex, and the latter method locks it again.
6414  symbol =
6415  builder_->LookupSymbol(name_part, options_to_interpret_->name_scope);
6416  if (!symbol.IsNull() && symbol.type == Symbol::FIELD) {
6417  field = symbol.field_descriptor;
6418  }
6419  // If we don't find the field then the field's descriptor was not in the
6420  // builder's pool, but there's no point in looking in the generated
6421  // pool. We require that you import the file that defines any extensions
6422  // you use, so they must be present in the builder's pool.
6423  } else {
6424  debug_msg_name += name_part;
6425  // Search for the field's descriptor as a regular field.
6426  field = descriptor->FindFieldByName(name_part);
6427  }
6428 
6429  if (field == nullptr) {
6430  if (get_allow_unknown(builder_->pool_)) {
6431  // We can't find the option, but AllowUnknownDependencies() is enabled,
6432  // so we will just leave it as uninterpreted.
6433  AddWithoutInterpreting(*uninterpreted_option_, options);
6434  return true;
6435  } else if (!(builder_->undefine_resolved_name_).empty()) {
6436  // Option is resolved to a name which is not defined.
6437  return AddNameError(
6438  "Option \"" + debug_msg_name + "\" is resolved to \"(" +
6439  builder_->undefine_resolved_name_ +
6440  ")\", which is not defined. The innermost scope is searched first "
6441  "in name resolution. Consider using a leading '.'(i.e., \"(." +
6442  debug_msg_name.substr(1) +
6443  "\") to start from the outermost scope.");
6444  } else {
6445  return AddNameError(
6446  "Option \"" + debug_msg_name +
6447  "\" unknown. Ensure that your proto" +
6448  " definition file imports the proto which defines the option.");
6449  }
6450  } else if (field->containing_type() != descriptor) {
6451  if (get_is_placeholder(field->containing_type())) {
6452  // The field is an extension of a placeholder type, so we can't
6453  // reliably verify whether it is a valid extension to use here (e.g.
6454  // we don't know if it is an extension of the correct *Options message,
6455  // or if it has a valid field number, etc.). Just leave it as
6456  // uninterpreted instead.
6457  AddWithoutInterpreting(*uninterpreted_option_, options);
6458  return true;
6459  } else {
6460  // This can only happen if, due to some insane misconfiguration of the
6461  // pools, we find the options message in one pool but the field in
6462  // another. This would probably imply a hefty bug somewhere.
6463  return AddNameError("Option field \"" + debug_msg_name +
6464  "\" is not a field or extension of message \"" +
6465  descriptor->name() + "\".");
6466  }
6467  } else {
6468  // accumulate field numbers to form path to interpreted option
6469  dest_path.push_back(field->number());
6470 
6471  if (i < uninterpreted_option_->name_size() - 1) {
6472  if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
6473  return AddNameError("Option \"" + debug_msg_name +
6474  "\" is an atomic type, not a message.");
6475  } else if (field->is_repeated()) {
6476  return AddNameError("Option field \"" + debug_msg_name +
6477  "\" is a repeated message. Repeated message "
6478  "options must be initialized using an "
6479  "aggregate value.");
6480  } else {
6481  // Drill down into the submessage.
6482  intermediate_fields.push_back(field);
6483  descriptor = field->message_type();
6484  }
6485  }
6486  }
6487  }
6488 
6489  // We've found the leaf field. Now we use UnknownFieldSets to set its value
6490  // on the options message. We do so because the message may not yet know
6491  // about its extension fields, so we may not be able to set the fields
6492  // directly. But the UnknownFieldSets will serialize to the same wire-format
6493  // message, so reading that message back in once the extension fields are
6494  // known will populate them correctly.
6495 
6496  // First see if the option is already set.
6497  if (!field->is_repeated() &&
6498  !ExamineIfOptionIsSet(
6499  intermediate_fields.begin(), intermediate_fields.end(), field,
6500  debug_msg_name,
6501  options->GetReflection()->GetUnknownFields(*options))) {
6502  return false; // ExamineIfOptionIsSet() already added the error.
6503  }
6504 
6505  // First set the value on the UnknownFieldSet corresponding to the
6506  // innermost message.
6507  std::unique_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet());
6508  if (!SetOptionValue(field, unknown_fields.get())) {
6509  return false; // SetOptionValue() already added the error.
6510  }
6511 
6512  // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all
6513  // the intermediate messages.
6514  for (std::vector<const FieldDescriptor*>::reverse_iterator iter =
6515  intermediate_fields.rbegin();
6516  iter != intermediate_fields.rend(); ++iter) {
6517  std::unique_ptr<UnknownFieldSet> parent_unknown_fields(
6518  new UnknownFieldSet());
6519  switch ((*iter)->type()) {
6521  io::StringOutputStream outstr(
6522  parent_unknown_fields->AddLengthDelimited((*iter)->number()));
6523  io::CodedOutputStream out(&outstr);
6524  internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out);
6525  GOOGLE_CHECK(!out.HadError())
6526  << "Unexpected failure while serializing option submessage "
6527  << debug_msg_name << "\".";
6528  break;
6529  }
6530 
6532  parent_unknown_fields->AddGroup((*iter)->number())
6533  ->MergeFrom(*unknown_fields);
6534  break;
6535  }
6536 
6537  default:
6538  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
6539  << (*iter)->type();
6540  return false;
6541  }
6542  unknown_fields.reset(parent_unknown_fields.release());
6543  }
6544 
6545  // Now merge the UnknownFieldSet corresponding to the top-level message into
6546  // the options message.
6547  options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
6548  *unknown_fields);
6549 
6550  // record the element path of the interpreted option
6551  if (field->is_repeated()) {
6552  int index = repeated_option_counts_[dest_path]++;
6553  dest_path.push_back(index);
6554  }
6555  interpreted_paths_[src_path] = dest_path;
6556 
6557  return true;
6558 }
6559 
6561  SourceCodeInfo* info) {
6562  if (interpreted_paths_.empty()) {
6563  // nothing to do!
6564  return;
6565  }
6566 
6567  // We find locations that match keys in interpreted_paths_ and
6568  // 1) replace the path with the corresponding value in interpreted_paths_
6569  // 2) remove any subsequent sub-locations (sub-location is one whose path
6570  // has the parent path as a prefix)
6571  //
6572  // To avoid quadratic behavior of removing interior rows as we go,
6573  // we keep a copy. But we don't actually copy anything until we've
6574  // found the first match (so if the source code info has no locations
6575  // that need to be changed, there is zero copy overhead).
6576 
6579  bool copying = false;
6580 
6581  std::vector<int> pathv;
6582  bool matched = false;
6583 
6585  loc != locs->end(); loc++) {
6586  if (matched) {
6587  // see if this location is in the range to remove
6588  bool loc_matches = true;
6589  if (loc->path_size() < pathv.size()) {
6590  loc_matches = false;
6591  } else {
6592  for (int j = 0; j < pathv.size(); j++) {
6593  if (loc->path(j) != pathv[j]) {
6594  loc_matches = false;
6595  break;
6596  }
6597  }
6598  }
6599 
6600  if (loc_matches) {
6601  // don't copy this row since it is a sub-location that we're removing
6602  continue;
6603  }
6604 
6605  matched = false;
6606  }
6607 
6608  pathv.clear();
6609  for (int j = 0; j < loc->path_size(); j++) {
6610  pathv.push_back(loc->path(j));
6611  }
6612 
6613  std::map<std::vector<int>, std::vector<int>>::iterator entry =
6614  interpreted_paths_.find(pathv);
6615 
6616  if (entry == interpreted_paths_.end()) {
6617  // not a match
6618  if (copying) {
6619  *new_locs.Add() = *loc;
6620  }
6621  continue;
6622  }
6623 
6624  matched = true;
6625 
6626  if (!copying) {
6627  // initialize the copy we are building
6628  copying = true;
6629  new_locs.Reserve(locs->size());
6631  locs->begin();
6632  it != loc; it++) {
6633  *new_locs.Add() = *it;
6634  }
6635  }
6636 
6637  // add replacement and update its path
6638  SourceCodeInfo_Location* replacement = new_locs.Add();
6639  *replacement = *loc;
6640  replacement->clear_path();
6641  for (std::vector<int>::iterator rit = entry->second.begin();
6642  rit != entry->second.end(); rit++) {
6643  replacement->add_path(*rit);
6644  }
6645  }
6646 
6647  // if we made a changed copy, put it in place
6648  if (copying) {
6649  *locs = new_locs;
6650  }
6651 }
6652 
6654  const UninterpretedOption& uninterpreted_option, Message* options) {
6655  const FieldDescriptor* field =
6656  options->GetDescriptor()->FindFieldByName("uninterpreted_option");
6657  GOOGLE_CHECK(field != nullptr);
6658 
6659  options->GetReflection()
6660  ->AddMessage(options, field)
6661  ->CopyFrom(uninterpreted_option);
6662 }
6663 
6665  std::vector<const FieldDescriptor*>::const_iterator
6666  intermediate_fields_iter,
6667  std::vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
6668  const FieldDescriptor* innermost_field, const std::string& debug_msg_name,
6669  const UnknownFieldSet& unknown_fields) {
6670  // We do linear searches of the UnknownFieldSet and its sub-groups. This
6671  // should be fine since it's unlikely that any one options structure will
6672  // contain more than a handful of options.
6673 
6674  if (intermediate_fields_iter == intermediate_fields_end) {
6675  // We're at the innermost submessage.
6676  for (int i = 0; i < unknown_fields.field_count(); i++) {
6677  if (unknown_fields.field(i).number() == innermost_field->number()) {
6678  return AddNameError("Option \"" + debug_msg_name +
6679  "\" was already set.");
6680  }
6681  }
6682  return true;
6683  }
6684 
6685  for (int i = 0; i < unknown_fields.field_count(); i++) {
6686  if (unknown_fields.field(i).number() ==
6687  (*intermediate_fields_iter)->number()) {
6688  const UnknownField* unknown_field = &unknown_fields.field(i);
6689  FieldDescriptor::Type type = (*intermediate_fields_iter)->type();
6690  // Recurse into the next submessage.
6691  switch (type) {
6693  if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) {
6694  UnknownFieldSet intermediate_unknown_fields;
6695  if (intermediate_unknown_fields.ParseFromString(
6696  unknown_field->length_delimited()) &&
6697  !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
6698  intermediate_fields_end, innermost_field,
6699  debug_msg_name,
6700  intermediate_unknown_fields)) {
6701  return false; // Error already added.
6702  }
6703  }
6704  break;
6705 
6707  if (unknown_field->type() == UnknownField::TYPE_GROUP) {
6708  if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
6709  intermediate_fields_end, innermost_field,
6710  debug_msg_name, unknown_field->group())) {
6711  return false; // Error already added.
6712  }
6713  }
6714  break;
6715 
6716  default:
6717  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type;
6718  return false;
6719  }
6720  }
6721  }
6722  return true;
6723 }
6724 
6726  const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
6727  // We switch on the CppType to validate.
6728  switch (option_field->cpp_type()) {
6730  if (uninterpreted_option_->has_positive_int_value()) {
6731  if (uninterpreted_option_->positive_int_value() >
6732  static_cast<uint64>(kint32max)) {
6733  return AddValueError("Value out of range for int32 option \"" +
6734  option_field->full_name() + "\".");
6735  } else {
6736  SetInt32(option_field->number(),
6737  uninterpreted_option_->positive_int_value(),
6738  option_field->type(), unknown_fields);
6739  }
6740  } else if (uninterpreted_option_->has_negative_int_value()) {
6741  if (uninterpreted_option_->negative_int_value() <
6742  static_cast<int64>(kint32min)) {
6743  return AddValueError("Value out of range for int32 option \"" +
6744  option_field->full_name() + "\".");
6745  } else {
6746  SetInt32(option_field->number(),
6747  uninterpreted_option_->negative_int_value(),
6748  option_field->type(), unknown_fields);
6749  }
6750  } else {
6751  return AddValueError("Value must be integer for int32 option \"" +
6752  option_field->full_name() + "\".");
6753  }
6754  break;
6755 
6757  if (uninterpreted_option_->has_positive_int_value()) {
6758  if (uninterpreted_option_->positive_int_value() >
6759  static_cast<uint64>(kint64max)) {
6760  return AddValueError("Value out of range for int64 option \"" +
6761  option_field->full_name() + "\".");
6762  } else {
6763  SetInt64(option_field->number(),
6764  uninterpreted_option_->positive_int_value(),
6765  option_field->type(), unknown_fields);
6766  }
6767  } else if (uninterpreted_option_->has_negative_int_value()) {
6768  SetInt64(option_field->number(),
6769  uninterpreted_option_->negative_int_value(),
6770  option_field->type(), unknown_fields);
6771  } else {
6772  return AddValueError("Value must be integer for int64 option \"" +
6773  option_field->full_name() + "\".");
6774  }
6775  break;
6776 
6778  if (uninterpreted_option_->has_positive_int_value()) {
6779  if (uninterpreted_option_->positive_int_value() > kuint32max) {
6780  return AddValueError("Value out of range for uint32 option \"" +
6781  option_field->name() + "\".");
6782  } else {
6783  SetUInt32(option_field->number(),
6784  uninterpreted_option_->positive_int_value(),
6785  option_field->type(), unknown_fields);
6786  }
6787  } else {
6788  return AddValueError(
6789  "Value must be non-negative integer for uint32 "
6790  "option \"" +
6791  option_field->full_name() + "\".");
6792  }
6793  break;
6794 
6796  if (uninterpreted_option_->has_positive_int_value()) {
6797  SetUInt64(option_field->number(),
6798  uninterpreted_option_->positive_int_value(),
6799  option_field->type(), unknown_fields);
6800  } else {
6801  return AddValueError(
6802  "Value must be non-negative integer for uint64 "
6803  "option \"" +
6804  option_field->full_name() + "\".");
6805  }
6806  break;
6807 
6809  float value;
6810  if (uninterpreted_option_->has_double_value()) {
6811  value = uninterpreted_option_->double_value();
6812  } else if (uninterpreted_option_->has_positive_int_value()) {
6813  value = uninterpreted_option_->positive_int_value();
6814  } else if (uninterpreted_option_->has_negative_int_value()) {
6815  value = uninterpreted_option_->negative_int_value();
6816  } else {
6817  return AddValueError("Value must be number for float option \"" +
6818  option_field->full_name() + "\".");
6819  }
6820  unknown_fields->AddFixed32(option_field->number(),
6822  break;
6823  }
6824 
6826  double value;
6827  if (uninterpreted_option_->has_double_value()) {
6828  value = uninterpreted_option_->double_value();
6829  } else if (uninterpreted_option_->has_positive_int_value()) {
6830  value = uninterpreted_option_->positive_int_value();
6831  } else if (uninterpreted_option_->has_negative_int_value()) {
6832  value = uninterpreted_option_->negative_int_value();
6833  } else {
6834  return AddValueError("Value must be number for double option \"" +
6835  option_field->full_name() + "\".");
6836  }
6837  unknown_fields->AddFixed64(option_field->number(),
6839  break;
6840  }
6841 
6843  uint64 value;
6844  if (!uninterpreted_option_->has_identifier_value()) {
6845  return AddValueError(
6846  "Value must be identifier for boolean option "
6847  "\"" +
6848  option_field->full_name() + "\".");
6849  }
6850  if (uninterpreted_option_->identifier_value() == "true") {
6851  value = 1;
6852  } else if (uninterpreted_option_->identifier_value() == "false") {
6853  value = 0;
6854  } else {
6855  return AddValueError(
6856  "Value must be \"true\" or \"false\" for boolean "
6857  "option \"" +
6858  option_field->full_name() + "\".");
6859  }
6860  unknown_fields->AddVarint(option_field->number(), value);
6861  break;
6862 
6864  if (!uninterpreted_option_->has_identifier_value()) {
6865  return AddValueError(
6866  "Value must be identifier for enum-valued option "
6867  "\"" +
6868  option_field->full_name() + "\".");
6869  }
6870  const EnumDescriptor* enum_type = option_field->enum_type();
6871  const std::string& value_name = uninterpreted_option_->identifier_value();
6872  const EnumValueDescriptor* enum_value = nullptr;
6873 
6874  if (enum_type->file()->pool() != DescriptorPool::generated_pool()) {
6875  // Note that the enum value's fully-qualified name is a sibling of the
6876  // enum's name, not a child of it.
6877  std::string fully_qualified_name = enum_type->full_name();
6878  fully_qualified_name.resize(fully_qualified_name.size() -
6879  enum_type->name().size());
6880  fully_qualified_name += value_name;
6881 
6882  // Search for the enum value's descriptor in the builder's pool. Note
6883  // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
6884  // DescriptorPool::FindEnumValueByName() because we're already holding
6885  // the pool's mutex, and the latter method locks it again.
6886  Symbol symbol =
6887  builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
6888  if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) {
6889  if (symbol.enum_value_descriptor->type() != enum_type) {
6890  return AddValueError(
6891  "Enum type \"" + enum_type->full_name() +
6892  "\" has no value named \"" + value_name + "\" for option \"" +
6893  option_field->full_name() +
6894  "\". This appears to be a value from a sibling type.");
6895  } else {
6896  enum_value = symbol.enum_value_descriptor;
6897  }
6898  }
6899  } else {
6900  // The enum type is in the generated pool, so we can search for the
6901  // value there.
6902  enum_value = enum_type->FindValueByName(value_name);
6903  }
6904 
6905  if (enum_value == nullptr) {
6906  return AddValueError("Enum type \"" +
6907  option_field->enum_type()->full_name() +
6908  "\" has no value named \"" + value_name +
6909  "\" for "
6910  "option \"" +
6911  option_field->full_name() + "\".");
6912  } else {
6913  // Sign-extension is not a problem, since we cast directly from int32 to
6914  // uint64, without first going through uint32.
6915  unknown_fields->AddVarint(
6916  option_field->number(),
6917  static_cast<uint64>(static_cast<int64>(enum_value->number())));
6918  }
6919  break;
6920  }
6921 
6923  if (!uninterpreted_option_->has_string_value()) {
6924  return AddValueError(
6925  "Value must be quoted string for string option "
6926  "\"" +
6927  option_field->full_name() + "\".");
6928  }
6929  // The string has already been unquoted and unescaped by the parser.
6930  unknown_fields->AddLengthDelimited(option_field->number(),
6931  uninterpreted_option_->string_value());
6932  break;
6933 
6935  if (!SetAggregateOption(option_field, unknown_fields)) {
6936  return false;
6937  }
6938  break;
6939  }
6940 
6941  return true;
6942 }
6943 
6945  : public TextFormat::Finder {
6946  public:
6948 
6950  const std::string& name) const override {
6951  assert_mutex_held(builder_->pool_);
6952  const Descriptor* descriptor = message->GetDescriptor();
6953  Symbol result =
6954  builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name());
6955  if (result.type == Symbol::FIELD &&
6956  result.field_descriptor->is_extension()) {
6957  return result.field_descriptor;
6958  } else if (result.type == Symbol::MESSAGE &&
6959  descriptor->options().message_set_wire_format()) {
6960  const Descriptor* foreign_type = result.descriptor;
6961  // The text format allows MessageSet items to be specified using
6962  // the type name, rather than the extension identifier. If the symbol
6963  // lookup returned a Message, and the enclosing Message has
6964  // message_set_wire_format = true, then return the message set
6965  // extension, if one exists.
6966  for (int i = 0; i < foreign_type->extension_count(); i++) {
6967  const FieldDescriptor* extension = foreign_type->extension(i);
6968  if (extension->containing_type() == descriptor &&
6970  extension->is_optional() &&
6971  extension->message_type() == foreign_type) {
6972  // Found it.
6973  return extension;
6974  }
6975  }
6976  }
6977  return nullptr;
6978  }
6979 };
6980 
6981 // A custom error collector to record any text-format parsing errors
6982 namespace {
6983 class AggregateErrorCollector : public io::ErrorCollector {
6984  public:
6986 
6987  void AddError(int /* line */, int /* column */,
6988  const std::string& message) override {
6989  if (!error_.empty()) {
6990  error_ += "; ";
6991  }
6992  error_ += message;
6993  }
6994 
6995  void AddWarning(int /* line */, int /* column */,
6996  const std::string& /* message */) override {
6997  // Ignore warnings
6998  }
6999 };
7000 } // namespace
7001 
7002 // We construct a dynamic message of the type corresponding to
7003 // option_field, parse the supplied text-format string into this
7004 // message, and serialize the resulting message to produce the value.
7006  const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
7007  if (!uninterpreted_option_->has_aggregate_value()) {
7008  return AddValueError("Option \"" + option_field->full_name() +
7009  "\" is a message. To set the entire message, use "
7010  "syntax like \"" +
7011  option_field->name() +
7012  " = { <proto text format> }\". "
7013  "To set fields within it, use "
7014  "syntax like \"" +
7015  option_field->name() + ".foo = value\".");
7016  }
7017 
7018  const Descriptor* type = option_field->message_type();
7019  std::unique_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
7020  GOOGLE_CHECK(dynamic.get() != nullptr)
7021  << "Could not create an instance of " << option_field->DebugString();
7022 
7023  AggregateErrorCollector collector;
7024  AggregateOptionFinder finder;
7025  finder.builder_ = builder_;
7027  parser.RecordErrorsTo(&collector);
7028  parser.SetFinder(&finder);
7029  if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
7030  dynamic.get())) {
7031  AddValueError("Error while parsing option value for \"" +
7032  option_field->name() + "\": " + collector.error_);
7033  return false;
7034  } else {
7035  std::string serial;
7036  dynamic->SerializeToString(&serial); // Never fails
7037  if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) {
7038  unknown_fields->AddLengthDelimited(option_field->number(), serial);
7039  } else {
7041  UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number());
7042  group->ParseFromString(serial);
7043  }
7044  return true;
7045  }
7046 }
7047 
7050  UnknownFieldSet* unknown_fields) {
7051  switch (type) {
7053  unknown_fields->AddVarint(number,
7054  static_cast<uint64>(static_cast<int64>(value)));
7055  break;
7056 
7058  unknown_fields->AddFixed32(number, static_cast<uint32>(value));
7059  break;
7060 
7062  unknown_fields->AddVarint(
7064  break;
7065 
7066  default:
7067  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type;
7068  break;
7069  }
7070 }
7071 
7074  UnknownFieldSet* unknown_fields) {
7075  switch (type) {
7077  unknown_fields->AddVarint(number, static_cast<uint64>(value));
7078  break;
7079 
7081  unknown_fields->AddFixed64(number, static_cast<uint64>(value));
7082  break;
7083 
7085  unknown_fields->AddVarint(
7087  break;
7088 
7089  default:
7090  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type;
7091  break;
7092  }
7093 }
7094 
7097  UnknownFieldSet* unknown_fields) {
7098  switch (type) {
7100  unknown_fields->AddVarint(number, static_cast<uint64>(value));
7101  break;
7102 
7104  unknown_fields->AddFixed32(number, static_cast<uint32>(value));
7105  break;
7106 
7107  default:
7108  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
7109  break;
7110  }
7111 }
7112 
7115  UnknownFieldSet* unknown_fields) {
7116  switch (type) {
7118  unknown_fields->AddVarint(number, value);
7119  break;
7120 
7122  unknown_fields->AddFixed64(number, value);
7123  break;
7124 
7125  default:
7126  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type;
7127  break;
7128  }
7129 }
7130 
7132  const FileDescriptor* result) {
7133 
7134  if (!unused_dependency_.empty()) {
7135  std::set<std::string> annotation_extensions;
7136  annotation_extensions.insert("google.protobuf.MessageOptions");
7137  annotation_extensions.insert("google.protobuf.FileOptions");
7138  annotation_extensions.insert("google.protobuf.FieldOptions");
7139  annotation_extensions.insert("google.protobuf.EnumOptions");
7140  annotation_extensions.insert("google.protobuf.EnumValueOptions");
7141  annotation_extensions.insert("google.protobuf.EnumValueOptions");
7142  annotation_extensions.insert("google.protobuf.ServiceOptions");
7143  annotation_extensions.insert("google.protobuf.MethodOptions");
7144  annotation_extensions.insert("google.protobuf.StreamOptions");
7145  for (std::set<const FileDescriptor*>::const_iterator it =
7146  unused_dependency_.begin();
7147  it != unused_dependency_.end(); ++it) {
7148  // Do not log warnings for proto files which extend annotations.
7149  int i;
7150  for (i = 0; i < (*it)->extension_count(); ++i) {
7151  if (annotation_extensions.find(
7152  (*it)->extension(i)->containing_type()->full_name()) !=
7153  annotation_extensions.end()) {
7154  break;
7155  }
7156  }
7157  // Log warnings for unused imported files.
7158  if (i == (*it)->extension_count()) {
7159  std::string error_message =
7160  "Import " + (*it)->name() + " but not used.";
7161  AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT,
7162  error_message);
7163  }
7164  }
7165  }
7166 }
7167 
7169  bool expecting_enum) const {
7170  std::string lookup_name = name;
7171  if (!lookup_name.empty() && lookup_name[0] == '.') {
7172  lookup_name = lookup_name.substr(1);
7173  }
7174  Symbol result = tables_->FindByNameHelper(this, lookup_name);
7175  return result;
7176 }
7177 
7178 // Handle the lazy import building for a message field whose type wasn't built
7179 // at cross link time. If that was the case, we saved the name of the type to
7180 // be looked up when the accessor for the type was called. Set type_,
7181 // enum_type_, message_type_, and default_value_enum_ appropriately.
7183  GOOGLE_CHECK(file()->finished_building_ == true);
7184  if (type_name_) {
7185  Symbol result = file()->pool()->CrossLinkOnDemandHelper(
7186  *type_name_, type_ == FieldDescriptor::TYPE_ENUM);
7187  if (result.type == Symbol::MESSAGE) {
7189  message_type_ = result.descriptor;
7190  } else if (result.type == Symbol::ENUM) {
7192  enum_type_ = result.enum_descriptor;
7193  }
7194  }
7195  if (enum_type_ && !default_value_enum_) {
7196  if (default_value_enum_name_) {
7197  // Have to build the full name now instead of at CrossLink time,
7198  // because enum_type_ may not be known at the time.
7199  std::string name = enum_type_->full_name();
7200  // Enum values reside in the same scope as the enum type.
7201  std::string::size_type last_dot = name.find_last_of('.');
7202  if (last_dot != std::string::npos) {
7203  name = name.substr(0, last_dot) + "." + *default_value_enum_name_;
7204  } else {
7205  name = *default_value_enum_name_;
7206  }
7207  Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true);
7208  if (result.type == Symbol::ENUM_VALUE) {
7209  default_value_enum_ = result.enum_value_descriptor;
7210  }
7211  }
7212  if (!default_value_enum_) {
7213  // We use the first defined value as the default
7214  // if a default is not explicitly defined.
7215  GOOGLE_CHECK(enum_type_->value_count());
7216  default_value_enum_ = enum_type_->value(0);
7217  }
7218  }
7219 }
7220 
7222  to_init->InternalTypeOnceInit();
7223 }
7224 
7225 // message_type(), enum_type(), default_value_enum(), and type()
7226 // all share the same internal::call_once init path to do lazy
7227 // import building and cross linking of a field of a message.
7229  if (type_once_) {
7231  }
7232  return message_type_;
7233 }
7234 
7236  if (type_once_) {
7238  }
7239  return enum_type_;
7240 }
7241 
7243  if (type_once_) {
7245  }
7246  return default_value_enum_;
7247 }
7248 
7250  const bool is_message_set_extension =
7251  is_extension() &&
7252  containing_type()->options().message_set_wire_format() &&
7253  type() == FieldDescriptor::TYPE_MESSAGE && is_optional() &&
7254  extension_scope() == message_type();
7255  return is_message_set_extension ? message_type()->full_name() : full_name();
7256 }
7257 
7259  GOOGLE_CHECK(finished_building_ == true);
7260  for (int i = 0; i < dependency_count(); i++) {
7261  if (dependencies_names_[i]) {
7262  dependencies_[i] = pool_->FindFileByName(*dependencies_names_[i]);
7263  }
7264  }
7265 }
7266 
7268  to_init->InternalDependenciesOnceInit();
7269 }
7270 
7272  if (dependencies_once_) {
7273  // Do once init for all indices, as it's unlikely only a single index would
7274  // be called, and saves on internal::call_once allocations.
7275  internal::call_once(*dependencies_once_,
7277  }
7278  return dependencies_[index];
7279 }
7280 
7282  return input_type_.Get();
7283 }
7284 
7286  return output_type_.Get();
7287 }
7288 
7289 
7290 namespace internal {
7291 void LazyDescriptor::Set(const Descriptor* descriptor) {
7292  GOOGLE_CHECK(!name_);
7293  GOOGLE_CHECK(!once_);
7294  GOOGLE_CHECK(!file_);
7296 }
7297 
7298 void LazyDescriptor::SetLazy(const std::string& name,
7299  const FileDescriptor* file) {
7300  // verify Init() has been called and Set hasn't been called yet.
7302  GOOGLE_CHECK(!file_);
7303  GOOGLE_CHECK(!name_);
7304  GOOGLE_CHECK(!once_);
7305  GOOGLE_CHECK(file && file->pool_);
7308  file_ = file;
7309  name_ = file->pool_->tables_->AllocateString(name);
7310  once_ = file->pool_->tables_->AllocateOnceDynamic();
7311 }
7312 
7313 void LazyDescriptor::Once() {
7314  if (once_) {
7315  internal::call_once(*once_, LazyDescriptor::OnceStatic, this);
7316  }
7317 }
7318 
7319 void LazyDescriptor::OnceStatic(LazyDescriptor* lazy) { lazy->OnceInternal(); }
7320 
7321 void LazyDescriptor::OnceInternal() {
7323  if (!descriptor_ && name_) {
7324  Symbol result = file_->pool_->CrossLinkOnDemandHelper(*name_, false);
7325  if (!result.IsNull() && result.type == Symbol::MESSAGE) {
7326  descriptor_ = result.descriptor;
7327  }
7328  }
7329 }
7330 } // namespace internal
7331 
7332 } // namespace protobuf
7333 } // namespace google
google::protobuf::FieldDescriptor::Label
Label
Definition: src/google/protobuf/descriptor.h:571
google::protobuf::UnknownField::group
const UnknownFieldSet & group() const
Definition: unknown_field_set.h:350
google::protobuf::FieldDescriptor::default_value_bool_
bool default_value_bool_
Definition: src/google/protobuf/descriptor.h:818
google::protobuf::Descriptor::full_name
const std::string & full_name() const
google::protobuf::DescriptorPool::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1463
FileDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:6576
google::protobuf::FieldDescriptor::Type
Type
Definition: src/google/protobuf/descriptor.h:521
google::protobuf::EnumDescriptor::is_unqualified_placeholder_
bool is_unqualified_placeholder_
Definition: src/google/protobuf/descriptor.h:1044
google::protobuf::FieldDescriptor::options_
const FieldOptions * options_
Definition: src/google/protobuf/descriptor.h:804
google::protobuf::DescriptorBuilder::OptionInterpreter::InterpretOptions
bool InterpretOptions(OptionsToInterpret *options_to_interpret)
Definition: src/google/protobuf/descriptor.cc:6269
FileDescriptorProto::add_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * add_message_type()
Definition: descriptor.pb.h:6873
google::protobuf::DescriptorPool::NewPlaceholder
Symbol NewPlaceholder(const std::string &name, PlaceholderType placeholder_type) const
Definition: src/google/protobuf/descriptor.cc:3864
google::protobuf::DescriptorPool::FindFileByName
const FileDescriptor * FindFileByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1389
google::protobuf::DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet
bool ExamineIfOptionIsSet(std::vector< const FieldDescriptor * >::const_iterator intermediate_fields_iter, std::vector< const FieldDescriptor * >::const_iterator intermediate_fields_end, const FieldDescriptor *innermost_field, const std::string &debug_msg_name, const UnknownFieldSet &unknown_fields)
Definition: src/google/protobuf/descriptor.cc:6664
google::protobuf::FileDescriptorTables::fields_by_lowercase_name_tmp_
std::unique_ptr< FieldsByNameMap > fields_by_lowercase_name_tmp_
Definition: src/google/protobuf/descriptor.cc:780
google::protobuf::DescriptorPool::TryFindFileInFallbackDatabase
bool TryFindFileInFallbackDatabase(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1852
GOOGLE_CHECK_EQ
#define GOOGLE_CHECK_EQ(A, B)
Definition: logging.h:156
google::protobuf::Descriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:459
google::protobuf::Symbol::descriptor
const Descriptor * descriptor
Definition: src/google/protobuf/descriptor.cc:93
google::protobuf::Symbol::Type
Type
Definition: src/google/protobuf/descriptor.cc:80
MethodDescriptorProto::set_input_type
void set_input_type(const std::string &value)
Definition: descriptor.pb.h:9189
google::protobuf::DescriptorBuilder::AllocateNameString
std::string * AllocateNameString(const std::string &scope, const std::string &proto_name)
Definition: src/google/protobuf/descriptor.cc:4524
google::protobuf::MethodDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:1297
google::protobuf::OneofDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2750
google::protobuf::IsLite
static bool IsLite(const FileDescriptor *file)
Definition: src/google/protobuf/descriptor.cc:5791
google::protobuf::EnumValueDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:1132
FileOptions::default_instance
static const FileOptions & default_instance()
Definition: descriptor.pb.cc:8415
SourceCodeInfo_Location::clear_path
void clear_path()
Definition: descriptor.pb.h:11415
google::protobuf::FieldDescriptor::TYPE_SINT64
@ TYPE_SINT64
Definition: src/google/protobuf/descriptor.h:544
google::protobuf::DescriptorPool::BuildFileCollectingErrors
const FileDescriptor * BuildFileCollectingErrors(const FileDescriptorProto &proto, ErrorCollector *error_collector)
Definition: src/google/protobuf/descriptor.cc:3561
google::protobuf::DescriptorPool::NewPlaceholderFileWithMutexHeld
FileDescriptor * NewPlaceholderFileWithMutexHeld(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:3974
google::protobuf::FieldDescriptor::CPPTYPE_ENUM
@ CPPTYPE_ENUM
Definition: src/google/protobuf/descriptor.h:561
google::protobuf::RepeatedPtrField
Definition: command_line_interface.h:62
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
google::protobuf::DescriptorBuilder::dependencies_
std::set< const FileDescriptor * > dependencies_
Definition: src/google/protobuf/descriptor.cc:3151
google::protobuf.internal::LazyDescriptor::Init
void Init()
Definition: src/google/protobuf/descriptor.h:186
ExtensionRangeOptions::default_instance
static const ExtensionRangeOptions & default_instance()
Definition: descriptor.pb.cc:4311
google::protobuf::FileDescriptor::dependencies_
const FileDescriptor ** dependencies_
Definition: src/google/protobuf/descriptor.h:1481
google::protobuf::FieldDescriptor::enum_type
const EnumDescriptor * enum_type() const
Definition: src/google/protobuf/descriptor.cc:7235
SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: type.pb.h:157
google::protobuf::RepeatedPtrField::Add
Element * Add()
Definition: repeated_field.h:2035
google::protobuf::ExistingFileMatchesProto
static bool ExistingFileMatchesProto(const FileDescriptor *existing_file, const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:4199
error_
std::string error_
Definition: src/google/protobuf/descriptor.cc:6985
google::protobuf::DescriptorBuilder::ValidateEnumValueOptions
void ValidateEnumValueOptions(EnumValueDescriptor *enum_value, const EnumValueDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6069
MethodDescriptorProto::server_streaming
bool server_streaming() const
Definition: descriptor.pb.h:9423
MethodDescriptorProto::set_output_type
void set_output_type(const std::string &value)
Definition: descriptor.pb.h:9269
google::protobuf::DescriptorBuilder::LogUnusedDependency
void LogUnusedDependency(const FileDescriptorProto &proto, const FileDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:7131
google::protobuf::DescriptorPool::Tables::AddCheckpoint
void AddCheckpoint()
Definition: src/google/protobuf/descriptor.cc:840
google::protobuf::DescriptorPool::ClearUnusedImportTrackFiles
void ClearUnusedImportTrackFiles()
Definition: src/google/protobuf/descriptor.cc:1312
google::protobuf::RepeatedPtrField::Reserve
void Reserve(int new_size)
Definition: repeated_field.h:2239
FieldOptions::JS_STRING
static constexpr JSType JS_STRING
Definition: descriptor.pb.h:4231
google::protobuf::MethodDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2911
google::protobuf::DescriptorBuilder::BuildEnumValue
void BuildEnumValue(const EnumValueDescriptorProto &proto, const EnumDescriptor *parent, EnumValueDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:5205
google::protobuf::value
const Descriptor::ReservedRange value
Definition: src/google/protobuf/descriptor.h:1954
google::protobuf::EnumValueDescriptor::type
const EnumDescriptor * type() const
google::protobuf::FieldDescriptor::containing_type_
const Descriptor * containing_type_
Definition: src/google/protobuf/descriptor.h:799
map_util.h
google::protobuf::Descriptor::reserved_name
const std::string & reserved_name(int index) const
Definition: src/google/protobuf/descriptor.h:2029
DescriptorProto::oneof_decl
const PROTOBUF_NAMESPACE_ID::OneofDescriptorProto & oneof_decl(int index) const
Definition: descriptor.pb.h:7563
google::protobuf::MethodDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2916
google::protobuf::FieldDescriptor::containing_oneof_
const OneofDescriptor * containing_oneof_
Definition: src/google/protobuf/descriptor.h:800
google::protobuf::FieldDescriptor::CPPTYPE_STRING
@ CPPTYPE_STRING
Definition: src/google/protobuf/descriptor.h:562
FieldDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:1917
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
MessageOptions::GetReflection
static const ::PROTOBUF_NAMESPACE_ID::Reflection * GetReflection()
Definition: descriptor.pb.h:3900
google::protobuf::DescriptorPool::Tables::FindSymbol
Symbol FindSymbol(const std::string &key) const
Definition: src/google/protobuf/descriptor.cc:905
google::protobuf::DescriptorBuilder::OptionInterpreter::~OptionInterpreter
~OptionInterpreter()
Definition: src/google/protobuf/descriptor.cc:6267
FieldDescriptorProto::TYPE_ENUM
static constexpr Type TYPE_ENUM
Definition: descriptor.pb.h:1842
google::protobuf::FieldDescriptor::type_
Type type_
Definition: src/google/protobuf/descriptor.h:790
google::protobuf::DescriptorPool::PlaceholderType
PlaceholderType
Definition: src/google/protobuf/descriptor.h:1835
google::protobuf::DescriptorPool::InternalIsFileLoaded
bool InternalIsFileLoaded(const std::string &filename) const
Definition: src/google/protobuf/descriptor.cc:1316
google::protobuf::FileDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2421
google::protobuf::EnumDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3069
google::protobuf::FieldDescriptor::kCppTypeToName
static const char *const kCppTypeToName[MAX_CPPTYPE+1]
Definition: src/google/protobuf/descriptor.h:828
SourceCodeInfo_Location::add_path
void add_path(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:11426
google::protobuf::DescriptorPool::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:3549
google::protobuf::UnescapeCEscapeString
int UnescapeCEscapeString(const string &src, string *dest)
Definition: strutil.cc:468
element_path
std::vector< int > element_path
Definition: src/google/protobuf/descriptor.cc:3117
google::protobuf::DescriptorPool::Tables::CheckPoint::pending_extensions_before_checkpoint
int pending_extensions_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:684
google::protobuf::SimpleDtoa
string SimpleDtoa(double value)
Definition: strutil.cc:1219
FileDescriptorProto::public_dependency_size
int public_dependency_size() const
Definition: descriptor.pb.h:6794
zero_copy_stream_impl.h
google::protobuf::OneofDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3063
google::protobuf::DescriptorPool::Tables::symbols_by_name_
SymbolsByNameMap symbols_by_name_
Definition: src/google/protobuf/descriptor.cc:660
FileOptions::LITE_RUNTIME
static constexpr OptimizeMode LITE_RUNTIME
Definition: descriptor.pb.h:3485
google::protobuf::DescriptorPool::Tables::extensions_
ExtensionsGroupedByDescriptorMap extensions_
Definition: src/google/protobuf/descriptor.cc:662
EnumDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::EnumOptions * mutable_options()
Definition: descriptor.pb.h:8633
google::protobuf::DescriptorPool::Tables::symbols_after_checkpoint_
std::vector< const char * > symbols_after_checkpoint_
Definition: src/google/protobuf/descriptor.cc:687
google::protobuf::FieldDescriptor::enum_type_
const EnumDescriptor * enum_type_
Definition: src/google/protobuf/descriptor.h:803
google::protobuf::util::converter::ToCamelCase
std::string ToCamelCase(const StringPiece input)
Definition: utility.cc:250
google::protobuf::FileDescriptor::services_
ServiceDescriptor * services_
Definition: src/google/protobuf/descriptor.h:1487
DescriptorProto::kExtensionFieldNumber
@ kExtensionFieldNumber
Definition: descriptor.pb.h:1350
google::protobuf::DescriptorBuilder::OptionInterpreter::SetUInt64
void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: src/google/protobuf/descriptor.cc:7113
google::protobuf::DescriptorPool::IsSubSymbolOfBuiltType
bool IsSubSymbolOfBuiltType(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1867
DescriptorProto::extension_range
const PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange & extension_range(int index) const
Definition: descriptor.pb.h:7533
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: src/google/protobuf/descriptor.h:2001
google::protobuf::DescriptorBuilder::BuildField
void BuildField(const FieldDescriptorProto &proto, const Descriptor *parent, FieldDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:3303
google::protobuf::DescriptorBuilder::OptionInterpreter::AddValueError
bool AddValueError(const std::string &msg)
Definition: src/google/protobuf/descriptor.cc:3448
google::protobuf::MethodDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:3016
end
GLuint GLuint end
Definition: glcorearb.h:2858
google::protobuf::DescriptorBuilder::unused_dependency_
std::set< const FileDescriptor * > unused_dependency_
Definition: src/google/protobuf/descriptor.cc:3155
google::protobuf::DescriptorPool::TryFindSymbolInFallbackDatabase
bool TryFindSymbolInFallbackDatabase(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1889
EnumValueDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:8773
google::protobuf::FieldDescriptor::kLastReservedNumber
static const int kLastReservedNumber
Definition: src/google/protobuf/descriptor.h:588
google::protobuf::OneofDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2755
EnumDescriptorProto::add_reserved_range
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange * add_reserved_range()
Definition: descriptor.pb.h:8682
google::protobuf::DescriptorBuilder::ValidateSymbolName
void ValidateSymbolName(const std::string &name, const std::string &full_name, const Message &proto)
Definition: src/google/protobuf/descriptor.cc:4069
google::protobuf::DescriptorPool::Tables::CheckPoint::pending_files_before_checkpoint
int pending_files_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:683
google::protobuf::DescriptorBuilder::ValidateMessageOptions
void ValidateMessageOptions(Descriptor *message, const DescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5941
google::protobuf::FileDescriptorTables::fields_by_lowercase_name_once_
internal::once_flag fields_by_lowercase_name_once_
Definition: src/google/protobuf/descriptor.cc:781
google::protobuf::DescriptorBuilder::AllocateOptionsImpl
void AllocateOptionsImpl(const std::string &name_scope, const std::string &element_name, const typename DescriptorT::OptionsType &orig_options, DescriptorT *descriptor, const std::vector< int > &options_path)
Definition: src/google/protobuf/descriptor.cc:4114
MethodOptions::default_instance
static const MethodOptions & default_instance()
Definition: descriptor.pb.cc:12347
google::protobuf::FieldDescriptor::lowercase_name_
const std::string * lowercase_name_
Definition: src/google/protobuf/descriptor.h:781
google::protobuf::EnumValueDescriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:1133
FileDescriptorProto::weak_dependency
::PROTOBUF_NAMESPACE_ID::int32 weak_dependency(int index) const
Definition: descriptor.pb.h:6830
google::protobuf::DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting
void AddWithoutInterpreting(const UninterpretedOption &uninterpreted_option, Message *options)
Definition: src/google/protobuf/descriptor.cc:6653
google::protobuf::DescriptorPool::~DescriptorPool
~DescriptorPool()
Definition: src/google/protobuf/descriptor.cc:1297
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
google::protobuf::Descriptor::options_
const MessageOptions * options_
Definition: src/google/protobuf/descriptor.h:462
google::protobuf::FieldDescriptor::is_extension
bool is_extension() const
google::protobuf::MethodDescriptor::client_streaming_
bool client_streaming_
Definition: src/google/protobuf/descriptor.h:1303
google::protobuf::FileDescriptor::InternalDependenciesOnceInit
void InternalDependenciesOnceInit() const
Definition: src/google/protobuf/descriptor.cc:7258
DescriptorProto::reserved_range_size
int reserved_range_size() const
Definition: descriptor.pb.h:7638
field_type
zend_class_entry * field_type
Definition: php/ext/google/protobuf/message.c:2028
google::protobuf::FileDescriptor::tables_
const FileDescriptorTables * tables_
Definition: src/google/protobuf/descriptor.h:1491
google::protobuf::DescriptorBuilder::OptionInterpreter::SetUInt32
void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: src/google/protobuf/descriptor.cc:7095
google::protobuf::FileDescriptorTables::AddFieldByStylizedNames
void AddFieldByStylizedNames(const FieldDescriptor *field)
Definition: src/google/protobuf/descriptor.cc:1134
FileDescriptorProto::extension
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & extension(int index) const
Definition: descriptor.pb.h:6959
google::protobuf::FieldDescriptor::full_name
const std::string & full_name() const
google::protobuf::DescriptorBuilder::AddTwiceListedError
void AddTwiceListedError(const FileDescriptorProto &proto, int index)
Definition: src/google/protobuf/descriptor.cc:4179
EnumDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::EnumOptions & options() const
Definition: descriptor.pb.h:8610
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: strutil.cc:1480
google::protobuf::Descriptor::CopyTo
void CopyTo(DescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2067
google::protobuf::DescriptorPool::FindExtensionByPrintableName
const FieldDescriptor * FindExtensionByPrintableName(const Descriptor *extendee, const std::string &printable_name) const
Definition: src/google/protobuf/descriptor.cc:1522
google::protobuf::FieldDescriptor::TYPE_SINT32
@ TYPE_SINT32
Definition: src/google/protobuf/descriptor.h:543
google::protobuf::DescriptorBuilder::AddNotDefinedError
void AddNotDefinedError(const std::string &element_name, const Message &descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &undefined_symbol)
Definition: src/google/protobuf/descriptor.cc:3624
google::protobuf::FieldDescriptor::CPPTYPE_UINT64
@ CPPTYPE_UINT64
Definition: src/google/protobuf/descriptor.h:557
FileDescriptorProto::add_service
PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto * add_service()
Definition: descriptor.pb.h:6933
upb_fielddef::full_name
const char * full_name
Definition: php/ext/google/protobuf/upb.c:1121
google::protobuf::Symbol::oneof_descriptor
const OneofDescriptor * oneof_descriptor
Definition: src/google/protobuf/descriptor.cc:95
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
google::protobuf::DescriptorPool::Tables::CheckPoint::strings_before_checkpoint
int strings_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:677
google::protobuf::strto64
int64 strto64(const char *nptr, char **endptr, int base)
Definition: strutil.h:374
google::protobuf::UnknownField::length_delimited
const std::string & length_delimited() const
Definition: unknown_field_set.h:346
input
std::string input
Definition: tokenizer_unittest.cc:197
google::protobuf::DescriptorBuilder::OptionInterpreter::SetOptionValue
bool SetOptionValue(const FieldDescriptor *option_field, UnknownFieldSet *unknown_fields)
Definition: src/google/protobuf/descriptor.cc:6725
source_loc_
SourceLocation source_loc_
Definition: src/google/protobuf/descriptor.cc:2409
google::protobuf::Symbol::service_descriptor
const ServiceDescriptor * service_descriptor
Definition: src/google/protobuf/descriptor.cc:98
FieldDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::FieldOptions & options() const
Definition: descriptor.pb.h:8252
google::protobuf::Descriptor::is_placeholder_
bool is_placeholder_
Definition: src/google/protobuf/descriptor.h:484
MethodDescriptorProto::set_client_streaming
void set_client_streaming(bool value)
Definition: descriptor.pb.h:9409
google::protobuf::io::CodedOutputStream::HadError
bool HadError() const
Definition: coded_stream.h:829
google::protobuf::EnumDescriptor::value_count
int value_count() const
google::protobuf::SourceLocation::start_column
int start_column
Definition: src/google/protobuf/descriptor.h:148
google::protobuf::DescriptorBuilder::AllocateArray
void AllocateArray(int size, Type **output)
Definition: src/google/protobuf/descriptor.cc:3268
FATAL
const int FATAL
Definition: log_severity.h:60
DescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:1355
google::protobuf.internal::WireFormatLite::ZigZagEncode64
static uint64 ZigZagEncode64(int64 n)
Definition: wire_format_lite.h:864
google::protobuf::DescriptorBuilder::ValidateEnumOptions
void ValidateEnumOptions(EnumDescriptor *enm, const EnumDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6043
DescriptorProto::nested_type_size
int nested_type_size() const
Definition: descriptor.pb.h:7458
FieldOptions::JS_NORMAL
static constexpr JSType JS_NORMAL
Definition: descriptor.pb.h:4229
google::protobuf::Descriptor::DescriptorBuilder
friend class DescriptorBuilder
Definition: src/google/protobuf/descriptor.h:494
EnumDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:2595
google::protobuf::EnumDescriptor::file_
const FileDescriptor * file_
Definition: src/google/protobuf/descriptor.h:1037
google::protobuf::FileDescriptor::FindExtensionByLowercaseName
const FieldDescriptor * FindExtensionByLowercaseName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1785
google::protobuf::DescriptorBuilder::ValidateProto3
void ValidateProto3(FileDescriptor *file, const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5826
google::protobuf::DescriptorPool::ErrorCollector::OUTPUT_TYPE
@ OUTPUT_TYPE
Definition: src/google/protobuf/descriptor.h:1645
EnumDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:8500
google::protobuf::FieldDescriptor::TYPE_BYTES
@ TYPE_BYTES
Definition: src/google/protobuf/descriptor.h:538
GOOGLE_DCHECK
#define GOOGLE_DCHECK
Definition: logging.h:194
google::protobuf::FindPtrOrNull
Collection::value_type::second_type FindPtrOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:166
checkpoint
static void checkpoint(upb_pbdecoder *d)
Definition: php/ext/google/protobuf/upb.c:6901
google::protobuf::TextFormat::Parser
Definition: text_format.h:509
google::protobuf::DescriptorBuilder::CrossLinkExtensionRange
void CrossLinkExtensionRange(Descriptor::ExtensionRange *range, const DescriptorProto::ExtensionRange &proto)
Definition: src/google/protobuf/descriptor.cc:5444
tokenizer.h
google::protobuf::DescriptorPool::ErrorCollector
Definition: src/google/protobuf/descriptor.h:1630
DescriptorProto::kExtensionRangeFieldNumber
@ kExtensionRangeFieldNumber
Definition: descriptor.pb.h:1349
EnumValueDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::EnumValueOptions & options() const
Definition: descriptor.pb.h:8867
DescriptorProto::descriptor
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * descriptor()
Definition: descriptor.pb.h:1241
google::protobuf::FileDescriptor::FindServiceByName
const ServiceDescriptor * FindServiceByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1765
google::protobuf::EnumValueDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3080
google::protobuf::DescriptorBuilder::ValidateFieldOptions
void ValidateFieldOptions(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5964
FileDescriptorProto::kEnumTypeFieldNumber
@ kEnumTypeFieldNumber
Definition: descriptor.pb.h:643
google::protobuf::ServiceDescriptor::full_name
const std::string & full_name() const
google::protobuf::io::SafeDoubleToFloat
float SafeDoubleToFloat(double value)
Definition: strtod.cc:116
UninterpretedOption
Definition: descriptor.pb.h:5466
FileOptions
Definition: descriptor.pb.h:3343
google::protobuf::DescriptorBuilder::BuildService
void BuildService(const ServiceDescriptorProto &proto, const void *dummy, ServiceDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:5276
MethodDescriptorProto::input_type
const std::string & input_type() const
Definition: descriptor.pb.h:9185
OneofDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::OneofOptions & options() const
Definition: descriptor.pb.h:8396
FieldDescriptorProto
Definition: descriptor.pb.h:1678
google::protobuf::FieldDescriptor::CPPTYPE_INT64
@ CPPTYPE_INT64
Definition: src/google/protobuf/descriptor.h:555
google::protobuf::ServiceDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3086
google::protobuf::Descriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:2992
google::protobuf::FieldDescriptor::CopyJsonNameTo
void CopyJsonNameTo(FieldDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2172
google::protobuf::Symbol::FIELD
@ FIELD
Definition: src/google/protobuf/descriptor.cc:83
FileDescriptorProto::set_syntax
void set_syntax(const std::string &value)
Definition: descriptor.pb.h:7105
google::protobuf::FieldDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2633
FileDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:125
DescriptorProto_ExtensionRange::options
const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions & options() const
Definition: descriptor.pb.h:7221
FieldDescriptorProto::set_number
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:7862
google::protobuf::RepeatedPtrField::end
iterator end()
Definition: repeated_field.h:2459
google::protobuf::FieldDescriptor::CPPTYPE_UINT32
@ CPPTYPE_UINT32
Definition: src/google/protobuf/descriptor.h:556
google::protobuf::FileDescriptorTables::GetEmptyInstance
static const FileDescriptorTables & GetEmptyInstance()
Definition: src/google/protobuf/descriptor.cc:834
label
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:4316
FieldDescriptorProto::extendee
const std::string & extendee() const
Definition: descriptor.pb.h:7994
google::protobuf::DescriptorBuilder::assert_mutex_held
static void assert_mutex_held(const DescriptorPool *pool)
Definition: src/google/protobuf/descriptor.cc:3502
google::protobuf::Descriptor::nested_type_count
int nested_type_count() const
google::protobuf::Descriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2517
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
google::protobuf::Descriptor::containing_type
const Descriptor * containing_type() const
google::protobuf::DescriptorBuilder::get_is_placeholder
static bool get_is_placeholder(const Descriptor *descriptor)
Definition: src/google/protobuf/descriptor.cc:3499
DescriptorProto::add_extension_range
PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange * add_extension_range()
Definition: descriptor.pb.h:7537
google::protobuf::DescriptorPool::Tables
Definition: src/google/protobuf/descriptor.cc:520
google::protobuf::UnknownField
Definition: unknown_field_set.h:223
google::protobuf::FileDescriptorTables::FileDescriptorTables
FileDescriptorTables()
Definition: src/google/protobuf/descriptor.cc:820
google::protobuf::Descriptor::FindFieldByNumber
const FieldDescriptor * FindFieldByNumber(int number) const
Definition: src/google/protobuf/descriptor.cc:1584
google::protobuf::OneofDescriptor::full_name
const std::string & full_name() const
google::protobuf.internal::call_once
void call_once(Args &&... args)
Definition: once.h:45
google::protobuf::FieldDescriptor::containing_type
const Descriptor * containing_type() const
ServiceDescriptorProto
Definition: descriptor.pb.h:2886
google::protobuf::CEscape
string CEscape(const string &src)
Definition: strutil.cc:615
desc
#define desc
Definition: extension_set.h:342
google::protobuf::DescriptorBuilder::FindSymbolNotEnforcingDepsHelper
Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool *pool, const std::string &name, bool build_it=true)
Definition: src/google/protobuf/descriptor.cc:3682
google::protobuf::DescriptorBuilder::ValidateProto3Field
void ValidateProto3Field(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5898
google::protobuf::DescriptorPool::ErrorCollector::TYPE
@ TYPE
Definition: src/google/protobuf/descriptor.h:1641
google::protobuf::FileDescriptorTables::BuildLocationsByPath
static void BuildLocationsByPath(std::pair< const FileDescriptorTables *, const SourceCodeInfo * > *p)
Definition: src/google/protobuf/descriptor.cc:1238
google::protobuf::DescriptorBuilder::OptionInterpreter::dynamic_factory_
DynamicMessageFactory dynamic_factory_
Definition: src/google/protobuf/descriptor.cc:3478
google::protobuf::MethodDescriptor::CopyTo
void CopyTo(MethodDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2224
google::protobuf::ServiceDescriptor::methods_
MethodDescriptor * methods_
Definition: src/google/protobuf/descriptor.h:1215
google::protobuf::EnumDescriptor::FindValueByNumberCreatingIfUnknown
const EnumValueDescriptor * FindValueByNumberCreatingIfUnknown(int number) const
Definition: src/google/protobuf/descriptor.cc:1718
google::protobuf::DescriptorBuilder::BuildOneof
void BuildOneof(const OneofDescriptorProto &proto, Descriptor *parent, OneofDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:5015
google::protobuf.internal::WireFormatLite::ZigZagEncode32
static uint32 ZigZagEncode32(int32 n)
Definition: wire_format_lite.h:853
google::protobuf::FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic
static void FieldsByLowercaseNamesLazyInitStatic(const FileDescriptorTables *tables)
Definition: src/google/protobuf/descriptor.cc:980
google::protobuf::DescriptorPool::mutex_
internal::WrappedMutex * mutex_
Definition: src/google/protobuf/descriptor.h:1848
google::protobuf::DescriptorPool::Tables::AllocateFileTables
FileDescriptorTables * AllocateFileTables()
Definition: src/google/protobuf/descriptor.cc:1220
FieldDescriptorProto::set_default_value
void set_default_value(const std::string &value)
Definition: descriptor.pb.h:8078
google::protobuf::DescriptorBuilder::ValidateServiceOptions
void ValidateServiceOptions(ServiceDescriptor *service, const ServiceDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6074
FieldDescriptorProto::type_name
const std::string & type_name() const
Definition: descriptor.pb.h:7914
google::protobuf::DescriptorBuilder::OptionInterpreter::InterpretSingleOption
bool InterpretSingleOption(Message *options, const std::vector< int > &src_path, const std::vector< int > &options_path)
Definition: src/google/protobuf/descriptor.cc:6351
EnumValueDescriptorProto::number
::PROTOBUF_NAMESPACE_ID::int32 number() const
Definition: descriptor.pb.h:8849
google::protobuf::OneofDescriptor
Definition: src/google/protobuf/descriptor.h:843
FileDescriptorProto::add_dependency
std::string * add_dependency()
Definition: descriptor.pb.h:6761
MethodDescriptorProto
Definition: descriptor.pb.h:3090
google::protobuf::Descriptor::extension_ranges_
ExtensionRange * extension_ranges_
Definition: src/google/protobuf/descriptor.h:469
google::protobuf::io::NoLocaleStrtod
double NoLocaleStrtod(const char *text, char **original_endptr)
Definition: strtod.cc:82
google::protobuf::Descriptor::FindOneofByName
const OneofDescriptor * FindOneofByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1626
google::protobuf::DescriptorPool::Tables::FindAllExtensions
void FindAllExtensions(const Descriptor *extendee, std::vector< const FieldDescriptor * > *out) const
Definition: src/google/protobuf/descriptor.cc:1090
google::protobuf::EnumDescriptor::FindValueByName
const EnumValueDescriptor * FindValueByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1703
DescriptorProto::kFieldFieldNumber
@ kFieldFieldNumber
Definition: descriptor.pb.h:1346
google::protobuf::DescriptorPool::Tables::FindExtension
const FieldDescriptor * FindExtension(const Descriptor *extendee, int number) const
Definition: src/google/protobuf/descriptor.cc:1085
dynamic_message.h
google::protobuf::FileDescriptor::dependency_count_
int dependency_count_
Definition: src/google/protobuf/descriptor.h:1466
SourceCodeInfo::CopyFrom
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message &from) final
Definition: descriptor.pb.cc:14539
google::protobuf::FieldDescriptor::is_extension_
bool is_extension_
Definition: src/google/protobuf/descriptor.h:796
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::DescriptorBuilder::CrossLinkField
void CrossLinkField(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5452
DescriptorProto::extension
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & extension(int index) const
Definition: descriptor.pb.h:7443
google::protobuf::OneofDescriptor::fields_
const FieldDescriptor ** fields_
Definition: src/google/protobuf/descriptor.h:901
google::protobuf::ServiceDescriptor::options_
const ServiceOptions * options_
Definition: src/google/protobuf/descriptor.h:1214
google::protobuf::ServiceDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2884
google::protobuf::RepeatedField< int32 >
MethodDescriptorProto::mutable_input_type
std::string * mutable_input_type()
Definition: descriptor.pb.h:9214
google::protobuf::SourceLocation
Definition: src/google/protobuf/descriptor.h:145
google::protobuf::FieldDescriptor::default_value_enum_name_
const std::string * default_value_enum_name_
Definition: src/google/protobuf/descriptor.h:806
ServiceDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::ServiceOptions & options() const
Definition: descriptor.pb.h:9041
OneofOptions::default_instance
static const OneofOptions & default_instance()
Definition: descriptor.pb.cc:10879
google::protobuf::ascii_tolower
char ascii_tolower(char c)
Definition: strutil.h:94
google::protobuf::python::cdescriptor_pool::Add
static PyObject * Add(PyObject *self, PyObject *file_descriptor_proto)
Definition: descriptor_pool.cc:621
google::protobuf::MethodDescriptor::output_type
const Descriptor * output_type() const
Definition: src/google/protobuf/descriptor.cc:7285
google::protobuf::DescriptorBuilder::FindSymbolNotEnforcingDeps
Symbol FindSymbolNotEnforcingDeps(const std::string &name, bool build_it=true)
Definition: src/google/protobuf/descriptor.cc:3710
google::protobuf::DescriptorBuilder::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:4214
google::protobuf::Descriptor::reserved_names_
const std::string ** reserved_names_
Definition: src/google/protobuf/descriptor.h:472
DescriptorProto::reserved_name
const std::string & reserved_name(int index) const
Definition: descriptor.pb.h:7674
google::protobuf::DescriptorPool::BuildFileFromDatabase
const FileDescriptor * BuildFileFromDatabase(const FileDescriptorProto &proto) const
Definition: src/google/protobuf/descriptor.cc:3574
google::protobuf::OneofDescriptor::options_
const OneofOptions * options_
Definition: src/google/protobuf/descriptor.h:902
FileDescriptorProto::dependency
const std::string & dependency(int index) const
Definition: descriptor.pb.h:6735
google::protobuf::FileDescriptor::SyntaxName
static const char * SyntaxName(Syntax syntax)
Definition: src/google/protobuf/descriptor.cc:222
descriptor_database.h
google::protobuf::FileDescriptor::pool_
const DescriptorPool * pool_
Definition: src/google/protobuf/descriptor.h:1460
MethodDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::MethodOptions * mutable_options()
Definition: descriptor.pb.h:9368
enum_type
zend_class_entry * enum_type
Definition: php/ext/google/protobuf/message.c:1904
google::protobuf::DescriptorPool::TryFindExtensionInFallbackDatabase
bool TryFindExtensionInFallbackDatabase(const Descriptor *containing_type, int field_number) const
Definition: src/google/protobuf/descriptor.cc:1931
google::protobuf::Reflection
Definition: src/google/protobuf/message.h:400
google::protobuf::SourceLocation::trailing_comments
std::string trailing_comments
Definition: src/google/protobuf/descriptor.h:154
descriptor
Descriptor * descriptor
Definition: php/ext/google/protobuf/protobuf.h:936
google::protobuf::MethodDescriptor::server_streaming_
bool server_streaming_
Definition: src/google/protobuf/descriptor.h:1304
DescriptorProto::options
const PROTOBUF_NAMESPACE_ID::MessageOptions & options() const
Definition: descriptor.pb.h:7585
google::protobuf::DescriptorBuilder::DetectMapConflicts
void DetectMapConflicts(const Descriptor *message, const DescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6165
google::protobuf::OneofDescriptor::name
const std::string & name() const
google::protobuf::FieldDescriptor::default_value_enum_
const EnumValueDescriptor * default_value_enum_
Definition: src/google/protobuf/descriptor.h:820
google::protobuf::FileDescriptor::SYNTAX_PROTO2
@ SYNTAX_PROTO2
Definition: src/google/protobuf/descriptor.h:1393
google::protobuf::OneofDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:897
google::protobuf::FieldDescriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:780
EnumDescriptorProto::reserved_name_size
int reserved_name_size() const
Definition: descriptor.pb.h:8693
google::protobuf::ServiceDescriptor::name
const std::string & name() const
google::protobuf::MethodDescriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:1298
google::protobuf::DescriptorBuilder::ResolveMode
ResolveMode
Definition: src/google/protobuf/descriptor.cc:3232
google::protobuf::Descriptor::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Descriptor)
EnumValue
Definition: type.pb.h:1012
dummy
ReturnVal dummy
Definition: register_benchmark_test.cc:68
google::protobuf::DescriptorBuilder::OptionInterpreter::SetAggregateOption
bool SetAggregateOption(const FieldDescriptor *option_field, UnknownFieldSet *unknown_fields)
Definition: src/google/protobuf/descriptor.cc:7005
google::protobuf::python::cmessage::UnknownFieldSet
static PyObject * UnknownFieldSet(CMessage *self)
Definition: python/google/protobuf/pyext/message.cc:2501
MessageOptions::map_entry
bool map_entry() const
Definition: descriptor.pb.h:10514
google::protobuf::Symbol::IsType
bool IsType() const
Definition: src/google/protobuf/descriptor.cc:105
FileDescriptorProto::kPackageFieldNumber
@ kPackageFieldNumber
Definition: descriptor.pb.h:649
FileDescriptorProto::mutable_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_extension(int index)
Definition: descriptor.pb.h:6950
google::protobuf::FileDescriptorTables::fields_by_camelcase_name_tmp_
std::unique_ptr< FieldsByNameMap > fields_by_camelcase_name_tmp_
Definition: src/google/protobuf/descriptor.cc:783
DescriptorProto::mutable_nested_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_nested_type(int index)
Definition: descriptor.pb.h:7464
google::protobuf::MethodDescriptor::name
const std::string & name() const
ServiceDescriptorProto::add_method
PROTOBUF_NAMESPACE_ID::MethodDescriptorProto * add_method()
Definition: descriptor.pb.h:9023
google::protobuf::DescriptorBuilder::CrossLinkMethod
void CrossLinkMethod(MethodDescriptor *method, const MethodDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5734
google::protobuf::FieldDescriptor::PrintableNameForExtension
const std::string & PrintableNameForExtension() const
Definition: src/google/protobuf/descriptor.cc:7249
google::protobuf::DescriptorPool::PLACEHOLDER_ENUM
@ PLACEHOLDER_ENUM
Definition: src/google/protobuf/descriptor.h:1837
FieldOptions::default_instance
static const FieldOptions & default_instance()
Definition: descriptor.pb.cc:10284
google::protobuf::UnknownField::type
Type type() const
Definition: unknown_field_set.h:330
google::protobuf::FileDescriptor::syntax_
Syntax syntax_
Definition: src/google/protobuf/descriptor.h:1473
google::protobuf::DescriptorBuilder::OptionInterpreter::uninterpreted_option_
const UninterpretedOption * uninterpreted_option_
Definition: src/google/protobuf/descriptor.cc:3464
BUILD_ARRAY
#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT)
Definition: src/google/protobuf/descriptor.cc:4154
error
Definition: cJSON.c:88
EnumValueDescriptorProto
Definition: descriptor.pb.h:2687
google::protobuf::FieldDescriptor::CopyTo
void CopyTo(FieldDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2120
google::protobuf::OneofDescriptor::field
const FieldDescriptor * field(int index) const
Definition: src/google/protobuf/descriptor.h:2179
Enum
Definition: type.pb.h:797
google::protobuf::DescriptorPool::Tables::Allocate
Type * Allocate()
Definition: src/google/protobuf/descriptor.cc:1186
Descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:113
google::protobuf::FileDescriptor::public_dependencies_
int * public_dependencies_
Definition: src/google/protobuf/descriptor.h:1483
google::protobuf::FieldDescriptor::kLabelToName
static const char *const kLabelToName[MAX_LABEL+1]
Definition: src/google/protobuf/descriptor.h:830
google::protobuf::UnknownFieldSet::ParseFromString
bool ParseFromString(const std::string &data)
Definition: unknown_field_set.h:168
google::protobuf::FileDescriptor::message_type_count_
int message_type_count_
Definition: src/google/protobuf/descriptor.h:1469
google::protobuf::DescriptorPool::Tables::RollbackToLastCheckpoint
void RollbackToLastCheckpoint()
Definition: src/google/protobuf/descriptor.cc:856
google::protobuf::FileDescriptor::DependenciesOnceInit
static void DependenciesOnceInit(const FileDescriptor *to_init)
Definition: src/google/protobuf/descriptor.cc:7267
google::protobuf::DescriptorPool::FindFileContainingSymbol
const FileDescriptor * FindFileContainingSymbol(const std::string &symbol_name) const
Definition: src/google/protobuf/descriptor.cc:1409
google::protobuf::DescriptorPool::Tables::AllocateBytes
void * AllocateBytes(int size)
Definition: src/google/protobuf/descriptor.cc:1226
DescriptorProto::kNestedTypeFieldNumber
@ kNestedTypeFieldNumber
Definition: descriptor.pb.h:1347
google::protobuf::DescriptorPool::Tables::AddExtension
bool AddExtension(const FieldDescriptor *field)
Definition: src/google/protobuf/descriptor.cc:1173
google::protobuf::FieldDescriptor::default_value_int64_
int64 default_value_int64_
Definition: src/google/protobuf/descriptor.h:813
google::protobuf::Descriptor::FindEnumValueByName
const EnumValueDescriptor * FindEnumValueByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1692
google::protobuf::FileDescriptor::enum_type_count
int enum_type_count() const
google::protobuf::FileDescriptorTables::FindParentForFieldsByMap
const void * FindParentForFieldsByMap(const FieldDescriptor *field) const
Definition: src/google/protobuf/descriptor.cc:967
FieldDescriptorProto_Type
FieldDescriptorProto_Type
Definition: descriptor.pb.h:172
google::protobuf::DescriptorBuilder::OptionInterpreter::SetInt64
void SetInt64(int number, int64 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: src/google/protobuf/descriptor.cc:7072
google::protobuf::FileDescriptor::syntax
Syntax syntax() const
Definition: src/google/protobuf/descriptor.h:2175
google::protobuf::EnumDescriptor::is_placeholder_
bool is_placeholder_
Definition: src/google/protobuf/descriptor.h:1042
SourceCodeInfo::default_instance
static const SourceCodeInfo & default_instance()
Definition: descriptor.pb.cc:14341
FileOptions::cc_generic_services
bool cc_generic_services() const
Definition: descriptor.pb.h:9758
google::protobuf::FieldDescriptor::is_packed
bool is_packed() const
Definition: src/google/protobuf/descriptor.cc:2983
EnumDescriptorProto_EnumReservedRange
Definition: descriptor.pb.h:2278
google::protobuf::FieldDescriptor::PrintLabelFlag
PrintLabelFlag
Definition: src/google/protobuf/descriptor.h:759
google::protobuf::UnknownFieldSet::field_count
int field_count() const
Definition: unknown_field_set.h:311
google::protobuf::DescriptorBuilder::CrossLinkFile
void CrossLinkFile(FileDescriptor *file, const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5334
google::protobuf::FileDescriptor::FindMessageTypeByName
const Descriptor * FindMessageTypeByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1734
FileDescriptorProto::service
const PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto & service(int index) const
Definition: descriptor.pb.h:6929
google::protobuf::DescriptorBuilder::ValidateProto3Message
void ValidateProto3Message(Descriptor *message, const DescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5853
FileDescriptorProto::add_weak_dependency
void add_weak_dependency(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:6838
google::protobuf::Descriptor::options
const MessageOptions & options() const
google::protobuf::EnumValueDescriptor::name
const std::string & name() const
google::protobuf::Symbol::MESSAGE
@ MESSAGE
Definition: src/google/protobuf/descriptor.cc:82
google::protobuf::FieldDescriptor::InternalTypeOnceInit
void InternalTypeOnceInit() const
Definition: src/google/protobuf/descriptor.cc:7182
google::protobuf::DescriptorPool::Tables::AllocateString
std::string * AllocateString(const std::string &value)
Definition: src/google/protobuf/descriptor.cc:1195
b
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:3228
google::protobuf::SourceLocation::leading_comments
std::string leading_comments
Definition: src/google/protobuf/descriptor.h:153
DescriptorProto::mutable_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_extension(int index)
Definition: descriptor.pb.h:7434
google::protobuf::MethodDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3091
google::protobuf::FileDescriptor::dependencies_names_
const std::string ** dependencies_names_
Definition: src/google/protobuf/descriptor.h:1482
google::protobuf::EnumDescriptor::FindValueByNumber
const EnumValueDescriptor * FindValueByNumber(int number) const
Definition: src/google/protobuf/descriptor.cc:1714
google::protobuf::DescriptorPool::Tables::CheckPoint::file_tables_before_checkpoint
int file_tables_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:680
FieldDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:129
original_options
const Message * original_options
Definition: src/google/protobuf/descriptor.cc:3118
values
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:3591
SourceCodeInfo_Location::path
::PROTOBUF_NAMESPACE_ID::int32 path(int index) const
Definition: descriptor.pb.h:11418
google::protobuf::Descriptor::ExtensionRange::options_
const ExtensionRangeOptions * options_
Definition: src/google/protobuf/descriptor.h:359
google::protobuf.internal::OnShutdownDelete
T * OnShutdownDelete(T *p)
Definition: common.h:185
google::protobuf::FieldDescriptor::kMaxNumber
static const int kMaxNumber
Definition: src/google/protobuf/descriptor.h:581
google::protobuf::FileDescriptor::source_code_info_
const SourceCodeInfo * source_code_info_
Definition: src/google/protobuf/descriptor.h:1492
google::protobuf::FileDescriptor::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1744
FileDescriptorProto::message_type_size
int message_type_size() const
Definition: descriptor.pb.h:6854
message_type
zend_class_entry * message_type
Definition: php/ext/google/protobuf/message.c:45
GOOGLE_ARRAYSIZE
#define GOOGLE_ARRAYSIZE(a)
Definition: macros.h:88
google::protobuf::FileDescriptor::package
const std::string & package() const
DescriptorProto::extension_size
int extension_size() const
Definition: descriptor.pb.h:7428
google::protobuf::Descriptor::field
const FieldDescriptor * field(int index) const
google::protobuf::DescriptorPool::ErrorCollector::IMPORT
@ IMPORT
Definition: src/google/protobuf/descriptor.h:1648
google::protobuf::ServiceDescriptor
Definition: src/google/protobuf/descriptor.h:1152
DescriptorProto::field
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & field(int index) const
Definition: descriptor.pb.h:7413
google::protobuf::DescriptorPool::CrossLinkOnDemandHelper
Symbol CrossLinkOnDemandHelper(const std::string &name, bool expecting_enum) const
Definition: src/google/protobuf/descriptor.cc:7168
google::protobuf::DescriptorBuilder::OptionInterpreter::OptionInterpreter
OptionInterpreter(DescriptorBuilder *builder)
Definition: src/google/protobuf/descriptor.cc:6261
range
GLenum GLint * range
Definition: glcorearb.h:3963
DescriptorProto_ExtensionRange::start
::PROTOBUF_NAMESPACE_ID::int32 start() const
Definition: descriptor.pb.h:7185
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
FileDescriptorProto::kExtensionFieldNumber
@ kExtensionFieldNumber
Definition: descriptor.pb.h:645
google::protobuf::Symbol::SERVICE
@ SERVICE
Definition: src/google/protobuf/descriptor.cc:87
google::protobuf::OneofDescriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:898
google::protobuf::UnknownFieldSet::AddGroup
UnknownFieldSet * AddGroup(int number)
Definition: unknown_field_set.cc:168
google::protobuf::DescriptorPool::Tables::FindFile
const FileDescriptor * FindFile(const std::string &key) const
Definition: src/google/protobuf/descriptor.cc:957
google::protobuf::FindOrNull
const Collection::value_type::second_type * FindOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: map_util.h:137
EnumDescriptorProto::reserved_range
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange & reserved_range(int index) const
Definition: descriptor.pb.h:8678
google::protobuf::SourceLocation::start_line
int start_line
Definition: src/google/protobuf/descriptor.h:146
EnumValueOptions::default_instance
static const EnumValueOptions & default_instance()
Definition: descriptor.pb.cc:11614
DescriptorProto_ExtensionRange::mutable_options
PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions * mutable_options()
Definition: descriptor.pb.h:7244
FileDescriptorProto::has_name
bool has_name() const
Definition: descriptor.pb.h:6569
google::protobuf::DescriptorBuilder::AddWarning
void AddWarning(const std::string &element_name, const Message &descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &error)
Definition: src/google/protobuf/descriptor.cc:3656
DescriptorProto_ExtensionRange
Definition: descriptor.pb.h:848
google::protobuf::kNonLinkedWeakMessageReplacementName
static const char *const kNonLinkedWeakMessageReplacementName
Definition: src/google/protobuf/descriptor.cc:235
package
string package
google::protobuf::Descriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:458
google::protobuf::FileDescriptorTables::fields_by_camelcase_name_once_
internal::once_flag fields_by_camelcase_name_once_
Definition: src/google/protobuf/descriptor.cc:784
FileOptions::java_generic_services
bool java_generic_services() const
Definition: descriptor.pb.h:9776
google::protobuf::FieldDescriptor::LABEL_REQUIRED
@ LABEL_REQUIRED
Definition: src/google/protobuf/descriptor.h:573
google::protobuf::FieldDescriptor::type_once_
internal::once_flag * type_once_
Definition: src/google/protobuf/descriptor.h:787
google::protobuf::FileDescriptorTables::FindNestedSymbol
Symbol FindNestedSymbol(const void *parent, const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:914
FileDescriptorProto::enum_type
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto & enum_type(int index) const
Definition: descriptor.pb.h:6899
google::protobuf::DescriptorPool::DescriptorPool
DescriptorPool()
Definition: src/google/protobuf/descriptor.cc:1260
google::protobuf::DescriptorBuilder::OptionInterpreter::builder_
DescriptorBuilder * builder_
Definition: src/google/protobuf/descriptor.cc:3454
google::protobuf::FileDescriptor::enum_types_
EnumDescriptor * enum_types_
Definition: src/google/protobuf/descriptor.h:1486
DescriptorProto::add_reserved_range
PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange * add_reserved_range()
Definition: descriptor.pb.h:7657
MessageOptions::default_instance
static const MessageOptions & default_instance()
Definition: descriptor.pb.cc:9774
google::protobuf::FieldDescriptor::default_value_string_
const std::string * default_value_string_
Definition: src/google/protobuf/descriptor.h:821
google::protobuf::FileDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2416
google::protobuf::EnumDescriptor::name
const std::string & name() const
google::protobuf::Descriptor::ReservedRange::end
int end
Definition: src/google/protobuf/descriptor.h:401
google::protobuf::ServiceDescriptor::file_
const FileDescriptor * file_
Definition: src/google/protobuf/descriptor.h:1213
google::protobuf::DescriptorPool::InternalAddGeneratedFile
static void InternalAddGeneratedFile(const void *encoded_file_descriptor, int size)
Definition: src/google/protobuf/descriptor.cc:1355
google::protobuf::DescriptorBuilder::OptionInterpreter::AddNameError
bool AddNameError(const std::string &msg)
Definition: src/google/protobuf/descriptor.cc:3442
google::protobuf::DescriptorPool::Tables::AddSymbol
bool AddSymbol(const std::string &full_name, Symbol symbol)
Definition: src/google/protobuf/descriptor.cc:1102
HASH_MAP
#define HASH_MAP
Definition: src/google/protobuf/descriptor.cc:405
google::protobuf::StripWhitespace
void StripWhitespace(string *str)
Definition: strutil.cc:113
google::protobuf::EnumValueDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2846
google::protobuf::EnumValueDescriptor::type_
const EnumDescriptor * type_
Definition: src/google/protobuf/descriptor.h:1135
google::protobuf::OneofDescriptor::containing_type_
const Descriptor * containing_type_
Definition: src/google/protobuf/descriptor.h:899
google::protobuf::FieldDescriptor::TypeOnceInit
static void TypeOnceInit(const FieldDescriptor *to_init)
Definition: src/google/protobuf/descriptor.cc:7221
google::protobuf::FieldDescriptor::FieldTypeNameDebugString
std::string FieldTypeNameDebugString() const
Definition: src/google/protobuf/descriptor.cc:2655
strutil.h
google::protobuf::FieldDescriptor::TYPE_UINT32
@ TYPE_UINT32
Definition: src/google/protobuf/descriptor.h:539
Type
Definition: type.pb.h:182
google::protobuf::EnumDescriptor::FindReservedRangeContainingNumber
const EnumDescriptor::ReservedRange * FindReservedRangeContainingNumber(int number) const
Definition: src/google/protobuf/descriptor.cc:1839
unknown_field_set.h
google::protobuf::FieldDescriptor::default_value_uint64_
uint64 default_value_uint64_
Definition: src/google/protobuf/descriptor.h:815
EnumOptions::has_allow_alias
bool has_allow_alias() const
Definition: descriptor.pb.h:10737
google::protobuf::ValidateQualifiedName
static bool ValidateQualifiedName(const std::string &name)
Definition: src/google/protobuf/descriptor.cc:3844
EnumDescriptorProto::value
const PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto & value(int index) const
Definition: descriptor.pb.h:8588
google::protobuf.internal::once_flag
std::once_flag once_flag
Definition: once.h:43
google::protobuf::FieldDescriptor::file
const FileDescriptor * file() const
path
GLsizei const GLchar ** path
Definition: glcorearb.h:3658
FieldDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::FieldOptions * mutable_options()
Definition: descriptor.pb.h:8275
FieldDescriptorProto::type
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type type() const
Definition: descriptor.pb.h:7895
FileDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:6580
google::protobuf::DescriptorPool::Tables::CheckPoint
Definition: src/google/protobuf/descriptor.cc:664
google::protobuf::EnumValueDescriptor::number_
int number_
Definition: src/google/protobuf/descriptor.h:1134
MethodDescriptorProto::mutable_output_type
std::string * mutable_output_type()
Definition: descriptor.pb.h:9294
DescriptorProto::add_field
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_field()
Definition: descriptor.pb.h:7417
coded_stream.h
google::protobuf::Symbol::NULL_SYMBOL
@ NULL_SYMBOL
Definition: src/google/protobuf/descriptor.cc:81
prefix
static const char prefix[]
Definition: test_pair_ipc.cpp:26
google::protobuf::FieldDescriptor::default_value_enum
const EnumValueDescriptor * default_value_enum() const
Definition: src/google/protobuf/descriptor.cc:7242
google::protobuf::Descriptor::extension_range
const ExtensionRange * extension_range(int index) const
google::protobuf::DescriptorBuilder::~DescriptorBuilder
~DescriptorBuilder()
Definition: src/google/protobuf/descriptor.cc:3599
google::protobuf::DescriptorDatabase::FindAllExtensionNumbers
virtual bool FindAllExtensionNumbers(const std::string &, std::vector< int > *)
Definition: src/google/protobuf/descriptor_database.h:105
google::protobuf.internal::WireFormatLite::EncodeFloat
static uint32 EncodeFloat(float value)
Definition: wire_format_lite.h:793
generated_pool
InternalDescriptorPool * generated_pool
Definition: def.c:582
google::protobuf::DescriptorPool::underlay_
const DescriptorPool * underlay_
Definition: src/google/protobuf/descriptor.h:1853
google::protobuf::reserved_range
reserved_range
Definition: src/google/protobuf/descriptor.h:1910
ServiceDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::ServiceOptions * mutable_options()
Definition: descriptor.pb.h:9064
google::protobuf::DescriptorPool::ErrorCollector::NUMBER
@ NUMBER
Definition: src/google/protobuf/descriptor.h:1640
google::protobuf::DescriptorBuilder::OptionInterpreter
Definition: src/google/protobuf/descriptor.cc:3361
google::protobuf::MethodDescriptor::service_
const ServiceDescriptor * service_
Definition: src/google/protobuf/descriptor.h:1299
google::protobuf::DescriptorPool::PLACEHOLDER_MESSAGE
@ PLACEHOLDER_MESSAGE
Definition: src/google/protobuf/descriptor.h:1836
google::protobuf::FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic
static void FieldsByCamelcaseNamesLazyInitStatic(const FileDescriptorTables *tables)
Definition: src/google/protobuf/descriptor.cc:1004
FieldDescriptorProto::label
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label label() const
Definition: descriptor.pb.h:7876
google::protobuf::DebugStringOptions::elide_group_body
bool elide_group_body
Definition: src/google/protobuf/descriptor.h:167
google::protobuf::StringPiece
Definition: stringpiece.h:180
FieldOptions::JS_NUMBER
static constexpr JSType JS_NUMBER
Definition: descriptor.pb.h:4233
google::protobuf::DescriptorPool::internal_generated_pool
static DescriptorPool * internal_generated_pool()
Definition: src/google/protobuf/descriptor.cc:1340
google::protobuf::DescriptorBuilder::ValidateMapEntry
bool ValidateMapEntry(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6093
start
GLuint start
Definition: glcorearb.h:2858
OneofDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:8320
google::protobuf::EnumDescriptor::file
const FileDescriptor * file() const
FileDescriptorProto::set_package
void set_package(const std::string &value)
Definition: descriptor.pb.h:6660
google::protobuf::FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal
void FieldsByLowercaseNamesLazyInitInternal() const
Definition: src/google/protobuf/descriptor.cc:985
google::protobuf::FileDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:2978
google::protobuf::Descriptor::oneof_decl
const OneofDescriptor * oneof_decl(int index) const
update_failure_list.str
str
Definition: update_failure_list.py:41
google::protobuf::FieldDescriptor::OMIT_LABEL
@ OMIT_LABEL
Definition: src/google/protobuf/descriptor.h:759
ReaderMutexLock
#define ReaderMutexLock(x)
Definition: glog/src/base/mutex.h:324
google::protobuf::FileDescriptor::public_dependency_count
int public_dependency_count() const
google::protobuf::DescriptorPool::Tables::strings_
std::vector< std::string * > strings_
Definition: src/google/protobuf/descriptor.cc:652
google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation
ErrorLocation
Definition: src/google/protobuf/descriptor.h:1638
google::protobuf::DescriptorBuilder::BuildFileImpl
FileDescriptor * BuildFileImpl(const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:4285
google::protobuf::EnumValueDescriptor::number
int number() const
google::protobuf::EnumDescriptor::value
const EnumValueDescriptor * value(int index) const
DescriptorProto_ExtensionRange::set_end
void set_end(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:7207
google::protobuf::DescriptorBuilder::OptionInterpreter::AddOptionError
bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &msg)
Definition: src/google/protobuf/descriptor.cc:3433
google::protobuf::Symbol::field_descriptor
const FieldDescriptor * field_descriptor
Definition: src/google/protobuf/descriptor.cc:94
FieldDescriptorProto_Label
FieldDescriptorProto_Label
Definition: descriptor.pb.h:211
google::protobuf::UnknownFieldSet::AddVarint
void AddVarint(int number, uint64 value)
Definition: unknown_field_set.cc:134
google::protobuf::DescriptorPool
Definition: src/google/protobuf/descriptor.h:1539
google::protobuf::FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown
const EnumValueDescriptor * FindEnumValueByNumberCreatingIfUnknown(const EnumDescriptor *parent, int number) const
Definition: src/google/protobuf/descriptor.cc:1035
DescriptorProto::reserved_name_size
int reserved_name_size() const
Definition: descriptor.pb.h:7668
OneofDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:2228
EnumDescriptorProto::add_reserved_name
std::string * add_reserved_name()
Definition: descriptor.pb.h:8725
google::protobuf::Descriptor::reserved_range
const ReservedRange * reserved_range(int index) const
google::protobuf::FieldDescriptor::number_
int number_
Definition: src/google/protobuf/descriptor.h:797
google::protobuf::Symbol::IsAggregate
bool IsAggregate() const
Definition: src/google/protobuf/descriptor.cc:106
FieldDescriptorProto::set_label
void set_label(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value)
Definition: descriptor.pb.h:7880
google::protobuf::DescriptorPool::ErrorCollector::~ErrorCollector
virtual ~ErrorCollector()
Definition: src/google/protobuf/descriptor.cc:1258
google::protobuf::STLDeleteElements
void STLDeleteElements(T *container)
Definition: stl_util.h:99
google::protobuf::FileDescriptor::CopySourceCodeInfoTo
void CopySourceCodeInfoTo(FileDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2060
google::protobuf::FileDescriptorTables::symbols_by_parent_
SymbolsByParentMap symbols_by_parent_
Definition: src/google/protobuf/descriptor.cc:778
EnumDescriptorProto_EnumReservedRange::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: descriptor.pb.h:8478
google::protobuf::DescriptorPool::fallback_database_
DescriptorDatabase * fallback_database_
Definition: src/google/protobuf/descriptor.h:1851
FieldDescriptorProto::clear_type
void clear_type()
Definition: descriptor.pb.h:7891
DescriptorProto::add_oneof_decl
PROTOBUF_NAMESPACE_ID::OneofDescriptorProto * add_oneof_decl()
Definition: descriptor.pb.h:7567
ServiceDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:8935
google::protobuf::Descriptor::FindReservedRangeContainingNumber
const ReservedRange * FindReservedRangeContainingNumber(int number) const
Definition: src/google/protobuf/descriptor.cc:1827
p
const char * p
Definition: gmock-matchers_test.cc:3863
google::protobuf::Descriptor::oneof_decl_count
int oneof_decl_count() const
SourceCodeInfo::mutable_location
PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location * mutable_location(int index)
Definition: descriptor.pb.h:11707
google::protobuf::Descriptor::FindExtensionByLowercaseName
const FieldDescriptor * FindExtensionByLowercaseName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1648
google::protobuf::DescriptorPool::default_error_collector_
ErrorCollector * default_error_collector_
Definition: src/google/protobuf/descriptor.h:1852
google::protobuf::DescriptorPool::allow_unknown_
bool allow_unknown_
Definition: src/google/protobuf/descriptor.h:1862
google::protobuf::FieldDescriptor::number
int number() const
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: logging.h:146
mutex_
internal::WrappedMutex mutex_
Definition: src/google/protobuf/message.cc:579
google::protobuf::FieldDescriptor::TYPE_BOOL
@ TYPE_BOOL
Definition: src/google/protobuf/descriptor.h:533
google::protobuf::FileDescriptor::package_
const std::string * package_
Definition: src/google/protobuf/descriptor.h:1459
google::protobuf::Descriptor::extension_count
int extension_count() const
google::protobuf::FileDescriptorTables::FindFieldByCamelcaseName
const FieldDescriptor * FindFieldByCamelcaseName(const void *parent, const std::string &camelcase_name) const
Definition: src/google/protobuf/descriptor.cc:1019
google::protobuf::DescriptorPool::Tables::ClearLastCheckpoint
void ClearLastCheckpoint()
Definition: src/google/protobuf/descriptor.cc:844
EnumValueDescriptor
struct EnumValueDescriptor EnumValueDescriptor
Definition: php/ext/google/protobuf/protobuf.h:634
strtod.h
google::protobuf::Descriptor::ExtensionRange::CopyTo
void CopyTo(DescriptorProto_ExtensionRange *proto) const
Definition: src/google/protobuf/descriptor.cc:1805
google::protobuf::Descriptor::enum_type
const EnumDescriptor * enum_type(int index) const
google::protobuf::DescriptorPool::ErrorCollector::INPUT_TYPE
@ INPUT_TYPE
Definition: src/google/protobuf/descriptor.h:1644
google::protobuf::OneofDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:3004
google::protobuf::MethodDescriptor::service
const ServiceDescriptor * service() const
google::protobuf::DescriptorPool::enforce_dependencies_
bool enforce_dependencies_
Definition: src/google/protobuf/descriptor.h:1860
EnumValueDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:8769
FieldDescriptorProto::default_value
const std::string & default_value() const
Definition: descriptor.pb.h:8074
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
google::protobuf.internal::LazyDescriptor::OnceInternal
void OnceInternal()
Definition: src/google/protobuf/descriptor.cc:7321
size
#define size
Definition: glcorearb.h:2944
DescriptorProto_ExtensionRange::has_options
bool has_options() const
Definition: descriptor.pb.h:7214
google::protobuf::DescriptorBuilder::BuildEnum
void BuildEnum(const EnumDescriptorProto &proto, const Descriptor *parent, EnumDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:5108
google::protobuf::DescriptorPool::Tables::~Tables
~Tables()
Definition: src/google/protobuf/descriptor.cc:807
google::protobuf::DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
Definition: src/google/protobuf/descriptor.cc:6944
google::protobuf::DescriptorBuilder::AddRecursiveImportError
void AddRecursiveImportError(const FileDescriptorProto &proto, int from_here)
Definition: src/google/protobuf/descriptor.cc:4161
google::protobuf.internal::RepeatedPtrIterator
Definition: repeated_field.h:369
google::protobuf::EnumDescriptor::CopyTo
void CopyTo(EnumDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2183
google::protobuf::WARNING
static const LogLevel WARNING
Definition: protobuf/src/google/protobuf/testing/googletest.h:71
google::protobuf::DescriptorPool::Tables::known_bad_symbols_
HASH_SET< std::string > known_bad_symbols_
Definition: src/google/protobuf/descriptor.cc:578
google::protobuf::FileDescriptorTables::locations_by_path_once_
internal::once_flag locations_by_path_once_
Definition: src/google/protobuf/descriptor.cc:791
google::protobuf::Descriptor::is_unqualified_placeholder_
bool is_unqualified_placeholder_
Definition: src/google/protobuf/descriptor.h:486
google::protobuf::Descriptor::ReservedRange::start
int start
Definition: src/google/protobuf/descriptor.h:400
google::protobuf::FieldDescriptor::TYPE_STRING
@ TYPE_STRING
Definition: src/google/protobuf/descriptor.h:534
google::protobuf::Descriptor::FindNestedTypeByName
const Descriptor * FindNestedTypeByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1670
EnumDescriptorProto::reserved_range_size
int reserved_range_size() const
Definition: descriptor.pb.h:8663
google::protobuf::STLDeleteContainerPointers
void STLDeleteContainerPointers(ForwardIterator begin, ForwardIterator end)
Definition: stl_util.h:52
google::protobuf::strings::Substitute
string Substitute(const char *format, const SubstituteArg &arg0, const SubstituteArg &arg1, const SubstituteArg &arg2, const SubstituteArg &arg3, const SubstituteArg &arg4, const SubstituteArg &arg5, const SubstituteArg &arg6, const SubstituteArg &arg7, const SubstituteArg &arg8, const SubstituteArg &arg9)
Definition: substitute.cc:55
google::protobuf::FileDescriptorTables::~FileDescriptorTables
~FileDescriptorTables()
Definition: src/google/protobuf/descriptor.cc:832
google::protobuf::Descriptor::extension
const FieldDescriptor * extension(int index) const
google::protobuf::FileDescriptor::finished_building_
bool finished_building_
Definition: src/google/protobuf/descriptor.h:1479
google::protobuf::DescriptorBuilder::LOOKUP_ALL
@ LOOKUP_ALL
Definition: src/google/protobuf/descriptor.cc:3232
text_format.h
google::protobuf::DescriptorPool::Tables::CheckPoint::once_dynamics_before_checkpoint
int once_dynamics_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:679
google::protobuf::FieldDescriptor::default_value_uint32_
uint32 default_value_uint32_
Definition: src/google/protobuf/descriptor.h:814
google::protobuf::Descriptor::extension_range_count
int extension_range_count() const
EnumOptions::allow_alias
bool allow_alias() const
Definition: descriptor.pb.h:10744
google::protobuf::DescriptorPool::FindEnumValueByName
const EnumValueDescriptor * FindEnumValueByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1469
google::protobuf::FileDescriptor::options
const FileOptions & options() const
EnumOptions::default_instance
static const EnumOptions & default_instance()
Definition: descriptor.pb.cc:11203
FileDescriptorProto
Definition: descriptor.pb.h:501
google::protobuf::DescriptorPool::tables_
std::unique_ptr< Tables > tables_
Definition: src/google/protobuf/descriptor.h:1857
google::protobuf::FieldDescriptor::label_
Label label_
Definition: src/google/protobuf/descriptor.h:791
name_
string name_
Definition: googletest.cc:182
google::protobuf::ServiceDescriptor::file
const FileDescriptor * file() const
google::protobuf::FileDescriptorTables::FindFieldByLowercaseName
const FieldDescriptor * FindFieldByLowercaseName(const void *parent, const std::string &lowercase_name) const
Definition: src/google/protobuf/descriptor.cc:995
google::protobuf::Descriptor::field_count
int field_count() const
FieldDescriptorProto::json_name
const std::string & json_name() const
Definition: descriptor.pb.h:8172
google::protobuf.internal::WireFormat::SerializeUnknownFields
static void SerializeUnknownFields(const UnknownFieldSet &unknown_fields, io::CodedOutputStream *output)
Definition: wire_format.cc:191
google::protobuf::DescriptorBuilder::AddSymbol
bool AddSymbol(const std::string &full_name, const void *parent, const std::string &name, const Message &proto, Symbol symbol)
Definition: src/google/protobuf/descriptor.cc:3996
EnumDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:137
google::protobuf::Descriptor::file_
const FileDescriptor * file_
Definition: src/google/protobuf/descriptor.h:460
google::protobuf::Symbol::PACKAGE
@ PACKAGE
Definition: src/google/protobuf/descriptor.cc:89
google::protobuf::FileDescriptor::SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: src/google/protobuf/descriptor.h:1394
google::protobuf::FieldDescriptor::has_default_value_
bool has_default_value_
Definition: src/google/protobuf/descriptor.h:792
FileDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:651
google::protobuf::Symbol::enum_descriptor
const EnumDescriptor * enum_descriptor
Definition: src/google/protobuf/descriptor.cc:96
EnumValueDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:2828
google::protobuf::DescriptorBuilder::ValidateProto3Enum
void ValidateProto3Enum(EnumDescriptor *enm, const EnumDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5932
google::protobuf::StringPrintf
string StringPrintf(const char *format,...)
Definition: stringprintf.cc:109
MethodDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:3233
EnumDescriptorProto::reserved_name
const std::string & reserved_name(int index) const
Definition: descriptor.pb.h:8699
google::protobuf::DebugStringOptions
Definition: src/google/protobuf/descriptor.h:160
google::protobuf::HasPrefixString
bool HasPrefixString(const string &str, const string &prefix)
Definition: strutil.h:115
google::protobuf::SimpleFtoa
string SimpleFtoa(float value)
Definition: strutil.cc:1224
testing::internal::ToLower
char ToLower(char ch)
Definition: gtest-port.h:2025
casts.h
name_scope
std::string name_scope
Definition: src/google/protobuf/descriptor.cc:3115
google::protobuf::MethodDescriptor
Definition: src/google/protobuf/descriptor.h:1234
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::TextFormat::Finder
Definition: text_format.h:201
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:4175
google::protobuf::DescriptorPool::Tables::files_by_name_
FilesByNameMap files_by_name_
Definition: src/google/protobuf/descriptor.cc:661
FileOptions::optimize_for
PROTOBUF_NAMESPACE_ID::FileOptions_OptimizeMode optimize_for() const
Definition: descriptor.pb.h:9659
google::protobuf::Reflection::FieldSize
int FieldSize(const Message &message, const FieldDescriptor *field) const
Definition: generated_message_reflection.cc:744
google::protobuf::SourceLocation::end_line
int end_line
Definition: src/google/protobuf/descriptor.h:147
google::protobuf::ERROR
static const LogLevel ERROR
Definition: protobuf/src/google/protobuf/testing/googletest.h:70
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
google::protobuf::Symbol::type
Type type
Definition: src/google/protobuf/descriptor.cc:91
google::protobuf::DescriptorPool::ErrorCollector::NAME
@ NAME
Definition: src/google/protobuf/descriptor.h:1639
depth
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glcorearb.h:2859
FileDescriptorProto::message_type
const PROTOBUF_NAMESPACE_ID::DescriptorProto & message_type(int index) const
Definition: descriptor.pb.h:6869
FieldDescriptorProto::mutable_extendee
std::string * mutable_extendee()
Definition: descriptor.pb.h:8023
google::protobuf::Service
Definition: service.h:132
google::protobuf::LowerString
void LowerString(string *s)
Definition: strutil.h:177
google::protobuf::DescriptorBuilder::LookupSymbol
Symbol LookupSymbol(const std::string &name, const std::string &relative_to, DescriptorPool::PlaceholderType placeholder_type=DescriptorPool::PLACEHOLDER_MESSAGE, ResolveMode resolve_mode=LOOKUP_ALL, bool build_it=true)
Definition: src/google/protobuf/descriptor.cc:3830
google::protobuf::FileDescriptor::CopyTo
void CopyTo(FileDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2010
google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE
@ CPPTYPE_DOUBLE
Definition: src/google/protobuf/descriptor.h:558
google::protobuf::FileDescriptorTables::AddFieldByNumber
bool AddFieldByNumber(const FieldDescriptor *field)
Definition: src/google/protobuf/descriptor.cc:1162
google::protobuf::DescriptorBuilder::OptionInterpreter::options_to_interpret_
const OptionsToInterpret * options_to_interpret_
Definition: src/google/protobuf/descriptor.cc:3458
google::protobuf.internal::WireFormatLite::EncodeDouble
static uint64 EncodeDouble(double value)
Definition: wire_format_lite.h:811
google::protobuf::Symbol::GetFile
const FileDescriptor * GetFile() const
Definition: src/google/protobuf/descriptor.cc:127
google::protobuf::FieldDescriptor::file_
const FileDescriptor * file_
Definition: src/google/protobuf/descriptor.h:786
google::protobuf::DescriptorPool::FileDescriptorTables
friend class FileDescriptorTables
Definition: src/google/protobuf/descriptor.h:1800
google::protobuf::DescriptorDatabase
Definition: src/google/protobuf/descriptor_database.h:71
google::protobuf::DescriptorBuilder::file_
FileDescriptor * file_
Definition: src/google/protobuf/descriptor.cc:3149
location
GLint location
Definition: glcorearb.h:3074
streq
bool streq(const char *lhs_, const char *rhs_)
Definition: testutil.cpp:508
google::protobuf::DescriptorPool::Tables::CheckPoint::CheckPoint
CheckPoint(const Tables *tables)
Definition: src/google/protobuf/descriptor.cc:665
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: logging.h:153
google::protobuf::FieldDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:779
google::protobuf::FileDescriptorTables::enum_values_by_number_
EnumValuesByNumberMap enum_values_by_number_
Definition: src/google/protobuf/descriptor.cc:786
google::protobuf::FileDescriptorTables::fields_by_camelcase_name_
FieldsByNameMap fields_by_camelcase_name_
Definition: src/google/protobuf/descriptor.cc:782
FieldDescriptorProto::set_type_name
void set_type_name(const std::string &value)
Definition: descriptor.pb.h:7918
google::protobuf::Symbol::enum_value_descriptor
const EnumValueDescriptor * enum_value_descriptor
Definition: src/google/protobuf/descriptor.cc:97
google::protobuf::DescriptorPool::Tables::AddFile
bool AddFile(const FileDescriptor *file)
Definition: src/google/protobuf/descriptor.cc:1119
ServiceDescriptorProto::kMethodFieldNumber
@ kMethodFieldNumber
Definition: descriptor.pb.h:3026
google::protobuf::DescriptorBuilder::BuildReservedRange
void BuildReservedRange(const DescriptorProto::ReservedRange &proto, const Descriptor *parent, Descriptor::ReservedRange *result)
Definition: src/google/protobuf/descriptor.cc:4992
google::protobuf::DescriptorPool::Tables::file_tables_
std::vector< FileDescriptorTables * > file_tables_
Definition: src/google/protobuf/descriptor.cc:657
google::protobuf::DescriptorPool::Tables::pending_files_
std::vector< std::string > pending_files_
Definition: src/google/protobuf/descriptor.cc:565
pool
InternalDescriptorPool * pool
Definition: php/ext/google/protobuf/protobuf.h:798
google::protobuf::OneofDescriptor::field_count_
int field_count_
Definition: src/google/protobuf/descriptor.h:900
google::protobuf::DescriptorBuilder::possible_undeclared_dependency_
const FileDescriptor * possible_undeclared_dependency_
Definition: src/google/protobuf/descriptor.cc:3164
FileDescriptorProto::kMessageTypeFieldNumber
@ kMessageTypeFieldNumber
Definition: descriptor.pb.h:642
google::protobuf::DescriptorPool::NewPlaceholderWithMutexHeld
Symbol NewPlaceholderWithMutexHeld(const std::string &name, PlaceholderType placeholder_type) const
Definition: src/google/protobuf/descriptor.cc:3870
MethodDescriptorProto::set_server_streaming
void set_server_streaming(bool value)
Definition: descriptor.pb.h:9427
google::protobuf::ServiceDescriptor::FindMethodByName
const MethodDescriptor * FindMethodByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1723
google::protobuf::io::CodedOutputStream
Definition: coded_stream.h:693
google::protobuf::FileDescriptor::SYNTAX_UNKNOWN
@ SYNTAX_UNKNOWN
Definition: src/google/protobuf/descriptor.h:1392
DescriptorProto_ReservedRange::start
::PROTOBUF_NAMESPACE_ID::int32 start() const
Definition: descriptor.pb.h:7285
google::protobuf::UnknownFieldSet::AddLengthDelimited
void AddLengthDelimited(int number, const std::string &value)
Definition: unknown_field_set.h:321
google::protobuf::DescriptorPool::Tables::once_dynamics_
std::vector< internal::once_flag * > once_dynamics_
Definition: src/google/protobuf/descriptor.cc:655
google::protobuf::DescriptorPool::Tables::CheckPoint::messages_before_checkpoint
int messages_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:678
FileDescriptorProto::public_dependency
::PROTOBUF_NAMESPACE_ID::int32 public_dependency(int index) const
Definition: descriptor.pb.h:6800
FileDescriptorProto::mutable_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_message_type(int index)
Definition: descriptor.pb.h:6860
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::Descriptor::containing_type_
const Descriptor * containing_type_
Definition: src/google/protobuf/descriptor.h:461
google::protobuf::RepeatedPtrField::size
int size() const
Definition: repeated_field.h:2009
google::protobuf::FileDescriptorTables::FindNestedSymbolOfType
Symbol FindNestedSymbolOfType(const void *parent, const std::string &name, const Symbol::Type type) const
Definition: src/google/protobuf/descriptor.cc:925
google::protobuf::kuint32max
static const uint32 kuint32max
Definition: protobuf/src/google/protobuf/stubs/port.h:163
google::protobuf::EnumDescriptor::containing_type_
const Descriptor * containing_type_
Definition: src/google/protobuf/descriptor.h:1038
google::protobuf::FileDescriptor::dependencies_once_
internal::once_flag * dependencies_once_
Definition: src/google/protobuf/descriptor.h:1461
google::protobuf::DescriptorBuilder::tables_
DescriptorPool::Tables * tables_
Definition: src/google/protobuf/descriptor.cc:3139
FileDescriptorProto::add_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_extension()
Definition: descriptor.pb.h:6963
google::protobuf::FieldDescriptor::TYPE_MESSAGE
@ TYPE_MESSAGE
Definition: src/google/protobuf/descriptor.h:536
google::protobuf::DebugStringOptions::elide_oneof_body
bool elide_oneof_body
Definition: src/google/protobuf/descriptor.h:168
MessageOptions::GetDescriptor
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * GetDescriptor()
Definition: descriptor.pb.h:3897
google::protobuf::DescriptorPool::Tables::known_bad_files_
HASH_SET< std::string > known_bad_files_
Definition: src/google/protobuf/descriptor.cc:572
google::protobuf::DynamicMessageFactory
Definition: dynamic_message.h:80
DescriptorProto::kEnumTypeFieldNumber
@ kEnumTypeFieldNumber
Definition: descriptor.pb.h:1348
google::protobuf.internal::MutexLockMaybe
Definition: protobuf/src/google/protobuf/stubs/mutex.h:130
google::protobuf::Descriptor::nested_type
const Descriptor * nested_type(int index) const
google::protobuf::FileDescriptor::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1775
google::protobuf.internal::GetEmptyString
const PROTOBUF_EXPORT std::string & GetEmptyString()
Definition: generated_message_util.h:87
google::protobuf::FieldDescriptor::TYPE_DOUBLE
@ TYPE_DOUBLE
Definition: src/google/protobuf/descriptor.h:522
google::protobuf::Descriptor::enum_type_count
int enum_type_count() const
FileDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::FileOptions & options() const
Definition: descriptor.pb.h:6981
FileDescriptorProto::kSyntaxFieldNumber
@ kSyntaxFieldNumber
Definition: descriptor.pb.h:650
google::protobuf::FileDescriptor::name
const std::string & name() const
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
google::protobuf::FileDescriptor::enum_type_count_
int enum_type_count_
Definition: src/google/protobuf/descriptor.h:1470
google::protobuf::DescriptorPool::Tables::extensions_after_checkpoint_
std::vector< DescriptorIntPair > extensions_after_checkpoint_
Definition: src/google/protobuf/descriptor.cc:689
google::protobuf::EnumValueDescriptor::CopyTo
void CopyTo(EnumValueDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2203
google::protobuf::FileDescriptor::is_placeholder_
bool is_placeholder_
Definition: src/google/protobuf/descriptor.h:1474
google::protobuf::FieldDescriptor::camelcase_name_
const std::string * camelcase_name_
Definition: src/google/protobuf/descriptor.h:782
google::protobuf::DescriptorPool::FindExtensionByNumber
const FieldDescriptor * FindExtensionByNumber(const Descriptor *extendee, int number) const
Definition: src/google/protobuf/descriptor.cc:1488
google::protobuf::DescriptorBuilder::file_tables_
FileDescriptorTables * file_tables_
Definition: src/google/protobuf/descriptor.cc:3150
google::protobuf::FieldDescriptor::has_json_name_
bool has_json_name_
Definition: src/google/protobuf/descriptor.h:795
google::protobuf::FieldDescriptor::CPPTYPE_FLOAT
@ CPPTYPE_FLOAT
Definition: src/google/protobuf/descriptor.h:559
google::protobuf::FileDescriptorTables::FinalizeTables
void FinalizeTables()
Definition: src/google/protobuf/descriptor.cc:1128
google::protobuf::DescriptorPool::Tables::CheckPoint::allocations_before_checkpoint
int allocations_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:681
google::protobuf::Descriptor::ExtensionRange::end
int end
Definition: src/google/protobuf/descriptor.h:357
type
GLenum type
Definition: glcorearb.h:2695
google::protobuf::FieldDescriptor::CPPTYPE_BOOL
@ CPPTYPE_BOOL
Definition: src/google/protobuf/descriptor.h:560
EnumDescriptorProto_EnumReservedRange::start
::PROTOBUF_NAMESPACE_ID::int32 start() const
Definition: descriptor.pb.h:8460
google::protobuf::UnknownField::TYPE_GROUP
@ TYPE_GROUP
Definition: unknown_field_set.h:230
google::protobuf::Symbol::ENUM_VALUE
@ ENUM_VALUE
Definition: src/google/protobuf/descriptor.cc:86
google::protobuf::FieldDescriptor::TYPE_INT32
@ TYPE_INT32
Definition: src/google/protobuf/descriptor.h:528
google::protobuf::Symbol::ONEOF
@ ONEOF
Definition: src/google/protobuf/descriptor.cc:84
google::protobuf::DescriptorBuilder::IsInPackage
bool IsInPackage(const FileDescriptor *file, const std::string &package_name)
Definition: src/google/protobuf/descriptor.cc:3668
google::protobuf::FieldDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2638
google::protobuf::Symbol::Symbol
Symbol()
Definition: src/google/protobuf/descriptor.cc:103
FieldOptions_JSType_descriptor
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor * FieldOptions_JSType_descriptor()
Definition: descriptor.pb.cc:1333
google::protobuf::FieldDescriptor::TYPE_FLOAT
@ TYPE_FLOAT
Definition: src/google/protobuf/descriptor.h:523
google::protobuf::DescriptorPool::FindOneofByName
const OneofDescriptor * FindOneofByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1457
google::protobuf::UnknownFieldSet::field
const UnknownField & field(int index) const
Definition: unknown_field_set.h:314
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
FileDescriptorProto::source_code_info
const PROTOBUF_NAMESPACE_ID::SourceCodeInfo & source_code_info() const
Definition: descriptor.pb.h:7041
DescriptorProto_ExtensionRange::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: descriptor.pb.h:7203
FileDescriptorProto::syntax
const std::string & syntax() const
Definition: descriptor.pb.h:7101
error_collector_
MockErrorCollector error_collector_
Definition: importer_unittest.cc:129
google::protobuf::DescriptorBuilder::OptionInterpreter::repeated_option_counts_
std::map< std::vector< int >, int > repeated_option_counts_
Definition: src/google/protobuf/descriptor.cc:3474
EnumDescriptorProto::kValueFieldNumber
@ kValueFieldNumber
Definition: descriptor.pb.h:2591
FileDescriptorProto::add_public_dependency
void add_public_dependency(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:6808
google::protobuf::io::StringOutputStream
Definition: zero_copy_stream_impl_lite.h:131
google::protobuf::FieldDescriptor::type
Type type() const
Definition: src/google/protobuf/descriptor.h:2052
google::protobuf::Descriptor::reserved_range_count
int reserved_range_count() const
FileDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::FileOptions * mutable_options()
Definition: descriptor.pb.h:7004
google::protobuf::FileDescriptorTables::fields_by_lowercase_name_
FieldsByNameMap fields_by_lowercase_name_
Definition: src/google/protobuf/descriptor.cc:779
google::protobuf::DescriptorBuilder::pool_
const DescriptorPool * pool_
Definition: src/google/protobuf/descriptor.cc:3138
google::protobuf::DescriptorBuilder::BuildMethod
void BuildMethod(const MethodDescriptorProto &proto, const ServiceDescriptor *parent, MethodDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:5300
google::protobuf::MethodDescriptor::input_type
const Descriptor * input_type() const
Definition: src/google/protobuf/descriptor.cc:7281
google::protobuf::EnumDescriptor::options_
const EnumOptions * options_
Definition: src/google/protobuf/descriptor.h:1039
len
int len
Definition: php/ext/google/protobuf/map.c:206
google::protobuf::FieldDescriptor::default_value_double_
double default_value_double_
Definition: src/google/protobuf/descriptor.h:817
FileDescriptorProto::dependency_size
int dependency_size() const
Definition: descriptor.pb.h:6729
google::protobuf::EnumValueDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2851
EnumValueDescriptorProto::set_number
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:8853
google::protobuf::Symbol::ENUM
@ ENUM
Definition: src/google/protobuf/descriptor.cc:85
google::protobuf::kint32max
static const int32 kint32max
Definition: protobuf/src/google/protobuf/stubs/port.h:159
google::protobuf::UnknownField::TYPE_LENGTH_DELIMITED
@ TYPE_LENGTH_DELIMITED
Definition: unknown_field_set.h:229
DescriptorProto::add_reserved_name
std::string * add_reserved_name()
Definition: descriptor.pb.h:7700
EnumDescriptorProto::add_value
PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto * add_value()
Definition: descriptor.pb.h:8592
google::protobuf::DescriptorPool::Tables::extensions_loaded_from_db_
HASH_SET< const Descriptor * > extensions_loaded_from_db_
Definition: src/google/protobuf/descriptor.cc:582
google::protobuf::Symbol::METHOD
@ METHOD
Definition: src/google/protobuf/descriptor.cc:88
google::protobuf::EnumDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2793
OneofDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:8316
google::protobuf::FieldDescriptor::name
const std::string & name() const
google::protobuf::DescriptorBuilder::filename_
std::string filename_
Definition: src/google/protobuf/descriptor.cc:3148
google::protobuf::DescriptorPool::lazily_build_dependencies_
bool lazily_build_dependencies_
Definition: src/google/protobuf/descriptor.h:1861
google::protobuf::EnumValueDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:3028
google::protobuf::DescriptorPool::FindFieldByName
const FieldDescriptor * FindFieldByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1436
VALIDATE_OPTIONS_FROM_ARRAY
#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type)
Definition: src/google/protobuf/descriptor.cc:5783
google::protobuf::EnumDescriptor::containing_type
const Descriptor * containing_type() const
common.h
DescriptorProto::kOneofDeclFieldNumber
@ kOneofDeclFieldNumber
Definition: descriptor.pb.h:1351
OneofDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:133
google::protobuf::FileDescriptor::message_type
const Descriptor * message_type(int index) const
FieldDescriptorProto::number
::PROTOBUF_NAMESPACE_ID::int32 number() const
Definition: descriptor.pb.h:7858
google::protobuf::FileDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:1458
google::protobuf::Descriptor::reserved_name_count
int reserved_name_count() const
EnumDescriptorProto
Definition: descriptor.pb.h:2449
google::protobuf::EnumDescriptor::full_name
const std::string & full_name() const
ServiceDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:3028
google::protobuf::FieldDescriptor::extension_scope_
const Descriptor * extension_scope_
Definition: src/google/protobuf/descriptor.h:801
google::protobuf::FileDescriptor::weak_dependency_count_
int weak_dependency_count_
Definition: src/google/protobuf/descriptor.h:1468
DescriptorProto_ReservedRange::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: descriptor.pb.h:7303
FieldDescriptorProto::set_extendee
void set_extendee(const std::string &value)
Definition: descriptor.pb.h:7998
google::protobuf::FieldDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3046
google::protobuf::Symbol
Definition: src/google/protobuf/descriptor.cc:79
google::protobuf::FieldDescriptor::PRINT_LABEL
@ PRINT_LABEL
Definition: src/google/protobuf/descriptor.h:759
DescriptorProto::nested_type
const PROTOBUF_NAMESPACE_ID::DescriptorProto & nested_type(int index) const
Definition: descriptor.pb.h:7473
google::protobuf::DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo
void UpdateSourceCodeInfo(SourceCodeInfo *info)
Definition: src/google/protobuf/descriptor.cc:6560
google::protobuf::Descriptor::FindFieldByName
const FieldDescriptor * FindFieldByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1615
FileDescriptorProto::extension_size
int extension_size() const
Definition: descriptor.pb.h:6944
google::protobuf::FileDescriptor::dependency
const FileDescriptor * dependency(int index) const
Definition: src/google/protobuf/descriptor.cc:7271
google::protobuf::EnumDescriptor::options
const EnumOptions & options() const
google::protobuf::Descriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: src/google/protobuf/descriptor.cc:2522
google::protobuf::FieldDescriptor::kTypeToName
static const char *const kTypeToName[MAX_TYPE+1]
Definition: src/google/protobuf/descriptor.h:826
google::protobuf::DescriptorPool::ErrorCollector::EXTENDEE
@ EXTENDEE
Definition: src/google/protobuf/descriptor.h:1642
DescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:7329
ch
char ch
Definition: gmock-matchers_test.cc:3871
FieldDescriptorProto::oneof_index
::PROTOBUF_NAMESPACE_ID::int32 oneof_index() const
Definition: descriptor.pb.h:8154
google::protobuf::DescriptorBuilder::undefine_resolved_name_
std::string undefine_resolved_name_
Definition: src/google/protobuf/descriptor.cc:3170
google::protobuf::FieldDescriptor::TYPE_FIXED64
@ TYPE_FIXED64
Definition: src/google/protobuf/descriptor.h:531
size
GLsizeiptr size
Definition: glcorearb.h:2943
SourceCodeInfo_Location
Definition: descriptor.pb.h:5729
google::protobuf::io::ErrorCollector
Definition: tokenizer.h:66
google::protobuf::EnumDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:1035
google::protobuf::FileDescriptor::service_count
int service_count() const
google::protobuf::DescriptorBuilder::get_enforce_weak
static bool get_enforce_weak(const DescriptorPool *pool)
Definition: src/google/protobuf/descriptor.cc:3496
stl_util.h
google::protobuf::DescriptorPool::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1447
google::protobuf::FileDescriptor::extensions_
FieldDescriptor * extensions_
Definition: src/google/protobuf/descriptor.h:1488
google::protobuf::OneofDescriptor::index
int index() const
Definition: src/google/protobuf/descriptor.h:2103
google::protobuf::Symbol::IsNull
bool IsNull() const
Definition: src/google/protobuf/descriptor.cc:104
google::protobuf::DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE
@ PLACEHOLDER_EXTENDABLE_MESSAGE
Definition: src/google/protobuf/descriptor.h:1838
google::protobuf::ToLowercaseWithoutUnderscores
static std::string ToLowercaseWithoutUnderscores(const std::string &name)
Definition: src/google/protobuf/descriptor.cc:5839
google::protobuf::DescriptorBuilder::AddImportError
void AddImportError(const FileDescriptorProto &proto, int index)
Definition: src/google/protobuf/descriptor.cc:4186
FileDescriptorProto::kServiceFieldNumber
@ kServiceFieldNumber
Definition: descriptor.pb.h:644
google::protobuf::RepeatedField::size
int size() const
Definition: repeated_field.h:1140
google::protobuf::DescriptorBuilder::BuildFieldOrExtension
void BuildFieldOrExtension(const FieldDescriptorProto &proto, const Descriptor *parent, FieldDescriptor *result, bool is_extension)
Definition: src/google/protobuf/descriptor.cc:4667
google::protobuf::UnknownFieldSet
Definition: unknown_field_set.h:86
MethodDescriptorProto::client_streaming
bool client_streaming() const
Definition: descriptor.pb.h:9405
DescriptorProto::add_nested_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * add_nested_type()
Definition: descriptor.pb.h:7477
google::protobuf::DescriptorPool::generated_pool
static const DescriptorPool * generated_pool()
Definition: src/google/protobuf/descriptor.cc:1346
google::protobuf::FileDescriptor::options_
const FileOptions * options_
Definition: src/google/protobuf/descriptor.h:1489
OneofDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::OneofOptions * mutable_options()
Definition: descriptor.pb.h:8419
stringprintf.h
google::protobuf::FileDescriptor::message_types_
Descriptor * message_types_
Definition: src/google/protobuf/descriptor.h:1485
google::protobuf::Descriptor::name
const std::string & name() const
google::protobuf::DescriptorBuilder::BuildExtensionRange
void BuildExtensionRange(const DescriptorProto::ExtensionRange &proto, const Descriptor *parent, Descriptor::ExtensionRange *result)
Definition: src/google/protobuf/descriptor.cc:4955
SourceCodeInfo
Definition: descriptor.pb.h:5977
google::protobuf::DescriptorPool::InternalDontEnforceDependencies
void InternalDontEnforceDependencies()
Definition: src/google/protobuf/descriptor.cc:1304
wire_format.h
google::protobuf::Descriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: src/google/protobuf/descriptor.cc:3035
google::protobuf::DescriptorPool::disallow_enforce_utf8_
bool disallow_enforce_utf8_
Definition: src/google/protobuf/descriptor.h:1864
google::protobuf::FieldDescriptor::message_type_
const Descriptor * message_type_
Definition: src/google/protobuf/descriptor.h:802
logging.h
google::protobuf::SourceLocation::end_column
int end_column
Definition: src/google/protobuf/descriptor.h:149
MethodDescriptorProto::output_type
const std::string & output_type() const
Definition: descriptor.pb.h:9265
google::protobuf::ServiceDescriptor::method_count
int method_count() const
google::protobuf::DescriptorPool::Tables::Tables
Tables()
Definition: src/google/protobuf/descriptor.cc:799
google::protobuf::FileDescriptorTables::locations_by_path_
LocationsByPathMap locations_by_path_
Definition: src/google/protobuf/descriptor.cc:792
DescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::MessageOptions * mutable_options()
Definition: descriptor.pb.h:7608
google::protobuf::Descriptor::file
const FileDescriptor * file() const
OneofDescriptorProto
Definition: descriptor.pb.h:2087
MethodDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::MethodOptions & options() const
Definition: descriptor.pb.h:9345
FileDescriptorProto::add_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * add_enum_type()
Definition: descriptor.pb.h:6903
DescriptorProto
Definition: descriptor.pb.h:1203
google::protobuf::EnumValueDescriptor
Definition: src/google/protobuf/descriptor.h:1075
google::protobuf::Split
std::vector< string > Split(const string &full, const char *delim, bool skip_empty=true)
Definition: strutil.h:235
google::protobuf::Descriptor
Definition: src/google/protobuf/descriptor.h:231
descriptor.h
google::protobuf::FieldDescriptor::TYPE_GROUP
@ TYPE_GROUP
Definition: src/google/protobuf/descriptor.h:535
google::protobuf::DescriptorBuilder::FindSymbol
Symbol FindSymbol(const std::string &name, bool build_it=true)
Definition: src/google/protobuf/descriptor.cc:3715
MethodDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:9105
default_value
def default_value(type_)
google::protobuf::FieldDescriptor::TYPE_SFIXED32
@ TYPE_SFIXED32
Definition: src/google/protobuf/descriptor.h:541
google::protobuf::DescriptorBuilder::error_collector_
DescriptorPool::ErrorCollector * error_collector_
Definition: src/google/protobuf/descriptor.cc:3140
google::protobuf::DescriptorBuilder::LookupSymbolNoPlaceholder
Symbol LookupSymbolNoPlaceholder(const std::string &name, const std::string &relative_to, ResolveMode resolve_mode=LOOKUP_ALL, bool build_it=true)
Definition: src/google/protobuf/descriptor.cc:3755
google::protobuf::Descriptor::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1637
FieldDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:7778
upb_fielddef::name
char * name
Definition: ruby/ext/google/protobuf_c/upb.h:2336
DescriptorProto::reserved_range
const PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange & reserved_range(int index) const
Definition: descriptor.pb.h:7653
google::protobuf::DescriptorPool::unused_import_track_files_
std::set< std::string > unused_import_track_files_
Definition: src/google/protobuf/descriptor.h:1865
google::protobuf::UnknownFieldSet::AddFixed32
void AddFixed32(int number, uint32 value)
Definition: unknown_field_set.cc:142
google::protobuf::FileDescriptor::FindExtensionByCamelcaseName
const FieldDescriptor * FindExtensionByCamelcaseName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1795
hash.h
EnumValueDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::EnumValueOptions * mutable_options()
Definition: descriptor.pb.h:8890
google::protobuf::ServiceDescriptor::name_
const std::string * name_
Definition: src/google/protobuf/descriptor.h:1211
google::protobuf::UnknownFieldSet::AddFixed64
void AddFixed64(int number, uint64 value)
Definition: unknown_field_set.cc:150
FileDescriptorProto::mutable_source_code_info
PROTOBUF_NAMESPACE_ID::SourceCodeInfo * mutable_source_code_info()
Definition: descriptor.pb.h:7064
google::protobuf::FieldDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:2998
google::protobuf::Descriptor::FindFieldByCamelcaseName
const FieldDescriptor * FindFieldByCamelcaseName(const std::string &camelcase_name) const
Definition: src/google/protobuf/descriptor.cc:1604
element_name
std::string element_name
Definition: src/google/protobuf/descriptor.cc:3116
generated_message_util.h
EnumDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:8504
google::protobuf::FieldDescriptor::DefaultValueAsString
std::string DefaultValueAsString(bool quote_string_type) const
Definition: src/google/protobuf/descriptor.cc:1961
google::protobuf::Descriptor::FindExtensionByCamelcaseName
const FieldDescriptor * FindExtensionByCamelcaseName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1659
ServiceDescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:8931
pool_
DescriptorPool pool_
Definition: parser_unittest.cc:183
google::protobuf::ToUpper
string ToUpper(const string &s)
Definition: strutil.h:193
google::protobuf::FieldDescriptor::message_type
const Descriptor * message_type() const
Definition: src/google/protobuf/descriptor.cc:7228
google::protobuf::FieldDescriptor::kFirstReservedNumber
static const int kFirstReservedNumber
Definition: src/google/protobuf/descriptor.h:585
Type
struct Type Type
Definition: php/ext/google/protobuf/protobuf.h:664
substitute.h
google::protobuf::DescriptorBuilder::CrossLinkService
void CrossLinkService(ServiceDescriptor *service, const ServiceDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5723
google::protobuf::FieldDescriptor::TYPE_UINT64
@ TYPE_UINT64
Definition: src/google/protobuf/descriptor.h:527
google::protobuf::FileDescriptor
Definition: src/google/protobuf/descriptor.h:1320
google::protobuf::FileDescriptorTables::FindEnumValueByNumber
const EnumValueDescriptor * FindEnumValueByNumber(const EnumDescriptor *parent, int number) const
Definition: src/google/protobuf/descriptor.cc:1028
google::protobuf.internal::LazyDescriptor
Definition: src/google/protobuf/descriptor.h:182
google::protobuf::DescriptorPool::ErrorCollector::DEFAULT_VALUE
@ DEFAULT_VALUE
Definition: src/google/protobuf/descriptor.h:1643
google::protobuf::FileDescriptor::weak_dependencies_
int * weak_dependencies_
Definition: src/google/protobuf/descriptor.h:1484
google::protobuf::EnumDescriptor::reserved_range
const EnumDescriptor::ReservedRange * reserved_range(int index) const
google::protobuf::DescriptorPool::Tables::AllocateOnceDynamic
internal::once_flag * AllocateOnceDynamic()
Definition: src/google/protobuf/descriptor.cc:1207
google::protobuf::DescriptorBuilder::BuildMessage
void BuildMessage(const DescriptorProto &proto, const Descriptor *parent, Descriptor *result)
Definition: src/google/protobuf/descriptor.cc:4536
google::protobuf::DescriptorPool::FindAllExtensions
void FindAllExtensions(const Descriptor *extendee, std::vector< const FieldDescriptor * > *out) const
Definition: src/google/protobuf/descriptor.cc:1549
google::protobuf::FileDescriptorTables::PROTOBUF_GUARDED_BY
EnumValuesByNumberMap unknown_enum_values_by_number_ PROTOBUF_GUARDED_BY(unknown_enum_values_mu_)
google::protobuf::FileDescriptorTables::AddAliasUnderParent
bool AddAliasUnderParent(const void *parent, const std::string &name, Symbol symbol)
Definition: src/google/protobuf/descriptor.cc:1112
google::protobuf::FileDescriptorTables
Definition: src/google/protobuf/descriptor.cc:705
google::protobuf::EnumValueDescriptor::full_name
const std::string & full_name() const
FieldDescriptorProto::has_type
bool has_type() const
Definition: descriptor.pb.h:7888
google::protobuf::DescriptorPool::Tables::CheckPoint::pending_symbols_before_checkpoint
int pending_symbols_before_checkpoint
Definition: src/google/protobuf/descriptor.cc:682
google::protobuf::FieldDescriptor::containing_oneof
const OneofDescriptor * containing_oneof() const
true
#define true
Definition: cJSON.c:65
google::protobuf::FieldDescriptor::LABEL_REPEATED
@ LABEL_REPEATED
Definition: src/google/protobuf/descriptor.h:574
google::protobuf::FieldDescriptor::TYPE_INT64
@ TYPE_INT64
Definition: src/google/protobuf/descriptor.h:524
google::protobuf::kint64max
static const int64 kint64max
Definition: protobuf/src/google/protobuf/stubs/port.h:161
google::protobuf::DescriptorBuilder::OptionInterpreter::interpreted_paths_
std::map< std::vector< int >, std::vector< int > > interpreted_paths_
Definition: src/google/protobuf/descriptor.cc:3469
google::protobuf::DescriptorPool::Tables::AllocateArray
Type * AllocateArray(int count)
Definition: src/google/protobuf/descriptor.cc:1191
internal
Definition: any.pb.h:40
google::protobuf::DescriptorBuilder::options_to_interpret_
std::vector< OptionsToInterpret > options_to_interpret_
Definition: src/google/protobuf/descriptor.cc:3145
google::protobuf::DescriptorBuilder::LOOKUP_TYPES
@ LOOKUP_TYPES
Definition: src/google/protobuf/descriptor.cc:3232
google::protobuf::RepeatedField::Get
const Element & Get(int index) const
Definition: repeated_field.h:1185
google::protobuf::FieldDescriptor::is_map_message_type
bool is_map_message_type() const
Definition: src/google/protobuf/descriptor.cc:1957
google::protobuf::DescriptorBuilder
Definition: src/google/protobuf/descriptor.cc:3124
google::protobuf::SourceLocation::leading_detached_comments
std::vector< std::string > leading_detached_comments
Definition: src/google/protobuf/descriptor.h:155
google::protobuf::FieldDescriptor::LABEL_OPTIONAL
@ LABEL_OPTIONAL
Definition: src/google/protobuf/descriptor.h:572
FieldOptions_JSType
FieldOptions_JSType
Definition: descriptor.pb.h:283
google::protobuf::FileDescriptorTables::GetSourceLocation
const SourceCodeInfo_Location * GetSourceLocation(const std::vector< int > &path, const SourceCodeInfo *info) const
Definition: src/google/protobuf/descriptor.cc:1246
WriterMutexLock
#define WriterMutexLock(x)
Definition: glog/src/base/mutex.h:325
google::protobuf::Descriptor::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1681
google::protobuf::DescriptorBuilder::OptionInterpreter::AggregateOptionFinder::FindExtension
const FieldDescriptor * FindExtension(Message *message, const std::string &name) const override
Definition: src/google/protobuf/descriptor.cc:6949
google::protobuf::FileDescriptor::public_dependency_count_
int public_dependency_count_
Definition: src/google/protobuf/descriptor.h:1467
google::protobuf::DescriptorBuilder::had_errors_
bool had_errors_
Definition: src/google/protobuf/descriptor.cc:3147
google::protobuf::DescriptorBuilder::ValidateFileOptions
void ValidateFileOptions(FileDescriptor *file, const FileDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5799
google::protobuf::DescriptorBuilder::ValidateMethodOptions
void ValidateMethodOptions(MethodDescriptor *method, const MethodDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6088
google::protobuf::OneofDescriptor::CopyTo
void CopyTo(OneofDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2176
google::protobuf::EnumDescriptor::reserved_name_count_
int reserved_name_count_
Definition: src/google/protobuf/descriptor.h:1050
FileDescriptorProto::has_source_code_info
bool has_source_code_info() const
Definition: descriptor.pb.h:7034
have_source_loc_
bool have_source_loc_
Definition: src/google/protobuf/descriptor.cc:2408
google::protobuf::Join
void Join(Iterator start, Iterator end, const char *delim, string *result)
Definition: strutil.h:769
google::protobuf::FileDescriptor::FindEnumValueByName
const EnumValueDescriptor * FindEnumValueByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1754
google::protobuf::ServiceDescriptor::CopyTo
void CopyTo(ServiceDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2212
DescriptorProto::add_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_extension()
Definition: descriptor.pb.h:7447
google::protobuf::EnumDescriptor::reserved_names_
const std::string ** reserved_names_
Definition: src/google/protobuf/descriptor.h:1052
google::protobuf::FieldDescriptor::default_value_int32_
int32 default_value_int32_
Definition: src/google/protobuf/descriptor.h:812
FieldDescriptorProto::set_json_name
void set_json_name(const std::string &value)
Definition: descriptor.pb.h:8176
Field
Definition: type.pb.h:416
DescriptorProto::name
const std::string & name() const
Definition: descriptor.pb.h:7325
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf::EnumDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:3010
google::protobuf::DescriptorBuilder::AllocateOptions
void AllocateOptions(const typename DescriptorT::OptionsType &orig_options, DescriptorT *descriptor, int options_field_tag)
Definition: src/google/protobuf/descriptor.cc:4093
google::protobuf::Symbol::method_descriptor
const MethodDescriptor * method_descriptor
Definition: src/google/protobuf/descriptor.cc:99
google::protobuf::DescriptorBuilder::AddError
void AddError(const std::string &element_name, const Message &descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &error)
Definition: src/google/protobuf/descriptor.cc:3601
google::protobuf::FileDescriptor::CopyJsonNameTo
void CopyJsonNameTo(FileDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2046
descriptor_
const Descriptor * descriptor_
Definition: field_comparator_test.cc:56
google::protobuf::DescriptorBuilder::possible_undeclared_dependency_name_
std::string possible_undeclared_dependency_name_
Definition: src/google/protobuf/descriptor.cc:3165
google::protobuf::DescriptorBuilder::DescriptorBuilder
DescriptorBuilder(const DescriptorPool *pool, DescriptorPool::Tables *tables, DescriptorPool::ErrorCollector *error_collector)
Definition: src/google/protobuf/descriptor.cc:3589
FileDescriptorProto::package
const std::string & package() const
Definition: descriptor.pb.h:6656
google::protobuf::OneofDescriptor::field_count
int field_count() const
google::protobuf::DescriptorPool::ErrorCollector::OTHER
@ OTHER
Definition: src/google/protobuf/descriptor.h:1649
descriptor.pb.h
google::protobuf::EnumDescriptor::reserved_range_count
int reserved_range_count() const
google::protobuf::UnknownField::number
int number() const
Definition: unknown_field_set.h:329
DescriptorProto::field_size
int field_size() const
Definition: descriptor.pb.h:7398
google::protobuf::DescriptorPool::NewPlaceholderFile
FileDescriptor * NewPlaceholderFile(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:3968
google::protobuf::DescriptorPool::enforce_weak_
bool enforce_weak_
Definition: src/google/protobuf/descriptor.h:1863
google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE
@ CPPTYPE_MESSAGE
Definition: src/google/protobuf/descriptor.h:563
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
google::protobuf::Descriptor::CopyJsonNameTo
void CopyJsonNameTo(DescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2102
google::protobuf::FileDescriptorTables::AddEnumValueByNumber
bool AddEnumValueByNumber(const EnumValueDescriptor *value)
Definition: src/google/protobuf/descriptor.cc:1167
benchmarks.python.py_benchmark.parser
parser
Definition: py_benchmark.py:10
google::protobuf::DescriptorPool::Tables::messages_
std::vector< Message * > messages_
Definition: src/google/protobuf/descriptor.cc:653
google::protobuf::FieldDescriptor::json_name_
const std::string * json_name_
Definition: src/google/protobuf/descriptor.h:785
DescriptorProto::mutable_field
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_field(int index)
Definition: descriptor.pb.h:7404
google::protobuf::FieldDescriptor::CPPTYPE_INT32
@ CPPTYPE_INT32
Definition: src/google/protobuf/descriptor.h:554
google::protobuf::FieldDescriptor::TYPE_ENUM
@ TYPE_ENUM
Definition: src/google/protobuf/descriptor.h:540
google::protobuf::FieldDescriptor::kTypeToCppTypeMap
static const CppType kTypeToCppTypeMap[MAX_TYPE+1]
Definition: src/google/protobuf/descriptor.h:824
google::protobuf::strtou64
uint64 strtou64(const char *nptr, char **endptr, int base)
Definition: strutil.h:380
count
GLint GLsizei count
Definition: glcorearb.h:2830
google::protobuf::EnumDescriptor
Definition: src/google/protobuf/descriptor.h:918
CONSTRUCTOR
#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD)
Definition: src/google/protobuf/descriptor.cc:111
google::protobuf::FieldDescriptor::TYPE_SFIXED64
@ TYPE_SFIXED64
Definition: src/google/protobuf/descriptor.h:542
false
#define false
Definition: cJSON.c:70
DescriptorPool
Definition: ruby/ext/google/protobuf_c/protobuf.h:109
google::protobuf::Descriptor::ExtensionRange::start
int start
Definition: src/google/protobuf/descriptor.h:356
google::protobuf::FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal
void FieldsByCamelcaseNamesLazyInitInternal() const
Definition: src/google/protobuf/descriptor.cc:1009
google::protobuf::Symbol::package_file_descriptor
const FileDescriptor * package_file_descriptor
Definition: src/google/protobuf/descriptor.cc:100
google::protobuf::DescriptorPool::Tables::AllocateMessage
Type * AllocateMessage(Type *dummy=nullptr)
Definition: src/google/protobuf/descriptor.cc:1214
google::protobuf::DescriptorBuilder::OptionInterpreter::AggregateOptionFinder::builder_
DescriptorBuilder * builder_
Definition: src/google/protobuf/descriptor.cc:6947
DescriptorPool
struct DescriptorPool DescriptorPool
Definition: php/ext/google/protobuf/protobuf.h:629
FileDescriptorProto::weak_dependency_size
int weak_dependency_size() const
Definition: descriptor.pb.h:6824
google::protobuf::EnumDescriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:1036
EnumDescriptorProto::value_size
int value_size() const
Definition: descriptor.pb.h:8573
FieldDescriptorProto::mutable_type_name
std::string * mutable_type_name()
Definition: descriptor.pb.h:7943
google::protobuf::ServiceDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: src/google/protobuf/descriptor.cc:3022
DescriptorProto::add_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * add_enum_type()
Definition: descriptor.pb.h:7507
google::protobuf::DescriptorBuilder::CrossLinkEnumValue
void CrossLinkEnumValue(EnumValueDescriptor *enum_value, const EnumValueDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5715
DescriptorProto_ExtensionRange::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: descriptor.pb.h:988
google::protobuf::DescriptorBuilder::RecordPublicDependencies
void RecordPublicDependencies(const FileDescriptor *file)
Definition: src/google/protobuf/descriptor.cc:3675
index
GLuint index
Definition: glcorearb.h:3055
google::protobuf::DescriptorPool::FindMethodByName
const MethodDescriptor * FindMethodByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1482
google::protobuf::DescriptorBuilder::OptionInterpreter::SetInt32
void SetInt32(int number, int32 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: src/google/protobuf/descriptor.cc:7048
MethodDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:9109
google::protobuf::FileDescriptor::public_dependency
const FileDescriptor * public_dependency(int index) const
Definition: src/google/protobuf/descriptor.h:2166
group
static uint32_t * group(tarjan *t, upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5943
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
google::protobuf::MethodDescriptor::output_type_
internal::LazyDescriptor output_type_
Definition: src/google/protobuf/descriptor.h:1301
google::protobuf::DescriptorBuilder::AddPackage
void AddPackage(const std::string &name, const Message &proto, const FileDescriptor *file)
Definition: src/google/protobuf/descriptor.cc:4039
google::protobuf::FileDescriptor::message_type_count
int message_type_count() const
google::protobuf::EnumDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2788
google::protobuf::FieldDescriptor::type_name_
const std::string * type_name_
Definition: src/google/protobuf/descriptor.h:805
FieldDescriptorProto::set_name
void set_name(const std::string &value)
Definition: descriptor.pb.h:7782
google::protobuf::ServiceDescriptor::full_name_
const std::string * full_name_
Definition: src/google/protobuf/descriptor.h:1212
google::protobuf::Reflection::ListFields
void ListFields(const Message &message, std::vector< const FieldDescriptor * > *output) const
Definition: generated_message_reflection.cc:1029
google::protobuf::EnumValueDescriptor::options_
const EnumValueOptions * options_
Definition: src/google/protobuf/descriptor.h:1136
google::protobuf::DescriptorPool::ErrorCollector::OPTION_NAME
@ OPTION_NAME
Definition: src/google/protobuf/descriptor.h:1646
google::protobuf::RepeatedPtrField::begin
iterator begin()
Definition: repeated_field.h:2444
google::protobuf::OneofDescriptor::containing_type
const Descriptor * containing_type() const
google::protobuf::FieldDescriptor::is_repeated
bool is_repeated() const
Definition: src/google/protobuf/descriptor.h:2067
google::protobuf::DescriptorPool::Tables::AllocateEmptyString
std::string * AllocateEmptyString()
Definition: src/google/protobuf/descriptor.cc:1201
google::protobuf::DescriptorPool::ErrorCollector::OPTION_VALUE
@ OPTION_VALUE
Definition: src/google/protobuf/descriptor.h:1647
google::protobuf::FileDescriptorTables::FindFieldByNumber
const FieldDescriptor * FindFieldByNumber(const Descriptor *parent, int number) const
Definition: src/google/protobuf/descriptor.cc:962
google::protobuf::Descriptor::index
int index() const
Definition: src/google/protobuf/descriptor.h:2091
google::protobuf::DescriptorPool::Tables::files_after_checkpoint_
std::vector< const char * > files_after_checkpoint_
Definition: src/google/protobuf/descriptor.cc:688
ServiceDescriptorProto::method
const PROTOBUF_NAMESPACE_ID::MethodDescriptorProto & method(int index) const
Definition: descriptor.pb.h:9019
Method
Definition: api.pb.h:285
google::protobuf::Descriptor::reserved_name_count_
int reserved_name_count_
Definition: src/google/protobuf/descriptor.h:481
google::protobuf::EncodedDescriptorDatabase
Definition: src/google/protobuf/descriptor_database.h:301
google::protobuf::FieldDescriptor::index_in_oneof_
int index_in_oneof_
Definition: src/google/protobuf/descriptor.h:798
google::protobuf::FieldDescriptor::default_value_float_
float default_value_float_
Definition: src/google/protobuf/descriptor.h:816
google::protobuf::DescriptorBuilder::CheckEnumValueUniqueness
void CheckEnumValueUniqueness(const EnumDescriptorProto &proto, const EnumDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:5042
google::protobuf::FieldDescriptor::cpp_type
CppType cpp_type() const
Definition: src/google/protobuf/descriptor.h:2139
google::protobuf::Descriptor::FindExtensionRangeContainingNumber
const ExtensionRange * FindExtensionRangeContainingNumber(int number) const
Definition: src/google/protobuf/descriptor.cc:1815
number
double number
Definition: cJSON.h:326
google::protobuf::MethodDescriptor::options_
const MethodOptions * options_
Definition: src/google/protobuf/descriptor.h:1302
google::protobuf::DescriptorPool::Tables::allocations_
std::vector< void * > allocations_
Definition: src/google/protobuf/descriptor.cc:658
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
google::protobuf::TextFormat::PrintFieldValueToString
static void PrintFieldValueToString(const Message &message, const FieldDescriptor *field, int index, std::string *output)
Definition: text_format.cc:2408
google::protobuf::FieldDescriptor::CppType
CppType
Definition: src/google/protobuf/descriptor.h:553
DescriptorProto_ExtensionRange::set_start
void set_start(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:7189
google::protobuf::ServiceDescriptor::DebugString
std::string DebugString() const
Definition: src/google/protobuf/descriptor.cc:2879
google::protobuf::InsertIfNotPresent
bool InsertIfNotPresent(Collection *const collection, const typename Collection::value_type &vt)
Definition: map_util.h:321
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
google::protobuf::DescriptorBuilder::BuildExtension
void BuildExtension(const FieldDescriptorProto &proto, const Descriptor *parent, FieldDescriptor *result)
Definition: src/google/protobuf/descriptor.cc:3307
google::protobuf::DescriptorPool::Tables::checkpoints_
std::vector< CheckPoint > checkpoints_
Definition: src/google/protobuf/descriptor.cc:686
google::protobuf::MethodDescriptor::full_name
const std::string & full_name() const
google::protobuf::DescriptorPool::Tables::FindByNameHelper
Symbol FindByNameHelper(const DescriptorPool *pool, const std::string &name)
Definition: src/google/protobuf/descriptor.cc:933
google::protobuf::FileDescriptor::extension_count
int extension_count() const
google::protobuf::DescriptorBuilder::get_allow_unknown
static bool get_allow_unknown(const DescriptorPool *pool)
Definition: src/google/protobuf/descriptor.cc:3493
google::protobuf::FileDescriptorTables::fields_by_number_
FieldsByNumberMap fields_by_number_
Definition: src/google/protobuf/descriptor.cc:785
google::protobuf::FileDescriptor::Syntax
Syntax
Definition: src/google/protobuf/descriptor.h:1391
FieldDescriptorProto::has_oneof_index
bool has_oneof_index() const
Definition: descriptor.pb.h:8147
google::protobuf::DescriptorBuilder::ValidateJSType
void ValidateJSType(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:6222
google::protobuf::method
const Descriptor::ReservedRange const EnumValueDescriptor method
Definition: src/google/protobuf/descriptor.h:1973
google::protobuf.internal::cpp_type
FieldDescriptor::CppType cpp_type(FieldType type)
Definition: extension_set_heavy.cc:133
google::protobuf::FileDescriptor::dependency_count
int dependency_count() const
ServiceOptions::default_instance
static const ServiceOptions & default_instance()
Definition: descriptor.pb.cc:11977
DescriptorProto::enum_type
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto & enum_type(int index) const
Definition: descriptor.pb.h:7503
DescriptorProto_ReservedRange
Definition: descriptor.pb.h:1032
google::protobuf::DescriptorPool::AddUnusedImportTrackFile
void AddUnusedImportTrackFile(const std::string &file_name)
Definition: src/google/protobuf/descriptor.cc:1308
google::protobuf::DescriptorPool::FindServiceByName
const ServiceDescriptor * FindServiceByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1476
google::protobuf::DescriptorBuilder::CrossLinkMessage
void CrossLinkMessage(Descriptor *message, const DescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5357
google::protobuf::FieldDescriptor::TYPE_FIXED32
@ TYPE_FIXED32
Definition: src/google/protobuf/descriptor.h:532
google::protobuf::kint32min
static const int32 kint32min
Definition: protobuf/src/google/protobuf/stubs/port.h:160
FieldDescriptorProto::set_oneof_index
void set_oneof_index(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: descriptor.pb.h:8158
google::protobuf::strings::SubstituteAndAppend
void SubstituteAndAppend(string *output, const char *format, const SubstituteArg &arg0, const SubstituteArg &arg1, const SubstituteArg &arg2, const SubstituteArg &arg3, const SubstituteArg &arg4, const SubstituteArg &arg5, const SubstituteArg &arg6, const SubstituteArg &arg7, const SubstituteArg &arg8, const SubstituteArg &arg9)
Definition: substitute.cc:68
prefix_
std::string prefix_
Definition: src/google/protobuf/descriptor.cc:378
google::protobuf::MethodDescriptor::input_type_
internal::LazyDescriptor input_type_
Definition: src/google/protobuf/descriptor.h:1300
MessageOptions::message_set_wire_format
bool message_set_wire_format() const
Definition: descriptor.pb.h:10460
google::protobuf::DescriptorBuilder::CrossLinkEnum
void CrossLinkEnum(EnumDescriptor *enum_type, const EnumDescriptorProto &proto)
Definition: src/google/protobuf/descriptor.cc:5704
google::protobuf::Descriptor::FindFieldByLowercaseName
const FieldDescriptor * FindFieldByLowercaseName(const std::string &lowercase_name) const
Definition: src/google/protobuf/descriptor.cc:1593
FieldDescriptorProto::set_type
void set_type(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value)
Definition: descriptor.pb.h:7899
google::protobuf::io::Tokenizer::IsIdentifier
static bool IsIdentifier(const std::string &text)
Definition: tokenizer.cc:1121
google::protobuf::FileDescriptorTables::unknown_enum_values_mu_
internal::WrappedMutex unknown_enum_values_mu_
Definition: src/google/protobuf/descriptor.cc:796
google::protobuf::DescriptorPool::FindMessageTypeByName
const Descriptor * FindMessageTypeByName(const std::string &name) const
Definition: src/google/protobuf/descriptor.cc:1430


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:49