protobuf/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 <google/protobuf/descriptor.h>
36 
37 #include <algorithm>
38 #include <array>
39 #include <functional>
40 #include <limits>
41 #include <map>
42 #include <memory>
43 #include <set>
44 #include <string>
45 #include <unordered_map>
46 #include <unordered_set>
47 #include <vector>
48 
49 #include <google/protobuf/stubs/common.h>
50 #include <google/protobuf/stubs/logging.h>
51 #include <google/protobuf/stubs/stringprintf.h>
52 #include <google/protobuf/stubs/strutil.h>
53 #include <google/protobuf/any.h>
54 #include <google/protobuf/descriptor.pb.h>
55 #include <google/protobuf/stubs/once.h>
56 #include <google/protobuf/io/coded_stream.h>
57 #include <google/protobuf/io/tokenizer.h>
58 #include <google/protobuf/io/zero_copy_stream_impl.h>
59 #include <google/protobuf/descriptor_database.h>
60 #include <google/protobuf/dynamic_message.h>
61 #include <google/protobuf/generated_message_util.h>
62 #include <google/protobuf/text_format.h>
63 #include <google/protobuf/unknown_field_set.h>
64 #include <google/protobuf/wire_format.h>
65 #include <google/protobuf/stubs/casts.h>
66 #include <google/protobuf/stubs/substitute.h>
67 #include <google/protobuf/io/strtod.h>
68 #include <google/protobuf/stubs/map_util.h>
69 #include <google/protobuf/stubs/stl_util.h>
70 #include <google/protobuf/stubs/hash.h>
71 
72 #undef PACKAGE // autoheader #defines this. :(
73 
74 
75 #include <google/protobuf/port_def.inc>
76 
77 namespace google {
78 namespace protobuf {
79 
80 class Symbol {
81  public:
82  enum Type {
84  MESSAGE,
85  FIELD,
86  ONEOF,
87  ENUM,
88  ENUM_VALUE,
90  SERVICE,
91  METHOD,
92  PACKAGE,
94  };
95 
96  Symbol() : ptr_(nullptr) {}
97 
98  // Every object we store derives from internal::SymbolBase, where we store the
99  // symbol type enum.
100  // Storing in the object can be done without using more space in most cases,
101  // while storing it in the Symbol type would require 8 bytes.
102 #define DEFINE_MEMBERS(TYPE, TYPE_CONSTANT, FIELD) \
103  explicit Symbol(TYPE* value) : ptr_(value) { \
104  value->symbol_type_ = TYPE_CONSTANT; \
105  } \
106  const TYPE* FIELD() const { \
107  return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
108  }
109 
116 
117  // We use a special node for FileDescriptor.
118  // It is potentially added to the table with multiple different names, so we
119  // need a separate place to put the name.
120  struct Package : internal::SymbolBase {
123  };
125 
126  // Enum values have two different parents.
127  // We use two different identitied for the same object to determine the two
128  // different insertions in the map.
130  Symbol s;
132  if (n == 0) {
133  ptr = static_cast<internal::SymbolBaseN<0>*>(value);
134  ptr->symbol_type_ = ENUM_VALUE;
135  } else {
136  ptr = static_cast<internal::SymbolBaseN<1>*>(value);
137  ptr->symbol_type_ = ENUM_VALUE_OTHER_PARENT;
138  }
139  s.ptr_ = ptr;
140  return s;
141  }
142 
144  return type() == ENUM_VALUE
145  ? static_cast<const EnumValueDescriptor*>(
146  static_cast<const internal::SymbolBaseN<0>*>(ptr_))
148  ? static_cast<const EnumValueDescriptor*>(
149  static_cast<const internal::SymbolBaseN<1>*>(ptr_))
150  : nullptr;
151  }
152 
153  // Not a real symbol.
154  // Only used for heterogeneous lookups and never actually inserted in the
155  // tables.
158  const void* parent;
160  };
161  DEFINE_MEMBERS(QueryKey, QUERY_KEY, query_key);
162 #undef DEFINE_MEMBERS
163 
164  Type type() const {
165  return ptr_ == nullptr ? NULL_SYMBOL
166  : static_cast<Type>(ptr_->symbol_type_);
167  }
168  bool IsNull() const { return type() == NULL_SYMBOL; }
169  bool IsType() const { return type() == MESSAGE || type() == ENUM; }
170  bool IsAggregate() const {
171  return type() == MESSAGE || type() == PACKAGE || type() == ENUM ||
172  type() == SERVICE;
173  }
174 
175  const FileDescriptor* GetFile() const {
176  switch (type()) {
177  case MESSAGE:
178  return descriptor()->file();
179  case FIELD:
180  return field_descriptor()->file();
181  case ONEOF:
182  return oneof_descriptor()->containing_type()->file();
183  case ENUM:
184  return enum_descriptor()->file();
185  case ENUM_VALUE:
186  return enum_value_descriptor()->type()->file();
187  case SERVICE:
188  return service_descriptor()->file();
189  case METHOD:
190  return method_descriptor()->service()->file();
191  case PACKAGE:
192  return package_file_descriptor()->file;
193  default:
194  return nullptr;
195  }
196  }
197 
199  switch (type()) {
200  case MESSAGE:
201  return descriptor()->full_name();
202  case FIELD:
203  return field_descriptor()->full_name();
204  case ONEOF:
205  return oneof_descriptor()->full_name();
206  case ENUM:
207  return enum_descriptor()->full_name();
208  case ENUM_VALUE:
209  return enum_value_descriptor()->full_name();
210  case SERVICE:
211  return service_descriptor()->full_name();
212  case METHOD:
213  return method_descriptor()->full_name();
214  case PACKAGE:
215  return *package_file_descriptor()->name;
216  case QUERY_KEY:
217  return query_key()->name;
218  default:
219  GOOGLE_CHECK(false);
220  }
221  return "";
222  }
223 
224  std::pair<const void*, StringPiece> parent_name_key() const {
225  const auto or_file = [&](const void* p) { return p ? p : GetFile(); };
226  switch (type()) {
227  case MESSAGE:
228  return {or_file(descriptor()->containing_type()), descriptor()->name()};
229  case FIELD: {
230  auto* field = field_descriptor();
231  return {or_file(field->is_extension() ? field->extension_scope()
232  : field->containing_type()),
233  field->name()};
234  }
235  case ONEOF:
236  return {oneof_descriptor()->containing_type(),
237  oneof_descriptor()->name()};
238  case ENUM:
239  return {or_file(enum_descriptor()->containing_type()),
240  enum_descriptor()->name()};
241  case ENUM_VALUE:
242  return {or_file(enum_value_descriptor()->type()->containing_type()),
245  return {enum_value_descriptor()->type(),
247  case SERVICE:
248  return {GetFile(), service_descriptor()->name()};
249  case METHOD:
250  return {method_descriptor()->service(), method_descriptor()->name()};
251  case QUERY_KEY:
252  return {query_key()->parent, query_key()->name};
253  default:
254  GOOGLE_CHECK(false);
255  }
256  return {};
257  }
258 
259  std::pair<const void*, int> parent_number_key() const {
260  switch (type()) {
261  case FIELD:
262  return {field_descriptor()->containing_type(),
263  field_descriptor()->number()};
264  case ENUM_VALUE:
265  return {enum_value_descriptor()->type(),
267  case QUERY_KEY:
268  return {query_key()->parent, query_key()->field_number};
269  default:
270  GOOGLE_CHECK(false);
271  }
272  return {};
273  }
274 
275  private:
277 };
278 
280  FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
281  static_cast<CppType>(0), // 0 is reserved for errors
282 
283  CPPTYPE_DOUBLE, // TYPE_DOUBLE
284  CPPTYPE_FLOAT, // TYPE_FLOAT
285  CPPTYPE_INT64, // TYPE_INT64
286  CPPTYPE_UINT64, // TYPE_UINT64
287  CPPTYPE_INT32, // TYPE_INT32
288  CPPTYPE_UINT64, // TYPE_FIXED64
289  CPPTYPE_UINT32, // TYPE_FIXED32
290  CPPTYPE_BOOL, // TYPE_BOOL
291  CPPTYPE_STRING, // TYPE_STRING
292  CPPTYPE_MESSAGE, // TYPE_GROUP
293  CPPTYPE_MESSAGE, // TYPE_MESSAGE
294  CPPTYPE_STRING, // TYPE_BYTES
295  CPPTYPE_UINT32, // TYPE_UINT32
296  CPPTYPE_ENUM, // TYPE_ENUM
297  CPPTYPE_INT32, // TYPE_SFIXED32
298  CPPTYPE_INT64, // TYPE_SFIXED64
299  CPPTYPE_INT32, // TYPE_SINT32
300  CPPTYPE_INT64, // TYPE_SINT64
301 };
302 
303 const char* const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
304  "ERROR", // 0 is reserved for errors
305 
306  "double", // TYPE_DOUBLE
307  "float", // TYPE_FLOAT
308  "int64", // TYPE_INT64
309  "uint64", // TYPE_UINT64
310  "int32", // TYPE_INT32
311  "fixed64", // TYPE_FIXED64
312  "fixed32", // TYPE_FIXED32
313  "bool", // TYPE_BOOL
314  "string", // TYPE_STRING
315  "group", // TYPE_GROUP
316  "message", // TYPE_MESSAGE
317  "bytes", // TYPE_BYTES
318  "uint32", // TYPE_UINT32
319  "enum", // TYPE_ENUM
320  "sfixed32", // TYPE_SFIXED32
321  "sfixed64", // TYPE_SFIXED64
322  "sint32", // TYPE_SINT32
323  "sint64", // TYPE_SINT64
324 };
325 
326 const char* const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = {
327  "ERROR", // 0 is reserved for errors
328 
329  "int32", // CPPTYPE_INT32
330  "int64", // CPPTYPE_INT64
331  "uint32", // CPPTYPE_UINT32
332  "uint64", // CPPTYPE_UINT64
333  "double", // CPPTYPE_DOUBLE
334  "float", // CPPTYPE_FLOAT
335  "bool", // CPPTYPE_BOOL
336  "enum", // CPPTYPE_ENUM
337  "string", // CPPTYPE_STRING
338  "message", // CPPTYPE_MESSAGE
339 };
340 
341 const char* const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
342  "ERROR", // 0 is reserved for errors
343 
344  "optional", // LABEL_OPTIONAL
345  "required", // LABEL_REQUIRED
346  "repeated", // LABEL_REPEATED
347 };
348 
350  switch (syntax) {
351  case SYNTAX_PROTO2:
352  return "proto2";
353  case SYNTAX_PROTO3:
354  return "proto3";
355  case SYNTAX_UNKNOWN:
356  return "unknown";
357  }
358  GOOGLE_LOG(FATAL) << "can't reach here.";
359  return nullptr;
360 }
361 
362 static const char* const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
363 
364 #if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)
368 #endif
369 
370 namespace {
371 
372 // Note: I distrust ctype.h due to locales.
373 char ToUpper(char ch) {
374  return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch;
375 }
376 
377 char ToLower(char ch) {
378  return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
379 }
380 
381 std::string ToCamelCase(const std::string& input, bool lower_first) {
382  bool capitalize_next = !lower_first;
384  result.reserve(input.size());
385 
386  for (char character : input) {
387  if (character == '_') {
388  capitalize_next = true;
389  } else if (capitalize_next) {
390  result.push_back(ToUpper(character));
391  capitalize_next = false;
392  } else {
393  result.push_back(character);
394  }
395  }
396 
397  // Lower-case the first letter.
398  if (lower_first && !result.empty()) {
399  result[0] = ToLower(result[0]);
400  }
401 
402  return result;
403 }
404 
405 std::string ToJsonName(const std::string& input) {
406  bool capitalize_next = false;
408  result.reserve(input.size());
409 
410  for (char character : input) {
411  if (character == '_') {
412  capitalize_next = true;
413  } else if (capitalize_next) {
414  result.push_back(ToUpper(character));
415  capitalize_next = false;
416  } else {
417  result.push_back(character);
418  }
419  }
420 
421  return result;
422 }
423 
424 std::string EnumValueToPascalCase(const std::string& input) {
425  bool next_upper = true;
427  result.reserve(input.size());
428 
429  for (char character : input) {
430  if (character == '_') {
431  next_upper = true;
432  } else {
433  if (next_upper) {
434  result.push_back(ToUpper(character));
435  } else {
436  result.push_back(ToLower(character));
437  }
438  next_upper = false;
439  }
440  }
441 
442  return result;
443 }
444 
445 // Class to remove an enum prefix from enum values.
446 class PrefixRemover {
447  public:
448  PrefixRemover(StringPiece prefix) {
449  // Strip underscores and lower-case the prefix.
450  for (char character : prefix) {
451  if (character != '_') {
452  prefix_ += ascii_tolower(character);
453  }
454  }
455  }
456 
457  // Tries to remove the enum prefix from this enum value.
458  // If this is not possible, returns the input verbatim.
459  std::string MaybeRemove(StringPiece str) {
460  // We can't just lowercase and strip str and look for a prefix.
461  // We need to properly recognize the difference between:
462  //
463  // enum Foo {
464  // FOO_BAR_BAZ = 0;
465  // FOO_BARBAZ = 1;
466  // }
467  //
468  // This is acceptable (though perhaps not advisable) because even when
469  // we PascalCase, these two will still be distinct (BarBaz vs. Barbaz).
470  size_t i, j;
471 
472  // Skip past prefix_ in str if we can.
473  for (i = 0, j = 0; i < str.size() && j < prefix_.size(); i++) {
474  if (str[i] == '_') {
475  continue;
476  }
477 
478  if (ascii_tolower(str[i]) != prefix_[j++]) {
479  return std::string(str);
480  }
481  }
482 
483  // If we didn't make it through the prefix, we've failed to strip the
484  // prefix.
485  if (j < prefix_.size()) {
486  return std::string(str);
487  }
488 
489  // Skip underscores between prefix and further characters.
490  while (i < str.size() && str[i] == '_') {
491  i++;
492  }
493 
494  // Enum label can't be the empty string.
495  if (i == str.size()) {
496  return std::string(str);
497  }
498 
499  // We successfully stripped the prefix.
500  str.remove_prefix(i);
501  return std::string(str);
502  }
503 
504  private:
506 };
507 
508 // A DescriptorPool contains a bunch of hash-maps to implement the
509 // various Find*By*() methods. Since hashtable lookups are O(1), it's
510 // most efficient to construct a fixed set of large hash-maps used by
511 // all objects in the pool rather than construct one or more small
512 // hash-maps for each object.
513 //
514 // The keys to these hash-maps are (parent, name) or (parent, number) pairs.
515 
516 typedef std::pair<const void*, StringPiece> PointerStringPair;
517 
518 typedef std::pair<const Descriptor*, int> DescriptorIntPair;
519 
520 #define HASH_MAP std::unordered_map
521 #define HASH_SET std::unordered_set
522 #define HASH_FXN hash
523 
524 template <typename PairType>
525 struct PointerIntegerPairHash {
526  size_t operator()(const PairType& p) const {
527  static const size_t prime1 = 16777499;
528  static const size_t prime2 = 16777619;
529  return reinterpret_cast<size_t>(p.first) * prime1 ^
530  static_cast<size_t>(p.second) * prime2;
531  }
532 
533 #ifdef _MSC_VER
534  // Used only by MSVC and platforms where hash_map is not available.
535  static const size_t bucket_size = 4;
536  static const size_t min_buckets = 8;
537 #endif
538  inline bool operator()(const PairType& a, const PairType& b) const {
539  return a < b;
540  }
541 };
542 
543 struct PointerStringPairHash {
544  size_t operator()(const PointerStringPair& p) const {
545  static const size_t prime = 16777619;
546  hash<StringPiece> string_hash;
547  return reinterpret_cast<size_t>(p.first) * prime ^
548  static_cast<size_t>(string_hash(p.second));
549  }
550 
551 #ifdef _MSC_VER
552  // Used only by MSVC and platforms where hash_map is not available.
553  static const size_t bucket_size = 4;
554  static const size_t min_buckets = 8;
555 #endif
556  inline bool operator()(const PointerStringPair& a,
557  const PointerStringPair& b) const {
558  return a < b;
559  }
560 };
561 
562 
563 const Symbol kNullSymbol;
564 
565 struct SymbolByFullNameHash {
566  size_t operator()(Symbol s) const {
567  return HASH_FXN<StringPiece>{}(s.full_name());
568  }
569 };
570 struct SymbolByFullNameEq {
571  bool operator()(Symbol a, Symbol b) const {
572  return a.full_name() == b.full_name();
573  }
574 };
575 using SymbolsByNameSet =
576  HASH_SET<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>;
577 
578 struct SymbolByParentHash {
579  size_t operator()(Symbol s) const {
580  return PointerStringPairHash{}(s.parent_name_key());
581  }
582 };
583 struct SymbolByParentEq {
584  bool operator()(Symbol a, Symbol b) const {
585  return a.parent_name_key() == b.parent_name_key();
586  }
587 };
588 using SymbolsByParentSet =
589  HASH_SET<Symbol, SymbolByParentHash, SymbolByParentEq>;
590 
591 typedef HASH_MAP<StringPiece, const FileDescriptor*,
592  HASH_FXN<StringPiece>>
593  FilesByNameMap;
594 
595 typedef HASH_MAP<PointerStringPair, const FieldDescriptor*,
596  PointerStringPairHash>
597  FieldsByNameMap;
598 
599 struct FieldsByNumberHash {
600  size_t operator()(Symbol s) const {
601  return PointerIntegerPairHash<std::pair<const void*, int>>{}(
602  s.parent_number_key());
603  }
604 };
605 struct FieldsByNumberEq {
606  bool operator()(Symbol a, Symbol b) const {
607  return a.parent_number_key() == b.parent_number_key();
608  }
609 };
610 using FieldsByNumberSet =
611  HASH_SET<Symbol, FieldsByNumberHash, FieldsByNumberEq>;
612 using EnumValuesByNumberSet = FieldsByNumberSet;
613 
614 // This is a map rather than a hash-map, since we use it to iterate
615 // through all the extensions that extend a given Descriptor, and an
616 // ordered data structure that implements lower_bound is convenient
617 // for that.
618 typedef std::map<DescriptorIntPair, const FieldDescriptor*>
619  ExtensionsGroupedByDescriptorMap;
620 typedef HASH_MAP<std::string, const SourceCodeInfo_Location*>
621  LocationsByPathMap;
622 
623 std::set<std::string>* NewAllowedProto3Extendee() {
624  auto allowed_proto3_extendees = new std::set<std::string>;
625  const char* kOptionNames[] = {
626  "FileOptions", "MessageOptions", "FieldOptions", "EnumOptions",
627  "EnumValueOptions", "ServiceOptions", "MethodOptions", "OneofOptions"};
628  for (const char* option_name : kOptionNames) {
629  // descriptor.proto has a different package name in opensource. We allow
630  // both so the opensource protocol compiler can also compile internal
631  // proto3 files with custom options. See: b/27567912
632  allowed_proto3_extendees->insert(std::string("google.protobuf.") +
633  option_name);
634  // Split the word to trick the opensource processing scripts so they
635  // will keep the original package name.
636  allowed_proto3_extendees->insert(std::string("proto") + "2." + option_name);
637  }
638  return allowed_proto3_extendees;
639 }
640 
641 // Checks whether the extendee type is allowed in proto3.
642 // Only extensions to descriptor options are allowed. We use name comparison
643 // instead of comparing the descriptor directly because the extensions may be
644 // defined in a different pool.
645 bool AllowedExtendeeInProto3(const std::string& name) {
646  static auto allowed_proto3_extendees =
647  internal::OnShutdownDelete(NewAllowedProto3Extendee());
648  return allowed_proto3_extendees->find(name) !=
649  allowed_proto3_extendees->end();
650 }
651 
652 // This bump allocator arena is optimized for the use case of this file. It is
653 // mostly optimized for memory usage, since these objects are expected to live
654 // for the entirety of the program.
655 //
656 // Some differences from other arenas:
657 // - It has a fixed number of non-trivial types it can hold. This allows
658 // tracking the allocations with a single byte. In contrast, google::protobuf::Arena
659 // uses 16 bytes per non-trivial object created.
660 // - It has some extra metadata for rollbacks. This is necessary for
661 // implementing the API below. This metadata is flushed at the end and would
662 // not cause persistent memory usage.
663 // - It tries to squeeze every byte of out the blocks. If an allocation is too
664 // large for the current block we move the block to a secondary area where we
665 // can still use it for smaller objects. This complicates rollback logic but
666 // makes it much more memory efficient.
667 //
668 // The allocation strategy is as follows:
669 // - Memory is allocated from the front, with a forced 8 byte alignment.
670 // - Metadata is allocated from the back, one byte per element.
671 // - The metadata encodes one of two things:
672 // * For types we want to track, the index into KnownTypes.
673 // * For raw memory blocks, the size of the block (in 8 byte increments
674 // to allow for a larger limit).
675 // - When the raw data is too large to represent in the metadata byte, we
676 // allocate this memory separately in the heap and store an OutOfLineAlloc
677 // object instead. These come from large array allocations and alike.
678 //
679 // Blocks are kept in 3 areas:
680 // - `current_` is the one we are currently allocating from. When we need to
681 // allocate a block that doesn't fit there, we make a new block and move the
682 // old `current_` to one of the areas below.
683 // - Blocks that have no more usable space left (ie less than 9 bytes) are
684 // stored in `full_blocks_`.
685 // - Blocks that have some usable space are categorized in
686 // `small_size_blocks_` depending on how much space they have left.
687 // See `kSmallSizes` to see which sizes we track.
688 //
689 class TableArena {
690  public:
691  // Allocate a block on `n` bytes, with no destructor information saved.
692  void* AllocateMemory(uint32_t n) {
693  uint32_t tag = SizeToRawTag(n) + kFirstRawTag;
694  if (tag > 255) {
695  // We can't fit the size, use an OutOfLineAlloc.
696  return Create<OutOfLineAlloc>(OutOfLineAlloc{::operator new(n), n})->ptr;
697  }
698 
699  return AllocRawInternal(n, static_cast<Tag>(tag));
700  }
701 
702  // Allocate and construct an element of type `T` as if by
703  // `T(std::forward<Args>(args...))`.
704  // The object is registered for destruction, if its destructor is not trivial.
705  template <typename T, typename... Args>
706  T* Create(Args&&... args) {
707  static_assert(alignof(T) <= 8, "");
708  return ::new (AllocRawInternal(sizeof(T), TypeTag<T>(KnownTypes{})))
709  T(std::forward<Args>(args)...);
710  }
711 
712  TableArena() {}
713 
714  TableArena(const TableArena&) = delete;
715  TableArena& operator=(const TableArena&) = delete;
716 
717  ~TableArena() {
718  // Uncomment this to debug usage statistics of the arena blocks.
719  // PrintUsageInfo();
720 
721  for (Block* list : GetLists()) {
722  while (list != nullptr) {
723  Block* b = list;
724  list = list->next;
725  b->VisitBlock(DestroyVisitor{});
726  b->Destroy();
727  }
728  }
729  }
730 
731 
732  // This function exists for debugging only.
733  // It can be called from the destructor to dump some info in the tests to
734  // inspect the usage of the arena.
735  void PrintUsageInfo() const {
736  const auto print_histogram = [](Block* b, int size) {
737  std::map<uint32_t, uint32_t> unused_space_count;
738  int count = 0;
739  for (; b != nullptr; b = b->next) {
740  ++unused_space_count[b->space_left()];
741  ++count;
742  }
743  if (size > 0) {
744  fprintf(stderr, " Blocks `At least %d`", size);
745  } else {
746  fprintf(stderr, " Blocks `full`");
747  }
748  fprintf(stderr, ": %d blocks.\n", count);
749  for (auto p : unused_space_count) {
750  fprintf(stderr, " space=%4u, count=%3u\n", p.first, p.second);
751  }
752  };
753 
754  fprintf(stderr, "TableArena unused space histogram:\n");
755  fprintf(stderr, " Current: %u\n",
756  current_ != nullptr ? current_->space_left() : 0);
758  for (size_t i = 0; i < kSmallSizes.size(); ++i) {
760  }
761  }
762 
763  // Current allocation count.
764  // This can be used for checkpointing.
765  size_t num_allocations() const { return num_allocations_; }
766 
767  // Rollback the latest allocations until we reach back to `checkpoint`
768  // num_allocations.
769  void RollbackTo(size_t checkpoint) {
770  while (num_allocations_ > checkpoint) {
771  GOOGLE_DCHECK(!rollback_info_.empty());
772  auto& info = rollback_info_.back();
773  Block* b = info.block;
774 
775  VisitAlloc(b->data(), &b->start_offset, &b->end_offset, DestroyVisitor{},
776  KnownTypes{});
777  if (--info.count == 0) {
778  rollback_info_.pop_back();
779  }
781  }
782 
783  // Reconstruct the lists and destroy empty blocks.
784  auto lists = GetLists();
785  current_ = full_blocks_ = nullptr;
786  small_size_blocks_.fill(nullptr);
787 
788  for (Block* list : lists) {
789  while (list != nullptr) {
790  Block* b = list;
791  list = list->next;
792 
793  if (b->start_offset == 0) {
794  // This is empty, free it.
795  b->Destroy();
796  } else {
797  RelocateToUsedList(b);
798  }
799  }
800  }
801  }
802 
803  // Clear all rollback information. Reduces memory usage.
804  // Trying to rollback past num_allocations() is now impossible.
805  void ClearRollbackData() {
806  rollback_info_.clear();
807  rollback_info_.shrink_to_fit();
808  }
809 
810  private:
811  static constexpr size_t RoundUp(size_t n) { return (n + 7) & ~7; }
812 
813  using Tag = unsigned char;
814 
815  void* AllocRawInternal(uint32_t size, Tag tag) {
817  size = RoundUp(size);
818 
819  Block* to_relocate = nullptr;
820  Block* to_use = nullptr;
821 
822  for (size_t i = 0; i < kSmallSizes.size(); ++i) {
823  if (small_size_blocks_[i] != nullptr && size <= kSmallSizes[i]) {
824  to_use = to_relocate = PopBlock(small_size_blocks_[i]);
825  break;
826  }
827  }
828 
829  if (to_relocate != nullptr) {
830  // We found one in the loop.
831  } else if (current_ != nullptr && size + 1 <= current_->space_left()) {
832  to_use = current_;
833  } else {
834  // No space left anywhere, make a new block.
835  to_relocate = current_;
836  // For now we hardcode the size to one page. Note that the maximum we can
837  // allocate in the block according to the limits of Tag is less than 2k,
838  // so this can fit anything that Tag can represent.
839  constexpr size_t kBlockSize = 4096;
840  to_use = current_ = ::new (::operator new(kBlockSize)) Block(kBlockSize);
841  GOOGLE_DCHECK_GE(current_->space_left(), size + 1);
842  }
843 
845  if (!rollback_info_.empty() && rollback_info_.back().block == to_use) {
846  ++rollback_info_.back().count;
847  } else {
848  rollback_info_.push_back({to_use, 1});
849  }
850 
851  void* p = to_use->Allocate(size, tag);
852  if (to_relocate != nullptr) {
853  RelocateToUsedList(to_relocate);
854  }
855  return p;
856  }
857 
858  static void OperatorDelete(void* p, size_t s) {
859 #if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation)
860  ::operator delete(p, s);
861 #else
862  ::operator delete(p);
863 #endif
864  }
865 
866  struct OutOfLineAlloc {
867  void* ptr;
869  };
870 
871  template <typename... T>
872  struct TypeList {
873  static constexpr Tag kSize = static_cast<Tag>(sizeof...(T));
874  };
875 
876  template <typename T, typename Visitor>
877  static void RunVisitor(char* p, uint16_t* start, Visitor visit) {
878  *start -= RoundUp(sizeof(T));
879  visit(reinterpret_cast<T*>(p + *start));
880  }
881 
882  // Visit the allocation at the passed location.
883  // It updates start/end to be after the visited object.
884  // This allows visiting a whole block by calling the function in a loop.
885  template <typename Visitor, typename... T>
886  static void VisitAlloc(char* p, uint16_t* start, uint16_t* end, Visitor visit,
887  TypeList<T...>) {
888  const Tag tag = static_cast<Tag>(p[*end]);
889  if (tag >= kFirstRawTag) {
890  // Raw memory. Skip it.
891  *start -= TagToSize(tag);
892  } else {
893  using F = void (*)(char*, uint16_t*, Visitor);
894  static constexpr F kFuncs[] = {&RunVisitor<T, Visitor>...};
895  kFuncs[tag](p, start, visit);
896  }
897  ++*end;
898  }
899 
900  template <typename U, typename... Ts>
901  static constexpr Tag TypeTag(TypeList<U, Ts...>) {
902  return 0;
903  }
904 
905  template <
906  typename U, typename T, typename... Ts,
908  static constexpr Tag TypeTag(TypeList<T, Ts...>) {
909  return 1 + TypeTag<U>(TypeList<Ts...>{});
910  }
911 
912  template <typename U>
913  static constexpr Tag TypeTag(TypeList<>) {
914  static_assert(std::is_trivially_destructible<U>::value, "");
915  return SizeToRawTag(sizeof(U));
916  }
917 
918  using KnownTypes =
919  TypeList<OutOfLineAlloc, std::string,
920  // For name arrays
921  std::array<std::string, 2>, std::array<std::string, 3>,
922  std::array<std::string, 4>, std::array<std::string, 5>,
923  FileDescriptorTables, SourceCodeInfo, FileOptions,
926  MethodOptions>;
927  static constexpr Tag kFirstRawTag = KnownTypes::kSize;
928 
929 
930  struct DestroyVisitor {
931  template <typename T>
932  void operator()(T* p) {
933  p->~T();
934  }
935  void operator()(OutOfLineAlloc* p) { OperatorDelete(p->ptr, p->size); }
936  };
937 
938  static uint32_t SizeToRawTag(size_t n) { return (RoundUp(n) / 8) - 1; }
939 
940  static uint32_t TagToSize(Tag tag) {
942  return static_cast<uint32_t>(tag - kFirstRawTag + 1) * 8;
943  }
944 
945  struct Block {
949  Block* next;
950 
951  // `allocated_size` is the total size of the memory block allocated.
952  // The `Block` structure is constructed at the start and the rest of the
953  // memory is used as the payload of the `Block`.
954  explicit Block(uint32_t allocated_size) {
955  start_offset = 0;
956  end_offset = capacity =
957  reinterpret_cast<char*>(this) + allocated_size - data();
958  next = nullptr;
959  }
960 
961  char* data() {
962  return reinterpret_cast<char*>(this) + RoundUp(sizeof(Block));
963  }
964 
965  uint32_t memory_used() {
966  return data() + capacity - reinterpret_cast<char*>(this);
967  }
968  uint32_t space_left() const { return end_offset - start_offset; }
969 
970  void* Allocate(uint32_t n, Tag tag) {
971  GOOGLE_DCHECK_LE(n + 1, space_left());
972  void* p = data() + start_offset;
973  start_offset += n;
974  data()[--end_offset] = tag;
975  return p;
976  }
977 
978  void Destroy() { OperatorDelete(this, memory_used()); }
979 
980  void PrependTo(Block*& list) {
981  next = list;
982  list = this;
983  }
984 
985  template <typename Visitor>
986  void VisitBlock(Visitor visit) {
987  for (uint16_t s = start_offset, e = end_offset; s != 0;) {
988  VisitAlloc(data(), &s, &e, visit, KnownTypes{});
989  }
990  }
991  };
992 
993  Block* PopBlock(Block*& list) {
994  Block* res = list;
995  list = list->next;
996  return res;
997  }
998 
999  void RelocateToUsedList(Block* to_relocate) {
1000  if (current_ == nullptr) {
1001  current_ = to_relocate;
1002  current_->next = nullptr;
1003  return;
1004  } else if (current_->space_left() < to_relocate->space_left()) {
1005  std::swap(current_, to_relocate);
1006  current_->next = nullptr;
1007  }
1008 
1009  for (int i = kSmallSizes.size(); --i >= 0;) {
1010  if (to_relocate->space_left() >= 1 + kSmallSizes[i]) {
1011  to_relocate->PrependTo(small_size_blocks_[i]);
1012  return;
1013  }
1014  }
1015 
1016  to_relocate->PrependTo(full_blocks_);
1017  }
1018 
1019  static constexpr std::array<uint8_t, 6> kSmallSizes = {
1020  {// Sizes for pointer arrays.
1021  8, 16, 24, 32,
1022  // Sizes for string arrays (for descriptor names).
1023  // The most common array sizes are 2 and 3.
1024  2 * sizeof(std::string), 3 * sizeof(std::string)}};
1025 
1026  // Helper function to iterate all lists.
1027  std::array<Block*, 2 + kSmallSizes.size()> GetLists() const {
1028  std::array<Block*, 2 + kSmallSizes.size()> res;
1029  res[0] = current_;
1030  res[1] = full_blocks_;
1031  std::copy(small_size_blocks_.begin(), small_size_blocks_.end(), &res[2]);
1032  return res;
1033  }
1034 
1035  Block* current_ = nullptr;
1037  Block* full_blocks_ = nullptr;
1038 
1039  size_t num_allocations_ = 0;
1040  struct RollbackInfo {
1041  Block* block;
1042  size_t count;
1043  };
1044  std::vector<RollbackInfo> rollback_info_;
1045 };
1046 
1047 constexpr std::array<uint8_t, 6> TableArena::kSmallSizes;
1048 
1049 } // anonymous namespace
1050 
1051 // ===================================================================
1052 // DescriptorPool::Tables
1053 
1054 class DescriptorPool::Tables {
1055  public:
1056  Tables();
1057  ~Tables();
1058 
1059  // Record the current state of the tables to the stack of checkpoints.
1060  // Each call to AddCheckpoint() must be paired with exactly one call to either
1061  // ClearLastCheckpoint() or RollbackToLastCheckpoint().
1062  //
1063  // This is used when building files, since some kinds of validation errors
1064  // cannot be detected until the file's descriptors have already been added to
1065  // the tables.
1066  //
1067  // This supports recursive checkpoints, since building a file may trigger
1068  // recursive building of other files. Note that recursive checkpoints are not
1069  // normally necessary; explicit dependencies are built prior to checkpointing.
1070  // So although we recursively build transitive imports, there is at most one
1071  // checkpoint in the stack during dependency building.
1072  //
1073  // Recursive checkpoints only arise during cross-linking of the descriptors.
1074  // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
1075  // friends. If the pending file references an unknown symbol
1076  // (e.g., it is not defined in the pending file's explicit dependencies), and
1077  // the pool is using a fallback database, and that database contains a file
1078  // defining that symbol, and that file has not yet been built by the pool,
1079  // the pool builds the file during cross-linking, leading to another
1080  // checkpoint.
1081  void AddCheckpoint();
1082 
1083  // Mark the last checkpoint as having cleared successfully, removing it from
1084  // the stack. If the stack is empty, all pending symbols will be committed.
1085  //
1086  // Note that this does not guarantee that the symbols added since the last
1087  // checkpoint won't be rolled back: if a checkpoint gets rolled back,
1088  // everything past that point gets rolled back, including symbols added after
1089  // checkpoints that were pushed onto the stack after it and marked as cleared.
1090  void ClearLastCheckpoint();
1091 
1092  // Roll back the Tables to the state of the checkpoint at the top of the
1093  // stack, removing everything that was added after that point.
1094  void RollbackToLastCheckpoint();
1095 
1096  // The stack of files which are currently being built. Used to detect
1097  // cyclic dependencies when loading files from a DescriptorDatabase. Not
1098  // used when fallback_database_ == nullptr.
1099  std::vector<std::string> pending_files_;
1100 
1101  // A set of files which we have tried to load from the fallback database
1102  // and encountered errors. We will not attempt to load them again during
1103  // execution of the current public API call, but for compatibility with
1104  // legacy clients, this is cleared at the beginning of each public API call.
1105  // Not used when fallback_database_ == nullptr.
1106  HASH_SET<std::string> known_bad_files_;
1107 
1108  // A set of symbols which we have tried to load from the fallback database
1109  // and encountered errors. We will not attempt to load them again during
1110  // execution of the current public API call, but for compatibility with
1111  // legacy clients, this is cleared at the beginning of each public API call.
1112  HASH_SET<std::string> known_bad_symbols_;
1113 
1114  // The set of descriptors for which we've already loaded the full
1115  // set of extensions numbers from fallback_database_.
1116  HASH_SET<const Descriptor*> extensions_loaded_from_db_;
1117 
1118  // Maps type name to Descriptor::WellKnownType. This is logically global
1119  // and const, but we make it a member here to simplify its construction and
1120  // destruction. This only has 20-ish entries and is one per DescriptorPool,
1121  // so the overhead is small.
1122  HASH_MAP<std::string, Descriptor::WellKnownType> well_known_types_;
1123 
1124  // -----------------------------------------------------------------
1125  // Finding items.
1126 
1127  // Find symbols. This returns a null Symbol (symbol.IsNull() is true)
1128  // if not found.
1129  inline Symbol FindSymbol(StringPiece key) const;
1130 
1131  // This implements the body of DescriptorPool::Find*ByName(). It should
1132  // really be a private method of DescriptorPool, but that would require
1133  // declaring Symbol in descriptor.h, which would drag all kinds of other
1134  // stuff into the header. Yay C++.
1136 
1137  // These return nullptr if not found.
1138  inline const FileDescriptor* FindFile(StringPiece key) const;
1139  inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
1140  int number) const;
1141  inline void FindAllExtensions(const Descriptor* extendee,
1142  std::vector<const FieldDescriptor*>* out) const;
1143 
1144  // -----------------------------------------------------------------
1145  // Adding items.
1146 
1147  // These add items to the corresponding tables. They return false if
1148  // the key already exists in the table. For AddSymbol(), the string passed
1149  // in must be one that was constructed using AllocateString(), as it will
1150  // be used as a key in the symbols_by_name_ map without copying.
1151  bool AddSymbol(const std::string& full_name, Symbol symbol);
1152  bool AddFile(const FileDescriptor* file);
1153  bool AddExtension(const FieldDescriptor* field);
1154 
1155  // -----------------------------------------------------------------
1156  // Allocating memory.
1157 
1158  // Allocate an object which will be reclaimed when the pool is
1159  // destroyed. Note that the object's destructor will never be called,
1160  // so its fields must be plain old data (primitive data types and
1161  // pointers). All of the descriptor types are such objects.
1162  template <typename Type>
1163  Type* Allocate();
1164 
1165  // Allocate an array of objects which will be reclaimed when the
1166  // pool in destroyed. Again, destructors are never called.
1167  template <typename Type>
1168  Type* AllocateArray(int count);
1169 
1170  // Allocate a string which will be destroyed when the pool is destroyed.
1171  // The string is initialized to the given value for convenience.
1173 
1174  // Copy the input into a NUL terminated string whose lifetime is managed by
1175  // the pool.
1176  const char* Strdup(StringPiece value);
1177 
1178  // Allocates an array of strings which will be destroyed when the pool is
1179  // destroyed. The array is initialized with the input values.
1180  template <typename... In>
1181  const std::string* AllocateStringArray(In&&... values);
1182 
1188  };
1189  // Allocate all 5 names of the field:
1190  // name, full name, lowercase, camelcase and json.
1191  // This function will dedup the strings when possible.
1192  // The resulting array contains `name` at index 0, `full_name` at index 1 and
1193  // the other 3 indices are specified in the result.
1195  const std::string& scope,
1196  const std::string* opt_json_name);
1197 
1198  // Create an object that will be deleted when the pool is destroyed.
1199  // The object is value initialized, and its destructor will be called if
1200  // non-trivial.
1201  template <typename Type>
1202  Type* Create();
1203 
1204  // Allocate a protocol message object. Some older versions of GCC have
1205  // trouble understanding explicit template instantiations in some cases, so
1206  // in those cases we have to pass a dummy pointer of the right type as the
1207  // parameter instead of specifying the type explicitly.
1208  template <typename Type>
1209  Type* AllocateMessage(Type* dummy = nullptr);
1210 
1211  // Allocate a FileDescriptorTables object.
1213 
1214  private:
1215  // All other memory allocated in the pool. Must be first as other objects can
1216  // point into these.
1217  TableArena arena_;
1218 
1219  SymbolsByNameSet symbols_by_name_;
1220  FilesByNameMap files_by_name_;
1221  ExtensionsGroupedByDescriptorMap extensions_;
1222 
1223  struct CheckPoint {
1224  explicit CheckPoint(const Tables* tables)
1225  : arena_before_checkpoint(tables->arena_.num_allocations()),
1227  tables->symbols_after_checkpoint_.size()),
1229  tables->files_after_checkpoint_.size()),
1231  tables->extensions_after_checkpoint_.size()) {}
1236  };
1237  std::vector<CheckPoint> checkpoints_;
1238  std::vector<const char*> symbols_after_checkpoint_;
1239  std::vector<const char*> files_after_checkpoint_;
1240  std::vector<DescriptorIntPair> extensions_after_checkpoint_;
1241 
1242  // Allocate some bytes which will be reclaimed when the pool is
1243  // destroyed.
1244  void* AllocateBytes(int size);
1245 };
1246 
1247 // Contains tables specific to a particular file. These tables are not
1248 // modified once the file has been constructed, so they need not be
1249 // protected by a mutex. This makes operations that depend only on the
1250 // contents of a single file -- e.g. Descriptor::FindFieldByName() --
1251 // lock-free.
1252 //
1253 // For historical reasons, the definitions of the methods of
1254 // FileDescriptorTables and DescriptorPool::Tables are interleaved below.
1255 // These used to be a single class.
1256 class FileDescriptorTables {
1257  public:
1260 
1261  // Empty table, used with placeholder files.
1262  inline static const FileDescriptorTables& GetEmptyInstance();
1263 
1264  // -----------------------------------------------------------------
1265  // Finding items.
1266 
1267  // Returns a null Symbol (symbol.IsNull() is true) if not found.
1268  inline Symbol FindNestedSymbol(const void* parent,
1269  StringPiece name) const;
1270 
1271  // These return nullptr if not found.
1272  inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent,
1273  int number) const;
1275  const void* parent, StringPiece lowercase_name) const;
1277  const void* parent, StringPiece camelcase_name) const;
1279  const EnumDescriptor* parent, int number) const;
1280  // This creates a new EnumValueDescriptor if not found, in a thread-safe way.
1282  const EnumDescriptor* parent, int number) const;
1283 
1284  // -----------------------------------------------------------------
1285  // Adding items.
1286 
1287  // These add items to the corresponding tables. They return false if
1288  // the key already exists in the table. For AddAliasUnderParent(), the
1289  // string passed in must be one that was constructed using AllocateString(),
1290  // as it will be used as a key in the symbols_by_parent_ map without copying.
1291  bool AddAliasUnderParent(const void* parent, const std::string& name,
1292  Symbol symbol);
1295 
1296  // Adds the field to the lowercase_name and camelcase_name maps. Never
1297  // fails because we allow duplicates; the first field by the name wins.
1299 
1300  // Populates p->first->locations_by_path_ from p->second.
1301  // Unusual signature dictated by internal::call_once.
1302  static void BuildLocationsByPath(
1303  std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
1304 
1305  // Returns the location denoted by the specified path through info,
1306  // or nullptr if not found.
1307  // The value of info must be that of the corresponding FileDescriptor.
1308  // (Conceptually a pure function, but stateful as an optimisation.)
1310  const std::vector<int>& path, const SourceCodeInfo* info) const;
1311 
1312  // Must be called after BuildFileImpl(), even if the build failed and
1313  // we are going to roll back to the last checkpoint.
1314  void FinalizeTables();
1315 
1316  private:
1317  const void* FindParentForFieldsByMap(const FieldDescriptor* field) const;
1319  const FileDescriptorTables* tables);
1322  const FileDescriptorTables* tables);
1324 
1325  SymbolsByParentSet symbols_by_parent_;
1326  mutable FieldsByNameMap fields_by_lowercase_name_;
1327  std::unique_ptr<FieldsByNameMap> fields_by_lowercase_name_tmp_;
1329  mutable FieldsByNameMap fields_by_camelcase_name_;
1330  std::unique_ptr<FieldsByNameMap> fields_by_camelcase_name_tmp_;
1332  FieldsByNumberSet fields_by_number_; // Not including extensions.
1333  EnumValuesByNumberSet enum_values_by_number_;
1334  mutable EnumValuesByNumberSet unknown_enum_values_by_number_
1336 
1337  // Populated on first request to save space, hence constness games.
1339  mutable LocationsByPathMap locations_by_path_;
1340 
1341  // Mutex to protect the unknown-enum-value map due to dynamic
1342  // EnumValueDescriptor creation on unknown values.
1343  mutable internal::WrappedMutex unknown_enum_values_mu_;
1344 };
1345 
1347  well_known_types_.insert({
1348  {"google.protobuf.DoubleValue", Descriptor::WELLKNOWNTYPE_DOUBLEVALUE},
1349  {"google.protobuf.FloatValue", Descriptor::WELLKNOWNTYPE_FLOATVALUE},
1350  {"google.protobuf.Int64Value", Descriptor::WELLKNOWNTYPE_INT64VALUE},
1351  {"google.protobuf.UInt64Value", Descriptor::WELLKNOWNTYPE_UINT64VALUE},
1352  {"google.protobuf.Int32Value", Descriptor::WELLKNOWNTYPE_INT32VALUE},
1353  {"google.protobuf.UInt32Value", Descriptor::WELLKNOWNTYPE_UINT32VALUE},
1354  {"google.protobuf.StringValue", Descriptor::WELLKNOWNTYPE_STRINGVALUE},
1355  {"google.protobuf.BytesValue", Descriptor::WELLKNOWNTYPE_BYTESVALUE},
1356  {"google.protobuf.BoolValue", Descriptor::WELLKNOWNTYPE_BOOLVALUE},
1357  {"google.protobuf.Any", Descriptor::WELLKNOWNTYPE_ANY},
1358  {"google.protobuf.FieldMask", Descriptor::WELLKNOWNTYPE_FIELDMASK},
1359  {"google.protobuf.Duration", Descriptor::WELLKNOWNTYPE_DURATION},
1360  {"google.protobuf.Timestamp", Descriptor::WELLKNOWNTYPE_TIMESTAMP},
1361  {"google.protobuf.Value", Descriptor::WELLKNOWNTYPE_VALUE},
1362  {"google.protobuf.ListValue", Descriptor::WELLKNOWNTYPE_LISTVALUE},
1363  {"google.protobuf.Struct", Descriptor::WELLKNOWNTYPE_STRUCT},
1364  });
1365 }
1366 
1367 DescriptorPool::Tables::~Tables() { GOOGLE_DCHECK(checkpoints_.empty()); }
1368 
1370  : fields_by_lowercase_name_tmp_(new FieldsByNameMap()),
1371  fields_by_camelcase_name_tmp_(new FieldsByNameMap()) {}
1372 
1374 
1375 inline const FileDescriptorTables& FileDescriptorTables::GetEmptyInstance() {
1376  static auto file_descriptor_tables =
1378  return *file_descriptor_tables;
1379 }
1380 
1382  checkpoints_.push_back(CheckPoint(this));
1383 }
1384 
1386  GOOGLE_DCHECK(!checkpoints_.empty());
1387  checkpoints_.pop_back();
1388  if (checkpoints_.empty()) {
1389  // All checkpoints have been cleared: we can now commit all of the pending
1390  // data.
1391  symbols_after_checkpoint_.clear();
1392  files_after_checkpoint_.clear();
1393  extensions_after_checkpoint_.clear();
1394  arena_.ClearRollbackData();
1395  }
1396 }
1397 
1399  GOOGLE_DCHECK(!checkpoints_.empty());
1400  const CheckPoint& checkpoint = checkpoints_.back();
1401 
1402  for (size_t i = checkpoint.pending_symbols_before_checkpoint;
1403  i < symbols_after_checkpoint_.size(); i++) {
1404  Symbol::QueryKey name;
1405  name.name = symbols_after_checkpoint_[i];
1406  symbols_by_name_.erase(Symbol(&name));
1407  }
1408  for (size_t i = checkpoint.pending_files_before_checkpoint;
1409  i < files_after_checkpoint_.size(); i++) {
1410  files_by_name_.erase(files_after_checkpoint_[i]);
1411  }
1412  for (size_t i = checkpoint.pending_extensions_before_checkpoint;
1413  i < extensions_after_checkpoint_.size(); i++) {
1414  extensions_.erase(extensions_after_checkpoint_[i]);
1415  }
1416 
1417  symbols_after_checkpoint_.resize(
1418  checkpoint.pending_symbols_before_checkpoint);
1419  files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
1420  extensions_after_checkpoint_.resize(
1421  checkpoint.pending_extensions_before_checkpoint);
1422 
1423  arena_.RollbackTo(checkpoint.arena_before_checkpoint);
1424  checkpoints_.pop_back();
1425 }
1426 
1427 // -------------------------------------------------------------------
1428 
1431  name.name = key;
1432  auto it = symbols_by_name_.find(Symbol(&name));
1433  return it == symbols_by_name_.end() ? kNullSymbol : *it;
1434 }
1435 
1437  const void* parent, StringPiece name) const {
1439  query.name = name;
1440  query.parent = parent;
1441  auto it = symbols_by_parent_.find(Symbol(&query));
1442  return it == symbols_by_parent_.end() ? kNullSymbol : *it;
1443 }
1444 
1446  StringPiece name) {
1447  if (pool->mutex_ != nullptr) {
1448  // Fast path: the Symbol is already cached. This is just a hash lookup.
1449  ReaderMutexLock lock(pool->mutex_);
1450  if (known_bad_symbols_.empty() && known_bad_files_.empty()) {
1451  Symbol result = FindSymbol(name);
1452  if (!result.IsNull()) return result;
1453  }
1454  }
1455  MutexLockMaybe lock(pool->mutex_);
1456  if (pool->fallback_database_ != nullptr) {
1457  known_bad_symbols_.clear();
1458  known_bad_files_.clear();
1459  }
1460  Symbol result = FindSymbol(name);
1461 
1462  if (result.IsNull() && pool->underlay_ != nullptr) {
1463  // Symbol not found; check the underlay.
1464  result = pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
1465  }
1466 
1467  if (result.IsNull()) {
1468  // Symbol still not found, so check fallback database.
1469  if (pool->TryFindSymbolInFallbackDatabase(name)) {
1470  result = FindSymbol(name);
1471  }
1472  }
1473 
1474  return result;
1475 }
1476 
1478  StringPiece key) const {
1479  return FindPtrOrNull(files_by_name_, key);
1480 }
1481 
1483  const Descriptor* parent, int number) const {
1484  // If `number` is within the sequential range, just index into the parent
1485  // without doing a table lookup.
1486  if (parent != nullptr && //
1487  1 <= number && number <= parent->sequential_field_limit_) {
1488  return parent->field(number - 1);
1489  }
1490 
1492  query.parent = parent;
1493  query.field_number = number;
1494 
1495  auto it = fields_by_number_.find(Symbol(&query));
1496  return it == fields_by_number_.end() ? nullptr : it->field_descriptor();
1497 }
1498 
1500  const FieldDescriptor* field) const {
1501  if (field->is_extension()) {
1502  if (field->extension_scope() == nullptr) {
1503  return field->file();
1504  } else {
1505  return field->extension_scope();
1506  }
1507  } else {
1508  return field->containing_type();
1509  }
1510 }
1511 
1513  const FileDescriptorTables* tables) {
1514  tables->FieldsByLowercaseNamesLazyInitInternal();
1515 }
1516 
1518  for (Symbol symbol : symbols_by_parent_) {
1519  const FieldDescriptor* field = symbol.field_descriptor();
1520  if (!field) continue;
1521  PointerStringPair lowercase_key(FindParentForFieldsByMap(field),
1522  field->lowercase_name().c_str());
1523  InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
1524  }
1525 }
1526 
1528  const void* parent, StringPiece lowercase_name) const {
1530  fields_by_lowercase_name_once_,
1532  return FindPtrOrNull(fields_by_lowercase_name_,
1533  PointerStringPair(parent, lowercase_name));
1534 }
1535 
1537  const FileDescriptorTables* tables) {
1539 }
1540 
1542  for (Symbol symbol : symbols_by_parent_) {
1543  const FieldDescriptor* field = symbol.field_descriptor();
1544  if (!field) continue;
1545  PointerStringPair camelcase_key(FindParentForFieldsByMap(field),
1546  field->camelcase_name().c_str());
1547  InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
1548  }
1549 }
1550 
1552  const void* parent, StringPiece camelcase_name) const {
1554  fields_by_camelcase_name_once_,
1556  return FindPtrOrNull(fields_by_camelcase_name_,
1557  PointerStringPair(parent, camelcase_name));
1558 }
1559 
1561  const EnumDescriptor* parent, int number) const {
1562  // If `number` is within the sequential range, just index into the parent
1563  // without doing a table lookup.
1564  const int base = parent->value(0)->number();
1565  if (base <= number &&
1566  number <= static_cast<int64_t>(base) + parent->sequential_value_limit_) {
1567  return parent->value(number - base);
1568  }
1569 
1570  Symbol::QueryKey query;
1571  query.parent = parent;
1572  query.field_number = number;
1573 
1574  auto it = enum_values_by_number_.find(Symbol(&query));
1575  return it == enum_values_by_number_.end() ? nullptr
1576  : it->enum_value_descriptor();
1577 }
1578 
1579 inline const EnumValueDescriptor*
1581  const EnumDescriptor* parent, int number) const {
1582  // First try, with map of compiled-in values.
1583  {
1584  const auto* value = FindEnumValueByNumber(parent, number);
1585  if (value != nullptr) {
1586  return value;
1587  }
1588  }
1589 
1590  Symbol::QueryKey query;
1591  query.parent = parent;
1592  query.field_number = number;
1593 
1594  // Second try, with reader lock held on unknown enum values: common case.
1595  {
1596  ReaderMutexLock l(&unknown_enum_values_mu_);
1597  auto it = unknown_enum_values_by_number_.find(Symbol(&query));
1598  if (it != unknown_enum_values_by_number_.end() &&
1599  it->enum_value_descriptor() != nullptr) {
1600  return it->enum_value_descriptor();
1601  }
1602  }
1603  // If not found, try again with writer lock held, and create new descriptor if
1604  // necessary.
1605  {
1606  WriterMutexLock l(&unknown_enum_values_mu_);
1607  auto it = unknown_enum_values_by_number_.find(Symbol(&query));
1608  if (it != unknown_enum_values_by_number_.end() &&
1609  it->enum_value_descriptor() != nullptr) {
1610  return it->enum_value_descriptor();
1611  }
1612 
1613  // Create an EnumValueDescriptor dynamically. We don't insert it into the
1614  // EnumDescriptor (it's not a part of the enum as originally defined), but
1615  // we do insert it into the table so that we can return the same pointer
1616  // later.
1617  std::string enum_value_name = StringPrintf("UNKNOWN_ENUM_VALUE_%s_%d",
1618  parent->name().c_str(), number);
1620  auto* tables = const_cast<DescriptorPool::Tables*>(pool->tables_.get());
1622  {
1623  // Must lock the pool because we will do allocations in the shared arena.
1624  MutexLockMaybe l2(pool->mutex_);
1625  result = tables->Allocate<EnumValueDescriptor>();
1626  result->all_names_ = tables->AllocateStringArray(
1627  enum_value_name,
1628  StrCat(parent->full_name(), ".", enum_value_name));
1629  }
1630  result->number_ = number;
1631  result->type_ = parent;
1633  unknown_enum_values_by_number_.insert(Symbol::EnumValue(result, 0));
1634  return result;
1635  }
1636 }
1637 
1639  const Descriptor* extendee, int number) const {
1640  return FindPtrOrNull(extensions_, std::make_pair(extendee, number));
1641 }
1642 
1644  const Descriptor* extendee,
1645  std::vector<const FieldDescriptor*>* out) const {
1646  ExtensionsGroupedByDescriptorMap::const_iterator it =
1647  extensions_.lower_bound(std::make_pair(extendee, 0));
1648  for (; it != extensions_.end() && it->first.first == extendee; ++it) {
1649  out->push_back(it->second);
1650  }
1651 }
1652 
1653 // -------------------------------------------------------------------
1654 
1655 bool DescriptorPool::Tables::AddSymbol(const std::string& full_name,
1656  Symbol symbol) {
1657  GOOGLE_DCHECK_EQ(full_name, symbol.full_name());
1658  if (symbols_by_name_.insert(symbol).second) {
1659  symbols_after_checkpoint_.push_back(full_name.c_str());
1660  return true;
1661  } else {
1662  return false;
1663  }
1664 }
1665 
1666 bool FileDescriptorTables::AddAliasUnderParent(const void* parent,
1667  const std::string& name,
1668  Symbol symbol) {
1669  GOOGLE_DCHECK_EQ(name, symbol.parent_name_key().second);
1670  GOOGLE_DCHECK_EQ(parent, symbol.parent_name_key().first);
1671  return symbols_by_parent_.insert(symbol).second;
1672 }
1673 
1675  if (InsertIfNotPresent(&files_by_name_, file->name(), file)) {
1676  files_after_checkpoint_.push_back(file->name().c_str());
1677  return true;
1678  } else {
1679  return false;
1680  }
1681 }
1682 
1684  // Clean up the temporary maps used by AddFieldByStylizedNames().
1685  fields_by_lowercase_name_tmp_ = nullptr;
1686  fields_by_camelcase_name_tmp_ = nullptr;
1687 }
1688 
1690  const FieldDescriptor* field) {
1691  const void* parent = FindParentForFieldsByMap(field);
1692 
1693  // We want fields_by_{lower,camel}case_name_ to be lazily built, but
1694  // cross-link order determines which entry will be present in the case of a
1695  // conflict. So we use the temporary maps that get destroyed after
1696  // BuildFileImpl() to detect the conflicts, and only store the conflicts in
1697  // the map that will persist. We will then lazily populate the rest of the
1698  // entries from fields_by_number_.
1699 
1700  PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
1701  if (!InsertIfNotPresent(fields_by_lowercase_name_tmp_.get(),
1702  lowercase_key, field)) {
1704  &fields_by_lowercase_name_, lowercase_key,
1705  FindPtrOrNull(*fields_by_lowercase_name_tmp_, lowercase_key));
1706  }
1707 
1708  PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
1709  if (!InsertIfNotPresent(fields_by_camelcase_name_tmp_.get(),
1710  camelcase_key, field)) {
1712  &fields_by_camelcase_name_, camelcase_key,
1713  FindPtrOrNull(*fields_by_camelcase_name_tmp_, camelcase_key));
1714  }
1715 }
1716 
1718  // Skip fields that are at the start of the sequence.
1719  if (field->containing_type() != nullptr && field->number() >= 1 &&
1720  field->number() <= field->containing_type()->sequential_field_limit_) {
1721  if (field->is_extension()) {
1722  // Conflicts with the field that already exists in the sequential range.
1723  return false;
1724  }
1725  // Only return true if the field at that index matches. Otherwise it
1726  // conflicts with the existing field in the sequential range.
1727  return field->containing_type()->field(field->number() - 1) == field;
1728  }
1729 
1730  return fields_by_number_.insert(Symbol(field)).second;
1731 }
1732 
1734  // Skip values that are at the start of the sequence.
1735  const int base = value->type()->value(0)->number();
1736  if (base <= value->number() &&
1737  value->number() <=
1738  static_cast<int64_t>(base) + value->type()->sequential_value_limit_)
1739  return true;
1740  return enum_values_by_number_.insert(Symbol::EnumValue(value, 0)).second;
1741 }
1742 
1744  DescriptorIntPair key(field->containing_type(), field->number());
1745  if (InsertIfNotPresent(&extensions_, key, field)) {
1746  extensions_after_checkpoint_.push_back(key);
1747  return true;
1748  } else {
1749  return false;
1750  }
1751 }
1752 
1753 // -------------------------------------------------------------------
1754 
1755 template <typename Type>
1757  return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type)));
1758 }
1759 
1760 template <typename Type>
1762  return reinterpret_cast<Type*>(AllocateBytes(sizeof(Type) * count));
1763 }
1764 
1766  StringPiece value) {
1767  return arena_.Create<std::string>(value);
1768 }
1769 
1771  char* p = AllocateArray<char>(static_cast<int>(value.size() + 1));
1772  memcpy(p, value.data(), value.size());
1773  p[value.size()] = 0;
1774  return p;
1775 }
1776 
1777 template <typename... In>
1779  auto& array = *arena_.Create<std::array<std::string, sizeof...(In)>>();
1780  array = {{std::string(std::forward<In>(values))...}};
1781  return array.data();
1782 }
1783 
1784 DescriptorPool::Tables::FieldNamesResult
1786  const std::string& scope,
1787  const std::string* opt_json_name) {
1788  std::string lowercase_name = name;
1789  LowerString(&lowercase_name);
1790 
1791  std::string camelcase_name = ToCamelCase(name, /* lower_first = */ true);
1792  std::string json_name;
1793  if (opt_json_name != nullptr) {
1794  json_name = *opt_json_name;
1795  } else {
1796  json_name = ToJsonName(name);
1797  }
1798 
1799  const bool lower_eq_name = lowercase_name == name;
1800  const bool camel_eq_name = camelcase_name == name;
1801  const bool json_eq_name = json_name == name;
1802  const bool json_eq_camel = json_name == camelcase_name;
1803 
1804  const int total_count = 2 + (lower_eq_name ? 0 : 1) +
1805  (camel_eq_name ? 0 : 1) +
1806  (json_eq_name || json_eq_camel ? 0 : 1);
1807  FieldNamesResult result{nullptr, 0, 0, 0};
1808  // We use std::array to allow handling of the destruction of the strings.
1809  switch (total_count) {
1810  case 2:
1811  result.array = arena_.Create<std::array<std::string, 2>>()->data();
1812  break;
1813  case 3:
1814  result.array = arena_.Create<std::array<std::string, 3>>()->data();
1815  break;
1816  case 4:
1817  result.array = arena_.Create<std::array<std::string, 4>>()->data();
1818  break;
1819  case 5:
1820  result.array = arena_.Create<std::array<std::string, 5>>()->data();
1821  break;
1822  }
1823 
1824  result.array[0] = name;
1825  if (scope.empty()) {
1826  result.array[1] = name;
1827  } else {
1828  result.array[1] = StrCat(scope, ".", name);
1829  }
1830  int index = 2;
1831  if (lower_eq_name) {
1832  result.lowercase_index = 0;
1833  } else {
1834  result.lowercase_index = index;
1835  result.array[index++] = std::move(lowercase_name);
1836  }
1837 
1838  if (camel_eq_name) {
1839  result.camelcase_index = 0;
1840  } else {
1841  result.camelcase_index = index;
1842  result.array[index++] = std::move(camelcase_name);
1843  }
1844 
1845  if (json_eq_name) {
1846  result.json_index = 0;
1847  } else if (json_eq_camel) {
1848  result.json_index = result.camelcase_index;
1849  } else {
1850  result.json_index = index;
1851  result.array[index] = std::move(json_name);
1852  }
1853 
1854  return result;
1855 }
1856 
1857 template <typename Type>
1859  return arena_.Create<Type>();
1860 }
1861 
1862 template <typename Type>
1864  return arena_.Create<Type>();
1865 }
1866 
1868  return arena_.Create<FileDescriptorTables>();
1869 }
1870 
1872  if (size == 0) return nullptr;
1873  return arena_.AllocateMemory(size);
1874 }
1875 
1877  std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
1878  for (int i = 0, len = p->second->location_size(); i < len; ++i) {
1879  const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
1880  p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
1881  }
1882 }
1883 
1885  const std::vector<int>& path, const SourceCodeInfo* info) const {
1886  std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
1887  std::make_pair(this, info));
1888  internal::call_once(locations_by_path_once_,
1890  return FindPtrOrNull(locations_by_path_, Join(path, ","));
1891 }
1892 
1893 // ===================================================================
1894 // DescriptorPool
1895 
1897 
1899  : mutex_(nullptr),
1900  fallback_database_(nullptr),
1901  default_error_collector_(nullptr),
1902  underlay_(nullptr),
1903  tables_(new Tables),
1909 
1911  ErrorCollector* error_collector)
1912  : mutex_(new internal::WrappedMutex),
1913  fallback_database_(fallback_database),
1914  default_error_collector_(error_collector),
1915  underlay_(nullptr),
1916  tables_(new Tables),
1922 
1924  : mutex_(nullptr),
1925  fallback_database_(nullptr),
1926  default_error_collector_(nullptr),
1927  underlay_(underlay),
1928  tables_(new Tables),
1934 
1936  if (mutex_ != nullptr) delete mutex_;
1937 }
1938 
1939 // DescriptorPool::BuildFile() defined later.
1940 // DescriptorPool::BuildFileCollectingErrors() defined later.
1941 
1943  enforce_dependencies_ = false;
1944 }
1945 
1947  bool is_error) {
1948  unused_import_track_files_[std::string(file_name)] = is_error;
1949 }
1950 
1953 }
1954 
1956  MutexLockMaybe lock(mutex_);
1957  return tables_->FindFile(filename) != nullptr;
1958 }
1959 
1960 // generated_pool ====================================================
1961 
1962 namespace {
1963 
1964 
1965 EncodedDescriptorDatabase* GeneratedDatabase() {
1966  static auto generated_database =
1967  internal::OnShutdownDelete(new EncodedDescriptorDatabase());
1968  return generated_database;
1969 }
1970 
1971 DescriptorPool* NewGeneratedPool() {
1972  auto generated_pool = new DescriptorPool(GeneratedDatabase());
1974  return generated_pool;
1975 }
1976 
1977 } // anonymous namespace
1978 
1980  return GeneratedDatabase();
1981 }
1982 
1984  static DescriptorPool* generated_pool =
1985  internal::OnShutdownDelete(NewGeneratedPool());
1986  return generated_pool;
1987 }
1988 
1991  // Ensure that descriptor.proto has been registered in the generated pool.
1993  return pool;
1994 }
1995 
1996 
1998  const void* encoded_file_descriptor, int size) {
1999  // So, this function is called in the process of initializing the
2000  // descriptors for generated proto classes. Each generated .pb.cc file
2001  // has an internal procedure called AddDescriptors() which is called at
2002  // process startup, and that function calls this one in order to register
2003  // the raw bytes of the FileDescriptorProto representing the file.
2004  //
2005  // We do not actually construct the descriptor objects right away. We just
2006  // hang on to the bytes until they are actually needed. We actually construct
2007  // the descriptor the first time one of the following things happens:
2008  // * Someone calls a method like descriptor(), GetDescriptor(), or
2009  // GetReflection() on the generated types, which requires returning the
2010  // descriptor or an object based on it.
2011  // * Someone looks up the descriptor in DescriptorPool::generated_pool().
2012  //
2013  // Once one of these happens, the DescriptorPool actually parses the
2014  // FileDescriptorProto and generates a FileDescriptor (and all its children)
2015  // based on it.
2016  //
2017  // Note that FileDescriptorProto is itself a generated protocol message.
2018  // Therefore, when we parse one, we have to be very careful to avoid using
2019  // any descriptor-based operations, since this might cause infinite recursion
2020  // or deadlock.
2021  GOOGLE_CHECK(GeneratedDatabase()->Add(encoded_file_descriptor, size));
2022 }
2023 
2024 
2025 // Find*By* methods ==================================================
2026 
2027 // TODO(kenton): There's a lot of repeated code here, but I'm not sure if
2028 // there's any good way to factor it out. Think about this some time when
2029 // there's nothing more important to do (read: never).
2030 
2032  ConstStringParam name) const {
2033  MutexLockMaybe lock(mutex_);
2034  if (fallback_database_ != nullptr) {
2035  tables_->known_bad_symbols_.clear();
2036  tables_->known_bad_files_.clear();
2037  }
2038  const FileDescriptor* result = tables_->FindFile(name);
2039  if (result != nullptr) return result;
2040  if (underlay_ != nullptr) {
2042  if (result != nullptr) return result;
2043  }
2045  result = tables_->FindFile(name);
2046  if (result != nullptr) return result;
2047  }
2048  return nullptr;
2049 }
2050 
2052  ConstStringParam symbol_name) const {
2053  MutexLockMaybe lock(mutex_);
2054  if (fallback_database_ != nullptr) {
2055  tables_->known_bad_symbols_.clear();
2056  tables_->known_bad_files_.clear();
2057  }
2058  Symbol result = tables_->FindSymbol(symbol_name);
2059  if (!result.IsNull()) return result.GetFile();
2060  if (underlay_ != nullptr) {
2061  const FileDescriptor* file_result =
2062  underlay_->FindFileContainingSymbol(symbol_name);
2063  if (file_result != nullptr) return file_result;
2064  }
2065  if (TryFindSymbolInFallbackDatabase(symbol_name)) {
2066  result = tables_->FindSymbol(symbol_name);
2067  if (!result.IsNull()) return result.GetFile();
2068  }
2069  return nullptr;
2070 }
2071 
2073  ConstStringParam name) const {
2074  return tables_->FindByNameHelper(this, name).descriptor();
2075 }
2076 
2078  ConstStringParam name) const {
2079  if (const FieldDescriptor* field =
2080  tables_->FindByNameHelper(this, name).field_descriptor()) {
2081  if (!field->is_extension()) {
2082  return field;
2083  }
2084  }
2085  return nullptr;
2086 }
2087 
2089  ConstStringParam name) const {
2090  if (const FieldDescriptor* field =
2091  tables_->FindByNameHelper(this, name).field_descriptor()) {
2092  if (field->is_extension()) {
2093  return field;
2094  }
2095  }
2096  return nullptr;
2097 }
2098 
2100  ConstStringParam name) const {
2101  return tables_->FindByNameHelper(this, name).oneof_descriptor();
2102 }
2103 
2105  ConstStringParam name) const {
2106  return tables_->FindByNameHelper(this, name).enum_descriptor();
2107 }
2108 
2110  ConstStringParam name) const {
2111  return tables_->FindByNameHelper(this, name).enum_value_descriptor();
2112 }
2113 
2115  ConstStringParam name) const {
2116  return tables_->FindByNameHelper(this, name).service_descriptor();
2117 }
2118 
2120  ConstStringParam name) const {
2121  return tables_->FindByNameHelper(this, name).method_descriptor();
2122 }
2123 
2125  const Descriptor* extendee, int number) const {
2126  if (extendee->extension_range_count() == 0) return nullptr;
2127  // A faster path to reduce lock contention in finding extensions, assuming
2128  // most extensions will be cache hit.
2129  if (mutex_ != nullptr) {
2130  ReaderMutexLock lock(mutex_);
2131  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
2132  if (result != nullptr) {
2133  return result;
2134  }
2135  }
2136  MutexLockMaybe lock(mutex_);
2137  if (fallback_database_ != nullptr) {
2138  tables_->known_bad_symbols_.clear();
2139  tables_->known_bad_files_.clear();
2140  }
2141  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
2142  if (result != nullptr) {
2143  return result;
2144  }
2145  if (underlay_ != nullptr) {
2147  if (result != nullptr) return result;
2148  }
2149  if (TryFindExtensionInFallbackDatabase(extendee, number)) {
2150  result = tables_->FindExtension(extendee, number);
2151  if (result != nullptr) {
2152  return result;
2153  }
2154  }
2155  return nullptr;
2156 }
2157 
2159  const Descriptor* extendee, int number) const {
2160  if (extendee->extension_range_count() == 0) return nullptr;
2161 
2162  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
2163  if (result != nullptr) {
2164  return result;
2165  }
2166 
2167  if (underlay_ != nullptr) {
2169  if (result != nullptr) return result;
2170  }
2171 
2172  return nullptr;
2173 }
2174 
2176  const Descriptor* extendee, ConstStringParam printable_name) const {
2177  if (extendee->extension_range_count() == 0) return nullptr;
2178  const FieldDescriptor* result = FindExtensionByName(printable_name);
2179  if (result != nullptr && result->containing_type() == extendee) {
2180  return result;
2181  }
2182  if (extendee->options().message_set_wire_format()) {
2183  // MessageSet extensions may be identified by type name.
2184  const Descriptor* type = FindMessageTypeByName(printable_name);
2185  if (type != nullptr) {
2186  // Look for a matching extension in the foreign type's scope.
2187  const int type_extension_count = type->extension_count();
2188  for (int i = 0; i < type_extension_count; i++) {
2189  const FieldDescriptor* extension = type->extension(i);
2190  if (extension->containing_type() == extendee &&
2192  extension->is_optional() && extension->message_type() == type) {
2193  // Found it.
2194  return extension;
2195  }
2196  }
2197  }
2198  }
2199  return nullptr;
2200 }
2201 
2203  const Descriptor* extendee,
2204  std::vector<const FieldDescriptor*>* out) const {
2205  MutexLockMaybe lock(mutex_);
2206  if (fallback_database_ != nullptr) {
2207  tables_->known_bad_symbols_.clear();
2208  tables_->known_bad_files_.clear();
2209  }
2210 
2211  // Initialize tables_->extensions_ from the fallback database first
2212  // (but do this only once per descriptor).
2213  if (fallback_database_ != nullptr &&
2214  tables_->extensions_loaded_from_db_.count(extendee) == 0) {
2215  std::vector<int> numbers;
2216  if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
2217  &numbers)) {
2218  for (int number : numbers) {
2219  if (tables_->FindExtension(extendee, number) == nullptr) {
2221  }
2222  }
2223  tables_->extensions_loaded_from_db_.insert(extendee);
2224  }
2225  }
2226 
2227  tables_->FindAllExtensions(extendee, out);
2228  if (underlay_ != nullptr) {
2229  underlay_->FindAllExtensions(extendee, out);
2230  }
2231 }
2232 
2233 
2234 // -------------------------------------------------------------------
2235 
2237  const FieldDescriptor* result = file()->tables_->FindFieldByNumber(this, key);
2238  if (result == nullptr || result->is_extension()) {
2239  return nullptr;
2240  } else {
2241  return result;
2242  }
2243 }
2244 
2246  ConstStringParam key) const {
2247  const FieldDescriptor* result =
2248  file()->tables_->FindFieldByLowercaseName(this, key);
2249  if (result == nullptr || result->is_extension()) {
2250  return nullptr;
2251  } else {
2252  return result;
2253  }
2254 }
2255 
2257  ConstStringParam key) const {
2258  const FieldDescriptor* result =
2259  file()->tables_->FindFieldByCamelcaseName(this, key);
2260  if (result == nullptr || result->is_extension()) {
2261  return nullptr;
2262  } else {
2263  return result;
2264  }
2265 }
2266 
2268  const FieldDescriptor* field =
2269  file()->tables_->FindNestedSymbol(this, key).field_descriptor();
2270  return field != nullptr && !field->is_extension() ? field : nullptr;
2271 }
2272 
2274  return file()->tables_->FindNestedSymbol(this, key).oneof_descriptor();
2275 }
2276 
2278  ConstStringParam key) const {
2279  const FieldDescriptor* field =
2280  file()->tables_->FindNestedSymbol(this, key).field_descriptor();
2281  return field != nullptr && field->is_extension() ? field : nullptr;
2282 }
2283 
2285  ConstStringParam key) const {
2286  const FieldDescriptor* result =
2287  file()->tables_->FindFieldByLowercaseName(this, key);
2288  if (result == nullptr || !result->is_extension()) {
2289  return nullptr;
2290  } else {
2291  return result;
2292  }
2293 }
2294 
2296  ConstStringParam key) const {
2297  const FieldDescriptor* result =
2298  file()->tables_->FindFieldByCamelcaseName(this, key);
2299  if (result == nullptr || !result->is_extension()) {
2300  return nullptr;
2301  } else {
2302  return result;
2303  }
2304 }
2305 
2307  return file()->tables_->FindNestedSymbol(this, key).descriptor();
2308 }
2309 
2311  ConstStringParam key) const {
2312  return file()->tables_->FindNestedSymbol(this, key).enum_descriptor();
2313 }
2314 
2316  ConstStringParam key) const {
2317  return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor();
2318 }
2319 
2321  if (!options().map_entry()) return nullptr;
2322  GOOGLE_DCHECK_EQ(field_count(), 2);
2323  return field(0);
2324 }
2325 
2327  if (!options().map_entry()) return nullptr;
2328  GOOGLE_DCHECK_EQ(field_count(), 2);
2329  return field(1);
2330 }
2331 
2333  ConstStringParam key) const {
2334  return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor();
2335 }
2336 
2338  return file()->tables_->FindEnumValueByNumber(this, key);
2339 }
2340 
2342  int key) const {
2343  return file()->tables_->FindEnumValueByNumberCreatingIfUnknown(this, key);
2344 }
2345 
2347  ConstStringParam key) const {
2348  return file()->tables_->FindNestedSymbol(this, key).method_descriptor();
2349 }
2350 
2352  ConstStringParam key) const {
2353  return tables_->FindNestedSymbol(this, key).descriptor();
2354 }
2355 
2357  ConstStringParam key) const {
2358  return tables_->FindNestedSymbol(this, key).enum_descriptor();
2359 }
2360 
2362  ConstStringParam key) const {
2363  return tables_->FindNestedSymbol(this, key).enum_value_descriptor();
2364 }
2365 
2367  ConstStringParam key) const {
2368  return tables_->FindNestedSymbol(this, key).service_descriptor();
2369 }
2370 
2372  ConstStringParam key) const {
2373  const FieldDescriptor* field =
2374  tables_->FindNestedSymbol(this, key).field_descriptor();
2375  return field != nullptr && field->is_extension() ? field : nullptr;
2376 }
2377 
2379  ConstStringParam key) const {
2380  const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
2381  if (result == nullptr || !result->is_extension()) {
2382  return nullptr;
2383  } else {
2384  return result;
2385  }
2386 }
2387 
2389  ConstStringParam key) const {
2390  const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
2391  if (result == nullptr || !result->is_extension()) {
2392  return nullptr;
2393  } else {
2394  return result;
2395  }
2396 }
2397 
2399  DescriptorProto_ExtensionRange* proto) const {
2400  proto->set_start(this->start);
2401  proto->set_end(this->end);
2403  *proto->mutable_options() = *options_;
2404  }
2405 }
2406 
2407 const Descriptor::ExtensionRange*
2409  // Linear search should be fine because we don't expect a message to have
2410  // more than a couple extension ranges.
2411  for (int i = 0; i < extension_range_count(); i++) {
2412  if (number >= extension_range(i)->start &&
2413  number < extension_range(i)->end) {
2414  return extension_range(i);
2415  }
2416  }
2417  return nullptr;
2418 }
2419 
2420 const Descriptor::ReservedRange* Descriptor::FindReservedRangeContainingNumber(
2421  int number) const {
2422  // TODO(chrisn): Consider a non-linear search.
2423  for (int i = 0; i < reserved_range_count(); i++) {
2424  if (number >= reserved_range(i)->start && number < reserved_range(i)->end) {
2425  return reserved_range(i);
2426  }
2427  }
2428  return nullptr;
2429 }
2430 
2431 const EnumDescriptor::ReservedRange*
2433  // TODO(chrisn): Consider a non-linear search.
2434  for (int i = 0; i < reserved_range_count(); i++) {
2435  if (number >= reserved_range(i)->start &&
2436  number <= reserved_range(i)->end) {
2437  return reserved_range(i);
2438  }
2439  }
2440  return nullptr;
2441 }
2442 
2443 // -------------------------------------------------------------------
2444 
2446  StringPiece name) const {
2447  if (fallback_database_ == nullptr) return false;
2448 
2449  auto name_string = std::string(name);
2450  if (tables_->known_bad_files_.count(name_string) > 0) return false;
2451 
2452  FileDescriptorProto file_proto;
2453  if (!fallback_database_->FindFileByName(name_string, &file_proto) ||
2454  BuildFileFromDatabase(file_proto) == nullptr) {
2455  tables_->known_bad_files_.insert(std::move(name_string));
2456  return false;
2457  }
2458  return true;
2459 }
2460 
2462  auto prefix = std::string(name);
2463  for (;;) {
2464  std::string::size_type dot_pos = prefix.find_last_of('.');
2465  if (dot_pos == std::string::npos) {
2466  break;
2467  }
2468  prefix = prefix.substr(0, dot_pos);
2469  Symbol symbol = tables_->FindSymbol(prefix);
2470  // If the symbol type is anything other than PACKAGE, then its complete
2471  // definition is already known.
2472  if (!symbol.IsNull() && symbol.type() != Symbol::PACKAGE) {
2473  return true;
2474  }
2475  }
2476  if (underlay_ != nullptr) {
2477  // Check to see if any prefix of this symbol exists in the underlay.
2479  }
2480  return false;
2481 }
2482 
2484  StringPiece name) const {
2485  if (fallback_database_ == nullptr) return false;
2486 
2487  auto name_string = std::string(name);
2488  if (tables_->known_bad_symbols_.count(name_string) > 0) return false;
2489 
2490  FileDescriptorProto file_proto;
2491  if ( // We skip looking in the fallback database if the name is a sub-symbol
2492  // of any descriptor that already exists in the descriptor pool (except
2493  // for package descriptors). This is valid because all symbols except
2494  // for packages are defined in a single file, so if the symbol exists
2495  // then we should already have its definition.
2496  //
2497  // The other reason to do this is to support "overriding" type
2498  // definitions by merging two databases that define the same type. (Yes,
2499  // people do this.) The main difficulty with making this work is that
2500  // FindFileContainingSymbol() is allowed to return both false positives
2501  // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and
2502  // false negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
2503  // When two such databases are merged, looking up a non-existent
2504  // sub-symbol of a type that already exists in the descriptor pool can
2505  // result in an attempt to load multiple definitions of the same type.
2506  // The check below avoids this.
2508 
2509  // Look up file containing this symbol in fallback database.
2510  || !fallback_database_->FindFileContainingSymbol(name_string, &file_proto)
2511 
2512  // Check if we've already built this file. If so, it apparently doesn't
2513  // contain the symbol we're looking for. Some DescriptorDatabases
2514  // return false positives.
2515  || tables_->FindFile(file_proto.name()) != nullptr
2516 
2517  // Build the file.
2518  || BuildFileFromDatabase(file_proto) == nullptr) {
2519  tables_->known_bad_symbols_.insert(std::move(name_string));
2520  return false;
2521  }
2522 
2523  return true;
2524 }
2525 
2527  const Descriptor* containing_type, int field_number) const {
2528  if (fallback_database_ == nullptr) return false;
2529 
2530  FileDescriptorProto file_proto;
2532  containing_type->full_name(), field_number, &file_proto)) {
2533  return false;
2534  }
2535 
2536  if (tables_->FindFile(file_proto.name()) != nullptr) {
2537  // We've already loaded this file, and it apparently doesn't contain the
2538  // extension we're looking for. Some DescriptorDatabases return false
2539  // positives.
2540  return false;
2541  }
2542 
2543  if (BuildFileFromDatabase(file_proto) == nullptr) {
2544  return false;
2545  }
2546 
2547  return true;
2548 }
2549 
2550 // ===================================================================
2551 
2553  return type_descriptor_.message_type->options().map_entry();
2554 }
2555 
2557  bool quote_string_type) const {
2558  GOOGLE_CHECK(has_default_value()) << "No default value";
2559  switch (cpp_type()) {
2560  case CPPTYPE_INT32:
2561  return StrCat(default_value_int32_t());
2562  case CPPTYPE_INT64:
2563  return StrCat(default_value_int64_t());
2564  case CPPTYPE_UINT32:
2565  return StrCat(default_value_uint32_t());
2566  case CPPTYPE_UINT64:
2567  return StrCat(default_value_uint64_t());
2568  case CPPTYPE_FLOAT:
2569  return SimpleFtoa(default_value_float());
2570  case CPPTYPE_DOUBLE:
2571  return SimpleDtoa(default_value_double());
2572  case CPPTYPE_BOOL:
2573  return default_value_bool() ? "true" : "false";
2574  case CPPTYPE_STRING:
2575  if (quote_string_type) {
2576  return "\"" + CEscape(default_value_string()) + "\"";
2577  } else {
2578  if (type() == TYPE_BYTES) {
2579  return CEscape(default_value_string());
2580  } else {
2581  return default_value_string();
2582  }
2583  }
2584  case CPPTYPE_ENUM:
2585  return default_value_enum()->name();
2586  case CPPTYPE_MESSAGE:
2587  GOOGLE_LOG(DFATAL) << "Messages can't have default values!";
2588  break;
2589  }
2590  GOOGLE_LOG(FATAL) << "Can't get here: failed to get default value as string";
2591  return "";
2592 }
2593 
2594 // CopyTo methods ====================================================
2595 
2596 void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
2597  proto->set_name(name());
2598  if (!package().empty()) proto->set_package(package());
2599  // TODO(liujisi): Also populate when syntax="proto2".
2600  if (syntax() == SYNTAX_PROTO3) proto->set_syntax(SyntaxName(syntax()));
2601 
2602  for (int i = 0; i < dependency_count(); i++) {
2603  proto->add_dependency(dependency(i)->name());
2604  }
2605 
2606  for (int i = 0; i < public_dependency_count(); i++) {
2607  proto->add_public_dependency(public_dependencies_[i]);
2608  }
2609 
2610  for (int i = 0; i < weak_dependency_count(); i++) {
2611  proto->add_weak_dependency(weak_dependencies_[i]);
2612  }
2613 
2614  for (int i = 0; i < message_type_count(); i++) {
2615  message_type(i)->CopyTo(proto->add_message_type());
2616  }
2617  for (int i = 0; i < enum_type_count(); i++) {
2618  enum_type(i)->CopyTo(proto->add_enum_type());
2619  }
2620  for (int i = 0; i < service_count(); i++) {
2621  service(i)->CopyTo(proto->add_service());
2622  }
2623  for (int i = 0; i < extension_count(); i++) {
2624  extension(i)->CopyTo(proto->add_extension());
2625  }
2626 
2627  if (&options() != &FileOptions::default_instance()) {
2628  proto->mutable_options()->CopyFrom(options());
2629  }
2630 }
2631 
2633  if (message_type_count() != proto->message_type_size() ||
2634  extension_count() != proto->extension_size()) {
2635  GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size.";
2636  return;
2637  }
2638  for (int i = 0; i < message_type_count(); i++) {
2639  message_type(i)->CopyJsonNameTo(proto->mutable_message_type(i));
2640  }
2641  for (int i = 0; i < extension_count(); i++) {
2642  extension(i)->CopyJsonNameTo(proto->mutable_extension(i));
2643  }
2644 }
2645 
2647  if (source_code_info_ &&
2648  source_code_info_ != &SourceCodeInfo::default_instance()) {
2649  proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
2650  }
2651 }
2652 
2653 void Descriptor::CopyTo(DescriptorProto* proto) const {
2654  proto->set_name(name());
2655 
2656  for (int i = 0; i < field_count(); i++) {
2657  field(i)->CopyTo(proto->add_field());
2658  }
2659  for (int i = 0; i < oneof_decl_count(); i++) {
2660  oneof_decl(i)->CopyTo(proto->add_oneof_decl());
2661  }
2662  for (int i = 0; i < nested_type_count(); i++) {
2663  nested_type(i)->CopyTo(proto->add_nested_type());
2664  }
2665  for (int i = 0; i < enum_type_count(); i++) {
2666  enum_type(i)->CopyTo(proto->add_enum_type());
2667  }
2668  for (int i = 0; i < extension_range_count(); i++) {
2669  extension_range(i)->CopyTo(proto->add_extension_range());
2670  }
2671  for (int i = 0; i < extension_count(); i++) {
2672  extension(i)->CopyTo(proto->add_extension());
2673  }
2674  for (int i = 0; i < reserved_range_count(); i++) {
2676  range->set_start(reserved_range(i)->start);
2677  range->set_end(reserved_range(i)->end);
2678  }
2679  for (int i = 0; i < reserved_name_count(); i++) {
2680  proto->add_reserved_name(reserved_name(i));
2681  }
2682 
2684  proto->mutable_options()->CopyFrom(options());
2685  }
2686 }
2687 
2688 void Descriptor::CopyJsonNameTo(DescriptorProto* proto) const {
2689  if (field_count() != proto->field_size() ||
2690  nested_type_count() != proto->nested_type_size() ||
2691  extension_count() != proto->extension_size()) {
2692  GOOGLE_LOG(ERROR) << "Cannot copy json_name to a proto of a different size.";
2693  return;
2694  }
2695  for (int i = 0; i < field_count(); i++) {
2696  field(i)->CopyJsonNameTo(proto->mutable_field(i));
2697  }
2698  for (int i = 0; i < nested_type_count(); i++) {
2699  nested_type(i)->CopyJsonNameTo(proto->mutable_nested_type(i));
2700  }
2701  for (int i = 0; i < extension_count(); i++) {
2702  extension(i)->CopyJsonNameTo(proto->mutable_extension(i));
2703  }
2704 }
2705 
2706 void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
2707  proto->set_name(name());
2708  proto->set_number(number());
2709  if (has_json_name_) {
2710  proto->set_json_name(json_name());
2711  }
2712  if (proto3_optional_) {
2713  proto->set_proto3_optional(true);
2714  }
2715  // Some compilers do not allow static_cast directly between two enum types,
2716  // so we must cast to int first.
2717  proto->set_label(static_cast<FieldDescriptorProto::Label>(
2718  implicit_cast<int>(label())));
2719  proto->set_type(static_cast<FieldDescriptorProto::Type>(
2720  implicit_cast<int>(type())));
2721 
2722  if (is_extension()) {
2723  if (!containing_type()->is_unqualified_placeholder_) {
2724  proto->set_extendee(".");
2725  }
2726  proto->mutable_extendee()->append(containing_type()->full_name());
2727  }
2728 
2729  if (cpp_type() == CPPTYPE_MESSAGE) {
2730  if (message_type()->is_placeholder_) {
2731  // We don't actually know if the type is a message type. It could be
2732  // an enum.
2733  proto->clear_type();
2734  }
2735 
2736  if (!message_type()->is_unqualified_placeholder_) {
2737  proto->set_type_name(".");
2738  }
2739  proto->mutable_type_name()->append(message_type()->full_name());
2740  } else if (cpp_type() == CPPTYPE_ENUM) {
2741  if (!enum_type()->is_unqualified_placeholder_) {
2742  proto->set_type_name(".");
2743  }
2744  proto->mutable_type_name()->append(enum_type()->full_name());
2745  }
2746 
2747  if (has_default_value()) {
2748  proto->set_default_value(DefaultValueAsString(false));
2749  }
2750 
2751  if (containing_oneof() != nullptr && !is_extension()) {
2752  proto->set_oneof_index(containing_oneof()->index());
2753  }
2754 
2755  if (&options() != &FieldOptions::default_instance()) {
2756  proto->mutable_options()->CopyFrom(options());
2757  }
2758 }
2759 
2761  proto->set_json_name(json_name());
2762 }
2763 
2764 void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
2765  proto->set_name(name());
2766  if (&options() != &OneofOptions::default_instance()) {
2767  proto->mutable_options()->CopyFrom(options());
2768  }
2769 }
2770 
2771 void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
2772  proto->set_name(name());
2773 
2774  for (int i = 0; i < value_count(); i++) {
2775  value(i)->CopyTo(proto->add_value());
2776  }
2777  for (int i = 0; i < reserved_range_count(); i++) {
2779  range->set_start(reserved_range(i)->start);
2780  range->set_end(reserved_range(i)->end);
2781  }
2782  for (int i = 0; i < reserved_name_count(); i++) {
2783  proto->add_reserved_name(reserved_name(i));
2784  }
2785 
2786  if (&options() != &EnumOptions::default_instance()) {
2787  proto->mutable_options()->CopyFrom(options());
2788  }
2789 }
2790 
2792  proto->set_name(name());
2793  proto->set_number(number());
2794 
2796  proto->mutable_options()->CopyFrom(options());
2797  }
2798 }
2799 
2801  proto->set_name(name());
2802 
2803  for (int i = 0; i < method_count(); i++) {
2804  method(i)->CopyTo(proto->add_method());
2805  }
2806 
2808  proto->mutable_options()->CopyFrom(options());
2809  }
2810 }
2811 
2813  proto->set_name(name());
2814 
2815  if (!input_type()->is_unqualified_placeholder_) {
2816  proto->set_input_type(".");
2817  }
2818  proto->mutable_input_type()->append(input_type()->full_name());
2819 
2820  if (!output_type()->is_unqualified_placeholder_) {
2821  proto->set_output_type(".");
2822  }
2823  proto->mutable_output_type()->append(output_type()->full_name());
2824 
2826  proto->mutable_options()->CopyFrom(options());
2827  }
2828 
2829  if (client_streaming_) {
2830  proto->set_client_streaming(true);
2831  }
2832  if (server_streaming_) {
2833  proto->set_server_streaming(true);
2834  }
2835 }
2836 
2837 // DebugString methods ===============================================
2838 
2839 namespace {
2840 
2841 bool RetrieveOptionsAssumingRightPool(
2842  int depth, const Message& options,
2843  std::vector<std::string>* option_entries) {
2844  option_entries->clear();
2845  const Reflection* reflection = options.GetReflection();
2846  std::vector<const FieldDescriptor*> fields;
2847  reflection->ListFields(options, &fields);
2848  for (const FieldDescriptor* field : fields) {
2849  int count = 1;
2850  bool repeated = false;
2851  if (field->is_repeated()) {
2852  count = reflection->FieldSize(options, field);
2853  repeated = true;
2854  }
2855  for (int j = 0; j < count; j++) {
2856  std::string fieldval;
2857  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
2858  std::string tmp;
2859  TextFormat::Printer printer;
2860  printer.SetExpandAny(true);
2861  printer.SetInitialIndentLevel(depth + 1);
2862  printer.PrintFieldValueToString(options, field, repeated ? j : -1,
2863  &tmp);
2864  fieldval.append("{\n");
2865  fieldval.append(tmp);
2866  fieldval.append(depth * 2, ' ');
2867  fieldval.append("}");
2868  } else {
2870  &fieldval);
2871  }
2872  std::string name;
2873  if (field->is_extension()) {
2874  name = "(." + field->full_name() + ")";
2875  } else {
2876  name = field->name();
2877  }
2878  option_entries->push_back(name + " = " + fieldval);
2879  }
2880  }
2881  return !option_entries->empty();
2882 }
2883 
2884 // Used by each of the option formatters.
2885 bool RetrieveOptions(int depth, const Message& options,
2886  const DescriptorPool* pool,
2887  std::vector<std::string>* option_entries) {
2888  // When printing custom options for a descriptor, we must use an options
2889  // message built on top of the same DescriptorPool where the descriptor
2890  // is coming from. This is to ensure we are interpreting custom options
2891  // against the right pool.
2892  if (options.GetDescriptor()->file()->pool() == pool) {
2893  return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
2894  } else {
2895  const Descriptor* option_descriptor =
2896  pool->FindMessageTypeByName(options.GetDescriptor()->full_name());
2897  if (option_descriptor == nullptr) {
2898  // descriptor.proto is not in the pool. This means no custom options are
2899  // used so we are safe to proceed with the compiled options message type.
2900  return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
2901  }
2902  DynamicMessageFactory factory;
2903  std::unique_ptr<Message> dynamic_options(
2904  factory.GetPrototype(option_descriptor)->New());
2905  std::string serialized = options.SerializeAsString();
2907  reinterpret_cast<const uint8_t*>(serialized.c_str()),
2908  serialized.size());
2909  input.SetExtensionRegistry(pool, &factory);
2910  if (dynamic_options->ParseFromCodedStream(&input)) {
2911  return RetrieveOptionsAssumingRightPool(depth, *dynamic_options,
2912  option_entries);
2913  } else {
2914  GOOGLE_LOG(ERROR) << "Found invalid proto option data for: "
2915  << options.GetDescriptor()->full_name();
2916  return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
2917  }
2918  }
2919 }
2920 
2921 // Formats options that all appear together in brackets. Does not include
2922 // brackets.
2923 bool FormatBracketedOptions(int depth, const Message& options,
2925  std::vector<std::string> all_options;
2926  if (RetrieveOptions(depth, options, pool, &all_options)) {
2927  output->append(Join(all_options, ", "));
2928  }
2929  return !all_options.empty();
2930 }
2931 
2932 // Formats options one per line
2933 bool FormatLineOptions(int depth, const Message& options,
2935  std::string prefix(depth * 2, ' ');
2936  std::vector<std::string> all_options;
2937  if (RetrieveOptions(depth, options, pool, &all_options)) {
2938  for (const std::string& option : all_options) {
2939  strings::SubstituteAndAppend(output, "$0option $1;\n", prefix, option);
2940  }
2941  }
2942  return !all_options.empty();
2943 }
2944 
2945 class SourceLocationCommentPrinter {
2946  public:
2947  template <typename DescType>
2948  SourceLocationCommentPrinter(const DescType* desc, const std::string& prefix,
2949  const DebugStringOptions& options)
2951  // Perform the SourceLocation lookup only if we're including user comments,
2952  // because the lookup is fairly expensive.
2954  options.include_comments && desc->GetSourceLocation(&source_loc_);
2955  }
2956  SourceLocationCommentPrinter(const FileDescriptor* file,
2957  const std::vector<int>& path,
2958  const std::string& prefix,
2959  const DebugStringOptions& options)
2961  // Perform the SourceLocation lookup only if we're including user comments,
2962  // because the lookup is fairly expensive.
2964  options.include_comments && file->GetSourceLocation(path, &source_loc_);
2965  }
2966  void AddPreComment(std::string* output) {
2967  if (have_source_loc_) {
2968  // Detached leading comments.
2969  for (const std::string& leading_detached_comment :
2970  source_loc_.leading_detached_comments) {
2971  *output += FormatComment(leading_detached_comment);
2972  *output += "\n";
2973  }
2974  // Attached leading comments.
2975  if (!source_loc_.leading_comments.empty()) {
2976  *output += FormatComment(source_loc_.leading_comments);
2977  }
2978  }
2979  }
2980  void AddPostComment(std::string* output) {
2981  if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) {
2982  *output += FormatComment(source_loc_.trailing_comments);
2983  }
2984  }
2985 
2986  // Format comment such that each line becomes a full-line C++-style comment in
2987  // the DebugString() output.
2988  std::string FormatComment(const std::string& comment_text) {
2989  std::string stripped_comment = comment_text;
2990  StripWhitespace(&stripped_comment);
2991  std::vector<std::string> lines = Split(stripped_comment, "\n");
2993  for (const std::string& line : lines) {
2995  }
2996  return output;
2997  }
2998 
2999  private:
3000 
3003  DebugStringOptions options_;
3005 };
3006 
3007 } // anonymous namespace
3008 
3010  DebugStringOptions options; // default options
3011  return DebugStringWithOptions(options);
3012 }
3013 
3015  const DebugStringOptions& debug_string_options) const {
3017  {
3018  std::vector<int> path;
3020  SourceLocationCommentPrinter syntax_comment(this, path, "",
3021  debug_string_options);
3022  syntax_comment.AddPreComment(&contents);
3023  strings::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
3024  SyntaxName(syntax()));
3025  syntax_comment.AddPostComment(&contents);
3026  }
3027 
3028  SourceLocationCommentPrinter comment_printer(this, "", debug_string_options);
3029  comment_printer.AddPreComment(&contents);
3030 
3031  std::set<int> public_dependencies;
3032  std::set<int> weak_dependencies;
3033  public_dependencies.insert(public_dependencies_,
3034  public_dependencies_ + public_dependency_count_);
3035  weak_dependencies.insert(weak_dependencies_,
3036  weak_dependencies_ + weak_dependency_count_);
3037 
3038  for (int i = 0; i < dependency_count(); i++) {
3039  if (public_dependencies.count(i) > 0) {
3040  strings::SubstituteAndAppend(&contents, "import public \"$0\";\n",
3041  dependency(i)->name());
3042  } else if (weak_dependencies.count(i) > 0) {
3043  strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n",
3044  dependency(i)->name());
3045  } else {
3046  strings::SubstituteAndAppend(&contents, "import \"$0\";\n",
3047  dependency(i)->name());
3048  }
3049  }
3050 
3051  if (!package().empty()) {
3052  std::vector<int> path;
3054  SourceLocationCommentPrinter package_comment(this, path, "",
3055  debug_string_options);
3056  package_comment.AddPreComment(&contents);
3057  strings::SubstituteAndAppend(&contents, "package $0;\n\n", package());
3058  package_comment.AddPostComment(&contents);
3059  }
3060 
3061  if (FormatLineOptions(0, options(), pool(), &contents)) {
3062  contents.append("\n"); // add some space if we had options
3063  }
3064 
3065  for (int i = 0; i < enum_type_count(); i++) {
3066  enum_type(i)->DebugString(0, &contents, debug_string_options);
3067  contents.append("\n");
3068  }
3069 
3070  // Find all the 'group' type extensions; we will not output their nested
3071  // definitions (those will be done with their group field descriptor).
3072  std::set<const Descriptor*> groups;
3073  for (int i = 0; i < extension_count(); i++) {
3075  groups.insert(extension(i)->message_type());
3076  }
3077  }
3078 
3079  for (int i = 0; i < message_type_count(); i++) {
3080  if (groups.count(message_type(i)) == 0) {
3081  message_type(i)->DebugString(0, &contents, debug_string_options,
3082  /* include_opening_clause */ true);
3083  contents.append("\n");
3084  }
3085  }
3086 
3087  for (int i = 0; i < service_count(); i++) {
3088  service(i)->DebugString(&contents, debug_string_options);
3089  contents.append("\n");
3090  }
3091 
3092  const Descriptor* containing_type = nullptr;
3093  for (int i = 0; i < extension_count(); i++) {
3094  if (extension(i)->containing_type() != containing_type) {
3095  if (i > 0) contents.append("}\n\n");
3096  containing_type = extension(i)->containing_type();
3097  strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
3098  containing_type->full_name());
3099  }
3100  extension(i)->DebugString(1, &contents, debug_string_options);
3101  }
3102  if (extension_count() > 0) contents.append("}\n\n");
3103 
3104  comment_printer.AddPostComment(&contents);
3105 
3106  return contents;
3107 }
3108 
3110  DebugStringOptions options; // default options
3111  return DebugStringWithOptions(options);
3112 }
3113 
3115  const DebugStringOptions& options) const {
3117  DebugString(0, &contents, options, /* include_opening_clause */ true);
3118  return contents;
3119 }
3120 
3122  const DebugStringOptions& debug_string_options,
3123  bool include_opening_clause) const {
3124  if (options().map_entry()) {
3125  // Do not generate debug string for auto-generated map-entry type.
3126  return;
3127  }
3128  std::string prefix(depth * 2, ' ');
3129  ++depth;
3130 
3131  SourceLocationCommentPrinter comment_printer(this, prefix,
3132  debug_string_options);
3133  comment_printer.AddPreComment(contents);
3134 
3135  if (include_opening_clause) {
3136  strings::SubstituteAndAppend(contents, "$0message $1", prefix, name());
3137  }
3138  contents->append(" {\n");
3139 
3140  FormatLineOptions(depth, options(), file()->pool(), contents);
3141 
3142  // Find all the 'group' types for fields and extensions; we will not output
3143  // their nested definitions (those will be done with their group field
3144  // descriptor).
3145  std::set<const Descriptor*> groups;
3146  for (int i = 0; i < field_count(); i++) {
3147  if (field(i)->type() == FieldDescriptor::TYPE_GROUP) {
3148  groups.insert(field(i)->message_type());
3149  }
3150  }
3151  for (int i = 0; i < extension_count(); i++) {
3153  groups.insert(extension(i)->message_type());
3154  }
3155  }
3156 
3157  for (int i = 0; i < nested_type_count(); i++) {
3158  if (groups.count(nested_type(i)) == 0) {
3159  nested_type(i)->DebugString(depth, contents, debug_string_options,
3160  /* include_opening_clause */ true);
3161  }
3162  }
3163  for (int i = 0; i < enum_type_count(); i++) {
3164  enum_type(i)->DebugString(depth, contents, debug_string_options);
3165  }
3166  for (int i = 0; i < field_count(); i++) {
3167  if (field(i)->real_containing_oneof() == nullptr) {
3168  field(i)->DebugString(depth, contents, debug_string_options);
3169  } else if (field(i)->containing_oneof()->field(0) == field(i)) {
3170  // This is the first field in this oneof, so print the whole oneof.
3171  field(i)->containing_oneof()->DebugString(depth, contents,
3172  debug_string_options);
3173  }
3174  }
3175 
3176  for (int i = 0; i < extension_range_count(); i++) {
3177  strings::SubstituteAndAppend(contents, "$0 extensions $1 to $2;\n", prefix,
3178  extension_range(i)->start,
3179  extension_range(i)->end - 1);
3180  }
3181 
3182  // Group extensions by what they extend, so they can be printed out together.
3183  const Descriptor* containing_type = nullptr;
3184  for (int i = 0; i < extension_count(); i++) {
3185  if (extension(i)->containing_type() != containing_type) {
3186  if (i > 0) strings::SubstituteAndAppend(contents, "$0 }\n", prefix);
3187  containing_type = extension(i)->containing_type();
3188  strings::SubstituteAndAppend(contents, "$0 extend .$1 {\n", prefix,
3189  containing_type->full_name());
3190  }
3191  extension(i)->DebugString(depth + 1, contents, debug_string_options);
3192  }
3193  if (extension_count() > 0)
3195 
3196  if (reserved_range_count() > 0) {
3197  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
3198  for (int i = 0; i < reserved_range_count(); i++) {
3199  const Descriptor::ReservedRange* range = reserved_range(i);
3200  if (range->end == range->start + 1) {
3201  strings::SubstituteAndAppend(contents, "$0, ", range->start);
3202  } else if (range->end > FieldDescriptor::kMaxNumber) {
3203  strings::SubstituteAndAppend(contents, "$0 to max, ", range->start);
3204  } else {
3205  strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start,
3206  range->end - 1);
3207  }
3208  }
3209  contents->replace(contents->size() - 2, 2, ";\n");
3210  }
3211 
3212  if (reserved_name_count() > 0) {
3213  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
3214  for (int i = 0; i < reserved_name_count(); i++) {
3216  CEscape(reserved_name(i)));
3217  }
3218  contents->replace(contents->size() - 2, 2, ";\n");
3219  }
3220 
3222  comment_printer.AddPostComment(contents);
3223 }
3224 
3226  DebugStringOptions options; // default options
3227  return DebugStringWithOptions(options);
3228 }
3229 
3231  const DebugStringOptions& debug_string_options) const {
3233  int depth = 0;
3234  if (is_extension()) {
3235  strings::SubstituteAndAppend(&contents, "extend .$0 {\n",
3236  containing_type()->full_name());
3237  depth = 1;
3238  }
3239  DebugString(depth, &contents, debug_string_options);
3240  if (is_extension()) {
3241  contents.append("}\n");
3242  }
3243  return contents;
3244 }
3245 
3246 // The field type string used in FieldDescriptor::DebugString()
3248  switch (type()) {
3249  case TYPE_MESSAGE:
3250  return "." + message_type()->full_name();
3251  case TYPE_ENUM:
3252  return "." + enum_type()->full_name();
3253  default:
3254  return kTypeToName[type()];
3255  }
3256 }
3257 
3259  int depth, std::string* contents,
3260  const DebugStringOptions& debug_string_options) const {
3261  std::string prefix(depth * 2, ' ');
3263 
3264  // Special case map fields.
3265  if (is_map()) {
3267  &field_type, "map<$0, $1>",
3268  message_type()->field(0)->FieldTypeNameDebugString(),
3269  message_type()->field(1)->FieldTypeNameDebugString());
3270  } else {
3271  field_type = FieldTypeNameDebugString();
3272  }
3273 
3274  std::string label = StrCat(kLabelToName[this->label()], " ");
3275 
3276  // Label is omitted for maps, oneof, and plain proto3 fields.
3277  if (is_map() || real_containing_oneof() ||
3278  (is_optional() && !has_optional_keyword())) {
3279  label.clear();
3280  }
3281 
3282  SourceLocationCommentPrinter comment_printer(this, prefix,
3283  debug_string_options);
3284  comment_printer.AddPreComment(contents);
3285 
3287  contents, "$0$1$2 $3 = $4", prefix, label, field_type,
3288  type() == TYPE_GROUP ? message_type()->name() : name(), number());
3289 
3290  bool bracketed = false;
3291  if (has_default_value()) {
3292  bracketed = true;
3293  strings::SubstituteAndAppend(contents, " [default = $0",
3294  DefaultValueAsString(true));
3295  }
3296  if (has_json_name_) {
3297  if (!bracketed) {
3298  bracketed = true;
3299  contents->append(" [");
3300  } else {
3301  contents->append(", ");
3302  }
3303  contents->append("json_name = \"");
3304  contents->append(CEscape(json_name()));
3305  contents->append("\"");
3306  }
3307 
3308  std::string formatted_options;
3309  if (FormatBracketedOptions(depth, options(), file()->pool(),
3310  &formatted_options)) {
3311  contents->append(bracketed ? ", " : " [");
3312  bracketed = true;
3313  contents->append(formatted_options);
3314  }
3315 
3316  if (bracketed) {
3317  contents->append("]");
3318  }
3319 
3320  if (type() == TYPE_GROUP) {
3321  if (debug_string_options.elide_group_body) {
3322  contents->append(" { ... };\n");
3323  } else {
3324  message_type()->DebugString(depth, contents, debug_string_options,
3325  /* include_opening_clause */ false);
3326  }
3327  } else {
3328  contents->append(";\n");
3329  }
3330 
3331  comment_printer.AddPostComment(contents);
3332 }
3333 
3335  DebugStringOptions options; // default values
3336  return DebugStringWithOptions(options);
3337 }
3338 
3340  const DebugStringOptions& options) const {
3343  return contents;
3344 }
3345 
3347  int depth, std::string* contents,
3348  const DebugStringOptions& debug_string_options) const {
3349  std::string prefix(depth * 2, ' ');
3350  ++depth;
3351  SourceLocationCommentPrinter comment_printer(this, prefix,
3352  debug_string_options);
3353  comment_printer.AddPreComment(contents);
3354  strings::SubstituteAndAppend(contents, "$0oneof $1 {", prefix, name());
3355 
3356  FormatLineOptions(depth, options(), containing_type()->file()->pool(),
3357  contents);
3358 
3359  if (debug_string_options.elide_oneof_body) {
3360  contents->append(" ... }\n");
3361  } else {
3362  contents->append("\n");
3363  for (int i = 0; i < field_count(); i++) {
3364  field(i)->DebugString(depth, contents, debug_string_options);
3365  }
3367  }
3368  comment_printer.AddPostComment(contents);
3369 }
3370 
3372  DebugStringOptions options; // default values
3373  return DebugStringWithOptions(options);
3374 }
3375 
3377  const DebugStringOptions& options) const {
3380  return contents;
3381 }
3382 
3384  int depth, std::string* contents,
3385  const DebugStringOptions& debug_string_options) const {
3386  std::string prefix(depth * 2, ' ');
3387  ++depth;
3388 
3389  SourceLocationCommentPrinter comment_printer(this, prefix,
3390  debug_string_options);
3391  comment_printer.AddPreComment(contents);
3392 
3393  strings::SubstituteAndAppend(contents, "$0enum $1 {\n", prefix, name());
3394 
3395  FormatLineOptions(depth, options(), file()->pool(), contents);
3396 
3397  for (int i = 0; i < value_count(); i++) {
3398  value(i)->DebugString(depth, contents, debug_string_options);
3399  }
3400 
3401  if (reserved_range_count() > 0) {
3402  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
3403  for (int i = 0; i < reserved_range_count(); i++) {
3404  const EnumDescriptor::ReservedRange* range = reserved_range(i);
3405  if (range->end == range->start) {
3406  strings::SubstituteAndAppend(contents, "$0, ", range->start);
3407  } else if (range->end == INT_MAX) {
3408  strings::SubstituteAndAppend(contents, "$0 to max, ", range->start);
3409  } else {
3410  strings::SubstituteAndAppend(contents, "$0 to $1, ", range->start,
3411  range->end);
3412  }
3413  }
3414  contents->replace(contents->size() - 2, 2, ";\n");
3415  }
3416 
3417  if (reserved_name_count() > 0) {
3418  strings::SubstituteAndAppend(contents, "$0 reserved ", prefix);
3419  for (int i = 0; i < reserved_name_count(); i++) {
3421  CEscape(reserved_name(i)));
3422  }
3423  contents->replace(contents->size() - 2, 2, ";\n");
3424  }
3425 
3427 
3428  comment_printer.AddPostComment(contents);
3429 }
3430 
3432  DebugStringOptions options; // default values
3433  return DebugStringWithOptions(options);
3434 }
3435 
3437  const DebugStringOptions& options) const {
3440  return contents;
3441 }
3442 
3444  int depth, std::string* contents,
3445  const DebugStringOptions& debug_string_options) const {
3446  std::string prefix(depth * 2, ' ');
3447 
3448  SourceLocationCommentPrinter comment_printer(this, prefix,
3449  debug_string_options);
3450  comment_printer.AddPreComment(contents);
3451 
3453 
3454  std::string formatted_options;
3455  if (FormatBracketedOptions(depth, options(), type()->file()->pool(),
3456  &formatted_options)) {
3457  strings::SubstituteAndAppend(contents, " [$0]", formatted_options);
3458  }
3459  contents->append(";\n");
3460 
3461  comment_printer.AddPostComment(contents);
3462 }
3463 
3465  DebugStringOptions options; // default values
3466  return DebugStringWithOptions(options);
3467 }
3468 
3470  const DebugStringOptions& options) const {
3473  return contents;
3474 }
3475 
3478  const DebugStringOptions& debug_string_options) const {
3479  SourceLocationCommentPrinter comment_printer(this, /* prefix */ "",
3480  debug_string_options);
3481  comment_printer.AddPreComment(contents);
3482 
3483  strings::SubstituteAndAppend(contents, "service $0 {\n", name());
3484 
3485  FormatLineOptions(1, options(), file()->pool(), contents);
3486 
3487  for (int i = 0; i < method_count(); i++) {
3488  method(i)->DebugString(1, contents, debug_string_options);
3489  }
3490 
3491  contents->append("}\n");
3492 
3493  comment_printer.AddPostComment(contents);
3494 }
3495 
3497  DebugStringOptions options; // default values
3498  return DebugStringWithOptions(options);
3499 }
3500 
3502  const DebugStringOptions& options) const {
3505  return contents;
3506 }
3507 
3509  int depth, std::string* contents,
3510  const DebugStringOptions& debug_string_options) const {
3511  std::string prefix(depth * 2, ' ');
3512  ++depth;
3513 
3514  SourceLocationCommentPrinter comment_printer(this, prefix,
3515  debug_string_options);
3516  comment_printer.AddPreComment(contents);
3517 
3519  contents, "$0rpc $1($4.$2) returns ($5.$3)", prefix, name(),
3520  input_type()->full_name(), output_type()->full_name(),
3521  client_streaming() ? "stream " : "", server_streaming() ? "stream " : "");
3522 
3523  std::string formatted_options;
3524  if (FormatLineOptions(depth, options(), service()->file()->pool(),
3525  &formatted_options)) {
3526  strings::SubstituteAndAppend(contents, " {\n$0$1}\n", formatted_options,
3527  prefix);
3528  } else {
3529  contents->append(";\n");
3530  }
3531 
3532  comment_printer.AddPostComment(contents);
3533 }
3534 
3535 
3536 // Location methods ===============================================
3537 
3538 bool FileDescriptor::GetSourceLocation(const std::vector<int>& path,
3539  SourceLocation* out_location) const {
3540  GOOGLE_CHECK(out_location != nullptr);
3541  if (source_code_info_) {
3542  if (const SourceCodeInfo_Location* loc =
3543  tables_->GetSourceLocation(path, source_code_info_)) {
3544  const RepeatedField<int32_t>& span = loc->span();
3545  if (span.size() == 3 || span.size() == 4) {
3546  out_location->start_line = span.Get(0);
3547  out_location->start_column = span.Get(1);
3548  out_location->end_line = span.Get(span.size() == 3 ? 0 : 2);
3549  out_location->end_column = span.Get(span.size() - 1);
3550 
3551  out_location->leading_comments = loc->leading_comments();
3552  out_location->trailing_comments = loc->trailing_comments();
3553  out_location->leading_detached_comments.assign(
3554  loc->leading_detached_comments().begin(),
3555  loc->leading_detached_comments().end());
3556  return true;
3557  }
3558  }
3559  }
3560  return false;
3561 }
3562 
3563 bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3564  std::vector<int> path; // empty path for root FileDescriptor
3565  return GetSourceLocation(path, out_location);
3566 }
3567 
3568 bool FieldDescriptor::is_packed() const {
3569  if (!is_packable()) return false;
3571  return (options_ != nullptr) && options_->packed();
3572  } else {
3573  return options_ == nullptr || !options_->has_packed() || options_->packed();
3574  }
3575 }
3576 
3577 bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
3578  std::vector<int> path;
3579  GetLocationPath(&path);
3580  return file()->GetSourceLocation(path, out_location);
3581 }
3582 
3583 bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3584  std::vector<int> path;
3585  GetLocationPath(&path);
3586  return file()->GetSourceLocation(path, out_location);
3587 }
3588 
3589 bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3590  std::vector<int> path;
3591  GetLocationPath(&path);
3592  return containing_type()->file()->GetSourceLocation(path, out_location);
3593 }
3594 
3595 bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3596  std::vector<int> path;
3597  GetLocationPath(&path);
3598  return file()->GetSourceLocation(path, out_location);
3599 }
3600 
3601 bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3602  std::vector<int> path;
3603  GetLocationPath(&path);
3604  return service()->file()->GetSourceLocation(path, out_location);
3605 }
3606 
3607 bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3608  std::vector<int> path;
3609  GetLocationPath(&path);
3610  return file()->GetSourceLocation(path, out_location);
3611 }
3612 
3614  SourceLocation* out_location) const {
3615  std::vector<int> path;
3616  GetLocationPath(&path);
3617  return type()->file()->GetSourceLocation(path, out_location);
3618 }
3619 
3620 void Descriptor::GetLocationPath(std::vector<int>* output) const {
3621  if (containing_type()) {
3622  containing_type()->GetLocationPath(output);
3624  output->push_back(index());
3625  } else {
3627  output->push_back(index());
3628  }
3629 }
3630 
3631 void FieldDescriptor::GetLocationPath(std::vector<int>* output) const {
3632  if (is_extension()) {
3633  if (extension_scope() == nullptr) {
3635  output->push_back(index());
3636  } else {
3637  extension_scope()->GetLocationPath(output);
3639  output->push_back(index());
3640  }
3641  } else {
3642  containing_type()->GetLocationPath(output);
3644  output->push_back(index());
3645  }
3646 }
3647 
3648 void OneofDescriptor::GetLocationPath(std::vector<int>* output) const {
3649  containing_type()->GetLocationPath(output);
3651  output->push_back(index());
3652 }
3653 
3654 void EnumDescriptor::GetLocationPath(std::vector<int>* output) const {
3655  if (containing_type()) {
3656  containing_type()->GetLocationPath(output);
3658  output->push_back(index());
3659  } else {
3661  output->push_back(index());
3662  }
3663 }
3664 
3665 void EnumValueDescriptor::GetLocationPath(std::vector<int>* output) const {
3666  type()->GetLocationPath(output);
3668  output->push_back(index());
3669 }
3670 
3671 void ServiceDescriptor::GetLocationPath(std::vector<int>* output) const {
3673  output->push_back(index());
3674 }
3675 
3676 void MethodDescriptor::GetLocationPath(std::vector<int>* output) const {
3677  service()->GetLocationPath(output);
3679  output->push_back(index());
3680 }
3681 
3682 // ===================================================================
3683 
3684 namespace {
3685 
3686 // Represents an options message to interpret. Extension names in the option
3687 // name are resolved relative to name_scope. element_name and orig_opt are
3688 // used only for error reporting (since the parser records locations against
3689 // pointers in the original options, not the mutable copy). The Message must be
3690 // one of the Options messages in descriptor.proto.
3691 struct OptionsToInterpret {
3692  OptionsToInterpret(const std::string& ns, const std::string& el,
3693  const std::vector<int>& path, const Message* orig_opt,
3694  Message* opt)
3695  : name_scope(ns),
3696  element_name(el),
3697  element_path(path),
3698  original_options(orig_opt),
3699  options(opt) {}
3702  std::vector<int> element_path;
3705 };
3706 
3707 } // namespace
3708 
3709 class DescriptorBuilder {
3710  public:
3711  DescriptorBuilder(const DescriptorPool* pool, DescriptorPool::Tables* tables,
3712  DescriptorPool::ErrorCollector* error_collector);
3713  ~DescriptorBuilder();
3714 
3715  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
3716 
3717  private:
3718  friend class OptionInterpreter;
3719 
3720  // Non-recursive part of BuildFile functionality.
3721  FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto);
3722 
3723  const DescriptorPool* pool_;
3724  DescriptorPool::Tables* tables_; // for convenience
3725  DescriptorPool::ErrorCollector* error_collector_;
3726 
3727  // As we build descriptors we store copies of the options messages in
3728  // them. We put pointers to those copies in this vector, as we build, so we
3729  // can later (after cross-linking) interpret those options.
3730  std::vector<OptionsToInterpret> options_to_interpret_;
3731 
3732  bool had_errors_;
3733  std::string filename_;
3735  FileDescriptorTables* file_tables_;
3736  std::set<const FileDescriptor*> dependencies_;
3737 
3738  // unused_dependency_ is used to record the unused imported files.
3739  // Note: public import is not considered.
3740  std::set<const FileDescriptor*> unused_dependency_;
3741 
3742  // If LookupSymbol() finds a symbol that is in a file which is not a declared
3743  // dependency of this file, it will fail, but will set
3744  // possible_undeclared_dependency_ to point at that file. This is only used
3745  // by AddNotDefinedError() to report a more useful error message.
3746  // possible_undeclared_dependency_name_ is the name of the symbol that was
3747  // actually found in possible_undeclared_dependency_, which may be a parent
3748  // of the symbol actually looked for.
3749  const FileDescriptor* possible_undeclared_dependency_;
3750  std::string possible_undeclared_dependency_name_;
3751 
3752  // If LookupSymbol() could resolve a symbol which is not defined,
3753  // record the resolved name. This is only used by AddNotDefinedError()
3754  // to report a more useful error message.
3755  std::string undefine_resolved_name_;
3756 
3757  void AddError(const std::string& element_name, const Message& descriptor,
3759  const std::string& error);
3760  void AddError(const std::string& element_name, const Message& descriptor,
3762  const char* error);
3763  void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
3764  void AddTwiceListedError(const FileDescriptorProto& proto, int index);
3765  void AddImportError(const FileDescriptorProto& proto, int index);
3766 
3767  // Adds an error indicating that undefined_symbol was not defined. Must
3768  // only be called after LookupSymbol() fails.
3769  void AddNotDefinedError(
3770  const std::string& element_name, const Message& descriptor,
3772  const std::string& undefined_symbol);
3773 
3774  void AddWarning(const std::string& element_name, const Message& descriptor,
3776  const std::string& error);
3777 
3778  // Silly helper which determines if the given file is in the given package.
3779  // I.e., either file->package() == package_name or file->package() is a
3780  // nested package within package_name.
3781  bool IsInPackage(const FileDescriptor* file, const std::string& package_name);
3782 
3783  // Helper function which finds all public dependencies of the given file, and
3784  // stores the them in the dependencies_ set in the builder.
3785  void RecordPublicDependencies(const FileDescriptor* file);
3786 
3787  // Like tables_->FindSymbol(), but additionally:
3788  // - Search the pool's underlay if not found in tables_.
3789  // - Insure that the resulting Symbol is from one of the file's declared
3790  // dependencies.
3791  Symbol FindSymbol(const std::string& name, bool build_it = true);
3792 
3793  // Like FindSymbol() but does not require that the symbol is in one of the
3794  // file's declared dependencies.
3795  Symbol FindSymbolNotEnforcingDeps(const std::string& name,
3796  bool build_it = true);
3797 
3798  // This implements the body of FindSymbolNotEnforcingDeps().
3799  Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
3800  const std::string& name,
3801  bool build_it = true);
3802 
3803  // Like FindSymbol(), but looks up the name relative to some other symbol
3804  // name. This first searches siblings of relative_to, then siblings of its
3805  // parents, etc. For example, LookupSymbol("foo.bar", "baz.qux.corge") makes
3806  // the following calls, returning the first non-null result:
3807  // FindSymbol("baz.qux.foo.bar"), FindSymbol("baz.foo.bar"),
3808  // FindSymbol("foo.bar"). If AllowUnknownDependencies() has been called
3809  // on the DescriptorPool, this will generate a placeholder type if
3810  // the name is not found (unless the name itself is malformed). The
3811  // placeholder_type parameter indicates what kind of placeholder should be
3812  // constructed in this case. The resolve_mode parameter determines whether
3813  // any symbol is returned, or only symbols that are types. Note, however,
3814  // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
3815  // if it believes that's all it could refer to. The caller should always
3816  // check that it receives the type of symbol it was expecting.
3817  enum ResolveMode { LOOKUP_ALL, LOOKUP_TYPES };
3818  Symbol LookupSymbol(const std::string& name, const std::string& relative_to,
3819  DescriptorPool::PlaceholderType placeholder_type =
3821  ResolveMode resolve_mode = LOOKUP_ALL,
3822  bool build_it = true);
3823 
3824  // Like LookupSymbol() but will not return a placeholder even if
3825  // AllowUnknownDependencies() has been used.
3826  Symbol LookupSymbolNoPlaceholder(const std::string& name,
3827  const std::string& relative_to,
3828  ResolveMode resolve_mode = LOOKUP_ALL,
3829  bool build_it = true);
3830 
3831  // Calls tables_->AddSymbol() and records an error if it fails. Returns
3832  // true if successful or false if failed, though most callers can ignore
3833  // the return value since an error has already been recorded.
3834  bool AddSymbol(const std::string& full_name, const void* parent,
3835  const std::string& name, const Message& proto, Symbol symbol);
3836 
3837  // Like AddSymbol(), but succeeds if the symbol is already defined as long
3838  // as the existing definition is also a package (because it's OK to define
3839  // the same package in two different files). Also adds all parents of the
3840  // package to the symbol table (e.g. AddPackage("foo.bar", ...) will add
3841  // "foo.bar" and "foo" to the table).
3842  void AddPackage(const std::string& name, const Message& proto,
3843  FileDescriptor* file);
3844 
3845  // Checks that the symbol name contains only alphanumeric characters and
3846  // underscores. Records an error otherwise.
3847  void ValidateSymbolName(const std::string& name, const std::string& full_name,
3848  const Message& proto);
3849 
3850  // Used by BUILD_ARRAY macro (below) to avoid having to have the type
3851  // specified as a macro parameter.
3852  template <typename Type>
3853  inline void AllocateArray(int size, Type** output) {
3854  *output = tables_->AllocateArray<Type>(size);
3855  }
3856 
3857  // Allocates a copy of orig_options in tables_ and stores it in the
3858  // descriptor. Remembers its uninterpreted options, to be interpreted
3859  // later. DescriptorT must be one of the Descriptor messages from
3860  // descriptor.proto.
3861  template <class DescriptorT>
3862  void AllocateOptions(const typename DescriptorT::OptionsType& orig_options,
3863  DescriptorT* descriptor, int options_field_tag,
3864  const std::string& option_name);
3865  // Specialization for FileOptions.
3866  void AllocateOptions(const FileOptions& orig_options,
3868 
3869  // Implementation for AllocateOptions(). Don't call this directly.
3870  template <class DescriptorT>
3871  void AllocateOptionsImpl(
3873  const typename DescriptorT::OptionsType& orig_options,
3874  DescriptorT* descriptor, const std::vector<int>& options_path,
3875  const std::string& option_name);
3876 
3877  // Allocates an array of two strings, the first one is a copy of `proto_name`,
3878  // and the second one is the full name.
3879  // Full proto name is "scope.proto_name" if scope is non-empty and
3880  // "proto_name" otherwise.
3881  const std::string* AllocateNameStrings(const std::string& scope,
3882  const std::string& proto_name);
3883 
3884  // These methods all have the same signature for the sake of the BUILD_ARRAY
3885  // macro, below.
3886  void BuildMessage(const DescriptorProto& proto, const Descriptor* parent,
3887  Descriptor* result);
3888  void BuildFieldOrExtension(const FieldDescriptorProto& proto,
3889  Descriptor* parent, FieldDescriptor* result,
3890  bool is_extension);
3891  void BuildField(const FieldDescriptorProto& proto, Descriptor* parent,
3893  BuildFieldOrExtension(proto, parent, result, false);
3894  }
3895  void BuildExtension(const FieldDescriptorProto& proto, Descriptor* parent,
3897  BuildFieldOrExtension(proto, parent, result, true);
3898  }
3899  void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
3900  const Descriptor* parent,
3901  Descriptor::ExtensionRange* result);
3902  void BuildReservedRange(const DescriptorProto::ReservedRange& proto,
3903  const Descriptor* parent,
3904  Descriptor::ReservedRange* result);
3905  void BuildReservedRange(const EnumDescriptorProto::EnumReservedRange& proto,
3906  const EnumDescriptor* parent,
3907  EnumDescriptor::ReservedRange* result);
3908  void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent,
3910  void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
3911  const EnumDescriptor* result);
3912  void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent,
3914  void BuildEnumValue(const EnumValueDescriptorProto& proto,
3915  const EnumDescriptor* parent,
3917  void BuildService(const ServiceDescriptorProto& proto, const void* dummy,
3919  void BuildMethod(const MethodDescriptorProto& proto,
3920  const ServiceDescriptor* parent, MethodDescriptor* result);
3921 
3922  void LogUnusedDependency(const FileDescriptorProto& proto,
3923  const FileDescriptor* result);
3924 
3925  // Must be run only after building.
3926  //
3927  // NOTE: Options will not be available during cross-linking, as they
3928  // have not yet been interpreted. Defer any handling of options to the
3929  // Validate*Options methods.
3930  void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
3931  void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
3932  void CrossLinkField(FieldDescriptor* field,
3933  const FieldDescriptorProto& proto);
3934  void CrossLinkExtensionRange(Descriptor::ExtensionRange* range,
3935  const DescriptorProto::ExtensionRange& proto);
3936  void CrossLinkEnum(EnumDescriptor* enum_type,
3937  const EnumDescriptorProto& proto);
3938  void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
3939  const EnumValueDescriptorProto& proto);
3940  void CrossLinkService(ServiceDescriptor* service,
3941  const ServiceDescriptorProto& proto);
3942  void CrossLinkMethod(MethodDescriptor* method,
3943  const MethodDescriptorProto& proto);
3944 
3945  // Must be run only after cross-linking.
3946  void InterpretOptions();
3947 
3948  // A helper class for interpreting options.
3949  class OptionInterpreter {
3950  public:
3951  // Creates an interpreter that operates in the context of the pool of the
3952  // specified builder, which must not be nullptr. We don't take ownership of
3953  // the builder.
3954  explicit OptionInterpreter(DescriptorBuilder* builder);
3955 
3956  ~OptionInterpreter();
3957 
3958  // Interprets the uninterpreted options in the specified Options message.
3959  // On error, calls AddError() on the underlying builder and returns false.
3960  // Otherwise returns true.
3961  bool InterpretOptions(OptionsToInterpret* options_to_interpret);
3962 
3963  // Updates the given source code info by re-writing uninterpreted option
3964  // locations to refer to the corresponding interpreted option.
3965  void UpdateSourceCodeInfo(SourceCodeInfo* info);
3966 
3967  class AggregateOptionFinder;
3968 
3969  private:
3970  // Interprets uninterpreted_option_ on the specified message, which
3971  // must be the mutable copy of the original options message to which
3972  // uninterpreted_option_ belongs. The given src_path is the source
3973  // location path to the uninterpreted option, and options_path is the
3974  // source location path to the options message. The location paths are
3975  // recorded and then used in UpdateSourceCodeInfo.
3976  bool InterpretSingleOption(Message* options,
3977  const std::vector<int>& src_path,
3978  const std::vector<int>& options_path);
3979 
3980  // Adds the uninterpreted_option to the given options message verbatim.
3981  // Used when AllowUnknownDependencies() is in effect and we can't find
3982  // the option's definition.
3983  void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
3984  Message* options);
3985 
3986  // A recursive helper function that drills into the intermediate fields
3987  // in unknown_fields to check if field innermost_field is set on the
3988  // innermost message. Returns false and sets an error if so.
3989  bool ExamineIfOptionIsSet(
3990  std::vector<const FieldDescriptor*>::const_iterator
3991  intermediate_fields_iter,
3992  std::vector<const FieldDescriptor*>::const_iterator
3993  intermediate_fields_end,
3994  const FieldDescriptor* innermost_field,
3995  const std::string& debug_msg_name,
3996  const UnknownFieldSet& unknown_fields);
3997 
3998  // Validates the value for the option field of the currently interpreted
3999  // option and then sets it on the unknown_field.
4000  bool SetOptionValue(const FieldDescriptor* option_field,
4001  UnknownFieldSet* unknown_fields);
4002 
4003  // Parses an aggregate value for a CPPTYPE_MESSAGE option and
4004  // saves it into *unknown_fields.
4005  bool SetAggregateOption(const FieldDescriptor* option_field,
4006  UnknownFieldSet* unknown_fields);
4007 
4008  // Convenience functions to set an int field the right way, depending on
4009  // its wire type (a single int CppType can represent multiple wire types).
4010  void SetInt32(int number, int32_t value, FieldDescriptor::Type type,
4011  UnknownFieldSet* unknown_fields);
4012  void SetInt64(int number, int64_t value, FieldDescriptor::Type type,
4013  UnknownFieldSet* unknown_fields);
4014  void SetUInt32(int number, uint32_t value, FieldDescriptor::Type type,
4015  UnknownFieldSet* unknown_fields);
4016  void SetUInt64(int number, uint64_t value, FieldDescriptor::Type type,
4017  UnknownFieldSet* unknown_fields);
4018 
4019  // A helper function that adds an error at the specified location of the
4020  // option we're currently interpreting, and returns false.
4022  const std::string& msg) {
4023  builder_->AddError(options_to_interpret_->element_name,
4024  *uninterpreted_option_, location, msg);
4025  return false;
4026  }
4027 
4028  // A helper function that adds an error at the location of the option name
4029  // and returns false.
4031 #ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4032  return true;
4033 #else // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4034  return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg);
4035 #endif // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4036  }
4037 
4038  // A helper function that adds an error at the location of the option name
4039  // and returns false.
4041  return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg);
4042  }
4043 
4044  // We interpret against this builder's pool. Is never nullptr. We don't own
4045  // this pointer.
4046  DescriptorBuilder* builder_;
4047 
4048  // The options we're currently interpreting, or nullptr if we're not in a
4049  // call to InterpretOptions.
4050  const OptionsToInterpret* options_to_interpret_;
4051 
4052  // The option we're currently interpreting within options_to_interpret_, or
4053  // nullptr if we're not in a call to InterpretOptions(). This points to a
4054  // submessage of the original option, not the mutable copy. Therefore we
4055  // can use it to find locations recorded by the parser.
4056  const UninterpretedOption* uninterpreted_option_;
4057 
4058  // This maps the element path of uninterpreted options to the element path
4059  // of the resulting interpreted option. This is used to modify a file's
4060  // source code info to account for option interpretation.
4061  std::map<std::vector<int>, std::vector<int>> interpreted_paths_;
4062 
4063  // This maps the path to a repeated option field to the known number of
4064  // elements the field contains. This is used to track the compute the
4065  // index portion of the element path when interpreting a single option.
4066  std::map<std::vector<int>, int> repeated_option_counts_;
4067 
4068  // Factory used to create the dynamic messages we need to parse
4069  // any aggregate option values we encounter.
4070  DynamicMessageFactory dynamic_factory_;
4071 
4073  };
4074 
4075  // Work-around for broken compilers: According to the C++ standard,
4076  // OptionInterpreter should have access to the private members of any class
4077  // which has declared DescriptorBuilder as a friend. Unfortunately some old
4078  // versions of GCC and other compilers do not implement this correctly. So,
4079  // we have to have these intermediate methods to provide access. We also
4080  // redundantly declare OptionInterpreter a friend just to make things extra
4081  // clear for these bad compilers.
4082  friend class OptionInterpreter;
4083  friend class OptionInterpreter::AggregateOptionFinder;
4084 
4085  static inline bool get_allow_unknown(const DescriptorPool* pool) {
4086  return pool->allow_unknown_;
4087  }
4088  static inline bool get_enforce_weak(const DescriptorPool* pool) {
4089  return pool->enforce_weak_;
4090  }
4091  static inline bool get_is_placeholder(const Descriptor* descriptor) {
4092  return descriptor != nullptr && descriptor->is_placeholder_;
4093  }
4094  static inline void assert_mutex_held(const DescriptorPool* pool) {
4095  if (pool->mutex_ != nullptr) {
4096  pool->mutex_->AssertHeld();
4097  }
4098  }
4099 
4100  // Must be run only after options have been interpreted.
4101  //
4102  // NOTE: Validation code must only reference the options in the mutable
4103  // descriptors, which are the ones that have been interpreted. The const
4104  // proto references are passed in only so they can be provided to calls to
4105  // AddError(). Do not look at their options, which have not been interpreted.
4106  void ValidateFileOptions(FileDescriptor* file,
4107  const FileDescriptorProto& proto);
4108  void ValidateMessageOptions(Descriptor* message,
4109  const DescriptorProto& proto);
4110  void ValidateFieldOptions(FieldDescriptor* field,
4111  const FieldDescriptorProto& proto);
4112  void ValidateEnumOptions(EnumDescriptor* enm,
4113  const EnumDescriptorProto& proto);
4114  void ValidateEnumValueOptions(EnumValueDescriptor* enum_value,
4115  const EnumValueDescriptorProto& proto);
4116  void ValidateExtensionRangeOptions(
4117  const std::string& full_name, Descriptor::ExtensionRange* extension_range,
4118  const DescriptorProto_ExtensionRange& proto);
4119  void ValidateServiceOptions(ServiceDescriptor* service,
4120  const ServiceDescriptorProto& proto);
4121  void ValidateMethodOptions(MethodDescriptor* method,
4122  const MethodDescriptorProto& proto);
4123  void ValidateProto3(FileDescriptor* file, const FileDescriptorProto& proto);
4124  void ValidateProto3Message(Descriptor* message, const DescriptorProto& proto);
4125  void ValidateProto3Field(FieldDescriptor* field,
4126  const FieldDescriptorProto& proto);
4127  void ValidateProto3Enum(EnumDescriptor* enm,
4128  const EnumDescriptorProto& proto);
4129 
4130  // Returns true if the map entry message is compatible with the
4131  // auto-generated entry message from map fields syntax.
4132  bool ValidateMapEntry(FieldDescriptor* field,
4133  const FieldDescriptorProto& proto);
4134 
4135  // Recursively detects naming conflicts with map entry types for a
4136  // better error message.
4137  void DetectMapConflicts(const Descriptor* message,
4138  const DescriptorProto& proto);
4139 
4140  void ValidateJSType(FieldDescriptor* field,
4141  const FieldDescriptorProto& proto);
4142 };
4143 
4145  const FileDescriptorProto& proto) {
4146  GOOGLE_CHECK(fallback_database_ == nullptr)
4147  << "Cannot call BuildFile on a DescriptorPool that uses a "
4148  "DescriptorDatabase. You must instead find a way to get your file "
4149  "into the underlying database.";
4150  GOOGLE_CHECK(mutex_ == nullptr); // Implied by the above GOOGLE_CHECK.
4151  tables_->known_bad_symbols_.clear();
4152  tables_->known_bad_files_.clear();
4153  return DescriptorBuilder(this, tables_.get(), nullptr).BuildFile(proto);
4154 }
4155 
4157  const FileDescriptorProto& proto, ErrorCollector* error_collector) {
4158  GOOGLE_CHECK(fallback_database_ == nullptr)
4159  << "Cannot call BuildFile on a DescriptorPool that uses a "
4160  "DescriptorDatabase. You must instead find a way to get your file "
4161  "into the underlying database.";
4162  GOOGLE_CHECK(mutex_ == nullptr); // Implied by the above GOOGLE_CHECK.
4163  tables_->known_bad_symbols_.clear();
4164  tables_->known_bad_files_.clear();
4165  return DescriptorBuilder(this, tables_.get(), error_collector)
4166  .BuildFile(proto);
4167 }
4168 
4170  const FileDescriptorProto& proto) const {
4171  mutex_->AssertHeld();
4172  if (tables_->known_bad_files_.count(proto.name()) > 0) {
4173  return nullptr;
4174  }
4175  const FileDescriptor* result =
4177  .BuildFile(proto);
4178  if (result == nullptr) {
4179  tables_->known_bad_files_.insert(proto.name());
4180  }
4181  return result;
4182 }
4183 
4185  const DescriptorPool* pool, DescriptorPool::Tables* tables,
4186  DescriptorPool::ErrorCollector* error_collector)
4187  : pool_(pool),
4188  tables_(tables),
4189  error_collector_(error_collector),
4190  had_errors_(false),
4191  possible_undeclared_dependency_(nullptr),
4192  undefine_resolved_name_("") {}
4193 
4195 
4197  const std::string& element_name, const Message& descriptor,
4199  const std::string& error) {
4200  if (error_collector_ == nullptr) {
4201  if (!had_errors_) {
4202  GOOGLE_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_
4203  << "\":";
4204  }
4205  GOOGLE_LOG(ERROR) << " " << element_name << ": " << error;
4206  } else {
4207  error_collector_->AddError(filename_, element_name, &descriptor, location,
4208  error);
4209  }
4210  had_errors_ = true;
4211 }
4212 
4214  const std::string& element_name, const Message& descriptor,
4215  DescriptorPool::ErrorCollector::ErrorLocation location, const char* error) {
4217 }
4218 
4220  const std::string& element_name, const Message& descriptor,
4222  const std::string& undefined_symbol) {
4223  if (possible_undeclared_dependency_ == nullptr &&
4224  undefine_resolved_name_.empty()) {
4225  AddError(element_name, descriptor, location,
4226  "\"" + undefined_symbol + "\" is not defined.");
4227  } else {
4228  if (possible_undeclared_dependency_ != nullptr) {
4229  AddError(element_name, descriptor, location,
4231  "\" seems to be defined in \"" +
4233  "\", which is not "
4234  "imported by \"" +
4235  filename_ +
4236  "\". To use it here, please "
4237  "add the necessary import.");
4238  }
4239  if (!undefine_resolved_name_.empty()) {
4240  AddError(element_name, descriptor, location,
4241  "\"" + undefined_symbol + "\" is resolved to \"" +
4243  "\", which is not defined. "
4244  "The innermost scope is searched first in name resolution. "
4245  "Consider using a leading '.'(i.e., \"." +
4246  undefined_symbol + "\") to start from the outermost scope.");
4247  }
4248  }
4249 }
4250 
4252  const std::string& element_name, const Message& descriptor,
4254  const std::string& error) {
4255  if (error_collector_ == nullptr) {
4256  GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
4257  } else {
4258  error_collector_->AddWarning(filename_, element_name, &descriptor, location,
4259  error);
4260  }
4261 }
4262 
4264  const std::string& package_name) {
4265  return HasPrefixString(file->package(), package_name) &&
4266  (file->package().size() == package_name.size() ||
4267  file->package()[package_name.size()] == '.');
4268 }
4269 
4271  if (file == nullptr || !dependencies_.insert(file).second) return;
4272  for (int i = 0; file != nullptr && i < file->public_dependency_count(); i++) {
4273  RecordPublicDependencies(file->public_dependency(i));
4274  }
4275 }
4276 
4278  const DescriptorPool* pool, const std::string& name, bool build_it) {
4279  // If we are looking at an underlay, we must lock its mutex_, since we are
4280  // accessing the underlay's tables_ directly.
4281  MutexLockMaybe lock((pool == pool_) ? nullptr : pool->mutex_);
4282 
4283  Symbol result = pool->tables_->FindSymbol(name);
4284  if (result.IsNull() && pool->underlay_ != nullptr) {
4285  // Symbol not found; check the underlay.
4287  }
4288 
4289  if (result.IsNull()) {
4290  // With lazily_build_dependencies_, a symbol lookup at cross link time is
4291  // not guaranteed to be successful. In most cases, build_it will be false,
4292  // which intentionally prevents us from building an import until it's
4293  // actually needed. In some cases, like registering an extension, we want
4294  // to build the file containing the symbol, and build_it will be set.
4295  // Also, build_it will be true when !lazily_build_dependencies_, to provide
4296  // better error reporting of missing dependencies.
4297  if (build_it && pool->TryFindSymbolInFallbackDatabase(name)) {
4298  result = pool->tables_->FindSymbol(name);
4299  }
4300  }
4301 
4302  return result;
4303 }
4304 
4306  bool build_it) {
4307  Symbol result = FindSymbolNotEnforcingDepsHelper(pool_, name, build_it);
4308  // Only find symbols which were defined in this file or one of its
4309  // dependencies.
4310  const FileDescriptor* file = result.GetFile();
4311  if (file == file_ || dependencies_.count(file) > 0) {
4312  unused_dependency_.erase(file);
4313  }
4314  return result;
4315 }
4316 
4317 Symbol DescriptorBuilder::FindSymbol(const std::string& name, bool build_it) {
4318  Symbol result = FindSymbolNotEnforcingDeps(name, build_it);
4319 
4320  if (result.IsNull()) return result;
4321 
4322  if (!pool_->enforce_dependencies_) {
4323  // Hack for CompilerUpgrader, and also used for lazily_build_dependencies_
4324  return result;
4325  }
4326 
4327  // Only find symbols which were defined in this file or one of its
4328  // dependencies.
4329  const FileDescriptor* file = result.GetFile();
4330  if (file == file_ || dependencies_.count(file) > 0) {
4331  return result;
4332  }
4333 
4334  if (result.type() == Symbol::PACKAGE) {
4335  // Arg, this is overcomplicated. The symbol is a package name. It could
4336  // be that the package was defined in multiple files. result.GetFile()
4337  // returns the first file we saw that used this package. We've determined
4338  // that that file is not a direct dependency of the file we are currently
4339  // building, but it could be that some other file which *is* a direct
4340  // dependency also defines the same package. We can't really rule out this
4341  // symbol unless none of the dependencies define it.
4342  if (IsInPackage(file_, name)) return result;
4343  for (std::set<const FileDescriptor*>::const_iterator it =
4344  dependencies_.begin();
4345  it != dependencies_.end(); ++it) {
4346  // Note: A dependency may be nullptr if it was not found or had errors.
4347  if (*it != nullptr && IsInPackage(*it, name)) return result;
4348  }
4349  }
4350 
4353  return kNullSymbol;
4354 }
4355 
4357  const std::string& name, const std::string& relative_to,
4358  ResolveMode resolve_mode, bool build_it) {
4360  undefine_resolved_name_.clear();
4361 
4362  if (!name.empty() && name[0] == '.') {
4363  // Fully-qualified name.
4364  return FindSymbol(name.substr(1), build_it);
4365  }
4366 
4367  // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
4368  // defined in multiple parent scopes, we only want to find "Bar.baz" in the
4369  // innermost one. E.g., the following should produce an error:
4370  // message Bar { message Baz {} }
4371  // message Foo {
4372  // message Bar {
4373  // }
4374  // optional Bar.Baz baz = 1;
4375  // }
4376  // So, we look for just "Foo" first, then look for "Bar.baz" within it if
4377  // found.
4378  std::string::size_type name_dot_pos = name.find_first_of('.');
4379  std::string first_part_of_name;
4380  if (name_dot_pos == std::string::npos) {
4381  first_part_of_name = name;
4382  } else {
4383  first_part_of_name = name.substr(0, name_dot_pos);
4384  }
4385 
4386  std::string scope_to_try(relative_to);
4387 
4388  while (true) {
4389  // Chop off the last component of the scope.
4390  std::string::size_type dot_pos = scope_to_try.find_last_of('.');
4391  if (dot_pos == std::string::npos) {
4392  return FindSymbol(name, build_it);
4393  } else {
4394  scope_to_try.erase(dot_pos);
4395  }
4396 
4397  // Append ".first_part_of_name" and try to find.
4398  std::string::size_type old_size = scope_to_try.size();
4399  scope_to_try.append(1, '.');
4400  scope_to_try.append(first_part_of_name);
4401  Symbol result = FindSymbol(scope_to_try, build_it);
4402  if (!result.IsNull()) {
4403  if (first_part_of_name.size() < name.size()) {
4404  // name is a compound symbol, of which we only found the first part.
4405  // Now try to look up the rest of it.
4406  if (result.IsAggregate()) {
4407  scope_to_try.append(name, first_part_of_name.size(),
4408  name.size() - first_part_of_name.size());
4409  result = FindSymbol(scope_to_try, build_it);
4410  if (result.IsNull()) {
4411  undefine_resolved_name_ = scope_to_try;
4412  }
4413  return result;
4414  } else {
4415  // We found a symbol but it's not an aggregate. Continue the loop.
4416  }
4417  } else {
4418  if (resolve_mode == LOOKUP_TYPES && !result.IsType()) {
4419  // We found a symbol but it's not a type. Continue the loop.
4420  } else {
4421  return result;
4422  }
4423  }
4424  }
4425 
4426  // Not found. Remove the name so we can try again.
4427  scope_to_try.erase(old_size);
4428  }
4429 }
4430 
4432  const std::string& name, const std::string& relative_to,
4433  DescriptorPool::PlaceholderType placeholder_type, ResolveMode resolve_mode,
4434  bool build_it) {
4435  Symbol result =
4436  LookupSymbolNoPlaceholder(name, relative_to, resolve_mode, build_it);
4437  if (result.IsNull() && pool_->allow_unknown_) {
4438  // Not found, but AllowUnknownDependencies() is enabled. Return a
4439  // placeholder instead.
4440  result = pool_->NewPlaceholderWithMutexHeld(name, placeholder_type);
4441  }
4442  return result;
4443 }
4444 
4446  bool last_was_period = false;
4447 
4448  for (char character : name) {
4449  // I don't trust isalnum() due to locales. :(
4450  if (('a' <= character && character <= 'z') ||
4451  ('A' <= character && character <= 'Z') ||
4452  ('0' <= character && character <= '9') || (character == '_')) {
4453  last_was_period = false;
4454  } else if (character == '.') {
4455  if (last_was_period) return false;
4456  last_was_period = true;
4457  } else {
4458  return false;
4459  }
4460  }
4461 
4462  return !name.empty() && !last_was_period;
4463 }
4464 
4466  PlaceholderType placeholder_type) const {
4467  MutexLockMaybe lock(mutex_);
4468  return NewPlaceholderWithMutexHeld(name, placeholder_type);
4469 }
4470 
4472  StringPiece name, PlaceholderType placeholder_type) const {
4473  if (mutex_) {
4474  mutex_->AssertHeld();
4475  }
4476  // Compute names.
4477  StringPiece placeholder_full_name;
4478  StringPiece placeholder_name;
4479  const std::string* placeholder_package;
4480 
4481  if (!ValidateQualifiedName(name)) return kNullSymbol;
4482  if (name[0] == '.') {
4483  // Fully-qualified.
4484  placeholder_full_name = name.substr(1);
4485  } else {
4486  placeholder_full_name = name;
4487  }
4488 
4489  std::string::size_type dotpos = placeholder_full_name.find_last_of('.');
4490  if (dotpos != std::string::npos) {
4491  placeholder_package =
4492  tables_->AllocateString(placeholder_full_name.substr(0, dotpos));
4493  placeholder_name = placeholder_full_name.substr(dotpos + 1);
4494  } else {
4495  placeholder_package = &internal::GetEmptyString();
4496  placeholder_name = placeholder_full_name;
4497  }
4498 
4499  // Create the placeholders.
4500  FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld(
4501  StrCat(placeholder_full_name, ".placeholder.proto"));
4502  placeholder_file->package_ = placeholder_package;
4503 
4504  if (placeholder_type == PLACEHOLDER_ENUM) {
4505  placeholder_file->enum_type_count_ = 1;
4506  placeholder_file->enum_types_ = tables_->AllocateArray<EnumDescriptor>(1);
4507 
4508  EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
4509  memset(static_cast<void*>(placeholder_enum), 0, sizeof(*placeholder_enum));
4510 
4511  placeholder_enum->all_names_ =
4512  tables_->AllocateStringArray(placeholder_name, placeholder_full_name);
4513  placeholder_enum->file_ = placeholder_file;
4514  placeholder_enum->options_ = &EnumOptions::default_instance();
4515  placeholder_enum->is_placeholder_ = true;
4516  placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
4517 
4518  // Enums must have at least one value.
4519  placeholder_enum->value_count_ = 1;
4520  placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1);
4521  // Disable fast-path lookup for this enum.
4522  placeholder_enum->sequential_value_limit_ = -1;
4523 
4524  EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
4525  memset(static_cast<void*>(placeholder_value), 0,
4526  sizeof(*placeholder_value));
4527 
4528  // Note that enum value names are siblings of their type, not children.
4529  placeholder_value->all_names_ = tables_->AllocateStringArray(
4530  "PLACEHOLDER_VALUE", placeholder_package->empty()
4531  ? "PLACEHOLDER_VALUE"
4532  : *placeholder_package + ".PLACEHOLDER_VALUE");
4533 
4534  placeholder_value->number_ = 0;
4535  placeholder_value->type_ = placeholder_enum;
4536  placeholder_value->options_ = &EnumValueOptions::default_instance();
4537 
4538  return Symbol(placeholder_enum);
4539  } else {
4540  placeholder_file->message_type_count_ = 1;
4541  placeholder_file->message_types_ = tables_->AllocateArray<Descriptor>(1);
4542 
4543  Descriptor* placeholder_message = &placeholder_file->message_types_[0];
4544  memset(static_cast<void*>(placeholder_message), 0,
4545  sizeof(*placeholder_message));
4546 
4547  placeholder_message->all_names_ =
4548  tables_->AllocateStringArray(placeholder_name, placeholder_full_name);
4549  placeholder_message->file_ = placeholder_file;
4550  placeholder_message->options_ = &MessageOptions::default_instance();
4551  placeholder_message->is_placeholder_ = true;
4552  placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
4553 
4554  if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
4555  placeholder_message->extension_range_count_ = 1;
4556  placeholder_message->extension_ranges_ =
4557  tables_->AllocateArray<Descriptor::ExtensionRange>(1);
4558  placeholder_message->extension_ranges_->start = 1;
4559  // kMaxNumber + 1 because ExtensionRange::end is exclusive.
4560  placeholder_message->extension_ranges_->end =
4562  placeholder_message->extension_ranges_->options_ = nullptr;
4563  }
4564 
4565  return Symbol(placeholder_message);
4566  }
4567 }
4568 
4570  StringPiece name) const {
4571  MutexLockMaybe lock(mutex_);
4573 }
4574 
4576  StringPiece name) const {
4577  if (mutex_) {
4578  mutex_->AssertHeld();
4579  }
4580  FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
4581  memset(static_cast<void*>(placeholder), 0, sizeof(*placeholder));
4582 
4583  placeholder->name_ = tables_->AllocateString(name);
4584  placeholder->package_ = &internal::GetEmptyString();
4585  placeholder->pool_ = this;
4586  placeholder->options_ = &FileOptions::default_instance();
4589  placeholder->is_placeholder_ = true;
4590  placeholder->syntax_ = FileDescriptor::SYNTAX_UNKNOWN;
4591  placeholder->finished_building_ = true;
4592  // All other fields are zero or nullptr.
4593 
4594  return placeholder;
4595 }
4596 
4597 bool DescriptorBuilder::AddSymbol(const std::string& full_name,
4598  const void* parent, const std::string& name,
4599  const Message& proto, Symbol symbol) {
4600  // If the caller passed nullptr for the parent, the symbol is at file scope.
4601  // Use its file as the parent instead.
4602  if (parent == nullptr) parent = file_;
4603 
4604  if (full_name.find('\0') != std::string::npos) {
4606  "\"" + full_name + "\" contains null character.");
4607  return false;
4608  }
4609  if (tables_->AddSymbol(full_name, symbol)) {
4610  if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) {
4611  // This is only possible if there was already an error adding something of
4612  // the same name.
4613  if (!had_errors_) {
4614  GOOGLE_LOG(DFATAL) << "\"" << full_name
4615  << "\" not previously defined in "
4616  "symbols_by_name_, but was defined in "
4617  "symbols_by_parent_; this shouldn't be possible.";
4618  }
4619  return false;
4620  }
4621  return true;
4622  } else {
4623  const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile();
4624  if (other_file == file_) {
4625  std::string::size_type dot_pos = full_name.find_last_of('.');
4626  if (dot_pos == std::string::npos) {
4628  "\"" + full_name + "\" is already defined.");
4629  } else {
4631  "\"" + full_name.substr(dot_pos + 1) +
4632  "\" is already defined in \"" +
4633  full_name.substr(0, dot_pos) + "\".");
4634  }
4635  } else {
4636  // Symbol seems to have been defined in a different file.
4638  "\"" + full_name + "\" is already defined in file \"" +
4639  (other_file == nullptr ? "null" : other_file->name()) +
4640  "\".");
4641  }
4642  return false;
4643  }
4644 }
4645 
4647  const Message& proto, FileDescriptor* file) {
4648  if (name.find('\0') != std::string::npos) {
4650  "\"" + name + "\" contains null character.");
4651  return;
4652  }
4653 
4654  Symbol existing_symbol = tables_->FindSymbol(name);
4655  // It's OK to redefine a package.
4656  if (existing_symbol.IsNull()) {
4657  auto* package = tables_->AllocateArray<Symbol::Package>(1);
4658  // If the name is the package name, then it is already in the arena.
4659  // If not, copy it there. It came from the call to AddPackage below.
4660  package->name =
4661  &name == &file->package() ? &name : tables_->AllocateString(name);
4662  package->file = file;
4663  tables_->AddSymbol(*package->name, Symbol(package));
4664  // Also add parent package, if any.
4665  std::string::size_type dot_pos = name.find_last_of('.');
4666  if (dot_pos == std::string::npos) {
4667  // No parents.
4668  ValidateSymbolName(name, name, proto);
4669  } else {
4670  // Has parent.
4671  AddPackage(name.substr(0, dot_pos), proto, file);
4672  ValidateSymbolName(name.substr(dot_pos + 1), name, proto);
4673  }
4674  } else if (existing_symbol.type() != Symbol::PACKAGE) {
4675  // Symbol seems to have been defined in a different file.
4677  "\"" + name +
4678  "\" is already defined (as something other than "
4679  "a package) in file \"" +
4680  existing_symbol.GetFile()->name() + "\".");
4681  }
4682 }
4683 
4685  const std::string& full_name,
4686  const Message& proto) {
4687  if (name.empty()) {
4689  "Missing name.");
4690  } else {
4691  for (char character : name) {
4692  // I don't trust isalnum() due to locales. :(
4693  if ((character < 'a' || 'z' < character) &&
4694  (character < 'A' || 'Z' < character) &&
4695  (character < '0' || '9' < character) && (character != '_')) {
4697  "\"" + name + "\" is not a valid identifier.");
4698  }
4699  }
4700  }
4701 }
4702 
4703 // -------------------------------------------------------------------
4704 
4705 // This generic implementation is good for all descriptors except
4706 // FileDescriptor.
4707 template <class DescriptorT>
4709  const typename DescriptorT::OptionsType& orig_options,
4710  DescriptorT* descriptor, int options_field_tag,
4711  const std::string& option_name) {
4712  std::vector<int> options_path;
4713  descriptor->GetLocationPath(&options_path);
4714  options_path.push_back(options_field_tag);
4715  AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
4716  orig_options, descriptor, options_path, option_name);
4717 }
4718 
4719 // We specialize for FileDescriptor.
4720 void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
4722  std::vector<int> options_path;
4723  options_path.push_back(FileDescriptorProto::kOptionsFieldNumber);
4724  // We add the dummy token so that LookupSymbol does the right thing.
4725  AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(),
4726  orig_options, descriptor, options_path,
4727  "google.protobuf.FileOptions");
4728 }
4729 
4730 template <class DescriptorT>
4733  const typename DescriptorT::OptionsType& orig_options,
4734  DescriptorT* descriptor, const std::vector<int>& options_path,
4735  const std::string& option_name) {
4736  // We need to use a dummy pointer to work around a bug in older versions of
4737  // GCC. Otherwise, the following two lines could be replaced with:
4738  // typename DescriptorT::OptionsType* options =
4739  // tables_->AllocateMessage<typename DescriptorT::OptionsType>();
4740  typename DescriptorT::OptionsType* const dummy = nullptr;
4741  typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
4742 
4743  if (!orig_options.IsInitialized()) {
4744  AddError(name_scope + "." + element_name, orig_options,
4746  "Uninterpreted option is missing name or value.");
4747  return;
4748  }
4749 
4750  // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
4751  // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
4752  // reflection based method, which requires the Descriptor. However, we are in
4753  // the middle of building the descriptors, thus the deadlock.
4754  options->ParseFromString(orig_options.SerializeAsString());
4755  descriptor->options_ = options;
4756 
4757  // Don't add to options_to_interpret_ unless there were uninterpreted
4758  // options. This not only avoids unnecessary work, but prevents a
4759  // bootstrapping problem when building descriptors for descriptor.proto.
4760  // descriptor.proto does not contain any uninterpreted options, but
4761  // attempting to interpret options anyway will cause
4762  // OptionsType::GetDescriptor() to be called which may then deadlock since
4763  // we're still trying to build it.
4764  if (options->uninterpreted_option_size() > 0) {
4765  options_to_interpret_.push_back(OptionsToInterpret(
4766  name_scope, element_name, options_path, &orig_options, options));
4767  }
4768 
4769  // If the custom option is in unknown fields, no need to interpret it.
4770  // Remove the dependency file from unused_dependency.
4771  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
4772  if (!unknown_fields.empty()) {
4773  // Can not use options->GetDescriptor() which may case deadlock.
4774  Symbol msg_symbol = tables_->FindSymbol(option_name);
4775  if (msg_symbol.type() == Symbol::MESSAGE) {
4776  for (int i = 0; i < unknown_fields.field_count(); ++i) {
4778  const FieldDescriptor* field =
4780  msg_symbol.descriptor(), unknown_fields.field(i).number());
4781  if (field) {
4782  unused_dependency_.erase(field->file());
4783  }
4784  }
4785  }
4786  }
4787 }
4788 
4789 // A common pattern: We want to convert a repeated field in the descriptor
4790 // to an array of values, calling some method to build each value.
4791 #define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \
4792  OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \
4793  AllocateArray(INPUT.NAME##_size(), &OUTPUT->NAME##s_); \
4794  for (int i = 0; i < INPUT.NAME##_size(); i++) { \
4795  METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i); \
4796  }
4797 
4799  const FileDescriptorProto& proto, int from_here) {
4800  std::string error_message("File recursively imports itself: ");
4801  for (size_t i = from_here; i < tables_->pending_files_.size(); i++) {
4802  error_message.append(tables_->pending_files_[i]);
4803  error_message.append(" -> ");
4804  }
4805  error_message.append(proto.name());
4806 
4807  if (static_cast<size_t>(from_here) < tables_->pending_files_.size() - 1) {
4808  AddError(tables_->pending_files_[from_here + 1], proto,
4810  } else {
4812  error_message);
4813  }
4814 }
4815 
4817  int index) {
4818  AddError(proto.dependency(index), proto,
4820  "Import \"" + proto.dependency(index) + "\" was listed twice.");
4821 }
4822 
4824  int index) {
4826  if (pool_->fallback_database_ == nullptr) {
4827  message = "Import \"" + proto.dependency(index) + "\" has not been loaded.";
4828  } else {
4829  message = "Import \"" + proto.dependency(index) +
4830  "\" was not found or had errors.";
4831  }
4832  AddError(proto.dependency(index), proto,
4834 }
4835 
4836 static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
4837  const FileDescriptorProto& proto) {
4838  FileDescriptorProto existing_proto;
4839  existing_file->CopyTo(&existing_proto);
4840  // TODO(liujisi): Remove it when CopyTo supports copying syntax params when
4841  // syntax="proto2".
4842  if (existing_file->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
4843  proto.has_syntax()) {
4844  existing_proto.set_syntax(
4845  existing_file->SyntaxName(existing_file->syntax()));
4846  }
4847 
4848  return existing_proto.SerializeAsString() == proto.SerializeAsString();
4849 }
4850 
4852  const FileDescriptorProto& proto) {
4853  filename_ = proto.name();
4854 
4855  // Check if the file already exists and is identical to the one being built.
4856  // Note: This only works if the input is canonical -- that is, it
4857  // fully-qualifies all type names, has no UninterpretedOptions, etc.
4858  // This is fine, because this idempotency "feature" really only exists to
4859  // accommodate one hack in the proto1->proto2 migration layer.
4860  const FileDescriptor* existing_file = tables_->FindFile(filename_);
4861  if (existing_file != nullptr) {
4862  // File already in pool. Compare the existing one to the input.
4863  if (ExistingFileMatchesProto(existing_file, proto)) {
4864  // They're identical. Return the existing descriptor.
4865  return existing_file;
4866  }
4867 
4868  // Not a match. The error will be detected and handled later.
4869  }
4870 
4871  // Check to see if this file is already on the pending files list.
4872  // TODO(kenton): Allow recursive imports? It may not work with some
4873  // (most?) programming languages. E.g., in C++, a forward declaration
4874  // of a type is not sufficient to allow it to be used even in a
4875  // generated header file due to inlining. This could perhaps be
4876  // worked around using tricks involving inserting #include statements
4877  // mid-file, but that's pretty ugly, and I'm pretty sure there are
4878  // some languages out there that do not allow recursive dependencies
4879  // at all.
4880  for (size_t i = 0; i < tables_->pending_files_.size(); i++) {
4881  if (tables_->pending_files_[i] == proto.name()) {
4882  AddRecursiveImportError(proto, i);
4883  return nullptr;
4884  }
4885  }
4886 
4887  // If we have a fallback_database_, and we aren't doing lazy import building,
4888  // attempt to load all dependencies now, before checkpointing tables_. This
4889  // avoids confusion with recursive checkpoints.
4891  if (pool_->fallback_database_ != nullptr) {
4892  tables_->pending_files_.push_back(proto.name());
4893  for (int i = 0; i < proto.dependency_size(); i++) {
4894  if (tables_->FindFile(proto.dependency(i)) == nullptr &&
4895  (pool_->underlay_ == nullptr ||
4896  pool_->underlay_->FindFileByName(proto.dependency(i)) ==
4897  nullptr)) {
4898  // We don't care what this returns since we'll find out below anyway.
4900  }
4901  }
4902  tables_->pending_files_.pop_back();
4903  }
4904  }
4905 
4906  // Checkpoint the tables so that we can roll back if something goes wrong.
4907  tables_->AddCheckpoint();
4908 
4910 
4912  if (result) {
4913  tables_->ClearLastCheckpoint();
4914  result->finished_building_ = true;
4915  } else {
4916  tables_->RollbackToLastCheckpoint();
4917  }
4918 
4919  return result;
4920 }
4921 
4923  const FileDescriptorProto& proto) {
4924  FileDescriptor* result = tables_->Allocate<FileDescriptor>();
4925  file_ = result;
4926 
4927  result->is_placeholder_ = false;
4928  result->finished_building_ = false;
4929  SourceCodeInfo* info = nullptr;
4930  if (proto.has_source_code_info()) {
4931  info = tables_->AllocateMessage<SourceCodeInfo>();
4932  info->CopyFrom(proto.source_code_info());
4933  result->source_code_info_ = info;
4934  } else {
4935  result->source_code_info_ = &SourceCodeInfo::default_instance();
4936  }
4937 
4938  file_tables_ = tables_->AllocateFileTables();
4940 
4941  if (!proto.has_name()) {
4943  "Missing field: FileDescriptorProto.name.");
4944  }
4945 
4946  // TODO(liujisi): Report error when the syntax is empty after all the protos
4947  // have added the syntax statement.
4948  if (proto.syntax().empty() || proto.syntax() == "proto2") {
4950  } else if (proto.syntax() == "proto3") {
4952  } else {
4955  "Unrecognized syntax: " + proto.syntax());
4956  }
4957 
4958  result->name_ = tables_->AllocateString(proto.name());
4959  if (proto.has_package()) {
4960  result->package_ = tables_->AllocateString(proto.package());
4961  } else {
4962  // We cannot rely on proto.package() returning a valid string if
4963  // proto.has_package() is false, because we might be running at static
4964  // initialization time, in which case default values have not yet been
4965  // initialized.
4966  result->package_ = tables_->AllocateString("");
4967  }
4968  result->pool_ = pool_;
4969 
4970  if (result->name().find('\0') != std::string::npos) {
4972  "\"" + result->name() + "\" contains null character.");
4973  return nullptr;
4974  }
4975 
4976  // Add to tables.
4977  if (!tables_->AddFile(result)) {
4979  "A file with this name is already in the pool.");
4980  // Bail out early so that if this is actually the exact same file, we
4981  // don't end up reporting that every single symbol is already defined.
4982  return nullptr;
4983  }
4984  if (!result->package().empty()) {
4985  AddPackage(result->package(), proto, result);
4986  }
4987 
4988  // Make sure all dependencies are loaded.
4989  std::set<std::string> seen_dependencies;
4990  result->dependency_count_ = proto.dependency_size();
4991  result->dependencies_ =
4992  tables_->AllocateArray<const FileDescriptor*>(proto.dependency_size());
4993  result->dependencies_once_ = nullptr;
4994  unused_dependency_.clear();
4995  std::set<int> weak_deps;
4996  for (int i = 0; i < proto.weak_dependency_size(); ++i) {
4997  weak_deps.insert(proto.weak_dependency(i));
4998  }
4999  for (int i = 0; i < proto.dependency_size(); i++) {
5000  if (!seen_dependencies.insert(proto.dependency(i)).second) {
5001  AddTwiceListedError(proto, i);
5002  }
5003 
5004  const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
5005  if (dependency == nullptr && pool_->underlay_ != nullptr) {
5006  dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
5007  }
5008 
5009  if (dependency == result) {
5010  // Recursive import. dependency/result is not fully initialized, and it's
5011  // dangerous to try to do anything with it. The recursive import error
5012  // will be detected and reported in DescriptorBuilder::BuildFile().
5013  return nullptr;
5014  }
5015 
5016  if (dependency == nullptr) {
5018  if (pool_->allow_unknown_ ||
5019  (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
5020  dependency =
5022  } else {
5023  AddImportError(proto, i);
5024  }
5025  }
5026  } else {
5027  // Add to unused_dependency_ to track unused imported files.
5028  // Note: do not track unused imported files for public import.
5030  (pool_->unused_import_track_files_.find(proto.name()) !=
5032  (dependency->public_dependency_count() == 0)) {
5033  unused_dependency_.insert(dependency);
5034  }
5035  }
5036 
5037  result->dependencies_[i] = dependency;
5038  if (pool_->lazily_build_dependencies_ && !dependency) {
5039  if (result->dependencies_once_ == nullptr) {
5040  result->dependencies_once_ =
5041  tables_->Create<FileDescriptor::LazyInitData>();
5042  result->dependencies_once_->dependencies_names =
5043  tables_->AllocateArray<const char*>(proto.dependency_size());
5044  if (proto.dependency_size() > 0) {
5045  std::fill_n(result->dependencies_once_->dependencies_names,
5046  proto.dependency_size(), nullptr);
5047  }
5048  }
5049 
5050  result->dependencies_once_->dependencies_names[i] =
5051  tables_->Strdup(proto.dependency(i));
5052  }
5053  }
5054 
5055  // Check public dependencies.
5056  int public_dependency_count = 0;
5057  result->public_dependencies_ =
5058  tables_->AllocateArray<int>(proto.public_dependency_size());
5059  for (int i = 0; i < proto.public_dependency_size(); i++) {
5060  // Only put valid public dependency indexes.
5061  int index = proto.public_dependency(i);
5062  if (index >= 0 && index < proto.dependency_size()) {
5063  result->public_dependencies_[public_dependency_count++] = index;
5064  // Do not track unused imported files for public import.
5065  // Calling dependency(i) builds that file when doing lazy imports,
5066  // need to avoid doing this. Unused dependency detection isn't done
5067  // when building lazily, anyways.
5069  unused_dependency_.erase(result->dependency(index));
5070  }
5071  } else {
5073  "Invalid public dependency index.");
5074  }
5075  }
5076  result->public_dependency_count_ = public_dependency_count;
5077 
5078  // Build dependency set
5079  dependencies_.clear();
5080  // We don't/can't do proper dependency error checking when
5081  // lazily_build_dependencies_, and calling dependency(i) will force
5082  // a dependency to be built, which we don't want.
5084  for (int i = 0; i < result->dependency_count(); i++) {
5085  RecordPublicDependencies(result->dependency(i));
5086  }
5087  }
5088 
5089  // Check weak dependencies.
5090  int weak_dependency_count = 0;
5091  result->weak_dependencies_ =
5092  tables_->AllocateArray<int>(proto.weak_dependency_size());
5093  for (int i = 0; i < proto.weak_dependency_size(); i++) {
5094  int index = proto.weak_dependency(i);
5095  if (index >= 0 && index < proto.dependency_size()) {
5096  result->weak_dependencies_[weak_dependency_count++] = index;
5097  } else {
5099  "Invalid weak dependency index.");
5100  }
5101  }
5102  result->weak_dependency_count_ = weak_dependency_count;
5103 
5104  // Convert children.
5105  BUILD_ARRAY(proto, result, message_type, BuildMessage, nullptr);
5106  BUILD_ARRAY(proto, result, enum_type, BuildEnum, nullptr);
5107  BUILD_ARRAY(proto, result, service, BuildService, nullptr);
5108  BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr);
5109 
5110  // Copy options.
5111  result->options_ = nullptr; // Set to default_instance later if necessary.
5112  if (proto.has_options()) {
5113  AllocateOptions(proto.options(), result);
5114  }
5115 
5116  // Note that the following steps must occur in exactly the specified order.
5117 
5118  // Cross-link.
5119  CrossLinkFile(result, proto);
5120 
5121  // Interpret any remaining uninterpreted options gathered into
5122  // options_to_interpret_ during descriptor building. Cross-linking has made
5123  // extension options known, so all interpretations should now succeed.
5124  if (!had_errors_) {
5125  OptionInterpreter option_interpreter(this);
5127  options_to_interpret_.begin();
5128  iter != options_to_interpret_.end(); ++iter) {
5129  option_interpreter.InterpretOptions(&(*iter));
5130  }
5131  options_to_interpret_.clear();
5132  if (info != nullptr) {
5133  option_interpreter.UpdateSourceCodeInfo(info);
5134  }
5135  }
5136 
5137  // Validate options. See comments at InternalSetLazilyBuildDependencies about
5138  // error checking and lazy import building.
5140  ValidateFileOptions(result, proto);
5141  }
5142 
5143  // Additional naming conflict check for map entry types. Only need to check
5144  // this if there are already errors.
5145  if (had_errors_) {
5146  for (int i = 0; i < proto.message_type_size(); ++i) {
5147  DetectMapConflicts(result->message_type(i), proto.message_type(i));
5148  }
5149  }
5150 
5151 
5152  // Again, see comments at InternalSetLazilyBuildDependencies about error
5153  // checking. Also, don't log unused dependencies if there were previous
5154  // errors, since the results might be inaccurate.
5155  if (!had_errors_ && !unused_dependency_.empty() &&
5157  LogUnusedDependency(proto, result);
5158  }
5159 
5160  if (had_errors_) {
5161  return nullptr;
5162  } else {
5163  return result;
5164  }
5165 }
5166 
5167 
5169  const std::string& scope, const std::string& proto_name) {
5170  if (scope.empty()) {
5171  return tables_->AllocateStringArray(proto_name, proto_name);
5172  } else {
5173  return tables_->AllocateStringArray(proto_name,
5174  StrCat(scope, ".", proto_name));
5175  }
5176 }
5177 
5179  const Descriptor* parent,
5180  Descriptor* result) {
5181  const std::string& scope =
5182  (parent == nullptr) ? file_->package() : parent->full_name();
5183  result->all_names_ = AllocateNameStrings(scope, proto.name());
5184  ValidateSymbolName(proto.name(), result->full_name(), proto);
5185 
5186  result->file_ = file_;
5187  result->containing_type_ = parent;
5188  result->is_placeholder_ = false;
5189  result->is_unqualified_placeholder_ = false;
5190  result->well_known_type_ = Descriptor::WELLKNOWNTYPE_UNSPECIFIED;
5191 
5192  auto it = pool_->tables_->well_known_types_.find(result->full_name());
5193  if (it != pool_->tables_->well_known_types_.end()) {
5194  result->well_known_type_ = it->second;
5195  }
5196 
5197  // Calculate the continuous sequence of fields.
5198  // These can be fast-path'd during lookup and don't need to be added to the
5199  // tables.
5200  // We use uint16_t to save space for sequential_field_limit_, so stop before
5201  // overflowing it. Worst case, we are not taking full advantage on huge
5202  // messages, but it is unlikely.
5203  result->sequential_field_limit_ = 0;
5204  for (int i = 0; i < std::numeric_limits<uint16_t>::max() &&
5205  i < proto.field_size() && proto.field(i).number() == i + 1;
5206  ++i) {
5207  result->sequential_field_limit_ = i + 1;
5208  }
5209 
5210  // Build oneofs first so that fields and extension ranges can refer to them.
5211  BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result);
5213  BUILD_ARRAY(proto, result, nested_type, BuildMessage, result);
5215  BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
5218 
5219  // Copy reserved names.
5220  int reserved_name_count = proto.reserved_name_size();
5221  result->reserved_name_count_ = reserved_name_count;
5222  result->reserved_names_ =
5223  tables_->AllocateArray<const std::string*>(reserved_name_count);
5224  for (int i = 0; i < reserved_name_count; ++i) {
5225  result->reserved_names_[i] =
5226  tables_->AllocateString(proto.reserved_name(i));
5227  }
5228 
5229  // Copy options.
5230  result->options_ = nullptr; // Set to default_instance later if necessary.
5231  if (proto.has_options()) {
5232  AllocateOptions(proto.options(), result,
5234  "google.protobuf.MessageOptions");
5235  }
5236 
5237  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5238 
5239  for (int i = 0; i < proto.reserved_range_size(); i++) {
5240  const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i);
5241  for (int j = i + 1; j < proto.reserved_range_size(); j++) {
5242  const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j);
5243  if (range1.end() > range2.start() && range2.end() > range1.start()) {
5244  AddError(result->full_name(), proto.reserved_range(i),
5246  strings::Substitute("Reserved range $0 to $1 overlaps with "
5247  "already-defined range $2 to $3.",
5248  range2.start(), range2.end() - 1,
5249  range1.start(), range1.end() - 1));
5250  }
5251  }
5252  }
5253 
5254  HASH_SET<std::string> reserved_name_set;
5255  for (int i = 0; i < proto.reserved_name_size(); i++) {
5256  const std::string& name = proto.reserved_name(i);
5257  if (reserved_name_set.find(name) == reserved_name_set.end()) {
5258  reserved_name_set.insert(name);
5259  } else {
5261  strings::Substitute("Field name \"$0\" is reserved multiple times.",
5262  name));
5263  }
5264  }
5265 
5266 
5267  for (int i = 0; i < result->field_count(); i++) {
5268  const FieldDescriptor* field = result->field(i);
5269  for (int j = 0; j < result->extension_range_count(); j++) {
5270  const Descriptor::ExtensionRange* range = result->extension_range(j);
5271  if (range->start <= field->number() && field->number() < range->end) {
5272  AddError(
5273  field->full_name(), proto.extension_range(j),
5276  "Extension range $0 to $1 includes field \"$2\" ($3).",
5277  range->start, range->end - 1, field->name(), field->number()));
5278  }
5279  }
5280  for (int j = 0; j < result->reserved_range_count(); j++) {
5281  const Descriptor::ReservedRange* range = result->reserved_range(j);
5282  if (range->start <= field->number() && field->number() < range->end) {
5283  AddError(field->full_name(), proto.reserved_range(j),
5285  strings::Substitute("Field \"$0\" uses reserved number $1.",
5286  field->name(), field->number()));
5287  }
5288  }
5289  if (reserved_name_set.find(field->name()) != reserved_name_set.end()) {
5290  AddError(
5291  field->full_name(), proto.field(i),
5293  strings::Substitute("Field name \"$0\" is reserved.", field->name()));
5294  }
5295 
5296  }
5297 
5298  // Check that extension ranges don't overlap and don't include
5299  // reserved field numbers or names.
5300  for (int i = 0; i < result->extension_range_count(); i++) {
5301  const Descriptor::ExtensionRange* range1 = result->extension_range(i);
5302  for (int j = 0; j < result->reserved_range_count(); j++) {
5303  const Descriptor::ReservedRange* range2 = result->reserved_range(j);
5304  if (range1->end > range2->start && range2->end > range1->start) {
5305  AddError(result->full_name(), proto.extension_range(i),
5307  strings::Substitute("Extension range $0 to $1 overlaps with "
5308  "reserved range $2 to $3.",
5309  range1->start, range1->end - 1, range2->start,
5310  range2->end - 1));
5311  }
5312  }
5313  for (int j = i + 1; j < result->extension_range_count(); j++) {
5314  const Descriptor::ExtensionRange* range2 = result->extension_range(j);
5315  if (range1->end > range2->start && range2->end > range1->start) {
5316  AddError(result->full_name(), proto.extension_range(i),
5318  strings::Substitute("Extension range $0 to $1 overlaps with "
5319  "already-defined range $2 to $3.",
5320  range2->start, range2->end - 1, range1->start,
5321  range1->end - 1));
5322  }
5323  }
5324  }
5325 }
5326 
5328  Descriptor* parent,
5330  bool is_extension) {
5331  const std::string& scope =
5332  (parent == nullptr) ? file_->package() : parent->full_name();
5333 
5334  // We allocate all names in a single array, and dedup them.
5335  // We remember the indices for the potentially deduped values.
5336  auto all_names = tables_->AllocateFieldNames(
5337  proto.name(), scope,
5338  proto.has_json_name() ? &proto.json_name() : nullptr);
5339  result->all_names_ = all_names.array;
5340  result->lowercase_name_index_ = all_names.lowercase_index;
5341  result->camelcase_name_index_ = all_names.camelcase_index;
5342  result->json_name_index_ = all_names.json_index;
5343 
5344  ValidateSymbolName(proto.name(), result->full_name(), proto);
5345 
5346  result->file_ = file_;
5347  result->number_ = proto.number();
5348  result->is_extension_ = is_extension;
5349  result->is_oneof_ = false;
5350  result->proto3_optional_ = proto.proto3_optional();
5351 
5352  if (proto.proto3_optional() &&
5355  "The [proto3_optional=true] option may only be set on proto3"
5356  "fields, not " +
5357  result->full_name());
5358  }
5359 
5360  result->has_json_name_ = proto.has_json_name();
5361 
5362  // Some compilers do not allow static_cast directly between two enum types,
5363  // so we must cast to int first.
5364  result->type_ = static_cast<FieldDescriptor::Type>(
5365  implicit_cast<int>(proto.type()));
5366  result->label_ = static_cast<FieldDescriptor::Label>(
5367  implicit_cast<int>(proto.label()));
5368 
5369  if (result->label_ == FieldDescriptor::LABEL_REQUIRED) {
5370  // An extension cannot have a required field (b/13365836).
5371  if (result->is_extension_) {
5372  AddError(result->full_name(), proto,
5373  // Error location `TYPE`: we would really like to indicate
5374  // `LABEL`, but the `ErrorLocation` enum has no entry for this,
5375  // and we don't necessarily know about all implementations of the
5376  // `ErrorCollector` interface to extend them to handle the new
5377  // error location type properly.
5379  "The extension " + result->full_name() + " cannot be required.");
5380  }
5381  }
5382 
5383  // Some of these may be filled in when cross-linking.
5384  result->containing_type_ = nullptr;
5385  result->type_once_ = nullptr;
5386  result->default_value_enum_ = nullptr;
5387 
5388  result->has_default_value_ = proto.has_default_value();
5389  if (proto.has_default_value() && result->is_repeated()) {
5390  AddError(result->full_name(), proto,
5392  "Repeated fields can't have default values.");
5393  }
5394 
5395  if (proto.has_type()) {
5396  if (proto.has_default_value()) {
5397  char* end_pos = nullptr;
5398  switch (result->cpp_type()) {
5400  result->default_value_int32_t_ =
5401  strtol(proto.default_value().c_str(), &end_pos, 0);
5402  break;
5404  result->default_value_int64_t_ =
5405  strto64(proto.default_value().c_str(), &end_pos, 0);
5406  break;
5408  result->default_value_uint32_t_ =
5409  strtoul(proto.default_value().c_str(), &end_pos, 0);
5410  break;
5412  result->default_value_uint64_t_ =
5413  strtou64(proto.default_value().c_str(), &end_pos, 0);
5414  break;
5416  if (proto.default_value() == "inf") {
5417  result->default_value_float_ =
5418  std::numeric_limits<float>::infinity();
5419  } else if (proto.default_value() == "-inf") {
5420  result->default_value_float_ =
5421  -std::numeric_limits<float>::infinity();
5422  } else if (proto.default_value() == "nan") {
5423  result->default_value_float_ =
5424  std::numeric_limits<float>::quiet_NaN();
5425  } else {
5426  result->default_value_float_ = io::SafeDoubleToFloat(
5427  io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos));
5428  }
5429  break;
5431  if (proto.default_value() == "inf") {
5432  result->default_value_double_ =
5433  std::numeric_limits<double>::infinity();
5434  } else if (proto.default_value() == "-inf") {
5435  result->default_value_double_ =
5436  -std::numeric_limits<double>::infinity();
5437  } else if (proto.default_value() == "nan") {
5438  result->default_value_double_ =
5439  std::numeric_limits<double>::quiet_NaN();
5440  } else {
5441  result->default_value_double_ =
5442  io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
5443  }
5444  break;
5446  if (proto.default_value() == "true") {
5447  result->default_value_bool_ = true;
5448  } else if (proto.default_value() == "false") {
5449  result->default_value_bool_ = false;
5450  } else {
5451  AddError(result->full_name(), proto,
5453  "Boolean default must be true or false.");
5454  }
5455  break;
5457  // This will be filled in when cross-linking.
5458  result->default_value_enum_ = nullptr;
5459  break;
5461  if (result->type() == FieldDescriptor::TYPE_BYTES) {
5462  result->default_value_string_ = tables_->AllocateString(
5464  } else {
5465  result->default_value_string_ =
5466  tables_->AllocateString(proto.default_value());
5467  }
5468  break;
5470  AddError(result->full_name(), proto,
5472  "Messages can't have default values.");
5473  result->has_default_value_ = false;
5474  result->default_generated_instance_ = nullptr;
5475  break;
5476  }
5477 
5478  if (end_pos != nullptr) {
5479  // end_pos is only set non-null by the parsers for numeric types,
5480  // above. This checks that the default was non-empty and had no extra
5481  // junk after the end of the number.
5482  if (proto.default_value().empty() || *end_pos != '\0') {
5483  AddError(result->full_name(), proto,
5485  "Couldn't parse default value \"" + proto.default_value() +
5486  "\".");
5487  }
5488  }
5489  } else {
5490  // No explicit default value
5491  switch (result->cpp_type()) {
5493  result->default_value_int32_t_ = 0;
5494  break;
5496  result->default_value_int64_t_ = 0;
5497  break;
5499  result->default_value_uint32_t_ = 0;
5500  break;
5502  result->default_value_uint64_t_ = 0;
5503  break;
5505  result->default_value_float_ = 0.0f;
5506  break;
5508  result->default_value_double_ = 0.0;
5509  break;
5511  result->default_value_bool_ = false;
5512  break;
5514  // This will be filled in when cross-linking.
5515  result->default_value_enum_ = nullptr;
5516  break;
5518  result->default_value_string_ = &internal::GetEmptyString();
5519  break;
5521  result->default_generated_instance_ = nullptr;
5522  break;
5523  }
5524  }
5525  }
5526 
5527  if (result->number() <= 0) {
5529  "Field numbers must be positive integers.");
5530  } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
5531  // Only validate that the number is within the valid field range if it is
5532  // not an extension. Since extension numbers are validated with the
5533  // extendee's valid set of extension numbers, and those are in turn
5534  // validated against the max allowed number, the check is unnecessary for
5535  // extension fields.
5536  // This avoids cross-linking issues that arise when attempting to check if
5537  // the extendee is a message_set_wire_format message, which has a higher max
5538  // on extension numbers.
5540  strings::Substitute("Field numbers cannot be greater than $0.",
5542  } else if (result->number() >= FieldDescriptor::kFirstReservedNumber &&
5546  "Field numbers $0 through $1 are reserved for the protocol "
5547  "buffer library implementation.",
5550  }
5551 
5552  if (is_extension) {
5553  if (!proto.has_extendee()) {
5554  AddError(result->full_name(), proto,
5556  "FieldDescriptorProto.extendee not set for extension field.");
5557  }
5558 
5559  result->scope_.extension_scope = parent;
5560 
5561  if (proto.has_oneof_index()) {
5563  "FieldDescriptorProto.oneof_index should not be set for "
5564  "extensions.");
5565  }
5566  } else {
5567  if (proto.has_extendee()) {
5568  AddError(result->full_name(), proto,
5570  "FieldDescriptorProto.extendee set for non-extension field.");
5571  }
5572 
5573  result->containing_type_ = parent;
5574 
5575  if (proto.has_oneof_index()) {
5576  if (proto.oneof_index() < 0 ||
5577  proto.oneof_index() >= parent->oneof_decl_count()) {
5578  AddError(result->full_name(), proto,
5580  strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
5581  "out of range for type \"$1\".",
5582  proto.oneof_index(), parent->name()));
5583  } else {
5584  result->is_oneof_ = true;
5585  result->scope_.containing_oneof =
5586  parent->oneof_decl(proto.oneof_index());
5587  }
5588  }
5589  }
5590 
5591  // Copy options.
5592  result->options_ = nullptr; // Set to default_instance later if necessary.
5593  if (proto.has_options()) {
5594  AllocateOptions(proto.options(), result,
5596  "google.protobuf.FieldOptions");
5597  }
5598 
5599 
5600  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5601 }
5602 
5604  const DescriptorProto::ExtensionRange& proto, const Descriptor* parent,
5605  Descriptor::ExtensionRange* result) {
5606  result->start = proto.start();
5607  result->end = proto.end();
5608  if (result->start <= 0) {
5610  "Extension numbers must be positive integers.");
5611  }
5612 
5613  // Checking of the upper bound of the extension range is deferred until after
5614  // options interpreting. This allows messages with message_set_wire_format to
5615  // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
5616  // numbers are actually used as int32s in the message_set_wire_format.
5617 
5618  if (result->start >= result->end) {
5620  "Extension range end number must be greater than start number.");
5621  }
5622 
5623  result->options_ = nullptr; // Set to default_instance later if necessary.
5624  if (proto.has_options()) {
5625  std::vector<int> options_path;
5626  parent->GetLocationPath(&options_path);
5627  options_path.push_back(DescriptorProto::kExtensionRangeFieldNumber);
5628  // find index of this extension range in order to compute path
5629  int index;
5630  for (index = 0; parent->extension_ranges_ + index != result; index++) {
5631  }
5632  options_path.push_back(index);
5634  AllocateOptionsImpl(parent->full_name(), parent->full_name(),
5635  proto.options(), result, options_path,
5636  "google.protobuf.ExtensionRangeOptions");
5637  }
5638 }
5639 
5641  const DescriptorProto::ReservedRange& proto, const Descriptor* parent,
5642  Descriptor::ReservedRange* result) {
5643  result->start = proto.start();
5644  result->end = proto.end();
5645  if (result->start <= 0) {
5646  AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
5647  "Reserved numbers must be positive integers.");
5648  }
5649 }
5650 
5653  const EnumDescriptor* parent, EnumDescriptor::ReservedRange* result) {
5654  result->start = proto.start();
5655  result->end = proto.end();
5656 
5657  if (result->start > result->end) {
5658  AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
5659  "Reserved range end number must be greater than start number.");
5660  }
5661 }
5662 
5664  Descriptor* parent,
5666  result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name());
5667  ValidateSymbolName(proto.name(), result->full_name(), proto);
5668 
5669  result->containing_type_ = parent;
5670 
5671  // We need to fill these in later.
5672  result->field_count_ = 0;
5673  result->fields_ = nullptr;
5674  result->options_ = nullptr;
5675 
5676  // Copy options.
5677  if (proto.has_options()) {
5678  AllocateOptions(proto.options(), result,
5680  "google.protobuf.OneofOptions");
5681  }
5682 
5683  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5684 }
5685 
5687  const EnumDescriptorProto& proto, const EnumDescriptor* result) {
5688 
5689  // Check that enum labels are still unique when we remove the enum prefix from
5690  // values that have it.
5691  //
5692  // This will fail for something like:
5693  //
5694  // enum MyEnum {
5695  // MY_ENUM_FOO = 0;
5696  // FOO = 1;
5697  // }
5698  //
5699  // By enforcing this reasonable constraint, we allow code generators to strip
5700  // the prefix and/or PascalCase it without creating conflicts. This can lead
5701  // to much nicer language-specific enums like:
5702  //
5703  // enum NameType {
5704  // FirstName = 1,
5705  // LastName = 2,
5706  // }
5707  //
5708  // Instead of:
5709  //
5710  // enum NameType {
5711  // NAME_TYPE_FIRST_NAME = 1,
5712  // NAME_TYPE_LAST_NAME = 2,
5713  // }
5714  PrefixRemover remover(result->name());
5715  std::map<std::string, const EnumValueDescriptor*> values;
5716  for (int i = 0; i < result->value_count(); i++) {
5717  const EnumValueDescriptor* value = result->value(i);
5718  std::string stripped =
5719  EnumValueToPascalCase(remover.MaybeRemove(value->name()));
5721  insert_result = values.insert(std::make_pair(stripped, value));
5722  bool inserted = insert_result.second;
5723 
5724  // We don't throw the error if the two conflicting symbols are identical, or
5725  // if they map to the same number. In the former case, the normal symbol
5726  // duplication error will fire so we don't need to (and its error message
5727  // will make more sense). We allow the latter case so users can create
5728  // aliases which add or remove the prefix (code generators that do prefix
5729  // stripping should de-dup the labels in this case).
5730  if (!inserted && insert_result.first->second->name() != value->name() &&
5731  insert_result.first->second->number() != value->number()) {
5732  std::string error_message =
5733  "Enum name " + value->name() + " has the same name as " +
5734  values[stripped]->name() +
5735  " if you ignore case and strip out the enum name prefix (if any). "
5736  "This is error-prone and can lead to undefined behavior. "
5737  "Please avoid doing this. If you are using allow_alias, please "
5738  "assign the same numeric value to both enums.";
5739  // There are proto2 enums out there with conflicting names, so to preserve
5740  // compatibility we issue only a warning for proto2.
5741  if (result->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) {
5742  AddWarning(value->full_name(), proto.value(i),
5743  DescriptorPool::ErrorCollector::NAME, error_message);
5744  } else {
5745  AddError(value->full_name(), proto.value(i),
5746  DescriptorPool::ErrorCollector::NAME, error_message);
5747  }
5748  }
5749  }
5750 }
5751 
5753  const Descriptor* parent,
5755  const std::string& scope =
5756  (parent == nullptr) ? file_->package() : parent->full_name();
5757 
5758  result->all_names_ = AllocateNameStrings(scope, proto.name());
5759  ValidateSymbolName(proto.name(), result->full_name(), proto);
5760  result->file_ = file_;
5761  result->containing_type_ = parent;
5762  result->is_placeholder_ = false;
5763  result->is_unqualified_placeholder_ = false;
5764 
5765  if (proto.value_size() == 0) {
5766  // We cannot allow enums with no values because this would mean there
5767  // would be no valid default value for fields of this type.
5769  "Enums must contain at least one value.");
5770  }
5771 
5772  // Calculate the continuous sequence of the labels.
5773  // These can be fast-path'd during lookup and don't need to be added to the
5774  // tables.
5775  // We use uint16_t to save space for sequential_value_limit_, so stop before
5776  // overflowing it. Worst case, we are not taking full advantage on huge
5777  // enums, but it is unlikely.
5778  for (int i = 0;
5780  // We do the math in int64_t to avoid overflows.
5781  proto.value(i).number() ==
5782  static_cast<int64_t>(i) + proto.value(0).number();
5783  ++i) {
5784  result->sequential_value_limit_ = i;
5785  }
5786 
5789 
5790  // Copy reserved names.
5791  int reserved_name_count = proto.reserved_name_size();
5792  result->reserved_name_count_ = reserved_name_count;
5793  result->reserved_names_ =
5794  tables_->AllocateArray<const std::string*>(reserved_name_count);
5795  for (int i = 0; i < reserved_name_count; ++i) {
5796  result->reserved_names_[i] =
5797  tables_->AllocateString(proto.reserved_name(i));
5798  }
5799 
5801 
5802  // Copy options.
5803  result->options_ = nullptr; // Set to default_instance later if necessary.
5804  if (proto.has_options()) {
5805  AllocateOptions(proto.options(), result,
5807  "google.protobuf.EnumOptions");
5808  }
5809 
5810  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5811 
5812  for (int i = 0; i < proto.reserved_range_size(); i++) {
5814  proto.reserved_range(i);
5815  for (int j = i + 1; j < proto.reserved_range_size(); j++) {
5817  proto.reserved_range(j);
5818  if (range1.end() >= range2.start() && range2.end() >= range1.start()) {
5819  AddError(result->full_name(), proto.reserved_range(i),
5821  strings::Substitute("Reserved range $0 to $1 overlaps with "
5822  "already-defined range $2 to $3.",
5823  range2.start(), range2.end(), range1.start(),
5824  range1.end()));
5825  }
5826  }
5827  }
5828 
5829  HASH_SET<std::string> reserved_name_set;
5830  for (int i = 0; i < proto.reserved_name_size(); i++) {
5831  const std::string& name = proto.reserved_name(i);
5832  if (reserved_name_set.find(name) == reserved_name_set.end()) {
5833  reserved_name_set.insert(name);
5834  } else {
5836  strings::Substitute("Enum value \"$0\" is reserved multiple times.",
5837  name));
5838  }
5839  }
5840 
5841  for (int i = 0; i < result->value_count(); i++) {
5842  const EnumValueDescriptor* value = result->value(i);
5843  for (int j = 0; j < result->reserved_range_count(); j++) {
5844  const EnumDescriptor::ReservedRange* range = result->reserved_range(j);
5845  if (range->start <= value->number() && value->number() <= range->end) {
5846  AddError(value->full_name(), proto.reserved_range(j),
5848  strings::Substitute("Enum value \"$0\" uses reserved number $1.",
5849  value->name(), value->number()));
5850  }
5851  }
5852  if (reserved_name_set.find(value->name()) != reserved_name_set.end()) {
5853  AddError(
5854  value->full_name(), proto.value(i),
5856  strings::Substitute("Enum value \"$0\" is reserved.", value->name()));
5857  }
5858  }
5859 }
5860 
5862  const EnumDescriptor* parent,
5864  // Note: full_name for enum values is a sibling to the parent's name, not a
5865  // child of it.
5866  std::string full_name;
5867  size_t scope_len = parent->full_name().size() - parent->name().size();
5868  full_name.reserve(scope_len + proto.name().size());
5869  full_name.append(parent->full_name().data(), scope_len);
5870  full_name.append(proto.name());
5871 
5872  result->all_names_ =
5873  tables_->AllocateStringArray(proto.name(), std::move(full_name));
5874  result->number_ = proto.number();
5875  result->type_ = parent;
5876 
5877  ValidateSymbolName(proto.name(), result->full_name(), proto);
5878 
5879  // Copy options.
5880  result->options_ = nullptr; // Set to default_instance later if necessary.
5881  if (proto.has_options()) {
5882  AllocateOptions(proto.options(), result,
5884  "google.protobuf.EnumValueOptions");
5885  }
5886 
5887  // Again, enum values are weird because we makes them appear as siblings
5888  // of the enum type instead of children of it. So, we use
5889  // parent->containing_type() as the value's parent.
5890  bool added_to_outer_scope =
5891  AddSymbol(result->full_name(), parent->containing_type(), result->name(),
5892  proto, Symbol::EnumValue(result, 0));
5893 
5894  // However, we also want to be able to search for values within a single
5895  // enum type, so we add it as a child of the enum type itself, too.
5896  // Note: This could fail, but if it does, the error has already been
5897  // reported by the above AddSymbol() call, so we ignore the return code.
5898  bool added_to_inner_scope = file_tables_->AddAliasUnderParent(
5899  parent, result->name(), Symbol::EnumValue(result, 1));
5900 
5901  if (added_to_inner_scope && !added_to_outer_scope) {
5902  // This value did not conflict with any values defined in the same enum,
5903  // but it did conflict with some other symbol defined in the enum type's
5904  // scope. Let's print an additional error to explain this.
5905  std::string outer_scope;
5906  if (parent->containing_type() == nullptr) {
5907  outer_scope = file_->package();
5908  } else {
5909  outer_scope = parent->containing_type()->full_name();
5910  }
5911 
5912  if (outer_scope.empty()) {
5913  outer_scope = "the global scope";
5914  } else {
5915  outer_scope = "\"" + outer_scope + "\"";
5916  }
5917 
5919  "Note that enum values use C++ scoping rules, meaning that "
5920  "enum values are siblings of their type, not children of it. "
5921  "Therefore, \"" +
5922  result->name() + "\" must be unique within " + outer_scope +
5923  ", not just within \"" + parent->name() + "\".");
5924  }
5925 
5926  // An enum is allowed to define two numbers that refer to the same value.
5927  // FindValueByNumber() should return the first such value, so we simply
5928  // ignore AddEnumValueByNumber()'s return code.
5930 }
5931 
5933  const void* /* dummy */,
5935  result->all_names_ = AllocateNameStrings(file_->package(), proto.name());
5936  result->file_ = file_;
5937  ValidateSymbolName(proto.name(), result->full_name(), proto);
5938 
5940 
5941  // Copy options.
5942  result->options_ = nullptr; // Set to default_instance later if necessary.
5943  if (proto.has_options()) {
5944  AllocateOptions(proto.options(), result,
5946  "google.protobuf.ServiceOptions");
5947  }
5948 
5949  AddSymbol(result->full_name(), nullptr, result->name(), proto,
5950  Symbol(result));
5951 }
5952 
5954  const ServiceDescriptor* parent,
5956  result->service_ = parent;
5957  result->all_names_ = AllocateNameStrings(parent->full_name(), proto.name());
5958 
5959  ValidateSymbolName(proto.name(), result->full_name(), proto);
5960 
5961  // These will be filled in when cross-linking.
5962  result->input_type_.Init();
5963  result->output_type_.Init();
5964 
5965  // Copy options.
5966  result->options_ = nullptr; // Set to default_instance later if necessary.
5967  if (proto.has_options()) {
5968  AllocateOptions(proto.options(), result,
5970  "google.protobuf.MethodOptions");
5971  }
5972 
5973  result->client_streaming_ = proto.client_streaming();
5974  result->server_streaming_ = proto.server_streaming();
5975 
5976  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
5977 }
5978 
5979 #undef BUILD_ARRAY
5980 
5981 // -------------------------------------------------------------------
5982 
5984  const FileDescriptorProto& proto) {
5985  if (file->options_ == nullptr) {
5986  file->options_ = &FileOptions::default_instance();
5987  }
5988 
5989  for (int i = 0; i < file->message_type_count(); i++) {
5990  CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
5991  }
5992 
5993  for (int i = 0; i < file->extension_count(); i++) {
5994  CrossLinkField(&file->extensions_[i], proto.extension(i));
5995  }
5996 
5997  for (int i = 0; i < file->enum_type_count(); i++) {
5998  CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i));
5999  }
6000 
6001  for (int i = 0; i < file->service_count(); i++) {
6002  CrossLinkService(&file->services_[i], proto.service(i));
6003  }
6004 }
6005 
6007  const DescriptorProto& proto) {
6008  if (message->options_ == nullptr) {
6010  }
6011 
6012  for (int i = 0; i < message->nested_type_count(); i++) {
6013  CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
6014  }
6015 
6016  for (int i = 0; i < message->enum_type_count(); i++) {
6017  CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i));
6018  }
6019 
6020  for (int i = 0; i < message->field_count(); i++) {
6021  CrossLinkField(&message->fields_[i], proto.field(i));
6022  }
6023 
6024  for (int i = 0; i < message->extension_count(); i++) {
6025  CrossLinkField(&message->extensions_[i], proto.extension(i));
6026  }
6027 
6028  for (int i = 0; i < message->extension_range_count(); i++) {
6029  CrossLinkExtensionRange(&message->extension_ranges_[i],
6030  proto.extension_range(i));
6031  }
6032 
6033  // Set up field array for each oneof.
6034 
6035  // First count the number of fields per oneof.
6036  for (int i = 0; i < message->field_count(); i++) {
6037  const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
6038  if (oneof_decl != nullptr) {
6039  // Make sure fields belonging to the same oneof are defined consecutively.
6040  // This enables optimizations in codegens and reflection libraries to
6041  // skip fields in the oneof group, as only one of the field can be set.
6042  // Note that field_count() returns how many fields in this oneof we have
6043  // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is
6044  // safe.
6045  if (oneof_decl->field_count() > 0 &&
6046  message->field(i - 1)->containing_oneof() != oneof_decl) {
6047  AddError(message->full_name() + "." + message->field(i - 1)->name(),
6050  "Fields in the same oneof must be defined consecutively. "
6051  "\"$0\" cannot be defined before the completion of the "
6052  "\"$1\" oneof definition.",
6053  message->field(i - 1)->name(), oneof_decl->name()));
6054  }
6055  // Must go through oneof_decls_ array to get a non-const version of the
6056  // OneofDescriptor.
6057  auto& out_oneof_decl = message->oneof_decls_[oneof_decl->index()];
6058  if (out_oneof_decl.field_count_ == 0) {
6059  out_oneof_decl.fields_ = message->field(i);
6060  }
6061 
6062  if (!had_errors_) {
6063  // Verify that they are contiguous.
6064  // This is assumed by OneofDescriptor::field(i).
6065  // But only if there are no errors.
6066  GOOGLE_CHECK_EQ(out_oneof_decl.fields_ + out_oneof_decl.field_count_,
6067  message->field(i));
6068  }
6069  ++out_oneof_decl.field_count_;
6070  }
6071  }
6072 
6073  // Then verify the sizes.
6074  for (int i = 0; i < message->oneof_decl_count(); i++) {
6075  OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
6076 
6077  if (oneof_decl->field_count() == 0) {
6078  AddError(message->full_name() + "." + oneof_decl->name(),
6080  "Oneof must have at least one field.");
6081  }
6082 
6083  if (oneof_decl->options_ == nullptr) {
6084  oneof_decl->options_ = &OneofOptions::default_instance();
6085  }
6086  }
6087 
6088  for (int i = 0; i < message->field_count(); i++) {
6089  const FieldDescriptor* field = message->field(i);
6090  if (field->proto3_optional_) {
6091  if (!field->containing_oneof() ||
6092  !field->containing_oneof()->is_synthetic()) {
6093  AddError(message->full_name(), proto.field(i),
6095  "Fields with proto3_optional set must be "
6096  "a member of a one-field oneof");
6097  }
6098  }
6099  }
6100 
6101  // Synthetic oneofs must be last.
6102  int first_synthetic = -1;
6103  for (int i = 0; i < message->oneof_decl_count(); i++) {
6104  const OneofDescriptor* oneof = message->oneof_decl(i);
6105  if (oneof->is_synthetic()) {
6106  if (first_synthetic == -1) {
6107  first_synthetic = i;
6108  }
6109  } else {
6110  if (first_synthetic != -1) {
6111  AddError(message->full_name(), proto.oneof_decl(i),
6113  "Synthetic oneofs must be after all other oneofs");
6114  }
6115  }
6116  }
6117 
6118  if (first_synthetic == -1) {
6119  message->real_oneof_decl_count_ = message->oneof_decl_count_;
6120  } else {
6121  message->real_oneof_decl_count_ = first_synthetic;
6122  }
6123 }
6124 
6126  Descriptor::ExtensionRange* range,
6127  const DescriptorProto::ExtensionRange& /*proto*/) {
6128  if (range->options_ == nullptr) {
6130  }
6131 }
6132 
6134  const FieldDescriptorProto& proto) {
6135  if (field->options_ == nullptr) {
6136  field->options_ = &FieldOptions::default_instance();
6137  }
6138 
6139  // Add the field to the lowercase-name and camelcase-name tables.
6141 
6142  if (proto.has_extendee()) {
6143  Symbol extendee =
6144  LookupSymbol(proto.extendee(), field->full_name(),
6146  if (extendee.IsNull()) {
6147  AddNotDefinedError(field->full_name(), proto,
6149  proto.extendee());
6150  return;
6151  } else if (extendee.type() != Symbol::MESSAGE) {
6152  AddError(field->full_name(), proto,
6154  "\"" + proto.extendee() + "\" is not a message type.");
6155  return;
6156  }
6157  field->containing_type_ = extendee.descriptor();
6158 
6159  const Descriptor::ExtensionRange* extension_range =
6160  field->containing_type()->FindExtensionRangeContainingNumber(
6161  field->number());
6162 
6163  if (extension_range == nullptr) {
6164  // Set of valid extension numbers for MessageSet is different (< 2^32)
6165  // from other extendees (< 2^29). If unknown deps are allowed, we may not
6166  // have that information, and wrongly deem the extension as invalid.
6167  auto skip_check = get_allow_unknown(pool_) &&
6168  proto.extendee() == "google.protobuf.bridge.MessageSet";
6169  if (!skip_check) {
6170  AddError(field->full_name(), proto,
6172  strings::Substitute("\"$0\" does not declare $1 as an "
6173  "extension number.",
6174  field->containing_type()->full_name(),
6175  field->number()));
6176  }
6177  }
6178  }
6179 
6180  if (field->containing_oneof() != nullptr) {
6181  if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
6182  // Note that this error will never happen when parsing .proto files.
6183  // It can only happen if you manually construct a FileDescriptorProto
6184  // that is incorrect.
6186  "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
6187  }
6188  }
6189 
6190  if (proto.has_type_name()) {
6191  // Assume we are expecting a message type unless the proto contains some
6192  // evidence that it expects an enum type. This only makes a difference if
6193  // we end up creating a placeholder.
6194  bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
6195  proto.has_default_value();
6196 
6197  // In case of weak fields we force building the dependency. We need to know
6198  // if the type exist or not. If it doesn't exist we substitute Empty which
6199  // should only be done if the type can't be found in the generated pool.
6200  // TODO(gerbens) Ideally we should query the database directly to check
6201  // if weak fields exist or not so that we don't need to force building
6202  // weak dependencies. However the name lookup rules for symbols are
6203  // somewhat complicated, so I defer it too another CL.
6204  bool is_weak = !pool_->enforce_weak_ && proto.options().weak();
6205  bool is_lazy = pool_->lazily_build_dependencies_ && !is_weak;
6206 
6207  Symbol type =
6208  LookupSymbol(proto.type_name(), field->full_name(),
6209  expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM
6211  LOOKUP_TYPES, !is_lazy);
6212 
6213  if (type.IsNull()) {
6214  if (is_lazy) {
6215  // Save the symbol names for later for lookup, and allocate the once
6216  // object needed for the accessors.
6217  std::string name = proto.type_name();
6218  field->type_once_ = tables_->Create<internal::once_flag>();
6219  field->type_descriptor_.lazy_type_name = tables_->Strdup(name);
6220  field->lazy_default_value_enum_name_ =
6221  proto.has_default_value() ? tables_->Strdup(proto.default_value())
6222  : nullptr;
6223 
6224  // AddFieldByNumber and AddExtension are done later in this function,
6225  // and can/must be done if the field type was not found. The related
6226  // error checking is not necessary when in lazily_build_dependencies_
6227  // mode, and can't be done without building the type's descriptor,
6228  // which we don't want to do.
6230  if (field->is_extension()) {
6231  tables_->AddExtension(field);
6232  }
6233  return;
6234  } else {
6235  // If the type is a weak type, we change the type to a google.protobuf.Empty
6236  // field.
6237  if (is_weak) {
6239  }
6240  if (type.IsNull()) {
6241  AddNotDefinedError(field->full_name(), proto,
6243  proto.type_name());
6244  return;
6245  }
6246  }
6247  }
6248 
6249  if (!proto.has_type()) {
6250  // Choose field type based on symbol.
6251  if (type.type() == Symbol::MESSAGE) {
6253  } else if (type.type() == Symbol::ENUM) {
6255  } else {
6256  AddError(field->full_name(), proto,
6258  "\"" + proto.type_name() + "\" is not a type.");
6259  return;
6260  }
6261  }
6262 
6263  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
6264  field->type_descriptor_.message_type = type.descriptor();
6265  if (field->type_descriptor_.message_type == nullptr) {
6266  AddError(field->full_name(), proto,
6268  "\"" + proto.type_name() + "\" is not a message type.");
6269  return;
6270  }
6271 
6272  if (field->has_default_value()) {
6273  AddError(field->full_name(), proto,
6275  "Messages can't have default values.");
6276  }
6277  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
6278  field->type_descriptor_.enum_type = type.enum_descriptor();
6279  if (field->type_descriptor_.enum_type == nullptr) {
6280  AddError(field->full_name(), proto,
6282  "\"" + proto.type_name() + "\" is not an enum type.");
6283  return;
6284  }
6285 
6286  if (field->enum_type()->is_placeholder_) {
6287  // We can't look up default values for placeholder types. We'll have
6288  // to just drop them.
6289  field->has_default_value_ = false;
6290  }
6291 
6292  if (field->has_default_value()) {
6293  // Ensure that the default value is an identifier. Parser cannot always
6294  // verify this because it does not have complete type information.
6295  // N.B. that this check yields better error messages but is not
6296  // necessary for correctness (an enum symbol must be a valid identifier
6297  // anyway), only for better errors.
6299  AddError(field->full_name(), proto,
6301  "Default value for an enum field must be an identifier.");
6302  } else {
6303  // We can't just use field->enum_type()->FindValueByName() here
6304  // because that locks the pool's mutex, which we have already locked
6305  // at this point.
6306  const EnumValueDescriptor* default_value =
6308  field->enum_type()->full_name())
6310 
6311  if (default_value != nullptr &&
6312  default_value->type() == field->enum_type()) {
6313  field->default_value_enum_ = default_value;
6314  } else {
6315  AddError(field->full_name(), proto,
6317  "Enum type \"" + field->enum_type()->full_name() +
6318  "\" has no value named \"" + proto.default_value() +
6319  "\".");
6320  }
6321  }
6322  } else if (field->enum_type()->value_count() > 0) {
6323  // All enums must have at least one value, or we would have reported
6324  // an error elsewhere. We use the first defined value as the default
6325  // if a default is not explicitly defined.
6326  field->default_value_enum_ = field->enum_type()->value(0);
6327  }
6328  } else {
6330  "Field with primitive type has type_name.");
6331  }
6332  } else {
6333  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
6334  field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
6336  "Field with message or enum type missing type_name.");
6337  }
6338  }
6339 
6340  // Add the field to the fields-by-number table.
6341  // Note: We have to do this *after* cross-linking because extensions do not
6342  // know their containing type until now. If we're in
6343  // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no
6344  // risk to calling containing_type() or other accessors that will build
6345  // dependencies.
6347  const FieldDescriptor* conflicting_field = file_tables_->FindFieldByNumber(
6348  field->containing_type(), field->number());
6349  std::string containing_type_name =
6350  field->containing_type() == nullptr
6351  ? "unknown"
6352  : field->containing_type()->full_name();
6353  if (field->is_extension()) {
6354  AddError(field->full_name(), proto,
6356  strings::Substitute("Extension number $0 has already been used "
6357  "in \"$1\" by extension \"$2\".",
6358  field->number(), containing_type_name,
6359  conflicting_field->full_name()));
6360  } else {
6361  AddError(field->full_name(), proto,
6363  strings::Substitute("Field number $0 has already been used in "
6364  "\"$1\" by field \"$2\".",
6365  field->number(), containing_type_name,
6366  conflicting_field->name()));
6367  }
6368  } else {
6369  if (field->is_extension()) {
6370  if (!tables_->AddExtension(field)) {
6371  const FieldDescriptor* conflicting_field =
6372  tables_->FindExtension(field->containing_type(), field->number());
6373  std::string containing_type_name =
6374  field->containing_type() == nullptr
6375  ? "unknown"
6376  : field->containing_type()->full_name();
6377  std::string error_msg = strings::Substitute(
6378  "Extension number $0 has already been used in \"$1\" by extension "
6379  "\"$2\" defined in $3.",
6380  field->number(), containing_type_name,
6381  conflicting_field->full_name(), conflicting_field->file()->name());
6382  // Conflicting extension numbers should be an error. However, before
6383  // turning this into an error we need to fix all existing broken
6384  // protos first.
6385  // TODO(xiaofeng): Change this to an error.
6386  AddWarning(field->full_name(), proto,
6388  }
6389  }
6390  }
6391 }
6392 
6394  const EnumDescriptorProto& proto) {
6395  if (enum_type->options_ == nullptr) {
6397  }
6398 
6399  for (int i = 0; i < enum_type->value_count(); i++) {
6400  CrossLinkEnumValue(&enum_type->values_[i], proto.value(i));
6401  }
6402 }
6403 
6405  EnumValueDescriptor* enum_value,
6406  const EnumValueDescriptorProto& /* proto */) {
6407  if (enum_value->options_ == nullptr) {
6408  enum_value->options_ = &EnumValueOptions::default_instance();
6409  }
6410 }
6411 
6413  const ServiceDescriptorProto& proto) {
6414  if (service->options_ == nullptr) {
6416  }
6417 
6418  for (int i = 0; i < service->method_count(); i++) {
6419  CrossLinkMethod(&service->methods_[i], proto.method(i));
6420  }
6421 }
6422 
6424  const MethodDescriptorProto& proto) {
6425  if (method->options_ == nullptr) {
6427  }
6428 
6429  Symbol input_type =
6433  if (input_type.IsNull()) {
6437  proto.input_type());
6438  } else {
6439  method->input_type_.SetLazy(proto.input_type(), file_);
6440  }
6441  } else if (input_type.type() != Symbol::MESSAGE) {
6442  AddError(method->full_name(), proto,
6444  "\"" + proto.input_type() + "\" is not a message type.");
6445  } else {
6446  method->input_type_.Set(input_type.descriptor());
6447  }
6448 
6449  Symbol output_type =
6453  if (output_type.IsNull()) {
6457  proto.output_type());
6458  } else {
6459  method->output_type_.SetLazy(proto.output_type(), file_);
6460  }
6461  } else if (output_type.type() != Symbol::MESSAGE) {
6462  AddError(method->full_name(), proto,
6464  "\"" + proto.output_type() + "\" is not a message type.");
6465  } else {
6466  method->output_type_.Set(output_type.descriptor());
6467  }
6468 }
6469 
6470 // -------------------------------------------------------------------
6471 
6472 #define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type) \
6473  for (int i = 0; i < descriptor->array_name##_count(); ++i) { \
6474  Validate##type##Options(descriptor->array_name##s_ + i, \
6475  proto.array_name(i)); \
6476  }
6477 
6478 // Determine if the file uses optimize_for = LITE_RUNTIME, being careful to
6479 // avoid problems that exist at init time.
6480 static bool IsLite(const FileDescriptor* file) {
6481  // TODO(kenton): I don't even remember how many of these conditions are
6482  // actually possible. I'm just being super-safe.
6483  return file != nullptr &&
6484  &file->options() != &FileOptions::default_instance() &&
6485  file->options().optimize_for() == FileOptions::LITE_RUNTIME;
6486 }
6487 
6489  const FileDescriptorProto& proto) {
6494 
6495  // Lite files can only be imported by other Lite files.
6496  if (!IsLite(file)) {
6497  for (int i = 0; i < file->dependency_count(); i++) {
6498  if (IsLite(file->dependency(i))) {
6499  AddError(
6500  file->dependency(i)->name(), proto,
6502  "Files that do not use optimize_for = LITE_RUNTIME cannot import "
6503  "files which do use this option. This file is not lite, but it "
6504  "imports \"" +
6505  file->dependency(i)->name() + "\" which is.");
6506  break;
6507  }
6508  }
6509  }
6510  if (file->syntax() == FileDescriptor::SYNTAX_PROTO3) {
6511  ValidateProto3(file, proto);
6512  }
6513 }
6514 
6516  const FileDescriptorProto& proto) {
6517  for (int i = 0; i < file->extension_count(); ++i) {
6518  ValidateProto3Field(file->extensions_ + i, proto.extension(i));
6519  }
6520  for (int i = 0; i < file->message_type_count(); ++i) {
6521  ValidateProto3Message(file->message_types_ + i, proto.message_type(i));
6522  }
6523  for (int i = 0; i < file->enum_type_count(); ++i) {
6524  ValidateProto3Enum(file->enum_types_ + i, proto.enum_type(i));
6525  }
6526 }
6527 
6530  for (char character : name) {
6531  if (character != '_') {
6532  if (character >= 'A' && character <= 'Z') {
6533  result.push_back(character - 'A' + 'a');
6534  } else {
6535  result.push_back(character);
6536  }
6537  }
6538  }
6539  return result;
6540 }
6541 
6543  const DescriptorProto& proto) {
6544  for (int i = 0; i < message->nested_type_count(); ++i) {
6545  ValidateProto3Message(message->nested_types_ + i, proto.nested_type(i));
6546  }
6547  for (int i = 0; i < message->enum_type_count(); ++i) {
6548  ValidateProto3Enum(message->enum_types_ + i, proto.enum_type(i));
6549  }
6550  for (int i = 0; i < message->field_count(); ++i) {
6551  ValidateProto3Field(message->fields_ + i, proto.field(i));
6552  }
6553  for (int i = 0; i < message->extension_count(); ++i) {
6554  ValidateProto3Field(message->extensions_ + i, proto.extension(i));
6555  }
6556  if (message->extension_range_count() > 0) {
6557  AddError(message->full_name(), proto.extension_range(0),
6559  "Extension ranges are not allowed in proto3.");
6560  }
6561  if (message->options().message_set_wire_format()) {
6562  // Using MessageSet doesn't make sense since we disallow extensions.
6564  "MessageSet is not supported in proto3.");
6565  }
6566 
6567  // In proto3, we reject field names if they conflict in camelCase.
6568  // Note that we currently enforce a stricter rule: Field names must be
6569  // unique after being converted to lowercase with underscores removed.
6570  std::map<std::string, const FieldDescriptor*> name_to_field;
6571  for (int i = 0; i < message->field_count(); ++i) {
6572  std::string lowercase_name =
6573  ToLowercaseWithoutUnderscores(message->field(i)->name());
6574  if (name_to_field.find(lowercase_name) != name_to_field.end()) {
6575  AddError(message->full_name(), proto.field(i),
6577  "The JSON camel-case name of field \"" +
6578  message->field(i)->name() + "\" conflicts with field \"" +
6579  name_to_field[lowercase_name]->name() + "\". This is not " +
6580  "allowed in proto3.");
6581  } else {
6582  name_to_field[lowercase_name] = message->field(i);
6583  }
6584  }
6585 }
6586 
6588  const FieldDescriptorProto& proto) {
6589  if (field->is_extension() &&
6590  !AllowedExtendeeInProto3(field->containing_type()->full_name())) {
6591  AddError(field->full_name(), proto,
6593  "Extensions in proto3 are only allowed for defining options.");
6594  }
6595  if (field->is_required()) {
6597  "Required fields are not allowed in proto3.");
6598  }
6599  if (field->has_default_value()) {
6600  AddError(field->full_name(), proto,
6602  "Explicit default values are not allowed in proto3.");
6603  }
6604  if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
6605  field->enum_type() &&
6606  field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
6607  field->enum_type()->file()->syntax() != FileDescriptor::SYNTAX_UNKNOWN) {
6608  // Proto3 messages can only use Proto3 enum types; otherwise we can't
6609  // guarantee that the default value is zero.
6611  "Enum type \"" + field->enum_type()->full_name() +
6612  "\" is not a proto3 enum, but is used in \"" +
6613  field->containing_type()->full_name() +
6614  "\" which is a proto3 message type.");
6615  }
6616  if (field->type() == FieldDescriptor::TYPE_GROUP) {
6618  "Groups are not supported in proto3 syntax.");
6619  }
6620 }
6621 
6623  const EnumDescriptorProto& proto) {
6624  if (enm->value_count() > 0 && enm->value(0)->number() != 0) {
6625  AddError(enm->full_name(), proto.value(0),
6627  "The first enum value must be zero in proto3.");
6628  }
6629 }
6630 
6632  const DescriptorProto& proto) {
6637 
6638  const int64_t max_extension_range =
6639  static_cast<int64_t>(message->options().message_set_wire_format()
6641  : FieldDescriptor::kMaxNumber);
6642  for (int i = 0; i < message->extension_range_count(); ++i) {
6643  if (message->extension_range(i)->end > max_extension_range + 1) {
6644  AddError(message->full_name(), proto.extension_range(i),
6646  strings::Substitute("Extension numbers cannot be greater than $0.",
6647  max_extension_range));
6648  }
6649 
6651  message->extension_ranges_ + i,
6652  proto.extension_range(i));
6653  }
6654 }
6655 
6656 
6658  FieldDescriptor* field, const FieldDescriptorProto& proto) {
6659  if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) {
6660  return;
6661  }
6662  // Only message type fields may be lazy.
6663  if (field->options().lazy()) {
6664  if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
6666  "[lazy = true] can only be specified for submessage fields.");
6667  }
6668  }
6669 
6670  // Only repeated primitive fields may be packed.
6671  if (field->options().packed() && !field->is_packable()) {
6672  AddError(
6673  field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
6674  "[packed = true] can only be specified for repeated primitive fields.");
6675  }
6676 
6677  // Note: Default instance may not yet be initialized here, so we have to
6678  // avoid reading from it.
6679  if (field->containing_type_ != nullptr &&
6680  &field->containing_type()->options() !=
6682  field->containing_type()->options().message_set_wire_format()) {
6683  if (field->is_extension()) {
6684  if (!field->is_optional() ||
6685  field->type() != FieldDescriptor::TYPE_MESSAGE) {
6686  AddError(field->full_name(), proto,
6688  "Extensions of MessageSets must be optional messages.");
6689  }
6690  } else {
6692  "MessageSets cannot have fields, only extensions.");
6693  }
6694  }
6695 
6696  // Lite extensions can only be of Lite types.
6697  if (IsLite(field->file()) && field->containing_type_ != nullptr &&
6698  !IsLite(field->containing_type()->file())) {
6699  AddError(field->full_name(), proto,
6701  "Extensions to non-lite types can only be declared in non-lite "
6702  "files. Note that you cannot extend a non-lite type to contain "
6703  "a lite type, but the reverse is allowed.");
6704  }
6705 
6706  // Validate map types.
6707  if (field->is_map()) {
6708  if (!ValidateMapEntry(field, proto)) {
6710  "map_entry should not be set explicitly. Use map<KeyType, "
6711  "ValueType> instead.");
6712  }
6713  }
6714 
6715  ValidateJSType(field, proto);
6716 
6717  // json_name option is not allowed on extension fields. Note that the
6718  // json_name field in FieldDescriptorProto is always populated by protoc
6719  // when it sends descriptor data to plugins (calculated from field name if
6720  // the option is not explicitly set) so we can't rely on its presence to
6721  // determine whether the json_name option is set on the field. Here we
6722  // compare it against the default calculated json_name value and consider
6723  // the option set if they are different. This won't catch the case when
6724  // an user explicitly sets json_name to the default value, but should be
6725  // good enough to catch common misuses.
6726  if (field->is_extension() &&
6727  (field->has_json_name() &&
6728  field->json_name() != ToJsonName(field->name()))) {
6729  AddError(field->full_name(), proto,
6731  "option json_name is not allowed on extension fields.");
6732  }
6733 
6734 }
6735 
6737  const EnumDescriptorProto& proto) {
6739  if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
6740  std::map<int, std::string> used_values;
6741  for (int i = 0; i < enm->value_count(); ++i) {
6742  const EnumValueDescriptor* enum_value = enm->value(i);
6743  if (used_values.find(enum_value->number()) != used_values.end()) {
6744  std::string error =
6745  "\"" + enum_value->full_name() +
6746  "\" uses the same enum value as \"" +
6747  used_values[enum_value->number()] +
6748  "\". If this is intended, set "
6749  "'option allow_alias = true;' to the enum definition.";
6750  if (!enm->options().allow_alias()) {
6751  // Generate error if duplicated enum values are explicitly disallowed.
6752  AddError(enm->full_name(), proto.value(i),
6754  }
6755  } else {
6756  used_values[enum_value->number()] = enum_value->full_name();
6757  }
6758  }
6759  }
6760 }
6761 
6763  EnumValueDescriptor* /* enum_value */,
6764  const EnumValueDescriptorProto& /* proto */) {
6765  // Nothing to do so far.
6766 }
6767 
6769  const std::string& full_name, Descriptor::ExtensionRange* extension_range,
6770  const DescriptorProto_ExtensionRange& proto) {
6771  (void)full_name; // Parameter is used by Google-internal code.
6772  (void)extension_range; // Parameter is used by Google-internal code.
6773 }
6774 
6777  if (IsLite(service->file()) &&
6778  (service->file()->options().cc_generic_services() ||
6779  service->file()->options().java_generic_services())) {
6781  "Files with optimize_for = LITE_RUNTIME cannot define services "
6782  "unless you set both options cc_generic_services and "
6783  "java_generic_services to false.");
6784  }
6785 
6787 }
6788 
6790  MethodDescriptor* /* method */, const MethodDescriptorProto& /* proto */) {
6791  // Nothing to do so far.
6792 }
6793 
6795  const FieldDescriptorProto& proto) {
6796  const Descriptor* message = field->message_type();
6797  if ( // Must not contain extensions, extension range or nested message or
6798  // enums
6799  message->extension_count() != 0 ||
6800  field->label() != FieldDescriptor::LABEL_REPEATED ||
6801  message->extension_range_count() != 0 ||
6802  message->nested_type_count() != 0 || message->enum_type_count() != 0 ||
6803  // Must contain exactly two fields
6804  message->field_count() != 2 ||
6805  // Field name and message name must match
6806  message->name() != ToCamelCase(field->name(), false) + "Entry" ||
6807  // Entry message must be in the same containing type of the field.
6808  field->containing_type() != message->containing_type()) {
6809  return false;
6810  }
6811 
6812  const FieldDescriptor* key = message->map_key();
6813  const FieldDescriptor* value = message->map_value();
6814  if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 ||
6815  key->name() != "key") {
6816  return false;
6817  }
6818  if (value->label() != FieldDescriptor::LABEL_OPTIONAL ||
6819  value->number() != 2 || value->name() != "value") {
6820  return false;
6821  }
6822 
6823  // Check key types are legal.
6824  switch (key->type()) {
6827  "Key in map fields cannot be enum types.");
6828  break;
6834  AddError(
6835  field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
6836  "Key in map fields cannot be float/double, bytes or message types.");
6837  break;
6850  // Legal cases
6851  break;
6852  // Do not add a default, so that the compiler will complain when new types
6853  // are added.
6854  }
6855 
6856  if (value->type() == FieldDescriptor::TYPE_ENUM) {
6857  if (value->enum_type()->value(0)->number() != 0) {
6859  "Enum value in map must define 0 as the first value.");
6860  }
6861  }
6862 
6863  return true;
6864 }
6865 
6867  const DescriptorProto& proto) {
6868  std::map<std::string, const Descriptor*> seen_types;
6869  for (int i = 0; i < message->nested_type_count(); ++i) {
6870  const Descriptor* nested = message->nested_type(i);
6872  seen_types.insert(std::make_pair(nested->name(), nested));
6873  if (!result.second) {
6874  if (result.first->second->options().map_entry() ||
6875  nested->options().map_entry()) {
6876  AddError(message->full_name(), proto,
6878  "Expanded map entry type " + nested->name() +
6879  " conflicts with an existing nested message type.");
6880  }
6881  }
6882  // Recursively test on the nested types.
6883  DetectMapConflicts(message->nested_type(i), proto.nested_type(i));
6884  }
6885  // Check for conflicted field names.
6886  for (int i = 0; i < message->field_count(); ++i) {
6887  const FieldDescriptor* field = message->field(i);
6889  seen_types.find(field->name());
6890  if (iter != seen_types.end() && iter->second->options().map_entry()) {
6891  AddError(message->full_name(), proto,
6893  "Expanded map entry type " + iter->second->name() +
6894  " conflicts with an existing field.");
6895  }
6896  }
6897  // Check for conflicted enum names.
6898  for (int i = 0; i < message->enum_type_count(); ++i) {
6899  const EnumDescriptor* enum_desc = message->enum_type(i);
6901  seen_types.find(enum_desc->name());
6902  if (iter != seen_types.end() && iter->second->options().map_entry()) {
6903  AddError(message->full_name(), proto,
6905  "Expanded map entry type " + iter->second->name() +
6906  " conflicts with an existing enum type.");
6907  }
6908  }
6909  // Check for conflicted oneof names.
6910  for (int i = 0; i < message->oneof_decl_count(); ++i) {
6911  const OneofDescriptor* oneof_desc = message->oneof_decl(i);
6913  seen_types.find(oneof_desc->name());
6914  if (iter != seen_types.end() && iter->second->options().map_entry()) {
6915  AddError(message->full_name(), proto,
6917  "Expanded map entry type " + iter->second->name() +
6918  " conflicts with an existing oneof type.");
6919  }
6920  }
6921 }
6922 
6924  const FieldDescriptorProto& proto) {
6925  FieldOptions::JSType jstype = field->options().jstype();
6926  // The default is always acceptable.
6927  if (jstype == FieldOptions::JS_NORMAL) {
6928  return;
6929  }
6930 
6931  switch (field->type()) {
6932  // Integral 64-bit types may be represented as JavaScript numbers or
6933  // strings.
6939  if (jstype == FieldOptions::JS_STRING ||
6940  jstype == FieldOptions::JS_NUMBER) {
6941  return;
6942  }
6944  "Illegal jstype for int64, uint64, sint64, fixed64 "
6945  "or sfixed64 field: " +
6946  FieldOptions_JSType_descriptor()->value(jstype)->name());
6947  break;
6948 
6949  // No other types permit a jstype option.
6950  default:
6952  "jstype is only allowed on int64, uint64, sint64, fixed64 "
6953  "or sfixed64 fields.");
6954  break;
6955  }
6956 }
6957 
6958 #undef VALIDATE_OPTIONS_FROM_ARRAY
6959 
6960 // -------------------------------------------------------------------
6961 
6964  : builder_(builder) {
6965  GOOGLE_CHECK(builder_);
6966 }
6967 
6969 
6971  OptionsToInterpret* options_to_interpret) {
6972  // Note that these may be in different pools, so we can't use the same
6973  // descriptor and reflection objects on both.
6974  Message* options = options_to_interpret->options;
6975  const Message* original_options = options_to_interpret->original_options;
6976 
6977  bool failed = false;
6978  options_to_interpret_ = options_to_interpret;
6979 
6980  // Find the uninterpreted_option field in the mutable copy of the options
6981  // and clear them, since we're about to interpret them.
6982  const FieldDescriptor* uninterpreted_options_field =
6983  options->GetDescriptor()->FindFieldByName("uninterpreted_option");
6984  GOOGLE_CHECK(uninterpreted_options_field != nullptr)
6985  << "No field named \"uninterpreted_option\" in the Options proto.";
6986  options->GetReflection()->ClearField(options, uninterpreted_options_field);
6987 
6988  std::vector<int> src_path = options_to_interpret->element_path;
6989  src_path.push_back(uninterpreted_options_field->number());
6990 
6991  // Find the uninterpreted_option field in the original options.
6992  const FieldDescriptor* original_uninterpreted_options_field =
6993  original_options->GetDescriptor()->FindFieldByName(
6994  "uninterpreted_option");
6995  GOOGLE_CHECK(original_uninterpreted_options_field != nullptr)
6996  << "No field named \"uninterpreted_option\" in the Options proto.";
6997 
6998  const int num_uninterpreted_options =
6999  original_options->GetReflection()->FieldSize(
7000  *original_options, original_uninterpreted_options_field);
7001  for (int i = 0; i < num_uninterpreted_options; ++i) {
7002  src_path.push_back(i);
7003  uninterpreted_option_ = down_cast<const UninterpretedOption*>(
7004  &original_options->GetReflection()->GetRepeatedMessage(
7005  *original_options, original_uninterpreted_options_field, i));
7006  if (!InterpretSingleOption(options, src_path,
7007  options_to_interpret->element_path)) {
7008  // Error already added by InterpretSingleOption().
7009  failed = true;
7010  break;
7011  }
7012  src_path.pop_back();
7013  }
7014  // Reset these, so we don't have any dangling pointers.
7015  uninterpreted_option_ = nullptr;
7016  options_to_interpret_ = nullptr;
7017 
7018  if (!failed) {
7019  // InterpretSingleOption() added the interpreted options in the
7020  // UnknownFieldSet, in case the option isn't yet known to us. Now we
7021  // serialize the options message and deserialize it back. That way, any
7022  // option fields that we do happen to know about will get moved from the
7023  // UnknownFieldSet into the real fields, and thus be available right away.
7024  // If they are not known, that's OK too. They will get reparsed into the
7025  // UnknownFieldSet and wait there until the message is parsed by something
7026  // that does know about the options.
7027 
7028  // Keep the unparsed options around in case the reparsing fails.
7029  std::unique_ptr<Message> unparsed_options(options->New());
7030  options->GetReflection()->Swap(unparsed_options.get(), options);
7031 
7032  std::string buf;
7033  if (!unparsed_options->AppendToString(&buf) ||
7034  !options->ParseFromString(buf)) {
7035  builder_->AddError(
7036  options_to_interpret->element_name, *original_options,
7038  "Some options could not be correctly parsed using the proto "
7039  "descriptors compiled into this binary.\n"
7040  "Unparsed options: " +
7041  unparsed_options->ShortDebugString() +
7042  "\n"
7043  "Parsing attempt: " +
7044  options->ShortDebugString());
7045  // Restore the unparsed options.
7046  options->GetReflection()->Swap(unparsed_options.get(), options);
7047  }
7048  }
7049 
7050  return !failed;
7051 }
7052 
7054  Message* options, const std::vector<int>& src_path,
7055  const std::vector<int>& options_path) {
7056  // First do some basic validation.
7057  if (uninterpreted_option_->name_size() == 0) {
7058  // This should never happen unless the parser has gone seriously awry or
7059  // someone has manually created the uninterpreted option badly.
7060  return AddNameError("Option must have a name.");
7061  }
7062  if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") {
7063  return AddNameError(
7064  "Option must not use reserved name "
7065  "\"uninterpreted_option\".");
7066  }
7067 
7068  const Descriptor* options_descriptor = nullptr;
7069  // Get the options message's descriptor from the builder's pool, so that we
7070  // get the version that knows about any extension options declared in the file
7071  // we're currently building. The descriptor should be there as long as the
7072  // file we're building imported descriptor.proto.
7073 
7074  // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
7075  // DescriptorPool::FindMessageTypeByName() because we're already holding the
7076  // pool's mutex, and the latter method locks it again. We don't use
7077  // FindSymbol() because files that use custom options only need to depend on
7078  // the file that defines the option, not descriptor.proto itself.
7079  Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
7080  options->GetDescriptor()->full_name());
7081  options_descriptor = symbol.descriptor();
7082  if (options_descriptor == nullptr) {
7083  // The options message's descriptor was not in the builder's pool, so use
7084  // the standard version from the generated pool. We're not holding the
7085  // generated pool's mutex, so we can search it the straightforward way.
7086  options_descriptor = options->GetDescriptor();
7087  }
7088  GOOGLE_CHECK(options_descriptor);
7089 
7090  // We iterate over the name parts to drill into the submessages until we find
7091  // the leaf field for the option. As we drill down we remember the current
7092  // submessage's descriptor in |descriptor| and the next field in that
7093  // submessage in |field|. We also track the fields we're drilling down
7094  // through in |intermediate_fields|. As we go, we reconstruct the full option
7095  // name in |debug_msg_name|, for use in error messages.
7096  const Descriptor* descriptor = options_descriptor;
7097  const FieldDescriptor* field = nullptr;
7098  std::vector<const FieldDescriptor*> intermediate_fields;
7099  std::string debug_msg_name = "";
7100 
7101  std::vector<int> dest_path = options_path;
7102 
7103  for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
7104  builder_->undefine_resolved_name_.clear();
7105  const std::string& name_part = uninterpreted_option_->name(i).name_part();
7106  if (debug_msg_name.size() > 0) {
7107  debug_msg_name += ".";
7108  }
7109  if (uninterpreted_option_->name(i).is_extension()) {
7110  debug_msg_name += "(" + name_part + ")";
7111  // Search for the extension's descriptor as an extension in the builder's
7112  // pool. Note that we use DescriptorBuilder::LookupSymbol(), not
7113  // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
7114  // relative lookups, and 2) because we're already holding the pool's
7115  // mutex, and the latter method locks it again.
7116  symbol =
7117  builder_->LookupSymbol(name_part, options_to_interpret_->name_scope);
7118  field = symbol.field_descriptor();
7119  // If we don't find the field then the field's descriptor was not in the
7120  // builder's pool, but there's no point in looking in the generated
7121  // pool. We require that you import the file that defines any extensions
7122  // you use, so they must be present in the builder's pool.
7123  } else {
7124  debug_msg_name += name_part;
7125  // Search for the field's descriptor as a regular field.
7126  field = descriptor->FindFieldByName(name_part);
7127  }
7128 
7129  if (field == nullptr) {
7130  if (get_allow_unknown(builder_->pool_)) {
7131  // We can't find the option, but AllowUnknownDependencies() is enabled,
7132  // so we will just leave it as uninterpreted.
7133  AddWithoutInterpreting(*uninterpreted_option_, options);
7134  return true;
7135  } else if (!(builder_->undefine_resolved_name_).empty()) {
7136  // Option is resolved to a name which is not defined.
7137  return AddNameError(
7138  "Option \"" + debug_msg_name + "\" is resolved to \"(" +
7139  builder_->undefine_resolved_name_ +
7140  ")\", which is not defined. The innermost scope is searched first "
7141  "in name resolution. Consider using a leading '.'(i.e., \"(." +
7142  debug_msg_name.substr(1) +
7143  "\") to start from the outermost scope.");
7144  } else {
7145  return AddNameError(
7146  "Option \"" + debug_msg_name +
7147  "\" unknown. Ensure that your proto" +
7148  " definition file imports the proto which defines the option.");
7149  }
7150  } else if (field->containing_type() != descriptor) {
7151  if (get_is_placeholder(field->containing_type())) {
7152  // The field is an extension of a placeholder type, so we can't
7153  // reliably verify whether it is a valid extension to use here (e.g.
7154  // we don't know if it is an extension of the correct *Options message,
7155  // or if it has a valid field number, etc.). Just leave it as
7156  // uninterpreted instead.
7157  AddWithoutInterpreting(*uninterpreted_option_, options);
7158  return true;
7159  } else {
7160  // This can only happen if, due to some insane misconfiguration of the
7161  // pools, we find the options message in one pool but the field in
7162  // another. This would probably imply a hefty bug somewhere.
7163  return AddNameError("Option field \"" + debug_msg_name +
7164  "\" is not a field or extension of message \"" +
7165  descriptor->name() + "\".");
7166  }
7167  } else {
7168  // accumulate field numbers to form path to interpreted option
7169  dest_path.push_back(field->number());
7170 
7171  if (i < uninterpreted_option_->name_size() - 1) {
7172  if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
7173  return AddNameError("Option \"" + debug_msg_name +
7174  "\" is an atomic type, not a message.");
7175  } else if (field->is_repeated()) {
7176  return AddNameError("Option field \"" + debug_msg_name +
7177  "\" is a repeated message. Repeated message "
7178  "options must be initialized using an "
7179  "aggregate value.");
7180  } else {
7181  // Drill down into the submessage.
7182  intermediate_fields.push_back(field);
7183  descriptor = field->message_type();
7184  }
7185  }
7186  }
7187  }
7188 
7189  // We've found the leaf field. Now we use UnknownFieldSets to set its value
7190  // on the options message. We do so because the message may not yet know
7191  // about its extension fields, so we may not be able to set the fields
7192  // directly. But the UnknownFieldSets will serialize to the same wire-format
7193  // message, so reading that message back in once the extension fields are
7194  // known will populate them correctly.
7195 
7196  // First see if the option is already set.
7197  if (!field->is_repeated() &&
7198  !ExamineIfOptionIsSet(
7199  intermediate_fields.begin(), intermediate_fields.end(), field,
7200  debug_msg_name,
7201  options->GetReflection()->GetUnknownFields(*options))) {
7202  return false; // ExamineIfOptionIsSet() already added the error.
7203  }
7204 
7205  // First set the value on the UnknownFieldSet corresponding to the
7206  // innermost message.
7207  std::unique_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet());
7208  if (!SetOptionValue(field, unknown_fields.get())) {
7209  return false; // SetOptionValue() already added the error.
7210  }
7211 
7212  // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all
7213  // the intermediate messages.
7214  for (std::vector<const FieldDescriptor*>::reverse_iterator iter =
7215  intermediate_fields.rbegin();
7216  iter != intermediate_fields.rend(); ++iter) {
7217  std::unique_ptr<UnknownFieldSet> parent_unknown_fields(
7218  new UnknownFieldSet());
7219  switch ((*iter)->type()) {
7221  io::StringOutputStream outstr(
7222  parent_unknown_fields->AddLengthDelimited((*iter)->number()));
7223  io::CodedOutputStream out(&outstr);
7225  GOOGLE_CHECK(!out.HadError())
7226  << "Unexpected failure while serializing option submessage "
7227  << debug_msg_name << "\".";
7228  break;
7229  }
7230 
7232  parent_unknown_fields->AddGroup((*iter)->number())
7233  ->MergeFrom(*unknown_fields);
7234  break;
7235  }
7236 
7237  default:
7238  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
7239  << (*iter)->type();
7240  return false;
7241  }
7242  unknown_fields.reset(parent_unknown_fields.release());
7243  }
7244 
7245  // Now merge the UnknownFieldSet corresponding to the top-level message into
7246  // the options message.
7247  options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
7248  *unknown_fields);
7249 
7250  // record the element path of the interpreted option
7251  if (field->is_repeated()) {
7252  int index = repeated_option_counts_[dest_path]++;
7253  dest_path.push_back(index);
7254  }
7255  interpreted_paths_[src_path] = dest_path;
7256 
7257  return true;
7258 }
7259 
7261  SourceCodeInfo* info) {
7262  if (interpreted_paths_.empty()) {
7263  // nothing to do!
7264  return;
7265  }
7266 
7267  // We find locations that match keys in interpreted_paths_ and
7268  // 1) replace the path with the corresponding value in interpreted_paths_
7269  // 2) remove any subsequent sub-locations (sub-location is one whose path
7270  // has the parent path as a prefix)
7271  //
7272  // To avoid quadratic behavior of removing interior rows as we go,
7273  // we keep a copy. But we don't actually copy anything until we've
7274  // found the first match (so if the source code info has no locations
7275  // that need to be changed, there is zero copy overhead).
7276 
7277  RepeatedPtrField<SourceCodeInfo_Location>* locs = info->mutable_location();
7278  RepeatedPtrField<SourceCodeInfo_Location> new_locs;
7279  bool copying = false;
7280 
7281  std::vector<int> pathv;
7282  bool matched = false;
7283 
7285  loc != locs->end(); loc++) {
7286  if (matched) {
7287  // see if this location is in the range to remove
7288  bool loc_matches = true;
7289  if (loc->path_size() < static_cast<int64_t>(pathv.size())) {
7290  loc_matches = false;
7291  } else {
7292  for (size_t j = 0; j < pathv.size(); j++) {
7293  if (loc->path(j) != pathv[j]) {
7294  loc_matches = false;
7295  break;
7296  }
7297  }
7298  }
7299 
7300  if (loc_matches) {
7301  // don't copy this row since it is a sub-location that we're removing
7302  continue;
7303  }
7304 
7305  matched = false;
7306  }
7307 
7308  pathv.clear();
7309  for (int j = 0; j < loc->path_size(); j++) {
7310  pathv.push_back(loc->path(j));
7311  }
7312 
7313  std::map<std::vector<int>, std::vector<int>>::iterator entry =
7314  interpreted_paths_.find(pathv);
7315 
7316  if (entry == interpreted_paths_.end()) {
7317  // not a match
7318  if (copying) {
7319  *new_locs.Add() = *loc;
7320  }
7321  continue;
7322  }
7323 
7324  matched = true;
7325 
7326  if (!copying) {
7327  // initialize the copy we are building
7328  copying = true;
7329  new_locs.Reserve(locs->size());
7331  locs->begin();
7332  it != loc; it++) {
7333  *new_locs.Add() = *it;
7334  }
7335  }
7336 
7337  // add replacement and update its path
7338  SourceCodeInfo_Location* replacement = new_locs.Add();
7339  *replacement = *loc;
7340  replacement->clear_path();
7341  for (std::vector<int>::iterator rit = entry->second.begin();
7342  rit != entry->second.end(); rit++) {
7343  replacement->add_path(*rit);
7344  }
7345  }
7346 
7347  // if we made a changed copy, put it in place
7348  if (copying) {
7349  *locs = new_locs;
7350  }
7351 }
7352 
7354  const UninterpretedOption& uninterpreted_option, Message* options) {
7355  const FieldDescriptor* field =
7356  options->GetDescriptor()->FindFieldByName("uninterpreted_option");
7357  GOOGLE_CHECK(field != nullptr);
7358 
7359  options->GetReflection()
7360  ->AddMessage(options, field)
7361  ->CopyFrom(uninterpreted_option);
7362 }
7363 
7365  std::vector<const FieldDescriptor*>::const_iterator
7366  intermediate_fields_iter,
7367  std::vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
7368  const FieldDescriptor* innermost_field, const std::string& debug_msg_name,
7369  const UnknownFieldSet& unknown_fields) {
7370  // We do linear searches of the UnknownFieldSet and its sub-groups. This
7371  // should be fine since it's unlikely that any one options structure will
7372  // contain more than a handful of options.
7373 
7374  if (intermediate_fields_iter == intermediate_fields_end) {
7375  // We're at the innermost submessage.
7376  for (int i = 0; i < unknown_fields.field_count(); i++) {
7377  if (unknown_fields.field(i).number() == innermost_field->number()) {
7378  return AddNameError("Option \"" + debug_msg_name +
7379  "\" was already set.");
7380  }
7381  }
7382  return true;
7383  }
7384 
7385  for (int i = 0; i < unknown_fields.field_count(); i++) {
7386  if (unknown_fields.field(i).number() ==
7387  (*intermediate_fields_iter)->number()) {
7388  const UnknownField* unknown_field = &unknown_fields.field(i);
7389  FieldDescriptor::Type type = (*intermediate_fields_iter)->type();
7390  // Recurse into the next submessage.
7391  switch (type) {
7393  if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) {
7394  UnknownFieldSet intermediate_unknown_fields;
7395  if (intermediate_unknown_fields.ParseFromString(
7396  unknown_field->length_delimited()) &&
7397  !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
7398  intermediate_fields_end, innermost_field,
7399  debug_msg_name,
7400  intermediate_unknown_fields)) {
7401  return false; // Error already added.
7402  }
7403  }
7404  break;
7405 
7407  if (unknown_field->type() == UnknownField::TYPE_GROUP) {
7408  if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
7409  intermediate_fields_end, innermost_field,
7410  debug_msg_name, unknown_field->group())) {
7411  return false; // Error already added.
7412  }
7413  }
7414  break;
7415 
7416  default:
7417  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type;
7418  return false;
7419  }
7420  }
7421  }
7422  return true;
7423 }
7424 
7426  const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
7427  // We switch on the CppType to validate.
7428  switch (option_field->cpp_type()) {
7430  if (uninterpreted_option_->has_positive_int_value()) {
7431  if (uninterpreted_option_->positive_int_value() >
7432  static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
7433  return AddValueError("Value out of range for int32 option \"" +
7434  option_field->full_name() + "\".");
7435  } else {
7436  SetInt32(option_field->number(),
7437  uninterpreted_option_->positive_int_value(),
7438  option_field->type(), unknown_fields);
7439  }
7440  } else if (uninterpreted_option_->has_negative_int_value()) {
7441  if (uninterpreted_option_->negative_int_value() <
7442  static_cast<int64_t>(std::numeric_limits<int32_t>::min())) {
7443  return AddValueError("Value out of range for int32 option \"" +
7444  option_field->full_name() + "\".");
7445  } else {
7446  SetInt32(option_field->number(),
7447  uninterpreted_option_->negative_int_value(),
7448  option_field->type(), unknown_fields);
7449  }
7450  } else {
7451  return AddValueError("Value must be integer for int32 option \"" +
7452  option_field->full_name() + "\".");
7453  }
7454  break;
7455 
7457  if (uninterpreted_option_->has_positive_int_value()) {
7458  if (uninterpreted_option_->positive_int_value() >
7459  static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
7460  return AddValueError("Value out of range for int64 option \"" +
7461  option_field->full_name() + "\".");
7462  } else {
7463  SetInt64(option_field->number(),
7464  uninterpreted_option_->positive_int_value(),
7465  option_field->type(), unknown_fields);
7466  }
7467  } else if (uninterpreted_option_->has_negative_int_value()) {
7468  SetInt64(option_field->number(),
7469  uninterpreted_option_->negative_int_value(),
7470  option_field->type(), unknown_fields);
7471  } else {
7472  return AddValueError("Value must be integer for int64 option \"" +
7473  option_field->full_name() + "\".");
7474  }
7475  break;
7476 
7478  if (uninterpreted_option_->has_positive_int_value()) {
7479  if (uninterpreted_option_->positive_int_value() >
7481  return AddValueError("Value out of range for uint32 option \"" +
7482  option_field->name() + "\".");
7483  } else {
7484  SetUInt32(option_field->number(),
7485  uninterpreted_option_->positive_int_value(),
7486  option_field->type(), unknown_fields);
7487  }
7488  } else {
7489  return AddValueError(
7490  "Value must be non-negative integer for uint32 "
7491  "option \"" +
7492  option_field->full_name() + "\".");
7493  }
7494  break;
7495 
7497  if (uninterpreted_option_->has_positive_int_value()) {
7498  SetUInt64(option_field->number(),
7499  uninterpreted_option_->positive_int_value(),
7500  option_field->type(), unknown_fields);
7501  } else {
7502  return AddValueError(
7503  "Value must be non-negative integer for uint64 "
7504  "option \"" +
7505  option_field->full_name() + "\".");
7506  }
7507  break;
7508 
7510  float value;
7511  if (uninterpreted_option_->has_double_value()) {
7512  value = uninterpreted_option_->double_value();
7513  } else if (uninterpreted_option_->has_positive_int_value()) {
7514  value = uninterpreted_option_->positive_int_value();
7515  } else if (uninterpreted_option_->has_negative_int_value()) {
7516  value = uninterpreted_option_->negative_int_value();
7517  } else {
7518  return AddValueError("Value must be number for float option \"" +
7519  option_field->full_name() + "\".");
7520  }
7521  unknown_fields->AddFixed32(option_field->number(),
7523  break;
7524  }
7525 
7527  double value;
7528  if (uninterpreted_option_->has_double_value()) {
7529  value = uninterpreted_option_->double_value();
7530  } else if (uninterpreted_option_->has_positive_int_value()) {
7531  value = uninterpreted_option_->positive_int_value();
7532  } else if (uninterpreted_option_->has_negative_int_value()) {
7533  value = uninterpreted_option_->negative_int_value();
7534  } else {
7535  return AddValueError("Value must be number for double option \"" +
7536  option_field->full_name() + "\".");
7537  }
7538  unknown_fields->AddFixed64(option_field->number(),
7540  break;
7541  }
7542 
7544  uint64_t value;
7545  if (!uninterpreted_option_->has_identifier_value()) {
7546  return AddValueError(
7547  "Value must be identifier for boolean option "
7548  "\"" +
7549  option_field->full_name() + "\".");
7550  }
7551  if (uninterpreted_option_->identifier_value() == "true") {
7552  value = 1;
7553  } else if (uninterpreted_option_->identifier_value() == "false") {
7554  value = 0;
7555  } else {
7556  return AddValueError(
7557  "Value must be \"true\" or \"false\" for boolean "
7558  "option \"" +
7559  option_field->full_name() + "\".");
7560  }
7561  unknown_fields->AddVarint(option_field->number(), value);
7562  break;
7563 
7565  if (!uninterpreted_option_->has_identifier_value()) {
7566  return AddValueError(
7567  "Value must be identifier for enum-valued option "
7568  "\"" +
7569  option_field->full_name() + "\".");
7570  }
7571  const EnumDescriptor* enum_type = option_field->enum_type();
7572  const std::string& value_name = uninterpreted_option_->identifier_value();
7573  const EnumValueDescriptor* enum_value = nullptr;
7574 
7575  if (enum_type->file()->pool() != DescriptorPool::generated_pool()) {
7576  // Note that the enum value's fully-qualified name is a sibling of the
7577  // enum's name, not a child of it.
7578  std::string fully_qualified_name = enum_type->full_name();
7579  fully_qualified_name.resize(fully_qualified_name.size() -
7580  enum_type->name().size());
7581  fully_qualified_name += value_name;
7582 
7583  // Search for the enum value's descriptor in the builder's pool. Note
7584  // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
7585  // DescriptorPool::FindEnumValueByName() because we're already holding
7586  // the pool's mutex, and the latter method locks it again.
7587  Symbol symbol =
7588  builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
7589  if (auto* candicate_descriptor = symbol.enum_value_descriptor()) {
7590  if (candicate_descriptor->type() != enum_type) {
7591  return AddValueError(
7592  "Enum type \"" + enum_type->full_name() +
7593  "\" has no value named \"" + value_name + "\" for option \"" +
7594  option_field->full_name() +
7595  "\". This appears to be a value from a sibling type.");
7596  } else {
7597  enum_value = candicate_descriptor;
7598  }
7599  }
7600  } else {
7601  // The enum type is in the generated pool, so we can search for the
7602  // value there.
7603  enum_value = enum_type->FindValueByName(value_name);
7604  }
7605 
7606  if (enum_value == nullptr) {
7607  return AddValueError("Enum type \"" +
7608  option_field->enum_type()->full_name() +
7609  "\" has no value named \"" + value_name +
7610  "\" for "
7611  "option \"" +
7612  option_field->full_name() + "\".");
7613  } else {
7614  // Sign-extension is not a problem, since we cast directly from int32_t
7615  // to uint64_t, without first going through uint32_t.
7616  unknown_fields->AddVarint(
7617  option_field->number(),
7618  static_cast<uint64_t>(static_cast<int64_t>(enum_value->number())));
7619  }
7620  break;
7621  }
7622 
7624  if (!uninterpreted_option_->has_string_value()) {
7625  return AddValueError(
7626  "Value must be quoted string for string option "
7627  "\"" +
7628  option_field->full_name() + "\".");
7629  }
7630  // The string has already been unquoted and unescaped by the parser.
7631  unknown_fields->AddLengthDelimited(option_field->number(),
7632  uninterpreted_option_->string_value());
7633  break;
7634 
7636  if (!SetAggregateOption(option_field, unknown_fields)) {
7637  return false;
7638  }
7639  break;
7640  }
7641 
7642  return true;
7643 }
7644 
7645 class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
7646  : public TextFormat::Finder {
7647  public:
7648  DescriptorBuilder* builder_;
7649 
7650  const Descriptor* FindAnyType(const Message& /*message*/,
7651  const std::string& prefix,
7652  const std::string& name) const override {
7655  return nullptr;
7656  }
7657  assert_mutex_held(builder_->pool_);
7658  return builder_->FindSymbol(name).descriptor();
7659  }
7660 
7662  const std::string& name) const override {
7663  assert_mutex_held(builder_->pool_);
7664  const Descriptor* descriptor = message->GetDescriptor();
7665  Symbol result =
7666  builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name());
7667  if (auto* field = result.field_descriptor()) {
7668  return field;
7669  } else if (result.type() == Symbol::MESSAGE &&
7670  descriptor->options().message_set_wire_format()) {
7671  const Descriptor* foreign_type = result.descriptor();
7672  // The text format allows MessageSet items to be specified using
7673  // the type name, rather than the extension identifier. If the symbol
7674  // lookup returned a Message, and the enclosing Message has
7675  // message_set_wire_format = true, then return the message set
7676  // extension, if one exists.
7677  for (int i = 0; i < foreign_type->extension_count(); i++) {
7678  const FieldDescriptor* extension = foreign_type->extension(i);
7679  if (extension->containing_type() == descriptor &&
7681  extension->is_optional() &&
7682  extension->message_type() == foreign_type) {
7683  // Found it.
7684  return extension;
7685  }
7686  }
7687  }
7688  return nullptr;
7689  }
7690 };
7691 
7692 // A custom error collector to record any text-format parsing errors
7693 namespace {
7694 class AggregateErrorCollector : public io::ErrorCollector {
7695  public:
7697 
7698  void AddError(int /* line */, int /* column */,
7699  const std::string& message) override {
7700  if (!error_.empty()) {
7701  error_ += "; ";
7702  }
7703  error_ += message;
7704  }
7705 
7706  void AddWarning(int /* line */, int /* column */,
7707  const std::string& /* message */) override {
7708  // Ignore warnings
7709  }
7710 };
7711 } // namespace
7712 
7713 // We construct a dynamic message of the type corresponding to
7714 // option_field, parse the supplied text-format string into this
7715 // message, and serialize the resulting message to produce the value.
7717  const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
7718  if (!uninterpreted_option_->has_aggregate_value()) {
7719  return AddValueError("Option \"" + option_field->full_name() +
7720  "\" is a message. To set the entire message, use "
7721  "syntax like \"" +
7722  option_field->name() +
7723  " = { <proto text format> }\". "
7724  "To set fields within it, use "
7725  "syntax like \"" +
7726  option_field->name() + ".foo = value\".");
7727  }
7728 
7729  const Descriptor* type = option_field->message_type();
7730  std::unique_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
7731  GOOGLE_CHECK(dynamic.get() != nullptr)
7732  << "Could not create an instance of " << option_field->DebugString();
7733 
7734  AggregateErrorCollector collector;
7735  AggregateOptionFinder finder;
7736  finder.builder_ = builder_;
7737  TextFormat::Parser parser;
7738  parser.RecordErrorsTo(&collector);
7739  parser.SetFinder(&finder);
7740  if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
7741  dynamic.get())) {
7742  AddValueError("Error while parsing option value for \"" +
7743  option_field->name() + "\": " + collector.error_);
7744  return false;
7745  } else {
7746  std::string serial;
7747  dynamic->SerializeToString(&serial); // Never fails
7748  if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) {
7749  unknown_fields->AddLengthDelimited(option_field->number(), serial);
7750  } else {
7751  GOOGLE_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP);
7752  UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number());
7753  group->ParseFromString(serial);
7754  }
7755  return true;
7756  }
7757 }
7758 
7761  UnknownFieldSet* unknown_fields) {
7762  switch (type) {
7764  unknown_fields->AddVarint(
7765  number, static_cast<uint64_t>(static_cast<int64_t>(value)));
7766  break;
7767 
7769  unknown_fields->AddFixed32(number, static_cast<uint32_t>(value));
7770  break;
7771 
7773  unknown_fields->AddVarint(
7775  break;
7776 
7777  default:
7778  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type;
7779  break;
7780  }
7781 }
7782 
7785  UnknownFieldSet* unknown_fields) {
7786  switch (type) {
7788  unknown_fields->AddVarint(number, static_cast<uint64_t>(value));
7789  break;
7790 
7792  unknown_fields->AddFixed64(number, static_cast<uint64_t>(value));
7793  break;
7794 
7796  unknown_fields->AddVarint(
7798  break;
7799 
7800  default:
7801  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type;
7802  break;
7803  }
7804 }
7805 
7808  UnknownFieldSet* unknown_fields) {
7809  switch (type) {
7811  unknown_fields->AddVarint(number, static_cast<uint64_t>(value));
7812  break;
7813 
7815  unknown_fields->AddFixed32(number, static_cast<uint32_t>(value));
7816  break;
7817 
7818  default:
7819  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
7820  break;
7821  }
7822 }
7823 
7826  UnknownFieldSet* unknown_fields) {
7827  switch (type) {
7829  unknown_fields->AddVarint(number, value);
7830  break;
7831 
7833  unknown_fields->AddFixed64(number, value);
7834  break;
7835 
7836  default:
7837  GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type;
7838  break;
7839  }
7840 }
7841 
7843  const FileDescriptor* result) {
7844  (void)result; // Parameter is used by Google-internal code.
7845 
7846  if (!unused_dependency_.empty()) {
7847  auto itr = pool_->unused_import_track_files_.find(proto.name());
7848  bool is_error =
7849  itr != pool_->unused_import_track_files_.end() && itr->second;
7850  for (std::set<const FileDescriptor*>::const_iterator it =
7851  unused_dependency_.begin();
7852  it != unused_dependency_.end(); ++it) {
7853  std::string error_message = "Import " + (*it)->name() + " is unused.";
7854  if (is_error) {
7855  AddError((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT,
7856  error_message);
7857  } else {
7858  AddWarning((*it)->name(), proto, DescriptorPool::ErrorCollector::IMPORT,
7859  error_message);
7860  }
7861  }
7862  }
7863 }
7864 
7866  bool expecting_enum) const {
7867  (void)expecting_enum; // Parameter is used by Google-internal code.
7868  auto lookup_name = std::string(name);
7869  if (!lookup_name.empty() && lookup_name[0] == '.') {
7870  lookup_name = lookup_name.substr(1);
7871  }
7872  Symbol result = tables_->FindByNameHelper(this, lookup_name);
7873  return result;
7874 }
7875 
7876 // Handle the lazy import building for a message field whose type wasn't built
7877 // at cross link time. If that was the case, we saved the name of the type to
7878 // be looked up when the accessor for the type was called. Set type_,
7879 // enum_type_, message_type_, and default_value_enum_ appropriately.
7881  GOOGLE_CHECK(file()->finished_building_ == true);
7882  const EnumDescriptor* enum_type = nullptr;
7883  Symbol result = file()->pool()->CrossLinkOnDemandHelper(
7884  type_descriptor_.lazy_type_name, type_ == FieldDescriptor::TYPE_ENUM);
7885  if (result.type() == Symbol::MESSAGE) {
7887  type_descriptor_.message_type = result.descriptor();
7888  } else if (result.type() == Symbol::ENUM) {
7890  enum_type = type_descriptor_.enum_type = result.enum_descriptor();
7891  }
7892 
7893  if (enum_type) {
7894  if (lazy_default_value_enum_name_) {
7895  // Have to build the full name now instead of at CrossLink time,
7896  // because enum_type may not be known at the time.
7897  std::string name = enum_type->full_name();
7898  // Enum values reside in the same scope as the enum type.
7899  std::string::size_type last_dot = name.find_last_of('.');
7900  if (last_dot != std::string::npos) {
7901  name = name.substr(0, last_dot) + "." + lazy_default_value_enum_name_;
7902  } else {
7903  name = lazy_default_value_enum_name_;
7904  }
7905  Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true);
7906  default_value_enum_ = result.enum_value_descriptor();
7907  } else {
7908  default_value_enum_ = nullptr;
7909  }
7910  if (!default_value_enum_) {
7911  // We use the first defined value as the default
7912  // if a default is not explicitly defined.
7913  GOOGLE_CHECK(enum_type->value_count());
7914  default_value_enum_ = enum_type->value(0);
7915  }
7916  }
7917 }
7918 
7919 void FieldDescriptor::TypeOnceInit(const FieldDescriptor* to_init) {
7920  to_init->InternalTypeOnceInit();
7921 }
7922 
7923 // message_type(), enum_type(), default_value_enum(), and type()
7924 // all share the same internal::call_once init path to do lazy
7925 // import building and cross linking of a field of a message.
7927  if (type_once_) {
7929  }
7930  return type_ == TYPE_MESSAGE || type_ == TYPE_GROUP
7931  ? type_descriptor_.message_type
7932  : nullptr;
7933 }
7934 
7936  if (type_once_) {
7938  }
7939  return type_ == TYPE_ENUM ? type_descriptor_.enum_type : nullptr;
7940 }
7941 
7943  if (type_once_) {
7945  }
7946  return default_value_enum_;
7947 }
7948 
7950  const bool is_message_set_extension =
7951  is_extension() &&
7952  containing_type()->options().message_set_wire_format() &&
7953  type() == FieldDescriptor::TYPE_MESSAGE && is_optional() &&
7954  extension_scope() == message_type();
7955  return is_message_set_extension ? message_type()->full_name() : full_name();
7956 }
7957 
7959  GOOGLE_CHECK(finished_building_ == true);
7960  auto* names = dependencies_once_->dependencies_names;
7961  for (int i = 0; i < dependency_count(); i++) {
7962  if (names[i]) {
7964  }
7965  }
7966 }
7967 
7969  to_init->InternalDependenciesOnceInit();
7970 }
7971 
7973  if (dependencies_once_) {
7974  // Do once init for all indices, as it's unlikely only a single index would
7975  // be called, and saves on internal::call_once allocations.
7976  internal::call_once(dependencies_once_->once,
7978  }
7979  return dependencies_[index];
7980 }
7981 
7983  return input_type_.Get(service());
7984 }
7985 
7987  return output_type_.Get(service());
7988 }
7989 
7990 
7991 namespace internal {
7992 void LazyDescriptor::Set(const Descriptor* descriptor) {
7993  GOOGLE_CHECK(!once_);
7995 }
7996 
7997 void LazyDescriptor::SetLazy(StringPiece name,
7998  const FileDescriptor* file) {
7999  // verify Init() has been called and Set hasn't been called yet.
8001  GOOGLE_CHECK(!once_);
8002  GOOGLE_CHECK(file && file->pool_);
8003  GOOGLE_CHECK(file->pool_->lazily_build_dependencies_);
8004  GOOGLE_CHECK(!file->finished_building_);
8005  once_ = file->pool_->tables_->Create<internal::once_flag>();
8006  lazy_name_ = file->pool_->tables_->Strdup(name);
8007 }
8008 
8009 void LazyDescriptor::Once(const ServiceDescriptor* service) {
8010  if (once_) {
8011  internal::call_once(*once_, [&] {
8012  auto* file = service->file();
8013  GOOGLE_CHECK(file->finished_building_);
8014  descriptor_ =
8015  file->pool_->CrossLinkOnDemandHelper(lazy_name_, false).descriptor();
8016  });
8017  }
8018 }
8019 
8020 } // namespace internal
8021 
8022 } // namespace protobuf
8023 } // namespace google
8024 
8025 #include <google/protobuf/port_undef.inc>
google::protobuf::FieldDescriptor::Label
Label
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:571
google::protobuf::Descriptor::WELLKNOWNTYPE_INT32VALUE
@ WELLKNOWNTYPE_INT32VALUE
Definition: protobuf/src/google/protobuf/descriptor.h:304
google::protobuf::RepeatedPtrField::iterator
internal::RepeatedPtrIterator< Element > iterator
Definition: bloaty/third_party/protobuf/src/google/protobuf/repeated_field.h:861
google::protobuf::Descriptor::full_name
const std::string & full_name() const
google::protobuf::DescriptorPool::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1443
element_path
std::vector< int > element_path
Definition: protobuf/src/google/protobuf/descriptor.cc:3702
google::protobuf::Symbol::PACKAGE
@ PACKAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:87
FileDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7321
google::protobuf::FieldDescriptor::Type
Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:521
xds_interop_client.str
str
Definition: xds_interop_client.py:487
google::protobuf::FileDescriptor::pool_
const DescriptorPool * pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1460
google::protobuf::DescriptorBuilder::OptionInterpreter::InterpretOptions
bool InterpretOptions(OptionsToInterpret *options_to_interpret)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6255
FieldDescriptorProto_Type
FieldDescriptorProto_Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:172
FileDescriptorProto::add_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * add_message_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7692
google::protobuf::DescriptorPool::NewPlaceholder
Symbol NewPlaceholder(const std::string &name, PlaceholderType placeholder_type) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3850
google::protobuf::DescriptorPool::FindFileByName
const FileDescriptor * FindFileByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1369
FieldDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9380
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6650
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
google::protobuf::FileDescriptorTables::fields_by_number_
FieldsByNumberSet fields_by_number_
Definition: protobuf/src/google/protobuf/descriptor.cc:1332
google::protobuf::DescriptorPool::TryFindFileInFallbackDatabase
bool TryFindFileInFallbackDatabase(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1832
google::protobuf::FieldDescriptor::kLabelToName
static const char *const kLabelToName[MAX_LABEL+1]
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:830
google::protobuf::Descriptor::map_key
const FieldDescriptor * map_key() const
Definition: protobuf/src/google/protobuf/descriptor.cc:2320
google::protobuf::DescriptorPool::Tables::Strdup
const char * Strdup(StringPiece value)
Definition: protobuf/src/google/protobuf/descriptor.cc:1770
google::protobuf::DescriptorBuilder::file_tables_
FileDescriptorTables * file_tables_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3130
kFirstRawTag
static constexpr Tag kFirstRawTag
Definition: protobuf/src/google/protobuf/descriptor.cc:927
google::protobuf::Symbol::descriptor
const Descriptor * descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:91
google::protobuf::FileDescriptor::tables_
const FileDescriptorTables * tables_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1491
MethodDescriptorProto::set_input_type
void set_input_type(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10494
google::protobuf::OneofDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2730
google::protobuf::IsLite
static bool IsLite(const FileDescriptor *file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5777
FieldDescriptorProto::has_default_value
bool has_default_value() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9165
FileOptions::default_instance
static const FileOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:6483
SourceCodeInfo_Location::clear_path
void clear_path()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13336
google::protobuf::DescriptorPool::BuildFileCollectingErrors
const FileDescriptor * BuildFileCollectingErrors(const FileDescriptorProto &proto, ErrorCollector *error_collector)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3541
current_
Block * current_
Definition: protobuf/src/google/protobuf/descriptor.cc:1035
google::protobuf::DescriptorPool::NewPlaceholderFileWithMutexHeld
FileDescriptor * NewPlaceholderFileWithMutexHeld(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3960
EnumDescriptorProto_EnumReservedRange::start
::PROTOBUF_NAMESPACE_ID::int32 start() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9626
descriptor_
string_view descriptor_
Definition: elf.cc:154
filename
const char * filename
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
ExtensionRangeOptions::default_instance
static const ExtensionRangeOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:3460
google::protobuf::Descriptor::WELLKNOWNTYPE_UINT32VALUE
@ WELLKNOWNTYPE_UINT32VALUE
Definition: protobuf/src/google/protobuf/descriptor.h:305
kSize
static constexpr Tag kSize
Definition: protobuf/src/google/protobuf/descriptor.cc:873
google::protobuf::ExistingFileMatchesProto
static bool ExistingFileMatchesProto(const FileDescriptor *existing_file, const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4185
google::protobuf::DescriptorBuilder::ValidateEnumValueOptions
void ValidateEnumValueOptions(EnumValueDescriptor *enum_value, const EnumValueDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6055
MethodDescriptorProto::server_streaming
bool server_streaming() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10775
MethodDescriptorProto::set_output_type
void set_output_type(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10587
WriterMutexLock
#define WriterMutexLock(x)
Definition: bloaty/third_party/re2/util/mutex.h:127
google::protobuf::DescriptorBuilder::LogUnusedDependency
void LogUnusedDependency(const FileDescriptorProto &proto, const FileDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7117
google::protobuf::DescriptorPool::Tables::AddCheckpoint
void AddCheckpoint()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:829
google::protobuf::DescriptorPool::ClearUnusedImportTrackFiles
void ClearUnusedImportTrackFiles()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1292
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
google::protobuf::EnumValueDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2826
google::protobuf::MethodDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2891
regen-readme.it
it
Definition: regen-readme.py:15
google::protobuf::DescriptorBuilder::BuildEnumValue
void BuildEnumValue(const EnumValueDescriptorProto &proto, const EnumDescriptor *parent, EnumValueDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5191
google::protobuf::DescriptorPool::ErrorCollector::INPUT_TYPE
@ INPUT_TYPE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1644
google::protobuf::EnumValueDescriptor::type
const EnumDescriptor * type() const
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
google::protobuf::DescriptorBuilder::options_to_interpret_
std::vector< OptionsToInterpret > options_to_interpret_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3125
google::protobuf::MethodDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2896
google::protobuf::DescriptorPool::Tables::Create
Type * Create()
Definition: protobuf/src/google/protobuf/descriptor.cc:1858
google::protobuf::FieldDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:515
google::protobuf::DescriptorBuilder::pool_
const DescriptorPool * pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3118
google::protobuf::DescriptorPool::Tables::FindSymbol
Symbol FindSymbol(const std::string &key) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:878
absl::str_format_internal::LengthMod::j
@ j
google::protobuf::DescriptorBuilder::OptionInterpreter::~OptionInterpreter
~OptionInterpreter()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6253
google::protobuf::DescriptorPool::PlaceholderType
PlaceholderType
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1835
google::protobuf::DescriptorPool::InternalIsFileLoaded
bool InternalIsFileLoaded(const std::string &filename) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1296
google::protobuf::FileDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2401
google::protobuf::EnumDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3049
DescriptorProto::reserved_range
const PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange & reserved_range(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8657
EnumDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2844
SourceCodeInfo_Location::add_path
void add_path(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13353
google::protobuf::FileDescriptor::package_
const std::string * package_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1459
google::protobuf::DescriptorPool::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3529
google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT
@ WELLKNOWNTYPE_STRUCT
Definition: protobuf/src/google/protobuf/descriptor.h:317
google::protobuf::UnescapeCEscapeString
int UnescapeCEscapeString(const string &src, string *dest)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:468
FileDescriptorProto::public_dependency_size
int public_dependency_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7573
DescriptorProto::kOneofDeclFieldNumber
@ kOneofDeclFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1453
FileDescriptorProto::kSyntaxFieldNumber
@ kSyntaxFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:643
google::protobuf::OneofDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3043
google::protobuf::DescriptorPool::Tables::extensions_
ExtensionsGroupedByDescriptorMap extensions_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:660
EnumDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::EnumOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9847
google::protobuf::util::converter::ToCamelCase
std::string ToCamelCase(const StringPiece input)
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/internal/utility.cc:250
memset
return memset(p, 0, total)
google::protobuf::FieldDescriptor::CPPTYPE_STRING
@ CPPTYPE_STRING
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:562
google::protobuf::DescriptorBuilder::OptionInterpreter::SetUInt64
void SetUInt64(int number, uint64 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7099
google::protobuf::DescriptorPool::IsSubSymbolOfBuiltType
bool IsSubSymbolOfBuiltType(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1847
google::protobuf::DescriptorPool::Tables::FieldNamesResult::json_index
int json_index
Definition: protobuf/src/google/protobuf/descriptor.cc:1187
google::protobuf::extension
const Descriptor::ReservedRange const EnumValueDescriptor const MethodDescriptor extension
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2001
google::protobuf::DescriptorBuilder::BuildField
void BuildField(const FieldDescriptorProto &proto, const Descriptor *parent, FieldDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3283
google::protobuf::DescriptorBuilder::OptionInterpreter::AddValueError
bool AddValueError(const std::string &msg)
Definition: protobuf/src/google/protobuf/descriptor.cc:4040
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
google::protobuf::MethodDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2996
google::protobuf::DescriptorPool::Tables::FieldNamesResult::array
std::string * array
Definition: protobuf/src/google/protobuf/descriptor.cc:1184
original_options
const Message * original_options
Definition: protobuf/src/google/protobuf/descriptor.cc:3703
google::protobuf::DescriptorPool::TryFindSymbolInFallbackDatabase
bool TryFindSymbolInFallbackDatabase(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1869
google::protobuf::Descriptor::WELLKNOWNTYPE_LISTVALUE
@ WELLKNOWNTYPE_LISTVALUE
Definition: protobuf/src/google/protobuf/descriptor.h:316
EnumValueDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10004
google::protobuf::OneofDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2735
EnumDescriptorProto::add_reserved_range
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange * add_reserved_range()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9900
google::protobuf::DescriptorBuilder::ValidateSymbolName
void ValidateSymbolName(const std::string &name, const std::string &full_name, const Message &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4055
google::protobuf::FileDescriptorTables::fields_by_lowercase_name_tmp_
std::unique_ptr< FieldsByNameMap > fields_by_lowercase_name_tmp_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:778
google::protobuf::DescriptorBuilder::ValidateMessageOptions
void ValidateMessageOptions(Descriptor *message, const DescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5927
google::protobuf::FieldDescriptor::TYPE_SFIXED64
@ TYPE_SFIXED64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:542
google::protobuf::FileDescriptor::SyntaxName
static const char * SyntaxName(Syntax syntax)
google::protobuf::FileDescriptorTables::fields_by_lowercase_name_once_
internal::once_flag fields_by_lowercase_name_once_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:779
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4100
MethodOptions::default_instance
static const MethodOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:9167
google::protobuf::DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting
void AddWithoutInterpreting(const UninterpretedOption &uninterpreted_option, Message *options)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6639
google::protobuf.internal::SymbolBaseN
Definition: protobuf/src/google/protobuf/descriptor.h:238
ServiceDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::ServiceOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10331
google::protobuf::DescriptorPool::~DescriptorPool
~DescriptorPool()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1277
google::protobuf::FileDescriptor::InternalDependenciesOnceInit
void InternalDependenciesOnceInit() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7222
DescriptorProto::reserved_range_size
int reserved_range_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8639
BUILD_ARRAY
#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT)
Definition: protobuf/src/google/protobuf/descriptor.cc:4791
google::protobuf::DescriptorBuilder::OptionInterpreter::SetUInt32
void SetUInt32(int number, uint32 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7081
google::protobuf::FileDescriptorTables::AddFieldByStylizedNames
void AddFieldByStylizedNames(const FieldDescriptor *field)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1115
google::protobuf::FieldDescriptor::full_name
const std::string & full_name() const
false
#define false
Definition: setup_once.h:323
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
google::protobuf::DescriptorBuilder::AddTwiceListedError
void AddTwiceListedError(const FileDescriptorProto &proto, int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4165
google::protobuf::Descriptor::CopyTo
void CopyTo(DescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2047
capacity
uint16_t capacity
Definition: protobuf/src/google/protobuf/descriptor.cc:948
google::protobuf::DescriptorPool::ErrorCollector::IMPORT
@ IMPORT
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1648
FileDescriptorProto::source_code_info
const PROTOBUF_NAMESPACE_ID::SourceCodeInfo & source_code_info() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7905
google::protobuf::DescriptorPool::FindExtensionByPrintableName
const FieldDescriptor * FindExtensionByPrintableName(const Descriptor *extendee, const std::string &printable_name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1502
google::protobuf::DescriptorPool::Tables::AllocateStringArray
const std::string * AllocateStringArray(In &&... values)
Definition: protobuf/src/google/protobuf/descriptor.cc:1778
google::protobuf::DescriptorBuilder::AddNotDefinedError
void AddNotDefinedError(const std::string &element_name, const Message &descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &undefined_symbol)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3604
FileDescriptorProto::add_service
PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto * add_service()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7770
capstone.range
range
Definition: third_party/bloaty/third_party/capstone/bindings/python/capstone/__init__.py:6
google::protobuf::UnknownField::TYPE_GROUP
@ TYPE_GROUP
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:223
google::protobuf::Symbol::oneof_descriptor
const OneofDescriptor * oneof_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:93
google::protobuf::strto64
int64 strto64(const char *nptr, char **endptr, int base)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:374
google::protobuf::DescriptorBuilder::AllocateNameStrings
const std::string * AllocateNameStrings(const std::string &scope, const std::string &proto_name)
Definition: protobuf/src/google/protobuf/descriptor.cc:5168
google::protobuf::DescriptorBuilder::OptionInterpreter::SetOptionValue
bool SetOptionValue(const FieldDescriptor *option_field, UnknownFieldSet *unknown_fields)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6711
google::protobuf::Symbol::service_descriptor
const ServiceDescriptor * service_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:96
google::protobuf::FileDescriptor::SYNTAX_PROTO2
@ SYNTAX_PROTO2
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1393
MethodDescriptorProto::set_client_streaming
void set_client_streaming(bool value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10755
FieldOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4590
google::protobuf::DescriptorBuilder::AllocateArray
void AllocateArray(int size, Type **output)
Definition: protobuf/src/google/protobuf/descriptor.cc:3853
GOOGLE_DCHECK
#define GOOGLE_DCHECK
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:194
phone_pb2.message_type
message_type
Definition: phone_pb2.py:200
next
Block * next
Definition: protobuf/src/google/protobuf/descriptor.cc:949
google::protobuf::DescriptorBuilder::ValidateEnumOptions
void ValidateEnumOptions(EnumDescriptor *enm, const EnumDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6029
DescriptorProto::nested_type_size
int nested_type_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8415
file_
FileDescriptorProto * file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/annotation_test_util.cc:68
google::protobuf::FileDescriptor::FindExtensionByLowercaseName
const FieldDescriptor * FindExtensionByLowercaseName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1765
google::protobuf::DescriptorBuilder::ValidateProto3
void ValidateProto3(FileDescriptor *file, const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5812
EnumDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9683
google::protobuf::FindPtrOrNull
Collection::value_type::second_type FindPtrOrNull(const Collection &collection, const typename Collection::value_type::first_type &key)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/map_util.h:166
VALIDATE_OPTIONS_FROM_ARRAY
#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type)
Definition: protobuf/src/google/protobuf/descriptor.cc:6472
google::protobuf::FileDescriptor::finished_building_
bool finished_building_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1479
copy
static int copy(grpc_slice_buffer *input, grpc_slice_buffer *output)
Definition: message_compress.cc:145
google::protobuf::DescriptorBuilder::CrossLinkExtensionRange
void CrossLinkExtensionRange(Descriptor::ExtensionRange *range, const DescriptorProto::ExtensionRange &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5430
google::protobuf::DescriptorBuilder::error_collector_
DescriptorPool::ErrorCollector * error_collector_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3120
google::protobuf::FileDescriptor::message_type_count_
int message_type_count_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1469
DescriptorProto::descriptor
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * descriptor()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1350
google::protobuf::FileDescriptor::FindServiceByName
const ServiceDescriptor * FindServiceByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1745
UnknownField
Definition: upb/upb/util/compare_test.cc:66
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
google::protobuf::DescriptorBuilder::ValidateFieldOptions
void ValidateFieldOptions(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5950
google::protobuf::ServiceDescriptor::full_name
const std::string & full_name() const
google::protobuf::FieldDescriptor::message_type
const Descriptor * message_type
Definition: protobuf/src/google/protobuf/descriptor.h:936
names
sub_type names
Definition: cxa_demangle.cpp:4905
google::protobuf::io::SafeDoubleToFloat
float SafeDoubleToFloat(double value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/strtod.cc:116
UninterpretedOption
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6089
FileOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3696
google::protobuf::DescriptorBuilder::BuildService
void BuildService(const ServiceDescriptorProto &proto, const void *dummy, ServiceDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5262
MethodDescriptorProto::input_type
const std::string & input_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10490
array
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern array
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:111
FieldDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1851
google::protobuf::DescriptorPool::PLACEHOLDER_ENUM
@ PLACEHOLDER_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1837
google::protobuf::ServiceDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3066
google::protobuf::Descriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2972
google::protobuf::FieldDescriptor::CopyJsonNameTo
void CopyJsonNameTo(FieldDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2152
FieldOptions::JS_NORMAL
static constexpr JSType JS_NORMAL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4753
FileDescriptorProto::set_syntax
void set_syntax(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7971
google::protobuf::FieldDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2613
FileDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:128
DebugString
std::string DebugString(const google::protobuf::Message &message)
Definition: bloaty/tests/test.h:60
google::protobuf::Descriptor::WELLKNOWNTYPE_UNSPECIFIED
@ WELLKNOWNTYPE_UNSPECIFIED
Definition: protobuf/src/google/protobuf/descriptor.h:297
GOOGLE_CHECK_EQ
#define GOOGLE_CHECK_EQ(A, B)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:156
FieldDescriptorProto::set_number
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8911
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::DescriptorBuilder::unused_dependency_
std::set< const FileDescriptor * > unused_dependency_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3135
error
grpc_error_handle error
Definition: retry_filter.cc:499
google::protobuf::FileDescriptorTables::GetEmptyInstance
static const FileDescriptorTables & GetEmptyInstance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:823
FileDescriptorProto::weak_dependency
::PROTOBUF_NAMESPACE_ID::int32 weak_dependency(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7629
google::protobuf::FieldDescriptor::TYPE_BYTES
@ TYPE_BYTES
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:538
FieldDescriptorProto::extendee
const std::string & extendee() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9079
google::protobuf::DescriptorBuilder::assert_mutex_held
static void assert_mutex_held(const DescriptorPool *pool)
Definition: protobuf/src/google/protobuf/descriptor.cc:4094
type_
std::string type_
Definition: client_channel_stress_test.cc:212
FieldDescriptorProto::has_extendee
bool has_extendee() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9072
google::protobuf::Descriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2497
google::protobuf::FieldDescriptor::TYPE_DOUBLE
@ TYPE_DOUBLE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:522
google::protobuf::DescriptorBuilder::get_is_placeholder
static bool get_is_placeholder(const Descriptor *descriptor)
Definition: protobuf/src/google/protobuf/descriptor.cc:4091
DescriptorProto::add_extension_range
PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange * add_extension_range()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8518
inserted
bool inserted
Definition: event_engine/iomgr_event_engine/timer_heap_test.cc:110
google::protobuf::FileDescriptorTables::FileDescriptorTables
FileDescriptorTables()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:809
google::protobuf::DescriptorPool::Tables::symbols_after_checkpoint_
std::vector< const char * > symbols_after_checkpoint_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:685
loc
OPENSSL_EXPORT X509_EXTENSION int loc
Definition: x509.h:1418
FileDescriptorProto::service
const PROTOBUF_NAMESPACE_ID::ServiceDescriptorProto & service(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7763
google::protobuf::Descriptor::FindFieldByNumber
const FieldDescriptor * FindFieldByNumber(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1564
google::protobuf::OneofDescriptor::full_name
const std::string & full_name() const
FileDescriptorProto::kExtensionFieldNumber
@ kExtensionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:638
google::protobuf.internal::call_once
void call_once(Args &&... args)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/once.h:45
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
google::protobuf::FieldDescriptor::containing_type
const Descriptor * containing_type() const
ServiceDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3186
google::protobuf::CEscape
string CEscape(const string &src)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:615
google::protobuf::DescriptorPool::Tables::FieldNamesResult::lowercase_index
int lowercase_index
Definition: protobuf/src/google/protobuf/descriptor.cc:1185
google::protobuf::DescriptorBuilder::FindSymbolNotEnforcingDepsHelper
Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool *pool, const std::string &name, bool build_it=true)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3662
google::protobuf::Symbol::ONEOF
@ ONEOF
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:82
grpc::protobuf::io::Printer
GRPC_CUSTOM_PRINTER Printer
Definition: src/compiler/config.h:54
google::protobuf::DescriptorBuilder::ValidateProto3Field
void ValidateProto3Field(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5884
FieldDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::FieldOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9392
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
grpc::protobuf::DynamicMessageFactory
GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory
Definition: config_grpc_cli.h:54
google::protobuf::FileDescriptorTables::BuildLocationsByPath
static void BuildLocationsByPath(std::pair< const FileDescriptorTables *, const SourceCodeInfo * > *p)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1218
FileDescriptorProto::kMessageTypeFieldNumber
@ kMessageTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:635
google::protobuf::MethodDescriptor::CopyTo
void CopyTo(MethodDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2204
google::protobuf::EnumDescriptor::FindValueByNumberCreatingIfUnknown
const EnumValueDescriptor * FindValueByNumberCreatingIfUnknown(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1698
google::protobuf::DescriptorBuilder::BuildOneof
void BuildOneof(const OneofDescriptorProto &proto, Descriptor *parent, OneofDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5001
google::protobuf::FieldDescriptor::TYPE_BOOL
@ TYPE_BOOL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:533
google::protobuf::DescriptorPool::ErrorCollector::NUMBER
@ NUMBER
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1640
google::protobuf::FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic
static void FieldsByLowercaseNamesLazyInitStatic(const FileDescriptorTables *tables)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:961
google::protobuf::DescriptorPool::Tables::AllocateFileTables
FileDescriptorTables * AllocateFileTables()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1201
FieldDescriptorProto::set_default_value
void set_default_value(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9176
google::protobuf::DescriptorBuilder::ValidateServiceOptions
void ValidateServiceOptions(ServiceDescriptor *service, const ServiceDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6060
FieldDescriptorProto::type_name
const std::string & type_name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8986
google::protobuf::StringPiece::find_last_of
stringpiece_ssize_type find_last_of(StringPiece s, size_type pos=npos) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.cc:211
google::protobuf::DescriptorBuilder::OptionInterpreter::InterpretSingleOption
bool InterpretSingleOption(Message *options, const std::vector< int > &src_path, const std::vector< int > &options_path)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6337
google::protobuf::OneofDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:843
pool_
DescriptorPool pool_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:181
google::protobuf::DescriptorBuilder::OptionInterpreter
friend class OptionInterpreter
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3113
FileDescriptorProto::add_dependency
std::string * add_dependency()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7505
MethodDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3405
setup.name
name
Definition: setup.py:542
google::protobuf::io::NoLocaleStrtod
double NoLocaleStrtod(const char *text, char **original_endptr)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/strtod.cc:82
google::protobuf::Descriptor::FindOneofByName
const OneofDescriptor * FindOneofByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1606
MethodDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10670
google::protobuf::DescriptorPool::Tables::FindAllExtensions
void FindAllExtensions(const Descriptor *extendee, std::vector< const FieldDescriptor * > *out) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1071
google::protobuf::EnumDescriptor::FindValueByName
const EnumValueDescriptor * FindValueByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1683
absl::FormatConversionChar::s
@ s
google::protobuf::DescriptorDatabase::FindFileContainingExtension
virtual bool FindFileContainingExtension(const std::string &containing_type, int field_number, FileDescriptorProto *output)=0
google::protobuf::DescriptorPool::Tables::FindExtension
const FieldDescriptor * FindExtension(const Descriptor *extendee, int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1066
SourceCodeInfo::CopyFrom
void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message &from) final
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:10699
check_documentation.path
path
Definition: check_documentation.py:57
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
google::protobuf::DescriptorBuilder::CrossLinkField
void CrossLinkField(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5438
google::protobuf::ServiceDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2864
OneofDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2462
MethodDescriptorProto::mutable_input_type
std::string * mutable_input_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10498
google::protobuf::DescriptorPool::Tables::arena_
TableArena arena_
Definition: protobuf/src/google/protobuf/descriptor.cc:1217
OneofOptions::default_instance
static const OneofOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:8086
xds_manager.p
p
Definition: xds_manager.py:60
google::protobuf::FieldDescriptor::LABEL_OPTIONAL
@ LABEL_OPTIONAL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:572
google::protobuf::ascii_tolower
char ascii_tolower(char c)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:94
google::protobuf::python::cdescriptor_pool::Add
static PyObject * Add(PyObject *self, PyObject *file_descriptor_proto)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/descriptor_pool.cc:621
google::protobuf::MethodDescriptor::output_type
const Descriptor * output_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7249
google::protobuf::Symbol::ENUM_VALUE_OTHER_PARENT
@ ENUM_VALUE_OTHER_PARENT
Definition: protobuf/src/google/protobuf/descriptor.cc:89
google::protobuf::DescriptorBuilder::FindSymbolNotEnforcingDeps
Symbol FindSymbolNotEnforcingDeps(const std::string &name, bool build_it=true)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3690
google::protobuf::DescriptorBuilder::BuildFile
const FileDescriptor * BuildFile(const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4200
google::protobuf.internal::WireFormatLite::EncodeDouble
static uint64 EncodeDouble(double value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:826
DescriptorProto::reserved_name
const std::string & reserved_name(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8691
google::protobuf::DescriptorPool::BuildFileFromDatabase
const FileDescriptor * BuildFileFromDatabase(const FileDescriptorProto &proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3554
google::protobuf::DescriptorPool::Tables::FieldNamesResult
Definition: protobuf/src/google/protobuf/descriptor.cc:1183
FileDescriptorProto::dependency
const std::string & dependency(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7512
google::protobuf::Symbol::FIELD
@ FIELD
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:81
google::protobuf::StringPiece::substr
StringPiece substr(size_type pos, size_type n=npos) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.cc:261
options
Message * options
Definition: protobuf/src/google/protobuf/descriptor.cc:3704
DescriptorProto::options
const PROTOBUF_NAMESPACE_ID::MessageOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8585
env.new
def new
Definition: env.py:51
MethodDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::MethodOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10708
google::protobuf::DescriptorPool::TryFindExtensionInFallbackDatabase
bool TryFindExtensionInFallbackDatabase(const Descriptor *containing_type, int field_number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1911
google::protobuf::FieldDescriptor::TYPE_GROUP
@ TYPE_GROUP
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:535
FieldDescriptorProto::number
::PROTOBUF_NAMESPACE_ID::int32 number() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8903
FileDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:644
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
iterator
const typedef MCPhysReg * iterator
Definition: MCRegisterInfo.h:27
google::protobuf::DescriptorBuilder::DetectMapConflicts
void DetectMapConflicts(const Descriptor *message, const DescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6151
google::protobuf::OneofDescriptor::name
const std::string & name() const
FileDescriptorProto::kPackageFieldNumber
@ kPackageFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:642
google::protobuf::DescriptorPool::ErrorCollector::OPTION_NAME
@ OPTION_NAME
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1646
EnumDescriptorProto::reserved_name_size
int reserved_name_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9914
google::protobuf::ServiceDescriptor::name
const std::string & name() const
google::protobuf::DescriptorBuilder::ResolveMode
ResolveMode
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3212
EnumValueDescriptorProto::number
::PROTOBUF_NAMESPACE_ID::int32 number() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10096
google::protobuf::FieldDescriptor::TYPE_INT64
@ TYPE_INT64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:524
EnumValue
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:1105
prefix_
std::string prefix_
Definition: protobuf/src/google/protobuf/descriptor.cc:505
google::protobuf::DescriptorBuilder::OptionInterpreter::SetAggregateOption
bool SetAggregateOption(const FieldDescriptor *option_field, UnknownFieldSet *unknown_fields)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6991
google::protobuf::python::cmessage::UnknownFieldSet
static PyObject * UnknownFieldSet(CMessage *self)
Definition: bloaty/third_party/protobuf/python/google/protobuf/pyext/message.cc:2512
google::protobuf.internal::WireFormatLite::ZigZagEncode32
static uint32 ZigZagEncode32(int32 n)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:868
google::protobuf::DescriptorPool::InternalSetLazilyBuildDependencies
void InternalSetLazilyBuildDependencies()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1768
FieldDescriptorProto::oneof_index
::PROTOBUF_NAMESPACE_ID::int32 oneof_index() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9268
ServiceDescriptorProto::kMethodFieldNumber
@ kMethodFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3319
google::protobuf::Symbol::IsType
bool IsType() const
Definition: protobuf/src/google/protobuf/descriptor.cc:169
FileDescriptorProto::mutable_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_extension(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7790
DescriptorProto::mutable_nested_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_nested_type(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8421
google::protobuf::MethodDescriptor::name
const std::string & name() const
ServiceDescriptorProto::add_method
PROTOBUF_NAMESPACE_ID::MethodDescriptorProto * add_method()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10303
google::protobuf::DescriptorBuilder::CrossLinkMethod
void CrossLinkMethod(MethodDescriptor *method, const MethodDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5720
google::protobuf::FieldDescriptor::PrintableNameForExtension
const std::string & PrintableNameForExtension() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7213
ExtensionRangeOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1680
FieldOptions::JS_STRING
static constexpr JSType JS_STRING
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4755
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
T
#define T(upbtypeconst, upbtype, ctype, default_value)
google::protobuf::DescriptorBuilder::BuildField
void BuildField(const FieldDescriptorProto &proto, Descriptor *parent, FieldDescriptor *result)
Definition: protobuf/src/google/protobuf/descriptor.cc:3891
FieldOptions::default_instance
static const FieldOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:7687
gen_build_yaml.struct
def struct(**kwargs)
Definition: test/core/end2end/gen_build_yaml.py:30
google::protobuf::FileDescriptor::syntax_
Syntax syntax_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1473
google::protobuf::Symbol::ENUM
@ ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:83
EnumValueDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2972
google::protobuf::FieldDescriptor::CopyTo
void CopyTo(FieldDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2100
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:1482
FieldOptions_JSType_descriptor
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor * FieldOptions_JSType_descriptor()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:1332
Enum
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:867
google::protobuf::DescriptorPool::Tables::Allocate
Type * Allocate()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1167
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
true
#define true
Definition: setup_once.h:324
google::protobuf.internal::OnShutdownDelete
T * OnShutdownDelete(T *p)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/common.h:185
EnumOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5086
google::protobuf::DescriptorPool::Tables::RollbackToLastCheckpoint
void RollbackToLastCheckpoint()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:845
google::protobuf::FileDescriptor::DependenciesOnceInit
static void DependenciesOnceInit(const FileDescriptor *to_init)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7231
google::protobuf::EnumDescriptor::sequential_value_limit_
int16_t sequential_value_limit_
Definition: protobuf/src/google/protobuf/descriptor.h:1193
google::protobuf::DescriptorPool::FindFileContainingSymbol
const FileDescriptor * FindFileContainingSymbol(const std::string &symbol_name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1389
google::protobuf::DescriptorPool::Tables::AllocateBytes
void * AllocateBytes(int size)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1207
error_
std::string error_
Definition: protobuf/src/google/protobuf/descriptor.cc:7696
google::protobuf::DescriptorPool::Tables::AddExtension
bool AddExtension(const FieldDescriptor *field)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1154
RepeatedField::size
int size
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:407
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
google::protobuf::Descriptor::FindEnumValueByName
const EnumValueDescriptor * FindEnumValueByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1672
google::protobuf::FileDescriptorTables::FindParentForFieldsByMap
const void * FindParentForFieldsByMap(const FieldDescriptor *field) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:948
google::protobuf::DescriptorPool::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool)
google::protobuf::DescriptorBuilder::OptionInterpreter::SetInt64
void SetInt64(int number, int64 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7058
google::protobuf::FileDescriptor::syntax
Syntax syntax() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2175
google::protobuf::FileDescriptor::options_
const FileOptions * options_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1489
google::protobuf::Symbol::SERVICE
@ SERVICE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:85
SourceCodeInfo::default_instance
static const SourceCodeInfo & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:10571
block
Block * block
Definition: protobuf/src/google/protobuf/descriptor.cc:1041
FileDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7825
google::protobuf::FieldDescriptor::is_packed
bool is_packed() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2963
EnumDescriptorProto_EnumReservedRange
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2527
google::protobuf::UnknownFieldSet::field_count
int field_count() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:308
google::protobuf::DescriptorBuilder::CrossLinkFile
void CrossLinkFile(FileDescriptor *file, const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5320
full_blocks_
Block * full_blocks_
Definition: protobuf/src/google/protobuf/descriptor.cc:1037
google::protobuf::FileDescriptor::FindMessageTypeByName
const Descriptor * FindMessageTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1714
DescriptorProto_ReservedRange::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8223
google::protobuf::DescriptorBuilder::ValidateProto3Message
void ValidateProto3Message(Descriptor *message, const DescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5839
FileDescriptorProto::add_weak_dependency
void add_weak_dependency(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7640
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
google::protobuf::Descriptor::options
const MessageOptions & options() const
google::protobuf::EnumValueDescriptor::name
const std::string & name() const
google::protobuf::FieldDescriptor::InternalTypeOnceInit
void InternalTypeOnceInit() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7146
google::protobuf::DescriptorPool::Tables::AllocateString
std::string * AllocateString(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1176
rollback_info_
std::vector< RollbackInfo > rollback_info_
Definition: protobuf/src/google/protobuf/descriptor.cc:1044
google::protobuf::DescriptorPool::ErrorCollector::NAME
@ NAME
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1639
DescriptorProto::mutable_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_extension(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8382
google::protobuf::MethodDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3071
google::protobuf::FileDescriptor::SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1394
change-comments.lines
lines
Definition: change-comments.py:32
grpc::protobuf::io::StringOutputStream
GRPC_CUSTOM_STRINGOUTPUTSTREAM StringOutputStream
Definition: src/compiler/config.h:56
google::protobuf::EnumDescriptor::FindValueByNumber
const EnumValueDescriptor * FindValueByNumber(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1694
google::protobuf::DescriptorBuilder::LOOKUP_TYPES
@ LOOKUP_TYPES
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3212
google::protobuf::Symbol::NULL_SYMBOL
@ NULL_SYMBOL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:79
DescriptorProto::kFieldFieldNumber
@ kFieldFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1448
google::protobuf::FileDescriptor::SYNTAX_UNKNOWN
@ SYNTAX_UNKNOWN
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1392
google::protobuf::DescriptorPool::fallback_database_
DescriptorDatabase * fallback_database_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1851
FieldDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:133
google::protobuf::FieldDescriptor::TYPE_ENUM
@ TYPE_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:540
google::protobuf::Descriptor::WELLKNOWNTYPE_INT64VALUE
@ WELLKNOWNTYPE_INT64VALUE
Definition: protobuf/src/google/protobuf/descriptor.h:302
FieldOptions::JS_NUMBER
static constexpr JSType JS_NUMBER
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4757
options_
DebugStringOptions options_
Definition: protobuf/src/google/protobuf/descriptor.cc:3003
google::protobuf::FileDescriptor::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1724
FileDescriptorProto::message_type_size
int message_type_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7667
DescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1457
google::protobuf::FileDescriptor::package
const std::string & package() const
DescriptorProto::extension_size
int extension_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8376
google::protobuf::Descriptor::field
const FieldDescriptor * field(int index) const
google::protobuf::ServiceDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1152
query
Definition: ares_private.h:198
google::protobuf::FileDescriptor::enum_types_
EnumDescriptor * enum_types_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1486
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
google::protobuf::DescriptorPool::CrossLinkOnDemandHelper
Symbol CrossLinkOnDemandHelper(const std::string &name, bool expecting_enum) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7132
google::protobuf::DescriptorBuilder::OptionInterpreter::OptionInterpreter
OptionInterpreter(DescriptorBuilder *builder)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6247
start
static uint64_t start
Definition: benchmark-pound.c:74
EnumDescriptorProto::kValueFieldNumber
@ kValueFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2840
google::protobuf::Symbol::QueryKey::field_number
int field_number
Definition: protobuf/src/google/protobuf/descriptor.cc:159
google::protobuf::Descriptor::WELLKNOWNTYPE_TIMESTAMP
@ WELLKNOWNTYPE_TIMESTAMP
Definition: protobuf/src/google/protobuf/descriptor.h:314
DescriptorProto::kExtensionRangeFieldNumber
@ kExtensionRangeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1451
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
google::protobuf::DescriptorPool::enforce_dependencies_
bool enforce_dependencies_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1860
google::protobuf::DescriptorPool::Tables::FindFile
const FileDescriptor * FindFile(const std::string &key) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:938
google::protobuf::FieldDescriptor::kFirstReservedNumber
static const int kFirstReservedNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:585
EnumValueOptions::default_instance
static const EnumValueOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:8628
asyncio_get_stats.parser
parser
Definition: asyncio_get_stats.py:34
DescriptorProto_ExtensionRange::mutable_options
PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8152
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
FileDescriptorProto::has_name
bool has_name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7314
google::protobuf::DescriptorBuilder::AddWarning
void AddWarning(const std::string &element_name, const Message &descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &error)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3636
EnumDescriptorProto::reserved_range
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto_EnumReservedRange & reserved_range(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9893
benchmark.syntax
syntax
Definition: benchmark.py:90
google::protobuf::ConstStringParam
const std::string & ConstStringParam
Definition: third_party/protobuf/src/google/protobuf/stubs/port.h:129
DescriptorProto_ExtensionRange
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:936
google::protobuf.descriptor_pool.DescriptorPool::Tables::CheckPoint::pending_extensions_before_checkpoint
int pending_extensions_before_checkpoint
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:682
google::protobuf::kNonLinkedWeakMessageReplacementName
static const char *const kNonLinkedWeakMessageReplacementName
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:233
google::protobuf::FileDescriptorTables::fields_by_camelcase_name_once_
internal::once_flag fields_by_camelcase_name_once_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:782
arena_
Arena * arena_
Definition: client_channel.cc:391
google::protobuf.internal::once_flag
std::once_flag once_flag
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/once.h:43
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
FileDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::FileOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7837
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
FileDescriptorProto::message_type
const PROTOBUF_NAMESPACE_ID::DescriptorProto & message_type(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7685
google::protobuf::DescriptorPool::Tables::AllocateFieldNames
FieldNamesResult AllocateFieldNames(const std::string &name, const std::string &scope, const std::string *opt_json_name)
Definition: protobuf/src/google/protobuf/descriptor.cc:1785
google::protobuf::FileDescriptorTables::FindNestedSymbol
Symbol FindNestedSymbol(const void *parent, const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:887
google::protobuf::DescriptorPool::DescriptorPool
DescriptorPool()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1240
DescriptorProto::enum_type
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto & enum_type(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8472
DescriptorProto::add_reserved_range
PROTOBUF_NAMESPACE_ID::DescriptorProto_ReservedRange * add_reserved_range()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8664
MessageOptions::default_instance
static const MessageOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:7325
OneofDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::OneofOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9557
FileDescriptorProto::kEnumTypeFieldNumber
@ kEnumTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:636
google::protobuf::FileDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2396
google::protobuf::EnumDescriptor::name
const std::string & name() const
hpack_encoder_fixtures::Args
Args({0, 16384})
array
Definition: undname.c:101
google::protobuf::DescriptorPool::InternalAddGeneratedFile
static void InternalAddGeneratedFile(const void *encoded_file_descriptor, int size)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1335
gen_synthetic_protos.label
label
Definition: gen_synthetic_protos.py:102
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
google::protobuf::DescriptorBuilder::OptionInterpreter::AddNameError
bool AddNameError(const std::string &msg)
Definition: protobuf/src/google/protobuf/descriptor.cc:4030
absl::string_view::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:277
google::protobuf::DescriptorPool::Tables::AddSymbol
bool AddSymbol(const std::string &full_name, Symbol symbol)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1083
google::protobuf::StripWhitespace
void StripWhitespace(string *str)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:113
size
uint32_t size
Definition: protobuf/src/google/protobuf/descriptor.cc:868
google::protobuf::FieldDescriptor::TypeOnceInit
static void TypeOnceInit(const FieldDescriptor *to_init)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7185
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
google::protobuf::FieldDescriptor::FieldTypeNameDebugString
std::string FieldTypeNameDebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2635
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:182
GOOGLE_DCHECK_GT
#define GOOGLE_DCHECK_GT
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:200
google::protobuf::EnumDescriptor::FindReservedRangeContainingNumber
const EnumDescriptor::ReservedRange * FindReservedRangeContainingNumber(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1819
google::protobuf::ValidateQualifiedName
static bool ValidateQualifiedName(const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3830
google::protobuf::FieldDescriptor::file
const FileDescriptor * file() const
small_size_blocks_
std::array< Block *, kSmallSizes.size()> small_size_blocks_
Definition: protobuf/src/google/protobuf/descriptor.cc:1036
ptr
void * ptr
Definition: protobuf/src/google/protobuf/descriptor.cc:867
google::protobuf.internal::kTypeGoogleApisComPrefix
const char kTypeGoogleApisComPrefix[]
Definition: bloaty/third_party/protobuf/src/google/protobuf/any_lite.cc:53
DescriptorProto::extension
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & extension(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8394
FieldDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::FieldOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9418
DescriptorProto_ExtensionRange::options
const PROTOBUF_NAMESPACE_ID::ExtensionRangeOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8126
FieldDescriptorProto::type
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8960
FileDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7325
MethodDescriptorProto::mutable_output_type
std::string * mutable_output_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10591
EnumValueDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10115
DescriptorProto::add_field
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_field()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8362
google::protobuf::DescriptorBuilder::tables_
DescriptorPool::Tables * tables_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3119
google::protobuf::FieldDescriptor::default_value_enum
const EnumValueDescriptor * default_value_enum() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7206
google::protobuf::DescriptorPool::ErrorCollector::OUTPUT_TYPE
@ OUTPUT_TYPE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1645
google::protobuf::DescriptorBuilder::~DescriptorBuilder
~DescriptorBuilder()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3579
google::protobuf::DescriptorDatabase::FindAllExtensionNumbers
virtual bool FindAllExtensionNumbers(const std::string &, std::vector< int > *)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:105
google::protobuf::FileDescriptorTables::fields_by_camelcase_name_tmp_
std::unique_ptr< FieldsByNameMap > fields_by_camelcase_name_tmp_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:781
ServiceDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::ServiceOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10357
google::protobuf::FieldDescriptor::TYPE_FIXED32
@ TYPE_FIXED32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:532
google::protobuf::DescriptorBuilder::OptionInterpreter
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3341
google::protobuf::FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic
static void FieldsByCamelcaseNamesLazyInitStatic(const FileDescriptorTables *tables)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:985
FieldDescriptorProto::label
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label label() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8931
google::protobuf::DebugStringOptions::elide_group_body
bool elide_group_body
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:167
google::protobuf::StringPiece
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.h:180
FileDescriptorProto::has_syntax
bool has_syntax() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7960
google::protobuf::DescriptorPool::internal_generated_pool
static DescriptorPool * internal_generated_pool()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1320
google::protobuf::DescriptorBuilder::ValidateMapEntry
bool ValidateMapEntry(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6079
OneofDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9462
google::protobuf::EnumDescriptor::file
const FileDescriptor * file() const
google::protobuf::FileDescriptor::is_placeholder_
bool is_placeholder_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1474
google::protobuf::FileDescriptorTables::enum_values_by_number_
EnumValuesByNumberSet enum_values_by_number_
Definition: protobuf/src/google/protobuf/descriptor.cc:1333
FileDescriptorProto::set_package
void set_package(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7418
client_streaming
void client_streaming(grpc_end2end_test_config config)
Definition: client_streaming.cc:267
google::protobuf::FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal
void FieldsByLowercaseNamesLazyInitInternal() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:966
grpc::protobuf::MethodDescriptor
GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:87
FileDescriptorProto::kServiceFieldNumber
@ kServiceFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:637
google::protobuf::FileDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2958
google::protobuf::Descriptor::oneof_decl
const OneofDescriptor * oneof_decl(int index) const
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
google::protobuf::SimpleFtoa
string SimpleFtoa(float value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:1226
google::protobuf::Symbol::Package::name
const std::string * name
Definition: protobuf/src/google/protobuf/descriptor.cc:121
google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation
ErrorLocation
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1638
google::protobuf::DescriptorBuilder::BuildFileImpl
FileDescriptor * BuildFileImpl(const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4271
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8103
opencensus.proto.stats.v1.stats_pb2.Tag
Tag
Definition: stats_pb2.py:431
google::protobuf::DescriptorBuilder::OptionInterpreter::AggregateOptionFinder::FindAnyType
const Descriptor * FindAnyType(const Message &, const std::string &prefix, const std::string &name) const override
Definition: protobuf/src/google/protobuf/descriptor.cc:7650
grpc::protobuf::io::CodedInputStream
GRPC_CUSTOM_CODEDINPUTSTREAM CodedInputStream
Definition: include/grpcpp/impl/codegen/config_protobuf.h:102
google::protobuf::DescriptorBuilder::OptionInterpreter::AddOptionError
bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &msg)
Definition: protobuf/src/google/protobuf/descriptor.cc:4021
google::protobuf::Symbol::field_descriptor
const FieldDescriptor * field_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:92
google::protobuf::FileDescriptor::message_types_
Descriptor * message_types_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1485
google::protobuf::Descriptor::WELLKNOWNTYPE_DOUBLEVALUE
@ WELLKNOWNTYPE_DOUBLEVALUE
Definition: protobuf/src/google/protobuf/descriptor.h:300
google::protobuf::FieldDescriptor::LABEL_REQUIRED
@ LABEL_REQUIRED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:573
google::protobuf::DescriptorPool
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1539
google::protobuf::FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown
const EnumValueDescriptor * FindEnumValueByNumberCreatingIfUnknown(const EnumDescriptor *parent, int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1016
DescriptorProto::reserved_name_size
int reserved_name_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8678
EnumDescriptorProto::add_reserved_name
std::string * add_reserved_name()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9920
google::protobuf::DescriptorPool::ServiceDescriptor
friend class ServiceDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1795
google::protobuf::DescriptorPool::Tables::files_after_checkpoint_
std::vector< const char * > files_after_checkpoint_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:686
google::protobuf::StringPrintf
string StringPrintf(const char *format,...)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc:109
MessageOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4359
google::protobuf::Symbol::IsAggregate
bool IsAggregate() const
Definition: protobuf/src/google/protobuf/descriptor.cc:170
FieldDescriptorProto::set_label
void set_label(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Label value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8940
google::protobuf::DescriptorPool::ErrorCollector::~ErrorCollector
virtual ~ErrorCollector()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1238
DescriptorProto::oneof_decl
const PROTOBUF_NAMESPACE_ID::OneofDescriptorProto & oneof_decl(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8550
google::protobuf::FileDescriptor::CopySourceCodeInfoTo
void CopySourceCodeInfoTo(FileDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2040
GOOGLE_DCHECK_GE
#define GOOGLE_DCHECK_GE
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:201
FieldDescriptorProto::clear_type
void clear_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8953
DescriptorProto::add_oneof_decl
PROTOBUF_NAMESPACE_ID::OneofDescriptorProto * add_oneof_decl()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8557
google::protobuf::Symbol::parent_number_key
std::pair< const void *, int > parent_number_key() const
Definition: protobuf/src/google/protobuf/descriptor.cc:259
ServiceDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10197
google::protobuf::reserved_range
reserved_range
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1910
google::protobuf::Descriptor::FindReservedRangeContainingNumber
const ReservedRange * FindReservedRangeContainingNumber(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1807
google::protobuf::Descriptor::oneof_decl_count
int oneof_decl_count() const
SourceCodeInfo::mutable_location
PROTOBUF_NAMESPACE_ID::SourceCodeInfo_Location * mutable_location(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:13697
google::protobuf::Descriptor::FindExtensionByLowercaseName
const FieldDescriptor * FindExtensionByLowercaseName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1628
google::protobuf::EnumValueDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3060
number
int32_t number
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:850
google::protobuf::FieldDescriptor::number
int number() const
FileOptions::LITE_RUNTIME
static constexpr OptimizeMode LITE_RUNTIME
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3831
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1000
google::protobuf::DescriptorPool::Tables::ClearLastCheckpoint
void ClearLastCheckpoint()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:833
EnumValueDescriptor
Definition: protobuf/php/ext/google/protobuf/def.c:63
google::protobuf.internal::SymbolBase
Definition: protobuf/src/google/protobuf/descriptor.h:227
google::protobuf::FieldDescriptor::kLastReservedNumber
static const int kLastReservedNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:588
google::protobuf::Descriptor::ExtensionRange::CopyTo
void CopyTo(DescriptorProto_ExtensionRange *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1785
google::protobuf::OneofDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2984
google::protobuf::MethodDescriptor::service
const ServiceDescriptor * service() const
EnumValueDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10000
FieldDescriptorProto::default_value
const std::string & default_value() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9172
google::protobuf::DescriptorPool::MethodDescriptor
friend class MethodDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1796
google::protobuf::FieldDescriptor::LABEL_REPEATED
@ LABEL_REPEATED
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:574
google::protobuf.descriptor_pool.DescriptorPool::Tables::CheckPoint::CheckPoint
CheckPoint(const Tables *tables)
Definition: protobuf/src/google/protobuf/descriptor.cc:1224
DescriptorProto_ExtensionRange::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8114
google::protobuf::DescriptorBuilder::BuildEnum
void BuildEnum(const EnumDescriptorProto &proto, const Descriptor *parent, EnumDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5094
google::protobuf::DescriptorPool::Tables::~Tables
~Tables()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:805
google::protobuf::DescriptorBuilder::AddRecursiveImportError
void AddRecursiveImportError(const FileDescriptorProto &proto, int from_here)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4147
EnumDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::EnumOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9821
google::protobuf::EnumDescriptor::CopyTo
void CopyTo(EnumDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2163
google::protobuf::Symbol::enum_value_descriptor
const EnumValueDescriptor * enum_value_descriptor() const
Definition: protobuf/src/google/protobuf/descriptor.cc:143
google::protobuf::WARNING
static const LogLevel WARNING
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:71
grpc::protobuf::DescriptorDatabase
GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase
Definition: include/grpcpp/impl/codegen/config_protobuf.h:83
google::protobuf::FileDescriptorTables::locations_by_path_once_
internal::once_flag locations_by_path_once_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:789
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
google::protobuf::Descriptor::FindNestedTypeByName
const Descriptor * FindNestedTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1650
google::protobuf::DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE
@ PLACEHOLDER_EXTENDABLE_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1838
google::protobuf::EnumValueDescriptor::type_
const EnumDescriptor * type_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1135
EnumDescriptorProto::reserved_range_size
int reserved_range_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9875
phone_pb2.containing_type
containing_type
Definition: phone_pb2.py:199
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: bloaty/third_party/protobuf/src/google/protobuf/stubs/substitute.cc:55
google::protobuf::FileDescriptorTables::~FileDescriptorTables
~FileDescriptorTables()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:821
google::protobuf::Descriptor::extension
const FieldDescriptor * extension(int index) const
ServiceDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3321
grpc::protobuf::io::CodedOutputStream
GRPC_CUSTOM_CODEDOUTPUTSTREAM CodedOutputStream
Definition: src/compiler/config.h:55
google::protobuf::Symbol::type
Type type() const
Definition: protobuf/src/google/protobuf/descriptor.cc:164
google::protobuf::DescriptorPool::ErrorCollector::TYPE
@ TYPE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1641
google::protobuf::Descriptor::extension_range_count
int extension_range_count() const
google::protobuf::DescriptorPool::FindEnumValueByName
const EnumValueDescriptor * FindEnumValueByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1449
google::protobuf::FieldDescriptor::CPPTYPE_UINT64
@ CPPTYPE_UINT64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:557
EnumOptions::default_instance
static const EnumOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:8331
min
#define min(a, b)
Definition: qsort.h:83
FileDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:501
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:976
google::protobuf::DescriptorPool::allow_unknown_
bool allow_unknown_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1862
FieldDescriptorProto::json_name
const std::string & json_name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9293
google::protobuf::EnumValueDescriptor::CopyTo
void CopyTo(EnumValueDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2183
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
google::protobuf::DescriptorBuilder::AddSymbol
bool AddSymbol(const std::string &full_name, const void *parent, const std::string &name, const Message &proto, Symbol symbol)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3982
EnumValueDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3106
FieldDescriptorProto::set_proto3_optional
void set_proto3_optional(bool value)
Definition: protobuf/src/google/protobuf/descriptor.pb.h:10586
hash< StringPiece >
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringpiece.h:481
EnumDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:143
start_offset
uint16_t start_offset
Definition: protobuf/src/google/protobuf/descriptor.cc:946
google::protobuf::FileDescriptor::source_code_info_
const SourceCodeInfo * source_code_info_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1492
google::protobuf::Descriptor::extension_ranges_
ExtensionRange * extension_ranges_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:469
google::protobuf::Symbol::enum_descriptor
const EnumDescriptor * enum_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:94
google::protobuf.descriptor_pool.DescriptorPool::Tables::CheckPoint::pending_symbols_before_checkpoint
int pending_symbols_before_checkpoint
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:680
google::protobuf::DescriptorBuilder::ValidateProto3Enum
void ValidateProto3Enum(EnumDescriptor *enm, const EnumDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5918
EnumDescriptorProto::reserved_name
const std::string & reserved_name(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9927
google::protobuf::DebugStringOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:160
google::protobuf::HasPrefixString
bool HasPrefixString(const string &str, const string &prefix)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:115
testing::internal::ToLower
char ToLower(char ch)
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:1943
google::protobuf::DescriptorPool::lazily_build_dependencies_
bool lazily_build_dependencies_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1861
FileDescriptorProto::extension
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & extension(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7802
google::protobuf::MethodDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1234
F
#define F(b, c, d)
Definition: md4.c:112
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
google::protobuf::DescriptorPool::Tables::files_by_name_
FilesByNameMap files_by_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:659
google::protobuf::Descriptor::WELLKNOWNTYPE_ANY
@ WELLKNOWNTYPE_ANY
Definition: protobuf/src/google/protobuf/descriptor.h:311
google::protobuf::ERROR
static const LogLevel ERROR
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:70
ServiceOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5473
google::protobuf::Symbol::type
Type type
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:89
FieldDescriptorProto::has_type_name
bool has_type_name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8979
google::protobuf::FieldDescriptor::enum_type
const EnumDescriptor * enum_type
Definition: protobuf/src/google/protobuf/descriptor.h:937
FieldDescriptorProto::mutable_extendee
std::string * mutable_extendee()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9087
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
google::protobuf::LowerString
void LowerString(string *s)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3816
google::protobuf::FileDescriptor::CopyTo
void CopyTo(FileDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1990
google::protobuf::UnknownField::TYPE_LENGTH_DELIMITED
@ TYPE_LENGTH_DELIMITED
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:222
google::protobuf.internal::WireFormatLite::EncodeFloat
static uint32 EncodeFloat(float value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:808
google::protobuf::Symbol::Package::file
const FileDescriptor * file
Definition: protobuf/src/google/protobuf/descriptor.cc:122
google::protobuf::FileDescriptorTables::AddFieldByNumber
bool AddFieldByNumber(const FieldDescriptor *field)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1143
google::protobuf::Symbol::GetFile
const FileDescriptor * GetFile() const
Definition: protobuf/src/google/protobuf/descriptor.cc:175
OneofDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9545
google::protobuf::DescriptorPool::Tables::known_bad_symbols_
HASH_SET< std::string > known_bad_symbols_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:576
google::protobuf::DescriptorPool::Tables::extensions_after_checkpoint_
std::vector< DescriptorIntPair > extensions_after_checkpoint_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:687
google::protobuf::DescriptorDatabase
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor_database.h:71
nested
static int nested
Definition: test-callback-stack.c:39
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
google::protobuf::Symbol::parent_name_key
std::pair< const void *, StringPiece > parent_name_key() const
Definition: protobuf/src/google/protobuf/descriptor.cc:224
kSmallSizes
static constexpr std::array< uint8_t, 6 > kSmallSizes
Definition: protobuf/src/google/protobuf/descriptor.cc:1019
google::protobuf::FileDescriptorTables::fields_by_camelcase_name_
FieldsByNameMap fields_by_camelcase_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:780
google::protobuf::DescriptorBuilder::LOOKUP_ALL
@ LOOKUP_ALL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3212
FieldDescriptorProto::set_type_name
void set_type_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8990
google::protobuf::Symbol::enum_value_descriptor
const EnumValueDescriptor * enum_value_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:95
google::protobuf::DescriptorPool::Tables::AddFile
bool AddFile(const FileDescriptor *file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1100
SYNTAX_PROTO3
@ SYNTAX_PROTO3
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:157
google::protobuf::DescriptorPool::ErrorCollector::OTHER
@ OTHER
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1649
google::protobuf::DescriptorBuilder::BuildReservedRange
void BuildReservedRange(const DescriptorProto::ReservedRange &proto, const Descriptor *parent, Descriptor::ReservedRange *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4978
ServiceDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10319
google::protobuf::DescriptorPool::NewPlaceholderWithMutexHeld
Symbol NewPlaceholderWithMutexHeld(const std::string &name, PlaceholderType placeholder_type) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3856
MethodDescriptorProto::set_server_streaming
void set_server_streaming(bool value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10783
google::protobuf::DescriptorPool::Tables::symbols_by_name_
SymbolsByNameSet symbols_by_name_
Definition: protobuf/src/google/protobuf/descriptor.cc:1219
google::protobuf::ServiceDescriptor::FindMethodByName
const MethodDescriptor * FindMethodByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1703
value
const char * value
Definition: hpack_parser_table.cc:165
FileDescriptorProto::mutable_message_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * mutable_message_type(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7673
FileDescriptorProto::add_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_extension()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7809
google::protobuf::FieldDescriptor::CPPTYPE_INT64
@ CPPTYPE_INT64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:555
google::protobuf::DynamicMessageFactory
Definition: bloaty/third_party/protobuf/src/google/protobuf/dynamic_message.h:80
google::protobuf::FileDescriptor::name_
const std::string * name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1458
google::protobuf::FieldDescriptor::TYPE_SINT32
@ TYPE_SINT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:543
DescriptorProto_ReservedRange::start
::PROTOBUF_NAMESPACE_ID::int32 start() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8195
google::protobuf.internal::MutexLockMaybe
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:130
google::protobuf::FileDescriptor::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1755
google::protobuf.internal::SymbolBase::symbol_type_
uint8_t symbol_type_
Definition: protobuf/src/google/protobuf/descriptor.h:230
google::protobuf::DescriptorPool::Tables::pending_files_
std::vector< std::string > pending_files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:563
google::protobuf::EnumValueDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2831
FATAL
#define FATAL(msg)
Definition: task.h:88
google::protobuf::FileDescriptor::name
const std::string & name() const
absl::base_internal::RoundUp
static uintptr_t RoundUp(uintptr_t addr, uintptr_t align)
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:444
source_loc_
SourceLocation source_loc_
Definition: protobuf/src/google/protobuf/descriptor.cc:3002
google::protobuf::DescriptorPool::FindExtensionByNumber
const FieldDescriptor * FindExtensionByNumber(const Descriptor *extendee, int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1468
DescriptorProto_ExtensionRange::start
::PROTOBUF_NAMESPACE_ID::int32 start() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8067
FieldDescriptorProto::TYPE_ENUM
static constexpr Type TYPE_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2008
google::protobuf::Symbol::EnumValue
static Symbol EnumValue(EnumValueDescriptor *value, int n)
Definition: protobuf/src/google/protobuf/descriptor.cc:129
google::protobuf::FileDescriptorTables::FinalizeTables
void FinalizeTables()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1109
contents
string_view contents
Definition: elf.cc:597
google::protobuf::SimpleDtoa
string SimpleDtoa(double value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:1221
google::protobuf::Symbol::ptr_
const internal::SymbolBase * ptr_
Definition: protobuf/src/google/protobuf/descriptor.cc:276
google::protobuf::EnumValueDescriptor::options_
const EnumValueOptions * options_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1136
google::protobuf::DescriptorPool::Tables::checkpoints_
std::vector< CheckPoint > checkpoints_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:684
google::protobuf::DescriptorBuilder::IsInPackage
bool IsInPackage(const FileDescriptor *file, const std::string &package_name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3648
google::protobuf::FieldDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2618
google::protobuf::Symbol::Symbol
Symbol()
Definition: protobuf/src/google/protobuf/descriptor.cc:96
google::protobuf.internal::kTypeGoogleProdComPrefix
const char kTypeGoogleProdComPrefix[]
Definition: bloaty/third_party/protobuf/src/google/protobuf/any_lite.cc:54
google::protobuf::DescriptorPool::FindOneofByName
const OneofDescriptor * FindOneofByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1437
checkpoint
static void checkpoint(upb_pbdecoder *d)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:6592
google::protobuf::UnknownFieldSet::field
const UnknownField & field(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:311
google::protobuf::Message
Definition: bloaty/third_party/protobuf/src/google/protobuf/message.h:205
print_histogram
static void print_histogram(grpc_histogram *histogram)
Definition: low_level_ping_pong.cc:279
field
const FieldDescriptor * field
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:2692
make_dist_html.groups
list groups
Definition: make_dist_html.py:120
phony_transport::Destroy
void Destroy(grpc_transport *)
Definition: bm_call_create.cc:443
FileDescriptorProto::syntax
const std::string & syntax() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7967
google::protobuf::DescriptorBuilder::ValidateExtensionRangeOptions
void ValidateExtensionRangeOptions(const std::string &full_name, Descriptor::ExtensionRange *extension_range, const DescriptorProto_ExtensionRange &proto)
Definition: protobuf/src/google/protobuf/descriptor.cc:6768
FileDescriptorProto::public_dependency
::PROTOBUF_NAMESPACE_ID::int32 public_dependency(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7582
google::protobuf::FieldDescriptor::kMaxNumber
static const int kMaxNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:581
key
const char * key
Definition: hpack_parser_table.cc:164
google::protobuf::EnumValueDescriptor::all_names_
const std::string * all_names_
Definition: protobuf/src/google/protobuf/descriptor.h:1292
FileDescriptorProto::add_public_dependency
void add_public_dependency(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7593
DescriptorProto_ExtensionRange::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1069
upload.group
group
Definition: bloaty/third_party/googletest/googlemock/scripts/upload.py:397
google::protobuf::Symbol::MESSAGE
@ MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:80
google::protobuf::FieldDescriptor::CPPTYPE_UINT32
@ CPPTYPE_UINT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:556
FileDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::FileOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7863
google::protobuf::FieldDescriptor::CPPTYPE_FLOAT
@ CPPTYPE_FLOAT
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:559
google::protobuf::FileDescriptorTables::fields_by_lowercase_name_
FieldsByNameMap fields_by_lowercase_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:777
google::protobuf::DescriptorBuilder::BuildMethod
void BuildMethod(const MethodDescriptorProto &proto, const ServiceDescriptor *parent, MethodDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5286
google::protobuf::MethodDescriptor::input_type
const Descriptor * input_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7245
google::protobuf::FieldDescriptor::TYPE_SINT64
@ TYPE_SINT64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:544
FileDescriptorProto::dependency_size
int dependency_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7499
EnumValueDescriptorProto::set_number
void set_number(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10104
DescriptorProto::add_reserved_name
std::string * add_reserved_name()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8684
EnumDescriptorProto::add_value
PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto * add_value()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9793
end_offset
uint16_t end_offset
Definition: protobuf/src/google/protobuf/descriptor.cc:947
google::protobuf::FieldDescriptor::TYPE_FLOAT
@ TYPE_FLOAT
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:523
EnumDescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9809
ReaderMutexLock
#define ReaderMutexLock(x)
Definition: bloaty/third_party/re2/util/mutex.h:126
google::protobuf::EnumDescriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2773
OneofDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9458
google::protobuf::DescriptorBuilder::filename_
std::string filename_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3128
google::protobuf::DescriptorPool::FindFieldByName
const FieldDescriptor * FindFieldByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1416
OneofDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:138
google::protobuf::FileDescriptor::enum_type_count_
int enum_type_count_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1470
google::protobuf::DescriptorPool::Tables::FieldNamesResult::camelcase_index
int camelcase_index
Definition: protobuf/src/google/protobuf/descriptor.cc:1186
google::protobuf::DescriptorBuilder::file_
FileDescriptor * file_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3129
google::protobuf::FieldDescriptor::TYPE_SFIXED32
@ TYPE_SFIXED32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:541
EnumDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2705
google::protobuf::EnumDescriptor::full_name
const std::string & full_name() const
EnumValueOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5287
google::protobuf::Descriptor::WELLKNOWNTYPE_BOOLVALUE
@ WELLKNOWNTYPE_BOOLVALUE
Definition: protobuf/src/google/protobuf/descriptor.h:308
dynamic
int dynamic(struct state *s)
Definition: bloaty/third_party/zlib/contrib/puff/puff.c:665
google::protobuf::UnknownFieldSet::empty
bool empty() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:302
FieldDescriptorProto::set_extendee
void set_extendee(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9083
google::protobuf::FieldDescriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3026
google::protobuf::Symbol
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:77
google::protobuf::DescriptorPool::InternalFindExtensionByNumberNoLock
const FieldDescriptor * InternalFindExtensionByNumberNoLock(const Descriptor *extendee, int number) const
Definition: protobuf/src/google/protobuf/descriptor.cc:2158
google::protobuf::DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo
void UpdateSourceCodeInfo(SourceCodeInfo *info)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6546
google::protobuf::Descriptor::WELLKNOWNTYPE_FIELDMASK
@ WELLKNOWNTYPE_FIELDMASK
Definition: protobuf/src/google/protobuf/descriptor.h:312
google::protobuf::Descriptor::FindFieldByName
const FieldDescriptor * FindFieldByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1595
phone_pb2.containing_oneof
containing_oneof
Definition: phone_pb2.py:204
FileDescriptorProto::extension_size
int extension_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7784
google::protobuf::FileDescriptor::dependency
const FileDescriptor * dependency(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7235
google::protobuf::FieldDescriptor::kTypeToName
static const char *const kTypeToName[MAX_TYPE+1]
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:826
google::protobuf::Descriptor::DebugStringWithOptions
std::string DebugStringWithOptions(const DebugStringOptions &options) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2502
google::protobuf::FieldDescriptor::CPPTYPE_BOOL
@ CPPTYPE_BOOL
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:560
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
DescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8256
google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE
@ CPPTYPE_DOUBLE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:558
EnumValueDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::EnumValueOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10127
google::protobuf::DescriptorBuilder::undefine_resolved_name_
std::string undefine_resolved_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3150
SourceCodeInfo_Location
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6397
google::protobuf::io::ErrorCollector
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer.h:66
google::protobuf::DescriptorBuilder::get_enforce_weak
static bool get_enforce_weak(const DescriptorPool *pool)
Definition: protobuf/src/google/protobuf/descriptor.cc:4088
DescriptorProto::extension_range
const PROTOBUF_NAMESPACE_ID::DescriptorProto_ExtensionRange & extension_range(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8511
google::protobuf::DescriptorPool::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1427
profile_analyzer.fields
list fields
Definition: profile_analyzer.py:266
name_scope
std::string name_scope
Definition: protobuf/src/google/protobuf/descriptor.cc:3700
google::protobuf.internal::WireFormatLite::ZigZagEncode64
static uint64 ZigZagEncode64(int64 n)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:879
google::protobuf::Symbol::IsNull
bool IsNull() const
Definition: protobuf/src/google/protobuf/descriptor.cc:168
google::protobuf::ToLowercaseWithoutUnderscores
static std::string ToLowercaseWithoutUnderscores(const std::string &name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5825
google::protobuf::DescriptorBuilder::AddImportError
void AddImportError(const FileDescriptorProto &proto, int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4172
google::protobuf::DescriptorBuilder::BuildFieldOrExtension
void BuildFieldOrExtension(const FieldDescriptorProto &proto, const Descriptor *parent, FieldDescriptor *result, bool is_extension)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4653
google::protobuf::Symbol::ENUM_VALUE
@ ENUM_VALUE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:84
google::protobuf::FieldDescriptor::CPPTYPE_ENUM
@ CPPTYPE_ENUM
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:561
google::protobuf::UnknownFieldSet
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:81
MethodDescriptorProto::client_streaming
bool client_streaming() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10747
DescriptorProto::add_nested_type
PROTOBUF_NAMESPACE_ID::DescriptorProto * add_nested_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8440
google::protobuf::DescriptorPool::generated_pool
static const DescriptorPool * generated_pool()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1326
OneofDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::OneofOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9583
MethodDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:3541
file::size
int size
Definition: bloaty/third_party/zlib/examples/gzappend.c:172
field_type
zend_class_entry * field_type
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/message.c:2030
google::protobuf::Descriptor::name
const std::string & name() const
values
std::array< int64_t, Size > values
Definition: abseil-cpp/absl/container/btree_benchmark.cc:608
google::protobuf::DescriptorBuilder::BuildExtensionRange
void BuildExtensionRange(const DescriptorProto::ExtensionRange &proto, const Descriptor *parent, Descriptor::ExtensionRange *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4941
SourceCodeInfo
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:6683
google::protobuf::DescriptorPool::InternalDontEnforceDependencies
void InternalDontEnforceDependencies()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1284
google::protobuf.internal::WireFormat::SerializeUnknownFields
static void SerializeUnknownFields(const UnknownFieldSet &unknown_fields, io::CodedOutputStream *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format.h:160
google::protobuf::Descriptor::GetLocationPath
void GetLocationPath(std::vector< int > *output) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3015
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
EnumDescriptorProto_EnumReservedRange::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9654
MethodDescriptorProto::output_type
const std::string & output_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10583
regen-readme.line
line
Definition: regen-readme.py:30
google::protobuf::DescriptorPool::Tables::Tables
Tables()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:797
google::protobuf::FileDescriptorTables::locations_by_path_
LocationsByPathMap locations_by_path_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:790
DescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::MessageOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8611
google::protobuf.internal::GetEmptyString
const PROTOBUF_EXPORT std::string & GetEmptyString()
Definition: bloaty/third_party/protobuf/src/google/protobuf/generated_message_util.h:87
google::protobuf::Descriptor::file
const FileDescriptor * file() const
OneofDescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2328
google::protobuf::Symbol::QUERY_KEY
@ QUERY_KEY
Definition: protobuf/src/google/protobuf/descriptor.cc:93
google::protobuf::DescriptorPool::default_error_collector_
ErrorCollector * default_error_collector_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1852
FileDescriptorProto::add_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * add_enum_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7731
DescriptorProto
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1312
google::protobuf::EnumValueDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1075
google::protobuf::Split
std::vector< string > Split(const string &full, const char *delim, bool skip_empty=true)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:235
google::protobuf::Symbol::QueryKey::name
StringPiece name
Definition: protobuf/src/google/protobuf/descriptor.cc:157
GOOGLE_CHECK
#define GOOGLE_CHECK(EXPRESSION)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:153
google::protobuf::Descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:231
google::protobuf::FieldDescriptor::TYPE_MESSAGE
@ TYPE_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:536
google::protobuf::DescriptorBuilder::FindSymbol
Symbol FindSymbol(const std::string &name, bool build_it=true)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3702
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
MethodDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10397
OneofOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:4915
google::protobuf::FieldDescriptor::TYPE_UINT32
@ TYPE_UINT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:539
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3741
google::protobuf::Descriptor::FindExtensionByName
const FieldDescriptor * FindExtensionByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1617
FieldDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8807
DescriptorProto::kExtensionFieldNumber
@ kExtensionFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1452
server_streaming
void server_streaming(grpc_end2end_test_config config)
Definition: server_streaming.cc:274
HASH_MAP
#define HASH_MAP
Definition: protobuf/src/google/protobuf/descriptor.cc:520
google::protobuf.internal::AllocateMemory
static SerialArena::Memory AllocateMemory(const AllocationPolicy *policy_ptr, size_t last_size, size_t min_bytes)
Definition: third_party/protobuf/src/google/protobuf/arena.cc:53
google::protobuf::DescriptorPool::ErrorCollector::EXTENDEE
@ EXTENDEE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1642
google::protobuf::DescriptorPool::underlay_
const DescriptorPool * underlay_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1853
GOOGLE_DCHECK_EQ
#define GOOGLE_DCHECK_EQ
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:196
google::protobuf::DescriptorPool::unused_import_track_files_
std::set< std::string > unused_import_track_files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1865
google::protobuf::DescriptorPool::enforce_weak_
bool enforce_weak_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1863
google::protobuf::FileDescriptor::FindExtensionByCamelcaseName
const FieldDescriptor * FindExtensionByCamelcaseName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1775
absl::ABSL_NAMESPACE_BEGIN::dummy
int dummy
Definition: function_type_benchmark.cc:28
EnumValueDescriptorProto::mutable_options
PROTOBUF_NAMESPACE_ID::EnumValueOptions * mutable_options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10153
FileDescriptorProto::mutable_source_code_info
PROTOBUF_NAMESPACE_ID::SourceCodeInfo * mutable_source_code_info()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7931
google::protobuf::FieldDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2978
google::protobuf::Descriptor::FindFieldByCamelcaseName
const FieldDescriptor * FindFieldByCamelcaseName(const std::string &camelcase_name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1584
google::protobuf::DescriptorPool::internal_generated_database
static DescriptorDatabase * internal_generated_database()
Definition: protobuf/src/google/protobuf/descriptor.cc:1979
EnumDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9687
ServiceDescriptorProto::method
const PROTOBUF_NAMESPACE_ID::MethodDescriptorProto & method(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10296
google::protobuf::FieldDescriptor::DefaultValueAsString
std::string DefaultValueAsString(bool quote_string_type) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1941
google::protobuf::Descriptor::WELLKNOWNTYPE_UINT64VALUE
@ WELLKNOWNTYPE_UINT64VALUE
Definition: protobuf/src/google/protobuf/descriptor.h:303
google::protobuf::Descriptor::FindExtensionByCamelcaseName
const FieldDescriptor * FindExtensionByCamelcaseName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1639
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
google::protobuf::DescriptorPool::FileDescriptorTables
friend class FileDescriptorTables
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1800
ServiceDescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10193
google::protobuf::ToUpper
string ToUpper(const string &s)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:193
google::protobuf::FieldDescriptor::TYPE_FIXED64
@ TYPE_FIXED64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:531
google::protobuf::Symbol::QueryKey::parent
const void * parent
Definition: protobuf/src/google/protobuf/descriptor.cc:158
google::protobuf::DescriptorBuilder::CrossLinkService
void CrossLinkService(ServiceDescriptor *service, const ServiceDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5709
FieldDescriptorProto::proto3_optional
bool proto3_optional() const
Definition: protobuf/src/google/protobuf/descriptor.pb.h:10578
FileDescriptorProto::enum_type
const PROTOBUF_NAMESPACE_ID::EnumDescriptorProto & enum_type(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7724
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
google::protobuf::FileDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1320
google::protobuf::FileDescriptorTables::FindEnumValueByNumber
const EnumValueDescriptor * FindEnumValueByNumber(const EnumDescriptor *parent, int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1009
google::protobuf::DescriptorPool::PLACEHOLDER_MESSAGE
@ PLACEHOLDER_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1836
count
size_t count
Definition: protobuf/src/google/protobuf/descriptor.cc:1042
google::protobuf::DescriptorBuilder::BuildMessage
void BuildMessage(const DescriptorProto &proto, const Descriptor *parent, Descriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4522
google::protobuf::Symbol::DEFINE_MEMBERS
DEFINE_MEMBERS(QueryKey, QUERY_KEY, query_key)
google::protobuf::DescriptorPool::FindAllExtensions
void FindAllExtensions(const Descriptor *extendee, std::vector< const FieldDescriptor * > *out) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1529
grpc::protobuf::SourceLocation
GRPC_CUSTOM_SOURCELOCATION SourceLocation
Definition: include/grpcpp/impl/codegen/config_protobuf.h:90
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1093
google::protobuf::FileDescriptorTables
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:703
google::protobuf::EnumValueDescriptor::full_name
const std::string & full_name() const
google::protobuf::DescriptorBuilder::possible_undeclared_dependency_
const FileDescriptor * possible_undeclared_dependency_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3144
ns
static int64_t ns
Definition: bloaty/third_party/re2/util/benchmark.cc:43
FieldDescriptorProto::has_type
bool has_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8950
google::protobuf::DescriptorPool::Tables::well_known_types_
HASH_MAP< std::string, Descriptor::WellKnownType > well_known_types_
Definition: protobuf/src/google/protobuf/descriptor.cc:1122
google::protobuf::Symbol::full_name
StringPiece full_name() const
Definition: protobuf/src/google/protobuf/descriptor.cc:198
google::protobuf::DescriptorPool::Tables::AllocateArray
Type * AllocateArray(int count)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1172
FieldDescriptorProto::kOptionsFieldNumber
@ kOptionsFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:2083
internal
Definition: benchmark/test/output_test_helper.cc:20
google::protobuf::Symbol::Package
Definition: protobuf/src/google/protobuf/descriptor.cc:120
google::protobuf::FieldDescriptor::is_map_message_type
bool is_map_message_type() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1937
google::protobuf::DescriptorBuilder
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3104
google::protobuf::FileDescriptorTables::GetSourceLocation
const SourceCodeInfo_Location * GetSourceLocation(const std::vector< int > &path, const SourceCodeInfo *info) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1226
google::protobuf::EnumValueDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3008
iter
Definition: test_winkernel.cpp:47
google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE
@ CPPTYPE_MESSAGE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:563
google::protobuf::EnumValueDescriptor::number_
int number_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1134
google::protobuf::Descriptor::map_value
const FieldDescriptor * map_value() const
Definition: protobuf/src/google/protobuf/descriptor.cc:2326
google::protobuf::Descriptor::FindEnumTypeByName
const EnumDescriptor * FindEnumTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1661
google::protobuf::DescriptorBuilder::OptionInterpreter::AggregateOptionFinder::FindExtension
const FieldDescriptor * FindExtension(Message *message, const std::string &name) const override
Definition: protobuf/src/google/protobuf/descriptor.cc:7661
EnumDescriptorProto::value
const PROTOBUF_NAMESPACE_ID::EnumValueDescriptorProto & value(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9786
google::protobuf::DescriptorBuilder::had_errors_
bool had_errors_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3127
google::protobuf::DescriptorBuilder::ValidateFileOptions
void ValidateFileOptions(FileDescriptor *file, const FileDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5785
google::protobuf::DescriptorBuilder::ValidateMethodOptions
void ValidateMethodOptions(MethodDescriptor *method, const MethodDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6074
google::protobuf::DescriptorDatabase::FindFileByName
virtual bool FindFileByName(const std::string &filename, FileDescriptorProto *output)=0
google::protobuf::OneofDescriptor::CopyTo
void CopyTo(OneofDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2156
absl::container_internal::Allocate
void * Allocate(Alloc *alloc, size_t n)
Definition: abseil-cpp/absl/container/internal/container_memory.h:54
FileDescriptorProto::has_source_code_info
bool has_source_code_info() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7893
google::protobuf::Join
void Join(Iterator start, Iterator end, const char *delim, string *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:769
google::protobuf::FileDescriptor::FindEnumValueByName
const EnumValueDescriptor * FindEnumValueByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1734
google::protobuf::DescriptorPool::disallow_enforce_utf8_
bool disallow_enforce_utf8_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1864
google::protobuf::ServiceDescriptor::CopyTo
void CopyTo(ServiceDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2192
DescriptorProto::add_extension
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * add_extension()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8401
google::protobuf::DescriptorPool::tables_
std::unique_ptr< Tables > tables_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1857
google::protobuf::UnknownField::number
int number() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/unknown_field_set.h:326
FieldDescriptorProto::set_json_name
void set_json_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9297
Field
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:446
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
google::protobuf::Descriptor::WELLKNOWNTYPE_FLOATVALUE
@ WELLKNOWNTYPE_FLOATVALUE
Definition: protobuf/src/google/protobuf/descriptor.h:301
DescriptorProto::name
const std::string & name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8252
ch
char ch
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3621
google::protobuf::EnumDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2990
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
google::protobuf::DescriptorBuilder::AllocateOptions
void AllocateOptions(const typename DescriptorT::OptionsType &orig_options, DescriptorT *descriptor, int options_field_tag)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4079
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
google::protobuf::FieldDescriptor::TYPE_INT32
@ TYPE_INT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:528
google::protobuf::Symbol::method_descriptor
const MethodDescriptor * method_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:97
google::protobuf::DescriptorBuilder::AddError
void AddError(const std::string &element_name, const Message &descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, const std::string &error)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3581
google::protobuf::FileDescriptor::CopyJsonNameTo
void CopyJsonNameTo(FileDescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2026
google::protobuf::DescriptorDatabase::FindFileContainingSymbol
virtual bool FindFileContainingSymbol(const std::string &symbol_name, FileDescriptorProto *output)=0
google::protobuf::DescriptorBuilder::possible_undeclared_dependency_name_
std::string possible_undeclared_dependency_name_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3145
google::protobuf::DescriptorBuilder::DescriptorBuilder
DescriptorBuilder(const DescriptorPool *pool, DescriptorPool::Tables *tables, DescriptorPool::ErrorCollector *error_collector)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3569
FileDescriptorProto::package
const std::string & package() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7414
google::protobuf::DescriptorPool::ErrorCollector::DEFAULT_VALUE
@ DEFAULT_VALUE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1643
absl::visit
variant_internal::VisitResult< Visitor, Variants... > visit(Visitor &&vis, Variants &&... vars)
Definition: abseil-cpp/absl/types/variant.h:430
EnumValueDescriptor::number
int32_t number
Definition: protobuf/php/ext/google/protobuf/def.c:66
DescriptorProto::field_size
int field_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8337
file::name
char * name
Definition: bloaty/third_party/zlib/examples/gzappend.c:176
google::protobuf::DescriptorPool::NewPlaceholderFile
FileDescriptor * NewPlaceholderFile(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3954
google::protobuf::Symbol::METHOD
@ METHOD
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:86
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
DescriptorProto::kNestedTypeFieldNumber
@ kNestedTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1449
google::protobuf::Descriptor::CopyJsonNameTo
void CopyJsonNameTo(DescriptorProto *proto) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2082
google::protobuf::FileDescriptorTables::AddEnumValueByNumber
bool AddEnumValueByNumber(const EnumValueDescriptor *value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1148
mkowners.depth
depth
Definition: mkowners.py:114
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
DescriptorProto::mutable_field
PROTOBUF_NAMESPACE_ID::FieldDescriptorProto * mutable_field(int index)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8343
google::protobuf::strtou64
uint64 strtou64(const char *nptr, char **endptr, int base)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.h:380
FieldOptions_JSType
FieldOptions_JSType
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:283
google::protobuf::EnumDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:918
DescriptorPool
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:110
google::protobuf::FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal
void FieldsByCamelcaseNamesLazyInitInternal() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:990
google::protobuf::Symbol::package_file_descriptor
const FileDescriptor * package_file_descriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:98
DescriptorProto::kEnumTypeFieldNumber
@ kEnumTypeFieldNumber
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1450
FileDescriptorProto::has_package
bool has_package() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7407
google::protobuf::DescriptorPool::Tables::AllocateMessage
Type * AllocateMessage(Type *dummy=nullptr)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1195
FileDescriptorProto::weak_dependency_size
int weak_dependency_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:7620
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:146
google::protobuf::Descriptor::WELLKNOWNTYPE_DURATION
@ WELLKNOWNTYPE_DURATION
Definition: protobuf/src/google/protobuf/descriptor.h:313
EnumDescriptorProto::value_size
int value_size() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9768
google::protobuf::DescriptorBuilder::dependencies_
std::set< const FileDescriptor * > dependencies_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3131
FieldDescriptorProto::mutable_type_name
std::string * mutable_type_name()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8994
google::protobuf::DescriptorPool::ErrorCollector::OPTION_VALUE
@ OPTION_VALUE
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1647
google::protobuf::ServiceDescriptor::GetSourceLocation
bool GetSourceLocation(SourceLocation *out_location) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3002
DescriptorProto::add_enum_type
PROTOBUF_NAMESPACE_ID::EnumDescriptorProto * add_enum_type()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8479
phone_pb2.enum_type
enum_type
Definition: phone_pb2.py:198
google::protobuf::DescriptorBuilder::CrossLinkEnumValue
void CrossLinkEnumValue(EnumValueDescriptor *enum_value, const EnumValueDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5701
google::protobuf::DescriptorBuilder::RecordPublicDependencies
void RecordPublicDependencies(const FileDescriptor *file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3655
google::protobuf::DescriptorPool::FindMethodByName
const MethodDescriptor * FindMethodByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1462
google::protobuf::DescriptorBuilder::OptionInterpreter::SetInt32
void SetInt32(int number, int32 value, FieldDescriptor::Type type, UnknownFieldSet *unknown_fields)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:7034
MethodDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10401
google::protobuf.descriptor_pool.DescriptorPool::Tables::CheckPoint::arena_before_checkpoint
int arena_before_checkpoint
Definition: protobuf/src/google/protobuf/descriptor.cc:1232
MethodOptions
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:5659
GOOGLE_DCHECK_LE
#define GOOGLE_DCHECK_LE
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:199
google::protobuf::FileDescriptorTables::symbols_by_parent_
SymbolsByParentSet symbols_by_parent_
Definition: protobuf/src/google/protobuf/descriptor.cc:1325
google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE
@ WELLKNOWNTYPE_VALUE
Definition: protobuf/src/google/protobuf/descriptor.h:315
google::protobuf::DescriptorBuilder::AddPackage
void AddPackage(const std::string &name, const Message &proto, const FileDescriptor *file)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:4025
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
google::protobuf::EnumDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2768
FieldDescriptorProto::set_name
void set_name(const std::string &value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8811
google::protobuf::DescriptorPool::Tables::extensions_loaded_from_db_
HASH_SET< const Descriptor * > extensions_loaded_from_db_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:580
google::protobuf::OneofDescriptor::containing_type
const Descriptor * containing_type() const
google_benchmark.option
option
Definition: third_party/benchmark/bindings/python/google_benchmark/__init__.py:115
error_collector_
MockErrorCollector error_collector_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/importer_unittest.cc:129
MethodDescriptorProto::options
const PROTOBUF_NAMESPACE_ID::MethodOptions & options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:10682
google::protobuf::FileDescriptorTables::FindFieldByNumber
const FieldDescriptor * FindFieldByNumber(const Descriptor *parent, int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:943
google::protobuf::FieldDescriptor::TYPE_STRING
@ TYPE_STRING
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:534
have_source_loc_
bool have_source_loc_
Definition: protobuf/src/google/protobuf/descriptor.cc:3001
FieldDescriptorProto_Label
FieldDescriptorProto_Label
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:211
grpc::protobuf::ServiceDescriptor
GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:88
Method
Definition: bloaty/third_party/protobuf/src/google/protobuf/api.pb.h:320
google::protobuf::DescriptorBuilder::CheckEnumValueUniqueness
void CheckEnumValueUniqueness(const EnumDescriptorProto &proto, const EnumDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5028
google::protobuf::Descriptor::FindExtensionRangeContainingNumber
const ExtensionRange * FindExtensionRangeContainingNumber(int number) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1795
google::protobuf::FieldDescriptor::kTypeToCppTypeMap
static const CppType kTypeToCppTypeMap[MAX_TYPE+1]
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:824
element_name
std::string element_name
Definition: protobuf/src/google/protobuf/descriptor.cc:3701
google::protobuf::TextFormat::PrintFieldValueToString
static void PrintFieldValueToString(const Message &message, const FieldDescriptor *field, int index, std::string *output)
Definition: bloaty/third_party/protobuf/src/google/protobuf/text_format.cc:2405
repeated
static grpc_slice repeated(char c, size_t length)
Definition: message_compress_test.cc:109
google::protobuf::FieldDescriptor::CppType
CppType
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:553
google::protobuf::DescriptorPool::DescriptorBuilder
friend class DescriptorBuilder
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1799
DescriptorProto_ExtensionRange::set_start
void set_start(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8075
DescriptorProto_ExtensionRange::end
::PROTOBUF_NAMESPACE_ID::int32 end() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8095
google::protobuf::ServiceDescriptor::DebugString
std::string DebugString() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:2859
google::protobuf::InsertIfNotPresent
bool InsertIfNotPresent(Collection *const collection, const typename Collection::value_type &vt)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/map_util.h:321
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf::DescriptorBuilder::BuildExtension
void BuildExtension(const FieldDescriptorProto &proto, const Descriptor *parent, FieldDescriptor *result)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:3287
binary_size.old_size
old_size
Definition: binary_size.py:125
DescriptorProto::nested_type
const PROTOBUF_NAMESPACE_ID::DescriptorProto & nested_type(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8433
google::protobuf::FieldDescriptor::kCppTypeToName
static const char *const kCppTypeToName[MAX_CPPTYPE+1]
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:828
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: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:906
num_allocations_
size_t num_allocations_
Definition: protobuf/src/google/protobuf/descriptor.cc:1039
google::protobuf::DescriptorBuilder::get_allow_unknown
static bool get_allow_unknown(const DescriptorPool *pool)
Definition: protobuf/src/google/protobuf/descriptor.cc:4085
Message
Definition: protobuf/php/ext/google/protobuf/message.c:53
google::protobuf::FileDescriptor::Syntax
Syntax
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1391
FieldDescriptorProto::has_oneof_index
bool has_oneof_index() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9258
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
google::protobuf::DescriptorPool::mutex_
internal::WrappedMutex * mutex_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1848
google::protobuf::DescriptorBuilder::ValidateJSType
void ValidateJSType(FieldDescriptor *field, const FieldDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:6208
FieldDescriptorProto::has_json_name
bool has_json_name() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9286
google::protobuf::method
const Descriptor::ReservedRange const EnumValueDescriptor method
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1973
google::protobuf.internal::cpp_type
FieldDescriptor::CppType cpp_type(FieldType type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set_heavy.cc:133
ServiceOptions::default_instance
static const ServiceOptions & default_instance()
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.cc:8894
DescriptorProto_ReservedRange
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:1134
DescriptorProto::field
const PROTOBUF_NAMESPACE_ID::FieldDescriptorProto & field(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8355
google::protobuf::DescriptorPool::AddUnusedImportTrackFile
void AddUnusedImportTrackFile(const std::string &file_name)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1288
google::protobuf::DescriptorPool::FindServiceByName
const ServiceDescriptor * FindServiceByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1456
google::protobuf::Symbol::QueryKey
Definition: protobuf/src/google/protobuf/descriptor.cc:156
google::protobuf::DescriptorBuilder::CrossLinkMessage
void CrossLinkMessage(Descriptor *message, const DescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5343
google::protobuf::FieldDescriptor::TYPE_UINT64
@ TYPE_UINT64
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:527
DescriptorProto::has_options
bool has_options() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8573
grpc._simple_stubs.OptionsType
OptionsType
Definition: _simple_stubs.py:30
FieldDescriptorProto::set_oneof_index
void set_oneof_index(::PROTOBUF_NAMESPACE_ID::int32 value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:9276
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: bloaty/third_party/protobuf/src/google/protobuf/stubs/substitute.cc:68
google::protobuf::Descriptor::WELLKNOWNTYPE_BYTESVALUE
@ WELLKNOWNTYPE_BYTESVALUE
Definition: protobuf/src/google/protobuf/descriptor.h:307
MessageOptions::message_set_wire_format
bool message_set_wire_format() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:12061
google::protobuf::FieldDescriptor::CPPTYPE_INT32
@ CPPTYPE_INT32
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:554
google::protobuf::DescriptorPool::Tables::known_bad_files_
HASH_SET< std::string > known_bad_files_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:570
google::protobuf::DescriptorBuilder::CrossLinkEnum
void CrossLinkEnum(EnumDescriptor *enum_type, const EnumDescriptorProto &proto)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:5690
google::protobuf::Descriptor::FindFieldByLowercaseName
const FieldDescriptor * FindFieldByLowercaseName(const std::string &lowercase_name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1573
FieldDescriptorProto::set_type
void set_type(PROTOBUF_NAMESPACE_ID::FieldDescriptorProto_Type value)
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:8969
google::protobuf.descriptor_pool.DescriptorPool::Tables::CheckPoint::pending_files_before_checkpoint
int pending_files_before_checkpoint
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:681
google::protobuf::service
const Descriptor::ReservedRange const EnumDescriptor::ReservedRange service
Definition: protobuf/src/google/protobuf/descriptor.h:2177
google::protobuf::io::Tokenizer::IsIdentifier
static bool IsIdentifier(const std::string &text)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer.cc:1122
google::protobuf::Descriptor::WELLKNOWNTYPE_STRINGVALUE
@ WELLKNOWNTYPE_STRINGVALUE
Definition: protobuf/src/google/protobuf/descriptor.h:306
RepeatedField
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:403
google::protobuf::FileDescriptorTables::unknown_enum_values_mu_
internal::WrappedMutex unknown_enum_values_mu_
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:794
google::protobuf::DescriptorBuilder::BuildExtension
void BuildExtension(const FieldDescriptorProto &proto, Descriptor *parent, FieldDescriptor *result)
Definition: protobuf/src/google/protobuf/descriptor.cc:3895
google::protobuf::DescriptorPool::FindMessageTypeByName
const Descriptor * FindMessageTypeByName(const std::string &name) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.cc:1410


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:11