Coverage Report

Created: 2024-02-25 06:11

/src/libprotobuf-mutator/build/external.protobuf/src/external.protobuf/src/google/protobuf/descriptor.cc
Line
Count
Source (jump to first uncovered line)
1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
//
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file or at
6
// https://developers.google.com/open-source/licenses/bsd
7
8
// Author: kenton@google.com (Kenton Varda)
9
//  Based on original Protocol Buffers design by
10
//  Sanjay Ghemawat, Jeff Dean, and others.
11
12
#include "google/protobuf/descriptor.h"
13
14
#include <algorithm>
15
#include <array>
16
#include <cstdlib>
17
#include <functional>
18
#include <iterator>
19
#include <limits>
20
#include <memory>
21
#include <sstream>
22
#include <string>
23
#include <type_traits>
24
#include <utility>
25
#include <vector>
26
27
#include "google/protobuf/stubs/common.h"
28
#include "absl/base/call_once.h"
29
#include "absl/base/casts.h"
30
#include "absl/base/dynamic_annotations.h"
31
#include "absl/container/btree_map.h"
32
#include "absl/container/flat_hash_map.h"
33
#include "absl/container/flat_hash_set.h"
34
#include "absl/functional/function_ref.h"
35
#include "absl/hash/hash.h"
36
#include "absl/log/absl_check.h"
37
#include "absl/log/absl_log.h"
38
#include "absl/memory/memory.h"
39
#include "absl/status/statusor.h"
40
#include "absl/strings/ascii.h"
41
#include "absl/strings/escaping.h"
42
#include "absl/strings/match.h"
43
#include "absl/strings/str_cat.h"
44
#include "absl/strings/str_format.h"
45
#include "absl/strings/str_join.h"
46
#include "absl/strings/str_split.h"
47
#include "absl/strings/string_view.h"
48
#include "absl/strings/strip.h"
49
#include "absl/strings/substitute.h"
50
#include "absl/synchronization/mutex.h"
51
#include "absl/types/optional.h"
52
#include "google/protobuf/any.h"
53
#include "google/protobuf/cpp_edition_defaults.h"
54
#include "google/protobuf/cpp_features.pb.h"
55
#include "google/protobuf/descriptor.pb.h"
56
#include "google/protobuf/descriptor_database.h"
57
#include "google/protobuf/descriptor_legacy.h"
58
#include "google/protobuf/descriptor_visitor.h"
59
#include "google/protobuf/dynamic_message.h"
60
#include "google/protobuf/feature_resolver.h"
61
#include "google/protobuf/generated_message_util.h"
62
#include "google/protobuf/io/strtod.h"
63
#include "google/protobuf/io/tokenizer.h"
64
#include "google/protobuf/parse_context.h"
65
#include "google/protobuf/port.h"
66
#include "google/protobuf/repeated_ptr_field.h"
67
#include "google/protobuf/text_format.h"
68
#include "google/protobuf/unknown_field_set.h"
69
70
71
// Must be included last.
72
#include "google/protobuf/port_def.inc"
73
74
namespace google {
75
namespace protobuf {
76
namespace {
77
using ::google::protobuf::internal::DownCast;
78
79
const int kPackageLimit = 100;
80
81
82
174
std::string ToCamelCase(const std::string& input, bool lower_first) {
83
174
  bool capitalize_next = !lower_first;
84
174
  std::string result;
85
174
  result.reserve(input.size());
86
87
2.74k
  for (char character : input) {
88
2.74k
    if (character == '_') {
89
236
      capitalize_next = true;
90
2.50k
    } else if (capitalize_next) {
91
236
      result.push_back(absl::ascii_toupper(character));
92
236
      capitalize_next = false;
93
2.27k
    } else {
94
2.27k
      result.push_back(character);
95
2.27k
    }
96
2.74k
  }
97
98
  // Lower-case the first letter.
99
174
  if (lower_first && !result.empty()) {
100
174
    result[0] = absl::ascii_tolower(result[0]);
101
174
  }
102
103
174
  return result;
104
174
}
105
106
0
std::string ToJsonName(const std::string& input) {
107
0
  bool capitalize_next = false;
108
0
  std::string result;
109
0
  result.reserve(input.size());
110
111
0
  for (char character : input) {
112
0
    if (character == '_') {
113
0
      capitalize_next = true;
114
0
    } else if (capitalize_next) {
115
0
      result.push_back(absl::ascii_toupper(character));
116
0
      capitalize_next = false;
117
0
    } else {
118
0
      result.push_back(character);
119
0
    }
120
0
  }
121
122
0
  return result;
123
0
}
124
125
template <typename OptionsT>
126
0
bool IsLegacyJsonFieldConflictEnabled(const OptionsT& options) {
127
0
#ifdef __GNUC__
128
0
#pragma GCC diagnostic push
129
0
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
130
0
#endif
131
0
  return options.deprecated_legacy_json_field_conflicts();
132
0
#ifdef __GNUC__
133
0
#pragma GCC diagnostic pop
134
0
#endif
135
0
}
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::IsLegacyJsonFieldConflictEnabled<google::protobuf::MessageOptions>(google::protobuf::MessageOptions const&)
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::IsLegacyJsonFieldConflictEnabled<google::protobuf::EnumOptions>(google::protobuf::EnumOptions const&)
136
137
// Backport of fold expressions for the comma operator to C++11.
138
// Usage:  Fold({expr...});
139
// Guaranteed to evaluate left-to-right
140
struct ExpressionEater {
141
  template <typename T>
142
2.11k
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Line
Count
Source
142
1.55k
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<bool>(bool&&)
Line
Count
Source
142
224
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<int&>(int&)
Line
Count
Source
142
224
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<char*&>(char*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::SourceCodeInfo*&>(google::protobuf::SourceCodeInfo*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::FileDescriptorTables*&>(google::protobuf::FileDescriptorTables*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::FeatureSet*&>(google::protobuf::FeatureSet*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::MessageOptions*&>(google::protobuf::MessageOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::FieldOptions*&>(google::protobuf::FieldOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::EnumOptions*&>(google::protobuf::EnumOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::EnumValueOptions*&>(google::protobuf::EnumValueOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::ExtensionRangeOptions*&>(google::protobuf::ExtensionRangeOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::OneofOptions*&>(google::protobuf::OneofOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::ServiceOptions*&>(google::protobuf::ServiceOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::MethodOptions*&>(google::protobuf::MethodOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
descriptor.cc:google::protobuf::(anonymous namespace)::ExpressionEater::ExpressionEater<google::protobuf::FileOptions*&>(google::protobuf::FileOptions*&)
Line
Count
Source
142
8
  ExpressionEater(T&&) {}  // NOLINT
143
};
144
736
void Fold(std::initializer_list<ExpressionEater>) {}
145
146
template <int R>
147
1.87k
constexpr size_t RoundUpTo(size_t n) {
148
1.87k
  static_assert((R & (R - 1)) == 0, "Must be power of two");
149
1.87k
  return (n + (R - 1)) & ~(R - 1);
150
1.87k
}
151
152
0
constexpr size_t Max(size_t a, size_t b) { return a > b ? a : b; }
153
template <typename T, typename... Ts>
154
0
constexpr size_t Max(T a, Ts... b) {
155
0
  return Max(a, Max(b...));
156
0
}
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::Max<unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long>(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)
157
158
template <typename T>
159
0
constexpr size_t EffectiveAlignof() {
160
0
  // `char` is special in that it gets aligned to 8. It is where we drop the
161
0
  // trivial structs.
162
0
  return std::is_same<T, char>::value ? 8 : alignof(T);
163
0
}
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<char>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::SourceCodeInfo>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::FileDescriptorTables>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::FeatureSet>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::MessageOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::FieldOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::EnumOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::EnumValueOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::ExtensionRangeOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::OneofOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::ServiceOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::MethodOptions>()
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::EffectiveAlignof<google::protobuf::FileOptions>()
164
165
template <int align, typename U, typename... T>
166
using AppendIfAlign =
167
    typename std::conditional<EffectiveAlignof<U>() == align, void (*)(T..., U),
168
                              void (*)(T...)>::type;
169
170
// Metafunction to sort types in descending order of alignment.
171
// Useful for the flat allocator to ensure proper alignment of all elements
172
// without having to add padding.
173
// Instead of implementing a proper sort metafunction we just do a
174
// filter+merge, which is much simpler to write as a metafunction.
175
// We have a fixed set of alignments we can filter on.
176
// For simplicity we use a function pointer as a type list.
177
template <typename In, typename T16, typename T8, typename T4, typename T2,
178
          typename T1>
179
struct TypeListSortImpl;
180
181
template <typename... T16, typename... T8, typename... T4, typename... T2,
182
          typename... T1>
183
struct TypeListSortImpl<void (*)(), void (*)(T16...), void (*)(T8...),
184
                        void (*)(T4...), void (*)(T2...), void (*)(T1...)> {
185
  using type = void (*)(T16..., T8..., T4..., T2..., T1...);
186
};
187
188
template <typename First, typename... Rest, typename... T16, typename... T8,
189
          typename... T4, typename... T2, typename... T1>
190
struct TypeListSortImpl<void (*)(First, Rest...), void (*)(T16...),
191
                        void (*)(T8...), void (*)(T4...), void (*)(T2...),
192
                        void (*)(T1...)> {
193
  using type = typename TypeListSortImpl<
194
      void (*)(Rest...), AppendIfAlign<16, First, T16...>,
195
      AppendIfAlign<8, First, T8...>, AppendIfAlign<4, First, T4...>,
196
      AppendIfAlign<2, First, T2...>, AppendIfAlign<1, First, T1...>>::type;
197
};
198
199
template <typename... T>
200
using SortByAlignment =
201
    typename TypeListSortImpl<void (*)(T...), void (*)(), void (*)(),
202
                              void (*)(), void (*)(), void (*)()>::type;
203
204
template <template <typename...> class C, typename... T>
205
auto ApplyTypeList(void (*)(T...)) -> C<T...>;
206
207
template <typename T>
208
0
constexpr int FindTypeIndex() {
209
0
  return -1;
210
0
}
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions>()
211
212
template <typename T, typename T1, typename... Ts>
213
0
constexpr int FindTypeIndex() {
214
0
  return std::is_same<T, T1>::value ? 0 : FindTypeIndex<T, Ts...>() + 1;
215
0
}
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<char, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::SourceCodeInfo, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileDescriptorTables, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FeatureSet, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MessageOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FieldOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::EnumValueOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ExtensionRangeOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::OneofOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::ServiceOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::MethodOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
Unexecuted instantiation: descriptor.cc:int google::protobuf::(anonymous namespace)::FindTypeIndex<google::protobuf::FileOptions, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>()
216
217
// A type to value map, where the possible keys as specified in `Keys...`.
218
// The values for key `K` is `ValueT<K>`
219
template <template <typename> class ValueT, typename... Keys>
220
class TypeMap {
221
 public:
222
  template <typename K>
223
6.92k
  ValueT<K>& Get() {
224
6.92k
    return static_cast<Base<K>&>(payload_).value;
225
6.92k
  }
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Line
Count
Source
223
704
  ValueT<K>& Get() {
224
704
    return static_cast<Base<K>&>(payload_).value;
225
704
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Line
Count
Source
223
2.25k
  ValueT<K>& Get() {
224
2.25k
    return static_cast<Base<K>&>(payload_).value;
225
2.25k
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FileDescriptorTables>()
Line
Count
Source
223
40
  ValueT<K>& Get() {
224
40
    return static_cast<Base<K>&>(payload_).value;
225
40
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FileOptions>()
Line
Count
Source
223
36
  ValueT<K>& Get() {
224
36
    return static_cast<Base<K>&>(payload_).value;
225
36
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::SourceCodeInfo>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<char>()
Line
Count
Source
223
2.62k
  ValueT<K>& Get() {
224
2.62k
    return static_cast<Base<K>&>(payload_).value;
225
2.62k
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::ServiceOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::MethodOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::MessageOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::ExtensionRangeOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::OneofOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::EnumOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::EnumValueOptions>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FieldOptions>()
Line
Count
Source
223
100
  ValueT<K>& Get() {
224
100
    return static_cast<Base<K>&>(payload_).value;
225
100
  }
descriptor.cc:int& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FeatureSet>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:char*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<char>()
Line
Count
Source
223
878
  ValueT<K>& Get() {
224
878
    return static_cast<Base<K>&>(payload_).value;
225
878
  }
descriptor.cc:google::protobuf::SourceCodeInfo*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::SourceCodeInfo>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::FileDescriptorTables*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FileDescriptorTables>()
Line
Count
Source
223
16
  ValueT<K>& Get() {
224
16
    return static_cast<Base<K>&>(payload_).value;
225
16
  }
descriptor.cc:google::protobuf::FeatureSet*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FeatureSet>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::MessageOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::MessageOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::FieldOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FieldOptions>()
Line
Count
Source
223
36
  ValueT<K>& Get() {
224
36
    return static_cast<Base<K>&>(payload_).value;
225
36
  }
descriptor.cc:google::protobuf::EnumOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::EnumOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::EnumValueOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::EnumValueOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::ExtensionRangeOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::ExtensionRangeOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::OneofOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::OneofOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::ServiceOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::ServiceOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::MethodOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::MethodOptions>()
Line
Count
Source
223
8
  ValueT<K>& Get() {
224
8
    return static_cast<Base<K>&>(payload_).value;
225
8
  }
descriptor.cc:google::protobuf::FileOptions*& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FileOptions>()
Line
Count
Source
223
12
  ValueT<K>& Get() {
224
12
    return static_cast<Base<K>&>(payload_).value;
225
12
  }
226
227
  template <typename K>
228
4.93k
  const ValueT<K>& Get() const {
229
4.93k
    return static_cast<const Base<K>&>(payload_).value;
230
4.93k
  }
descriptor.cc:char* const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::PointerT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<char>() const
Line
Count
Source
228
4.17k
  const ValueT<K>& Get() const {
229
4.17k
    return static_cast<const Base<K>&>(payload_).value;
230
4.17k
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<char>() const
Line
Count
Source
228
48
  const ValueT<K>& Get() const {
229
48
    return static_cast<const Base<K>&>(payload_).value;
230
48
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::SourceCodeInfo>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FileDescriptorTables>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FeatureSet>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::MessageOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FieldOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::EnumOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::EnumValueOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::ExtensionRangeOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::OneofOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::ServiceOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::MethodOptions>() const
Line
Count
Source
228
56
  const ValueT<K>& Get() const {
229
56
    return static_cast<const Base<K>&>(payload_).value;
230
56
  }
descriptor.cc:int const& google::protobuf::(anonymous namespace)::TypeMap<google::protobuf::(anonymous namespace)::IntT, char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Get<google::protobuf::FileOptions>() const
Line
Count
Source
228
40
  const ValueT<K>& Get() const {
229
40
    return static_cast<const Base<K>&>(payload_).value;
230
40
  }
231
232
 private:
233
  template <typename K>
234
  struct Base {
235
    ValueT<K> value{};
236
  };
237
  struct Payload : Base<Keys>... {};
238
  Payload payload_;
239
};
240
241
template <typename T>
242
using IntT = int;
243
template <typename T>
244
using PointerT = T*;
245
246
// Manages an allocation of sequential arrays of type `T...`.
247
// It is more space efficient than storing N (ptr, size) pairs, by storing only
248
// the pointer to the head and the boundaries between the arrays.
249
template <typename... T>
250
class FlatAllocation {
251
 public:
252
  static constexpr size_t kMaxAlign = Max(alignof(T)...);
253
254
8
  FlatAllocation(const TypeMap<IntT, T...>& ends) : ends_(ends) {
255
    // The arrays start just after FlatAllocation, so adjust the ends.
256
8
    Fold({(ends_.template Get<T>() +=
257
8
           RoundUpTo<kMaxAlign>(sizeof(FlatAllocation)))...});
258
8
    Fold({Init<T>()...});
259
8
  }
260
261
0
  void Destroy() {
262
0
    Fold({Destroy<T>()...});
263
0
    internal::SizedDelete(this, total_bytes());
264
0
  }
265
266
  template <int I>
267
  using type = typename std::tuple_element<I, std::tuple<T...>>::type;
268
269
  // Gets a tuple of the head pointers for the arrays
270
8
  TypeMap<PointerT, T...> Pointers() const {
271
8
    TypeMap<PointerT, T...> out;
272
8
    Fold({(out.template Get<T>() = Begin<T>())...});
273
8
    return out;
274
8
  }
275
276
277
 private:
278
  // Total number of bytes used by all arrays.
279
0
  int total_bytes() const {
280
    // Get the last end.
281
0
    return ends_.template Get<typename std::tuple_element<
282
0
        sizeof...(T) - 1, std::tuple<T...>>::type>();
283
0
  }
284
285
286
  template <typename U>
287
216
  int BeginOffset() const {
288
216
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
216
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
216
    using PrevType =
292
216
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
216
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
216
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
216
                           : ends_.template Get<PrevType>();
297
216
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::SourceCodeInfo>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::FileDescriptorTables>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::FeatureSet>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::MessageOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::FieldOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::EnumOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::EnumValueOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::ExtensionRangeOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::OneofOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::ServiceOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::MethodOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<google::protobuf::FileOptions>() const
Line
Count
Source
287
16
  int BeginOffset() const {
288
16
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
16
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
16
    using PrevType =
292
16
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
16
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
16
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
16
                           : ends_.template Get<PrevType>();
297
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::BeginOffset<char>() const
Line
Count
Source
287
8
  int BeginOffset() const {
288
8
    constexpr int type_index = FindTypeIndex<U, T...>();
289
    // Avoid a negative value here to keep it compiling when type_index == 0
290
8
    constexpr int prev_type_index = type_index == 0 ? 0 : type_index - 1;
291
8
    using PrevType =
292
8
        typename std::tuple_element<prev_type_index, std::tuple<T...>>::type;
293
    // Ensure the types are properly aligned.
294
8
    static_assert(EffectiveAlignof<PrevType>() >= EffectiveAlignof<U>(), "");
295
8
    return type_index == 0 ? RoundUpTo<kMaxAlign>(sizeof(FlatAllocation))
296
8
                           : ends_.template Get<PrevType>();
297
8
  }
298
299
  template <typename U>
300
216
  int EndOffset() const {
301
216
    return ends_.template Get<U>();
302
216
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::SourceCodeInfo>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::FileDescriptorTables>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::FeatureSet>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::MessageOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::FieldOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::EnumOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::EnumValueOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::ExtensionRangeOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::OneofOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::ServiceOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::MethodOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<google::protobuf::FileOptions>() const
Line
Count
Source
300
16
  int EndOffset() const {
301
16
    return ends_.template Get<U>();
302
16
  }
descriptor.cc:int google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::EndOffset<char>() const
Line
Count
Source
300
8
  int EndOffset() const {
301
8
    return ends_.template Get<U>();
302
8
  }
303
304
  // Avoid the reinterpret_cast if the array is empty.
305
  // Clang's Control Flow Integrity does not like the cast pointing to memory
306
  // that is not yet initialized to be of that type.
307
  // (from -fsanitize=cfi-unrelated-cast)
308
  template <typename U>
309
112
  U* Begin() const {
310
112
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
112
    if (begin == end) return nullptr;
312
32
    return reinterpret_cast<U*>(data() + begin);
313
112
  }
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
8
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::SourceCodeInfo* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::SourceCodeInfo>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::FileDescriptorTables* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::FileDescriptorTables>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
8
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::FeatureSet* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::FeatureSet>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::MessageOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::MessageOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::FieldOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::FieldOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
4
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::EnumOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::EnumOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::EnumValueOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::EnumValueOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::ExtensionRangeOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::ExtensionRangeOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::OneofOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::OneofOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::ServiceOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::ServiceOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::MethodOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::MethodOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
0
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:google::protobuf::FileOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<google::protobuf::FileOptions>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
4
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
descriptor.cc:char* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Begin<char>() const
Line
Count
Source
309
8
  U* Begin() const {
310
8
    int begin = BeginOffset<U>(), end = EndOffset<U>();
311
8
    if (begin == end) return nullptr;
312
8
    return reinterpret_cast<U*>(data() + begin);
313
8
  }
314
315
  template <typename U>
316
0
  U* End() const {
317
0
    int begin = BeginOffset<U>(), end = EndOffset<U>();
318
0
    if (begin == end) return nullptr;
319
0
    return reinterpret_cast<U*>(data() + end);
320
0
  }
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Unexecuted instantiation: descriptor.cc:google::protobuf::SourceCodeInfo* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::SourceCodeInfo>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::FileDescriptorTables* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::FileDescriptorTables>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::FeatureSet* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::FeatureSet>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::MessageOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::MessageOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::FieldOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::FieldOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::EnumOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::EnumOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::EnumValueOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::EnumValueOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::ExtensionRangeOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::ExtensionRangeOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::OneofOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::OneofOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::ServiceOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::ServiceOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::MethodOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::MethodOptions>() const
Unexecuted instantiation: descriptor.cc:google::protobuf::FileOptions* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<google::protobuf::FileOptions>() const
Unexecuted instantiation: descriptor.cc:char* google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::End<char>() const
321
322
  template <typename U>
323
112
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
112
    if (std::is_same<U, char>::value) return true;
326
104
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
1.69k
         p != end; p += sizeof(U)) {
328
1.59k
      ::new (p) U{};
329
1.59k
    }
330
104
    return true;
331
112
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<char>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
0
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
0
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
0
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
1.55k
         p != end; p += sizeof(U)) {
328
1.55k
      ::new (p) U{};
329
1.55k
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::SourceCodeInfo>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::FileDescriptorTables>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
16
         p != end; p += sizeof(U)) {
328
8
      ::new (p) U{};
329
8
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::FeatureSet>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::MessageOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::FieldOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
36
         p != end; p += sizeof(U)) {
328
28
      ::new (p) U{};
329
28
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::EnumOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::EnumValueOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::ExtensionRangeOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::OneofOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::ServiceOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::MethodOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
8
         p != end; p += sizeof(U)) {
328
0
      ::new (p) U{};
329
0
    }
330
8
    return true;
331
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Init<google::protobuf::FileOptions>()
Line
Count
Source
323
8
  bool Init() {
324
    // Skip for the `char` block. No need to zero initialize it.
325
8
    if (std::is_same<U, char>::value) return true;
326
8
    for (char *p = data() + BeginOffset<U>(), *end = data() + EndOffset<U>();
327
12
         p != end; p += sizeof(U)) {
328
4
      ::new (p) U{};
329
4
    }
330
8
    return true;
331
8
  }
332
333
  template <typename U>
334
0
  bool Destroy() {
335
0
    if (std::is_trivially_destructible<U>::value) return true;
336
0
    for (U *it = Begin<U>(), *end = End<U>(); it != end; ++it) {
337
0
      it->~U();
338
0
    }
339
0
    return true;
340
0
  }
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<char>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::SourceCodeInfo>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::FileDescriptorTables>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::FeatureSet>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::MessageOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::FieldOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::EnumOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::EnumValueOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::ExtensionRangeOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::OneofOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::ServiceOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::MethodOptions>()
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocation<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::Destroy<google::protobuf::FileOptions>()
341
342
240
  char* data() const {
343
240
    return const_cast<char*>(reinterpret_cast<const char*>(this));
344
240
  }
345
346
  TypeMap<IntT, T...> ends_;
347
};
348
349
template <typename... T>
350
8
TypeMap<IntT, T...> CalculateEnds(const TypeMap<IntT, T...>& sizes) {
351
8
  int total = 0;
352
8
  TypeMap<IntT, T...> out;
353
8
  Fold({(out.template Get<T>() = total +=
354
8
         sizeof(T) * sizes.template Get<T>())...});
355
8
  return out;
356
8
}
357
358
// The implementation for FlatAllocator below.
359
// This separate class template makes it easier to have methods that fold on
360
// `T...`.
361
template <typename... T>
362
class FlatAllocatorImpl {
363
 public:
364
  using Allocation = FlatAllocation<T...>;
365
366
  template <typename U>
367
1.75k
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
1.75k
    ABSL_CHECK(!has_allocated());
370
1.75k
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
870
      static_assert(alignof(U) <= 8, "");
373
870
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
888
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
888
      using TypeToUse =
378
888
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
888
                                    char, U>::type;
380
888
      total_.template Get<TypeToUse>() += array_size;
381
888
    }
382
1.75k
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::FileDescriptorTables>(int)
Line
Count
Source
367
8
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
8
    ABSL_CHECK(!has_allocated());
370
8
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
0
      static_assert(alignof(U) <= 8, "");
373
0
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
8
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
8
      using TypeToUse =
378
8
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
8
                                    char, U>::type;
380
8
      total_.template Get<TypeToUse>() += array_size;
381
8
    }
382
8
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::FileOptions>(int)
Line
Count
Source
367
4
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
4
    ABSL_CHECK(!has_allocated());
370
4
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
0
      static_assert(alignof(U) <= 8, "");
373
0
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
4
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
4
      using TypeToUse =
378
4
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
4
                                    char, U>::type;
380
4
      total_.template Get<TypeToUse>() += array_size;
381
4
    }
382
4
  }
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::SourceCodeInfo>(int)
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::ServiceDescriptor>(int)
Line
Count
Source
367
8
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
8
    ABSL_CHECK(!has_allocated());
370
8
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
8
      static_assert(alignof(U) <= 8, "");
373
8
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
8
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
8
  }
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::ServiceOptions>(int)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::MethodDescriptor>(int)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::MethodOptions>(int)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::MessageOptions>(int)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::ExtensionRangeOptions>(int)
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::Descriptor::ReservedRange>(int)
Line
Count
Source
367
88
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
88
    ABSL_CHECK(!has_allocated());
370
88
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
88
      static_assert(alignof(U) <= 8, "");
373
88
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
88
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
88
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>(int)
Line
Count
Source
367
122
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
122
    ABSL_CHECK(!has_allocated());
370
122
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
122
      static_assert(alignof(U) <= 8, "");
373
122
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
122
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
122
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::OneofDescriptor>(int)
Line
Count
Source
367
88
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
88
    ABSL_CHECK(!has_allocated());
370
88
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
88
      static_assert(alignof(U) <= 8, "");
373
88
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
88
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
88
  }
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::OneofOptions>(int)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::EnumOptions>(int)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::EnumValueOptions>(int)
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::EnumDescriptor::ReservedRange>(int)
Line
Count
Source
367
34
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
34
    ABSL_CHECK(!has_allocated());
370
34
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
34
      static_assert(alignof(U) <= 8, "");
373
34
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
34
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
34
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::FieldDescriptor>(int)
Line
Count
Source
367
184
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
184
    ABSL_CHECK(!has_allocated());
370
184
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
184
      static_assert(alignof(U) <= 8, "");
373
184
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
184
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
184
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::FieldOptions>(int)
Line
Count
Source
367
28
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
28
    ABSL_CHECK(!has_allocated());
370
28
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
0
      static_assert(alignof(U) <= 8, "");
373
0
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
28
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
28
      using TypeToUse =
378
28
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
28
                                    char, U>::type;
380
28
      total_.template Get<TypeToUse>() += array_size;
381
28
    }
382
28
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<int>(int)
Line
Count
Source
367
16
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
16
    ABSL_CHECK(!has_allocated());
370
16
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
16
      static_assert(alignof(U) <= 8, "");
373
16
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
16
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
16
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::FileDescriptor const*>(int)
Line
Count
Source
367
8
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
8
    ABSL_CHECK(!has_allocated());
370
8
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
8
      static_assert(alignof(U) <= 8, "");
373
8
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
8
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
8
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::EnumValueDescriptor>(int)
Line
Count
Source
367
34
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
34
    ABSL_CHECK(!has_allocated());
370
34
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
34
      static_assert(alignof(U) <= 8, "");
373
34
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
34
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
34
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(int)
Line
Count
Source
367
848
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
848
    ABSL_CHECK(!has_allocated());
370
848
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
0
      static_assert(alignof(U) <= 8, "");
373
0
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
848
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
848
      using TypeToUse =
378
848
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
848
                                    char, U>::type;
380
848
      total_.template Get<TypeToUse>() += array_size;
381
848
    }
382
848
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::FileDescriptor>(int)
Line
Count
Source
367
8
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
8
    ABSL_CHECK(!has_allocated());
370
8
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
8
      static_assert(alignof(U) <= 8, "");
373
8
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
8
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
8
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::EnumDescriptor>(int)
Line
Count
Source
367
96
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
96
    ABSL_CHECK(!has_allocated());
370
96
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
96
      static_assert(alignof(U) <= 8, "");
373
96
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
96
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
96
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::Descriptor>(int)
Line
Count
Source
367
96
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
96
    ABSL_CHECK(!has_allocated());
370
96
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
96
      static_assert(alignof(U) <= 8, "");
373
96
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
96
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
96
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::PlanArray<google::protobuf::Descriptor::ExtensionRange>(int)
Line
Count
Source
367
88
  void PlanArray(int array_size) {
368
    // We can't call PlanArray after FinalizePlanning has been called.
369
88
    ABSL_CHECK(!has_allocated());
370
88
    if (std::is_trivially_destructible<U>::value) {
371
      // Trivial types are aligned to 8 bytes.
372
88
      static_assert(alignof(U) <= 8, "");
373
88
      total_.template Get<char>() += RoundUpTo<8>(array_size * sizeof(U));
374
88
    } else {
375
      // Since we can't use `if constexpr`, just make the expression compile
376
      // when this path is not taken.
377
0
      using TypeToUse =
378
0
          typename std::conditional<std::is_trivially_destructible<U>::value,
379
0
                                    char, U>::type;
380
0
      total_.template Get<TypeToUse>() += array_size;
381
0
    }
382
88
  }
383
384
  template <typename U>
385
1.60k
  U* AllocateArray(int array_size) {
386
1.60k
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
1.60k
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
1.60k
    ABSL_CHECK(has_allocated());
391
392
1.60k
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
1.60k
    int& used = used_.template Get<TypeToUse>();
394
1.60k
    U* res = reinterpret_cast<U*>(data + used);
395
1.60k
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
1.60k
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
1.60k
    return res;
398
1.60k
  }
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(int)
Line
Count
Source
385
696
  U* AllocateArray(int array_size) {
386
696
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
696
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
696
    ABSL_CHECK(has_allocated());
391
392
696
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
696
    int& used = used_.template Get<TypeToUse>();
394
696
    U* res = reinterpret_cast<U*>(data + used);
395
696
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
696
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
696
    return res;
398
696
  }
descriptor.cc:google::protobuf::EnumValueDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::EnumValueDescriptor>(int)
Line
Count
Source
385
34
  U* AllocateArray(int array_size) {
386
34
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
34
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
34
    ABSL_CHECK(has_allocated());
391
392
34
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
34
    int& used = used_.template Get<TypeToUse>();
394
34
    U* res = reinterpret_cast<U*>(data + used);
395
34
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
34
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
34
    return res;
398
34
  }
descriptor.cc:google::protobuf::EnumDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::EnumDescriptor>(int)
Line
Count
Source
385
96
  U* AllocateArray(int array_size) {
386
96
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
96
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
96
    ABSL_CHECK(has_allocated());
391
392
96
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
96
    int& used = used_.template Get<TypeToUse>();
394
96
    U* res = reinterpret_cast<U*>(data + used);
395
96
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
96
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
96
    return res;
398
96
  }
descriptor.cc:google::protobuf::Descriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::Descriptor>(int)
Line
Count
Source
385
96
  U* AllocateArray(int array_size) {
386
96
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
96
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
96
    ABSL_CHECK(has_allocated());
391
392
96
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
96
    int& used = used_.template Get<TypeToUse>();
394
96
    U* res = reinterpret_cast<U*>(data + used);
395
96
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
96
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
96
    return res;
398
96
  }
descriptor.cc:google::protobuf::Descriptor::ExtensionRange* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::Descriptor::ExtensionRange>(int)
Line
Count
Source
385
88
  U* AllocateArray(int array_size) {
386
88
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
88
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
88
    ABSL_CHECK(has_allocated());
391
392
88
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
88
    int& used = used_.template Get<TypeToUse>();
394
88
    U* res = reinterpret_cast<U*>(data + used);
395
88
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
88
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
88
    return res;
398
88
  }
descriptor.cc:google::protobuf::FileDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::FileDescriptor>(int)
Line
Count
Source
385
8
  U* AllocateArray(int array_size) {
386
8
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
8
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
8
    ABSL_CHECK(has_allocated());
391
392
8
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
8
    int& used = used_.template Get<TypeToUse>();
394
8
    U* res = reinterpret_cast<U*>(data + used);
395
8
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
8
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
8
    return res;
398
8
  }
descriptor.cc:google::protobuf::FileOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::FileOptions>(int)
Line
Count
Source
385
4
  U* AllocateArray(int array_size) {
386
4
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
4
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
4
    ABSL_CHECK(has_allocated());
391
392
4
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
4
    int& used = used_.template Get<TypeToUse>();
394
4
    U* res = reinterpret_cast<U*>(data + used);
395
4
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
4
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
4
    return res;
398
4
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::SourceCodeInfo* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::SourceCodeInfo>(int)
descriptor.cc:google::protobuf::FileDescriptorTables* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::FileDescriptorTables>(int)
Line
Count
Source
385
8
  U* AllocateArray(int array_size) {
386
8
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
8
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
8
    ABSL_CHECK(has_allocated());
391
392
8
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
8
    int& used = used_.template Get<TypeToUse>();
394
8
    U* res = reinterpret_cast<U*>(data + used);
395
8
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
8
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
8
    return res;
398
8
  }
descriptor.cc:google::protobuf::FileDescriptor const** google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::FileDescriptor const*>(int)
Line
Count
Source
385
8
  U* AllocateArray(int array_size) {
386
8
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
8
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
8
    ABSL_CHECK(has_allocated());
391
392
8
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
8
    int& used = used_.template Get<TypeToUse>();
394
8
    U* res = reinterpret_cast<U*>(data + used);
395
8
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
8
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
8
    return res;
398
8
  }
descriptor.cc:int* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<int>(int)
Line
Count
Source
385
16
  U* AllocateArray(int array_size) {
386
16
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
16
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
16
    ABSL_CHECK(has_allocated());
391
392
16
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
16
    int& used = used_.template Get<TypeToUse>();
394
16
    U* res = reinterpret_cast<U*>(data + used);
395
16
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
16
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
16
    return res;
398
16
  }
descriptor.cc:google::protobuf::ServiceDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::ServiceDescriptor>(int)
Line
Count
Source
385
8
  U* AllocateArray(int array_size) {
386
8
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
8
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
8
    ABSL_CHECK(has_allocated());
391
392
8
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
8
    int& used = used_.template Get<TypeToUse>();
394
8
    U* res = reinterpret_cast<U*>(data + used);
395
8
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
8
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
8
    return res;
398
8
  }
descriptor.cc:google::protobuf::FieldDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::FieldDescriptor>(int)
Line
Count
Source
385
184
  U* AllocateArray(int array_size) {
386
184
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
184
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
184
    ABSL_CHECK(has_allocated());
391
392
184
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
184
    int& used = used_.template Get<TypeToUse>();
394
184
    U* res = reinterpret_cast<U*>(data + used);
395
184
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
184
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
184
    return res;
398
184
  }
descriptor.cc:google::protobuf::OneofDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::OneofDescriptor>(int)
Line
Count
Source
385
88
  U* AllocateArray(int array_size) {
386
88
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
88
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
88
    ABSL_CHECK(has_allocated());
391
392
88
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
88
    int& used = used_.template Get<TypeToUse>();
394
88
    U* res = reinterpret_cast<U*>(data + used);
395
88
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
88
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
88
    return res;
398
88
  }
descriptor.cc:google::protobuf::Descriptor::ReservedRange* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::Descriptor::ReservedRange>(int)
Line
Count
Source
385
88
  U* AllocateArray(int array_size) {
386
88
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
88
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
88
    ABSL_CHECK(has_allocated());
391
392
88
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
88
    int& used = used_.template Get<TypeToUse>();
394
88
    U* res = reinterpret_cast<U*>(data + used);
395
88
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
88
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
88
    return res;
398
88
  }
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const** google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>(int)
Line
Count
Source
385
122
  U* AllocateArray(int array_size) {
386
122
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
122
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
122
    ABSL_CHECK(has_allocated());
391
392
122
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
122
    int& used = used_.template Get<TypeToUse>();
394
122
    U* res = reinterpret_cast<U*>(data + used);
395
122
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
122
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
122
    return res;
398
122
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::MessageOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::MessageOptions>(int)
descriptor.cc:google::protobuf::FieldOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::FieldOptions>(int)
Line
Count
Source
385
28
  U* AllocateArray(int array_size) {
386
28
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
28
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
28
    ABSL_CHECK(has_allocated());
391
392
28
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
28
    int& used = used_.template Get<TypeToUse>();
394
28
    U* res = reinterpret_cast<U*>(data + used);
395
28
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
28
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
28
    return res;
398
28
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::ExtensionRangeOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::ExtensionRangeOptions>(int)
Unexecuted instantiation: descriptor.cc:google::protobuf::OneofOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::OneofOptions>(int)
descriptor.cc:google::protobuf::EnumDescriptor::ReservedRange* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::EnumDescriptor::ReservedRange>(int)
Line
Count
Source
385
34
  U* AllocateArray(int array_size) {
386
34
    constexpr bool trivial = std::is_trivially_destructible<U>::value;
387
34
    using TypeToUse = typename std::conditional<trivial, char, U>::type;
388
389
    // We can only allocate after FinalizePlanning has been called.
390
34
    ABSL_CHECK(has_allocated());
391
392
34
    TypeToUse*& data = pointers_.template Get<TypeToUse>();
393
34
    int& used = used_.template Get<TypeToUse>();
394
34
    U* res = reinterpret_cast<U*>(data + used);
395
34
    used += trivial ? RoundUpTo<8>(array_size * sizeof(U)) : array_size;
396
34
    ABSL_CHECK_LE(used, total_.template Get<TypeToUse>());
397
34
    return res;
398
34
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::EnumOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::EnumOptions>(int)
Unexecuted instantiation: descriptor.cc:google::protobuf::EnumValueOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::EnumValueOptions>(int)
Unexecuted instantiation: descriptor.cc:google::protobuf::MethodDescriptor* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::MethodDescriptor>(int)
Unexecuted instantiation: descriptor.cc:google::protobuf::ServiceOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::ServiceOptions>(int)
Unexecuted instantiation: descriptor.cc:google::protobuf::MethodOptions* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateArray<google::protobuf::MethodOptions>(int)
399
400
  template <typename... In>
401
696
  const std::string* AllocateStrings(In&&... in) {
402
696
    std::string* strings = AllocateArray<std::string>(sizeof...(in));
403
696
    std::string* res = strings;
404
696
    Fold({(*strings++ = std::string(std::forward<In>(in)))...});
405
696
    return res;
406
696
  }
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<absl::lts_20230802::string_view>(absl::lts_20230802::string_view&&)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<char const (&) [1]>(char const (&) [1])
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<absl::lts_20230802::string_view&, absl::lts_20230802::string_view&>(absl::lts_20230802::string_view&, absl::lts_20230802::string_view&)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<char const (&) [18], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const (&) [18], std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<absl::lts_20230802::string_view&>(absl::lts_20230802::string_view&)
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
401
16
  const std::string* AllocateStrings(In&&... in) {
402
16
    std::string* strings = AllocateArray<std::string>(sizeof...(in));
403
16
    std::string* res = strings;
404
16
    Fold({(*strings++ = std::string(std::forward<In>(in)))...});
405
16
    return res;
406
16
  }
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
401
506
  const std::string* AllocateStrings(In&&... in) {
402
506
    std::string* strings = AllocateArray<std::string>(sizeof...(in));
403
506
    std::string* res = strings;
404
506
    Fold({(*strings++ = std::string(std::forward<In>(in)))...});
405
506
    return res;
406
506
  }
descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
401
174
  const std::string* AllocateStrings(In&&... in) {
402
174
    std::string* strings = AllocateArray<std::string>(sizeof...(in));
403
174
    std::string* res = strings;
404
174
    Fold({(*strings++ = std::string(std::forward<In>(in)))...});
405
174
    return res;
406
174
  }
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const* google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::AllocateStrings<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
407
408
  // Allocate all 5 names of the field:
409
  // name, full name, lowercase, camelcase and json.
410
  // It will dedup the strings when possible.
411
  // The resulting array contains `name` at index 0, `full_name` at index 1
412
  // and the other 3 indices are specified in the result.
413
  void PlanFieldNames(const std::string& name,
414
396
                      const std::string* opt_json_name) {
415
396
    ABSL_CHECK(!has_allocated());
416
417
    // Fast path for snake_case names, which follow the style guide.
418
396
    if (opt_json_name == nullptr) {
419
396
      switch (GetFieldNameCase(name)) {
420
222
        case FieldNameCase::kAllLower:
421
          // Case 1: they are all the same.
422
222
          return PlanArray<std::string>(2);
423
174
        case FieldNameCase::kSnakeCase:
424
          // Case 2: name==lower, camel==json
425
174
          return PlanArray<std::string>(3);
426
0
        default:
427
0
          break;
428
396
      }
429
396
    }
430
431
0
    std::string lowercase_name = name;
432
0
    absl::AsciiStrToLower(&lowercase_name);
433
434
0
    std::string camelcase_name = ToCamelCase(name, /* lower_first = */ true);
435
0
    std::string json_name =
436
0
        opt_json_name != nullptr ? *opt_json_name : ToJsonName(name);
437
438
0
    absl::string_view all_names[] = {name, lowercase_name, camelcase_name,
439
0
                                     json_name};
440
0
    std::sort(all_names, all_names + 4);
441
0
    int unique =
442
0
        static_cast<int>(std::unique(all_names, all_names + 4) - all_names);
443
444
0
    PlanArray<std::string>(unique + 1);
445
0
  }
446
447
  struct FieldNamesResult {
448
    const std::string* array;
449
    int lowercase_index;
450
    int camelcase_index;
451
    int json_index;
452
  };
453
  FieldNamesResult AllocateFieldNames(const std::string& name,
454
                                      const std::string& scope,
455
396
                                      const std::string* opt_json_name) {
456
396
    ABSL_CHECK(has_allocated());
457
458
396
    std::string full_name =
459
396
        scope.empty() ? name : absl::StrCat(scope, ".", name);
460
461
    // Fast path for snake_case names, which follow the style guide.
462
396
    if (opt_json_name == nullptr) {
463
396
      switch (GetFieldNameCase(name)) {
464
222
        case FieldNameCase::kAllLower:
465
          // Case 1: they are all the same.
466
222
          return {AllocateStrings(name, std::move(full_name)), 0, 0, 0};
467
174
        case FieldNameCase::kSnakeCase:
468
          // Case 2: name==lower, camel==json
469
174
          return {AllocateStrings(name, std::move(full_name),
470
174
                                  ToCamelCase(name, /* lower_first = */ true)),
471
174
                  0, 2, 2};
472
0
        default:
473
0
          break;
474
396
      }
475
396
    }
476
477
0
    std::vector<std::string> names;
478
0
    names.push_back(name);
479
0
    names.push_back(std::move(full_name));
480
481
0
    const auto push_name = [&](std::string new_name) {
482
0
      for (size_t i = 0; i < names.size(); ++i) {
483
        // Do not compare the full_name. It is unlikely to match, except in
484
        // custom json_name. We are not taking this into account in
485
        // PlanFieldNames so better to not try it.
486
0
        if (i == 1) continue;
487
0
        if (names[i] == new_name) return i;
488
0
      }
489
0
      names.push_back(std::move(new_name));
490
0
      return names.size() - 1;
491
0
    };
492
493
0
    FieldNamesResult result{nullptr, 0, 0, 0};
494
495
0
    std::string lowercase_name = name;
496
0
    absl::AsciiStrToLower(&lowercase_name);
497
0
    result.lowercase_index = push_name(std::move(lowercase_name));
498
0
    result.camelcase_index =
499
0
        push_name(ToCamelCase(name, /* lower_first = */ true));
500
0
    result.json_index =
501
0
        push_name(opt_json_name != nullptr ? *opt_json_name : ToJsonName(name));
502
503
0
    std::string* all_names = AllocateArray<std::string>(names.size());
504
0
    result.array = all_names;
505
0
    std::move(names.begin(), names.end(), all_names);
506
507
0
    return result;
508
396
  }
509
510
  template <typename Alloc>
511
8
  void FinalizePlanning(Alloc& alloc) {
512
8
    ABSL_CHECK(!has_allocated());
513
514
8
    pointers_ = alloc->CreateFlatAlloc(total_)->Pointers();
515
516
8
    ABSL_CHECK(has_allocated());
517
8
  }
descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::FinalizePlanning<google::protobuf::DescriptorPool::Tables*>(google::protobuf::DescriptorPool::Tables*&)
Line
Count
Source
511
8
  void FinalizePlanning(Alloc& alloc) {
512
8
    ABSL_CHECK(!has_allocated());
513
514
8
    pointers_ = alloc->CreateFlatAlloc(total_)->Pointers();
515
516
8
    ABSL_CHECK(has_allocated());
517
8
  }
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::FinalizePlanning<std::__1::unique_ptr<google::protobuf::DescriptorPool::Tables, std::__1::default_delete<google::protobuf::DescriptorPool::Tables> > const>(std::__1::unique_ptr<google::protobuf::DescriptorPool::Tables, std::__1::default_delete<google::protobuf::DescriptorPool::Tables> > const&)
518
519
8
  void ExpectConsumed() const {
520
    // We verify that we consumed all the memory requested if there was no
521
    // error in processing.
522
8
    Fold({ExpectConsumed<T>()...});
523
8
  }
524
525
 private:
526
4.17k
  bool has_allocated() const {
527
4.17k
    return pointers_.template Get<char>() != nullptr;
528
4.17k
  }
529
530
9.10k
  static bool IsLower(char c) { return 'a' <= c && c <= 'z'; }
531
492
  static bool IsDigit(char c) { return '0' <= c && c <= '9'; }
532
8.30k
  static bool IsLowerOrDigit(char c) { return IsLower(c) || IsDigit(c); }
533
534
  enum class FieldNameCase { kAllLower, kSnakeCase, kOther };
535
792
  FieldNameCase GetFieldNameCase(const std::string& name) {
536
792
    if (!IsLower(name[0])) return FieldNameCase::kOther;
537
792
    FieldNameCase best = FieldNameCase::kAllLower;
538
8.30k
    for (char c : name) {
539
8.30k
      if (IsLowerOrDigit(c)) {
540
        // nothing to do
541
7.83k
      } else if (c == '_') {
542
472
        best = FieldNameCase::kSnakeCase;
543
472
      } else {
544
0
        return FieldNameCase::kOther;
545
0
      }
546
8.30k
    }
547
792
    return best;
548
792
  }
549
550
  template <typename U>
551
112
  bool ExpectConsumed() const {
552
112
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
112
    return true;
554
112
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<char>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::SourceCodeInfo>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::FileDescriptorTables>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::FeatureSet>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::MessageOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::FieldOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::EnumOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::EnumValueOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::ExtensionRangeOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::OneofOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::ServiceOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::MethodOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::FlatAllocatorImpl<char, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, google::protobuf::SourceCodeInfo, google::protobuf::FileDescriptorTables, google::protobuf::FeatureSet, google::protobuf::MessageOptions, google::protobuf::FieldOptions, google::protobuf::EnumOptions, google::protobuf::EnumValueOptions, google::protobuf::ExtensionRangeOptions, google::protobuf::OneofOptions, google::protobuf::ServiceOptions, google::protobuf::MethodOptions, google::protobuf::FileOptions>::ExpectConsumed<google::protobuf::FileOptions>() const
Line
Count
Source
551
8
  bool ExpectConsumed() const {
552
8
    ABSL_CHECK_EQ(total_.template Get<U>(), used_.template Get<U>());
553
8
    return true;
554
8
  }
555
556
  TypeMap<PointerT, T...> pointers_;
557
  TypeMap<IntT, T...> total_;
558
  TypeMap<IntT, T...> used_;
559
};
560
561
}  // namespace
562
563
class Symbol {
564
 public:
565
  enum Type {
566
    NULL_SYMBOL,
567
    MESSAGE,
568
    FIELD,
569
    ONEOF,
570
    ENUM,
571
    ENUM_VALUE,
572
    ENUM_VALUE_OTHER_PARENT,
573
    SERVICE,
574
    METHOD,
575
    FULL_PACKAGE,
576
    SUB_PACKAGE,
577
  };
578
579
442
  Symbol() {
580
442
    static constexpr internal::SymbolBase null_symbol{};
581
442
    static_assert(null_symbol.symbol_type_ == NULL_SYMBOL, "");
582
    // Initialize with a sentinel to make sure `ptr_` is never null.
583
442
    ptr_ = &null_symbol;
584
442
  }
585
586
  // Every object we store derives from internal::SymbolBase, where we store the
587
  // symbol type enum.
588
  // Storing in the object can be done without using more space in most cases,
589
  // while storing it in the Symbol type would require 8 bytes.
590
#define DEFINE_MEMBERS(TYPE, TYPE_CONSTANT, FIELD)                             \
591
532
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
532
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
532
  }                                                                            \
google::protobuf::Symbol::Symbol(google::protobuf::EnumDescriptor*)
Line
Count
Source
591
34
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
34
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
34
  }                                                                            \
google::protobuf::Symbol::Symbol(google::protobuf::Descriptor*)
Line
Count
Source
591
88
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
88
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
88
  }                                                                            \
google::protobuf::Symbol::Symbol(google::protobuf::FileDescriptor*)
Line
Count
Source
591
6
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
6
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
6
  }                                                                            \
google::protobuf::Symbol::Symbol(google::protobuf::Symbol::Subpackage*)
Line
Count
Source
591
4
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
4
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
4
  }                                                                            \
google::protobuf::Symbol::Symbol(google::protobuf::FieldDescriptor*)
Line
Count
Source
591
396
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
396
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
396
  }                                                                            \
google::protobuf::Symbol::Symbol(google::protobuf::OneofDescriptor*)
Line
Count
Source
591
4
  explicit Symbol(TYPE* value) : ptr_(value) {                                 \
592
4
    value->symbol_type_ = TYPE_CONSTANT;                                       \
593
4
  }                                                                            \
Unexecuted instantiation: google::protobuf::Symbol::Symbol(google::protobuf::ServiceDescriptor*)
Unexecuted instantiation: google::protobuf::Symbol::Symbol(google::protobuf::MethodDescriptor*)
594
294k
  const TYPE* FIELD() const {                                                  \
595
294k
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
294k
  }
google::protobuf::Symbol::file_descriptor() const
Line
Count
Source
594
25
  const TYPE* FIELD() const {                                                  \
595
25
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
25
  }
google::protobuf::Symbol::sub_package_file_descriptor() const
Line
Count
Source
594
38
  const TYPE* FIELD() const {                                                  \
595
38
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
38
  }
google::protobuf::Symbol::field_descriptor() const
Line
Count
Source
594
292k
  const TYPE* FIELD() const {                                                  \
595
292k
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
292k
  }
google::protobuf::Symbol::descriptor() const
Line
Count
Source
594
1.31k
  const TYPE* FIELD() const {                                                  \
595
1.31k
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
1.31k
  }
google::protobuf::Symbol::oneof_descriptor() const
Line
Count
Source
594
24
  const TYPE* FIELD() const {                                                  \
595
24
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
24
  }
google::protobuf::Symbol::enum_descriptor() const
Line
Count
Source
594
317
  const TYPE* FIELD() const {                                                  \
595
317
    return type() == TYPE_CONSTANT ? static_cast<const TYPE*>(ptr_) : nullptr; \
596
317
  }
Unexecuted instantiation: google::protobuf::Symbol::service_descriptor() const
Unexecuted instantiation: google::protobuf::Symbol::method_descriptor() const
597
598
  DEFINE_MEMBERS(Descriptor, MESSAGE, descriptor)
599
  DEFINE_MEMBERS(FieldDescriptor, FIELD, field_descriptor)
600
  DEFINE_MEMBERS(OneofDescriptor, ONEOF, oneof_descriptor)
601
  DEFINE_MEMBERS(EnumDescriptor, ENUM, enum_descriptor)
602
  DEFINE_MEMBERS(ServiceDescriptor, SERVICE, service_descriptor)
603
  DEFINE_MEMBERS(MethodDescriptor, METHOD, method_descriptor)
604
  DEFINE_MEMBERS(FileDescriptor, FULL_PACKAGE, file_descriptor)
605
606
  // We use a special node for subpackage FileDescriptor.
607
  // It is potentially added to the table with multiple different names, so we
608
  // need a separate place to put the name.
609
  struct Subpackage : internal::SymbolBase {
610
    int name_size;
611
    const FileDescriptor* file;
612
  };
613
  DEFINE_MEMBERS(Subpackage, SUB_PACKAGE, sub_package_file_descriptor)
614
615
  // Enum values have two different parents.
616
  // We use two different identitied for the same object to determine the two
617
  // different insertions in the map.
618
316
  static Symbol EnumValue(EnumValueDescriptor* value, int n) {
619
316
    Symbol s;
620
316
    internal::SymbolBase* ptr;
621
316
    if (n == 0) {
622
158
      ptr = static_cast<internal::SymbolBaseN<0>*>(value);
623
158
      ptr->symbol_type_ = ENUM_VALUE;
624
158
    } else {
625
158
      ptr = static_cast<internal::SymbolBaseN<1>*>(value);
626
158
      ptr->symbol_type_ = ENUM_VALUE_OTHER_PARENT;
627
158
    }
628
316
    s.ptr_ = ptr;
629
316
    return s;
630
316
  }
631
632
1.69k
  const EnumValueDescriptor* enum_value_descriptor() const {
633
1.69k
    return type() == ENUM_VALUE
634
1.69k
               ? static_cast<const EnumValueDescriptor*>(
635
1.02k
                     static_cast<const internal::SymbolBaseN<0>*>(ptr_))
636
1.69k
           : type() == ENUM_VALUE_OTHER_PARENT
637
668
               ? static_cast<const EnumValueDescriptor*>(
638
668
                     static_cast<const internal::SymbolBaseN<1>*>(ptr_))
639
668
               : nullptr;
640
1.69k
  }
641
642
#undef DEFINE_MEMBERS
643
644
447k
  Type type() const { return static_cast<Type>(ptr_->symbol_type_); }
645
912
  bool IsNull() const { return type() == NULL_SYMBOL; }
646
0
  bool IsType() const { return type() == MESSAGE || type() == ENUM; }
647
0
  bool IsAggregate() const {
648
0
    return IsType() || IsPackage() || type() == SERVICE;
649
0
  }
650
182
  bool IsPackage() const {
651
182
    return type() == FULL_PACKAGE || type() == SUB_PACKAGE;
652
182
  }
653
654
424
  const FileDescriptor* GetFile() const {
655
424
    switch (type()) {
656
347
      case MESSAGE:
657
347
        return descriptor()->file();
658
2
      case FIELD:
659
2
        return field_descriptor()->file();
660
0
      case ONEOF:
661
0
        return oneof_descriptor()->containing_type()->file();
662
45
      case ENUM:
663
45
        return enum_descriptor()->file();
664
30
      case ENUM_VALUE:
665
30
        return enum_value_descriptor()->type()->file();
666
0
      case SERVICE:
667
0
        return service_descriptor()->file();
668
0
      case METHOD:
669
0
        return method_descriptor()->service()->file();
670
0
      case FULL_PACKAGE:
671
0
        return file_descriptor();
672
0
      case SUB_PACKAGE:
673
0
        return sub_package_file_descriptor()->file;
674
0
      default:
675
0
        return nullptr;
676
424
    }
677
424
  }
678
679
1.85k
  absl::string_view full_name() const {
680
1.85k
    switch (type()) {
681
325
      case MESSAGE:
682
325
        return descriptor()->full_name();
683
1.04k
      case FIELD:
684
1.04k
        return field_descriptor()->full_name();
685
4
      case ONEOF:
686
4
        return oneof_descriptor()->full_name();
687
104
      case ENUM:
688
104
        return enum_descriptor()->full_name();
689
333
      case ENUM_VALUE:
690
333
        return enum_value_descriptor()->full_name();
691
0
      case SERVICE:
692
0
        return service_descriptor()->full_name();
693
0
      case METHOD:
694
0
        return method_descriptor()->full_name();
695
25
      case FULL_PACKAGE:
696
25
        return file_descriptor()->package();
697
19
      case SUB_PACKAGE:
698
19
        return absl::string_view(sub_package_file_descriptor()->file->package())
699
19
            .substr(0, sub_package_file_descriptor()->name_size);
700
0
      default:
701
0
        ABSL_CHECK(false);
702
1.85k
    }
703
0
    return "";
704
1.85k
  }
705
706
147k
  std::pair<const void*, absl::string_view> parent_name_key() const {
707
147k
    const auto or_file = [&](const void* p) { return p ? p : GetFile(); };
708
147k
    switch (type()) {
709
257
      case MESSAGE:
710
257
        return {or_file(descriptor()->containing_type()), descriptor()->name()};
711
146k
      case FIELD: {
712
146k
        auto* field = field_descriptor();
713
146k
        return {or_file(field->is_extension() ? field->extension_scope()
714
146k
                                              : field->containing_type()),
715
146k
                field->name()};
716
0
      }
717
10
      case ONEOF:
718
10
        return {oneof_descriptor()->containing_type(),
719
10
                oneof_descriptor()->name()};
720
63
      case ENUM:
721
63
        return {or_file(enum_descriptor()->containing_type()),
722
63
                enum_descriptor()->name()};
723
325
      case ENUM_VALUE:
724
325
        return {or_file(enum_value_descriptor()->type()->containing_type()),
725
325
                enum_value_descriptor()->name()};
726
334
      case ENUM_VALUE_OTHER_PARENT:
727
334
        return {enum_value_descriptor()->type(),
728
334
                enum_value_descriptor()->name()};
729
0
      case SERVICE:
730
0
        return {GetFile(), service_descriptor()->name()};
731
0
      case METHOD:
732
0
        return {method_descriptor()->service(), method_descriptor()->name()};
733
0
      default:
734
0
        ABSL_CHECK(false);
735
147k
    }
736
0
    return {};
737
147k
  }
738
739
 private:
740
  const internal::SymbolBase* ptr_;
741
};
742
743
const FieldDescriptor::CppType
744
    FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = {
745
        static_cast<CppType>(0),  // 0 is reserved for errors
746
747
        CPPTYPE_DOUBLE,   // TYPE_DOUBLE
748
        CPPTYPE_FLOAT,    // TYPE_FLOAT
749
        CPPTYPE_INT64,    // TYPE_INT64
750
        CPPTYPE_UINT64,   // TYPE_UINT64
751
        CPPTYPE_INT32,    // TYPE_INT32
752
        CPPTYPE_UINT64,   // TYPE_FIXED64
753
        CPPTYPE_UINT32,   // TYPE_FIXED32
754
        CPPTYPE_BOOL,     // TYPE_BOOL
755
        CPPTYPE_STRING,   // TYPE_STRING
756
        CPPTYPE_MESSAGE,  // TYPE_GROUP
757
        CPPTYPE_MESSAGE,  // TYPE_MESSAGE
758
        CPPTYPE_STRING,   // TYPE_BYTES
759
        CPPTYPE_UINT32,   // TYPE_UINT32
760
        CPPTYPE_ENUM,     // TYPE_ENUM
761
        CPPTYPE_INT32,    // TYPE_SFIXED32
762
        CPPTYPE_INT64,    // TYPE_SFIXED64
763
        CPPTYPE_INT32,    // TYPE_SINT32
764
        CPPTYPE_INT64,    // TYPE_SINT64
765
};
766
767
const char* const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = {
768
    "ERROR",  // 0 is reserved for errors
769
770
    "double",    // TYPE_DOUBLE
771
    "float",     // TYPE_FLOAT
772
    "int64",     // TYPE_INT64
773
    "uint64",    // TYPE_UINT64
774
    "int32",     // TYPE_INT32
775
    "fixed64",   // TYPE_FIXED64
776
    "fixed32",   // TYPE_FIXED32
777
    "bool",      // TYPE_BOOL
778
    "string",    // TYPE_STRING
779
    "group",     // TYPE_GROUP
780
    "message",   // TYPE_MESSAGE
781
    "bytes",     // TYPE_BYTES
782
    "uint32",    // TYPE_UINT32
783
    "enum",      // TYPE_ENUM
784
    "sfixed32",  // TYPE_SFIXED32
785
    "sfixed64",  // TYPE_SFIXED64
786
    "sint32",    // TYPE_SINT32
787
    "sint64",    // TYPE_SINT64
788
};
789
790
const char* const FieldDescriptor::kCppTypeToName[MAX_CPPTYPE + 1] = {
791
    "ERROR",  // 0 is reserved for errors
792
793
    "int32",    // CPPTYPE_INT32
794
    "int64",    // CPPTYPE_INT64
795
    "uint32",   // CPPTYPE_UINT32
796
    "uint64",   // CPPTYPE_UINT64
797
    "double",   // CPPTYPE_DOUBLE
798
    "float",    // CPPTYPE_FLOAT
799
    "bool",     // CPPTYPE_BOOL
800
    "enum",     // CPPTYPE_ENUM
801
    "string",   // CPPTYPE_STRING
802
    "message",  // CPPTYPE_MESSAGE
803
};
804
805
const char* const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
806
    "ERROR",  // 0 is reserved for errors
807
808
    "optional",  // LABEL_OPTIONAL
809
    "required",  // LABEL_REQUIRED
810
    "repeated",  // LABEL_REPEATED
811
};
812
813
PROTOBUF_IGNORE_DEPRECATION_START
814
0
const char* FileDescriptor::SyntaxName(FileDescriptor::Syntax syntax) {
815
0
  switch (syntax) {
816
0
    case SYNTAX_PROTO2:
817
0
      return "proto2";
818
0
    case SYNTAX_PROTO3:
819
0
      return "proto3";
820
0
    case SYNTAX_EDITIONS:
821
0
      return "editions";
822
0
    case SYNTAX_UNKNOWN:
823
0
      return "unknown";
824
0
  }
825
0
  ABSL_LOG(FATAL) << "can't reach here.";
826
0
  return nullptr;
827
0
}
828
PROTOBUF_IGNORE_DEPRECATION_STOP
829
830
static const char* const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
831
832
#if !defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912)
833
const int FieldDescriptor::kMaxNumber;
834
const int FieldDescriptor::kFirstReservedNumber;
835
const int FieldDescriptor::kLastReservedNumber;
836
#endif
837
838
namespace {
839
840
0
std::string EnumValueToPascalCase(const std::string& input) {
841
0
  bool next_upper = true;
842
0
  std::string result;
843
0
  result.reserve(input.size());
844
845
0
  for (char character : input) {
846
0
    if (character == '_') {
847
0
      next_upper = true;
848
0
    } else {
849
0
      if (next_upper) {
850
0
        result.push_back(absl::ascii_toupper(character));
851
0
      } else {
852
0
        result.push_back(absl::ascii_tolower(character));
853
0
      }
854
0
      next_upper = false;
855
0
    }
856
0
  }
857
858
0
  return result;
859
0
}
860
861
// Class to remove an enum prefix from enum values.
862
class PrefixRemover {
863
 public:
864
0
  PrefixRemover(absl::string_view prefix) {
865
    // Strip underscores and lower-case the prefix.
866
0
    for (char character : prefix) {
867
0
      if (character != '_') {
868
0
        prefix_ += absl::ascii_tolower(character);
869
0
      }
870
0
    }
871
0
  }
872
873
  // Tries to remove the enum prefix from this enum value.
874
  // If this is not possible, returns the input verbatim.
875
0
  std::string MaybeRemove(absl::string_view str) {
876
    // We can't just lowercase and strip str and look for a prefix.
877
    // We need to properly recognize the difference between:
878
    //
879
    //   enum Foo {
880
    //     FOO_BAR_BAZ = 0;
881
    //     FOO_BARBAZ = 1;
882
    //   }
883
    //
884
    // This is acceptable (though perhaps not advisable) because even when
885
    // we PascalCase, these two will still be distinct (BarBaz vs. Barbaz).
886
0
    size_t i, j;
887
888
    // Skip past prefix_ in str if we can.
889
0
    for (i = 0, j = 0; i < str.size() && j < prefix_.size(); i++) {
890
0
      if (str[i] == '_') {
891
0
        continue;
892
0
      }
893
894
0
      if (absl::ascii_tolower(str[i]) != prefix_[j++]) {
895
0
        return std::string(str);
896
0
      }
897
0
    }
898
899
    // If we didn't make it through the prefix, we've failed to strip the
900
    // prefix.
901
0
    if (j < prefix_.size()) {
902
0
      return std::string(str);
903
0
    }
904
905
    // Skip underscores between prefix and further characters.
906
0
    while (i < str.size() && str[i] == '_') {
907
0
      i++;
908
0
    }
909
910
    // Enum label can't be the empty string.
911
0
    if (i == str.size()) {
912
0
      return std::string(str);
913
0
    }
914
915
    // We successfully stripped the prefix.
916
0
    str.remove_prefix(i);
917
0
    return std::string(str);
918
0
  }
919
920
 private:
921
  std::string prefix_;
922
};
923
924
// A DescriptorPool contains a bunch of hash-maps to implement the
925
// various Find*By*() methods.  Since hashtable lookups are O(1), it's
926
// most efficient to construct a fixed set of large hash-maps used by
927
// all objects in the pool rather than construct one or more small
928
// hash-maps for each object.
929
//
930
// The keys to these hash-maps are (parent, name) or (parent, number) pairs.
931
struct FullNameQuery {
932
  absl::string_view query;
933
380
  absl::string_view full_name() const { return query; }
934
};
935
struct SymbolByFullNameHash {
936
  using is_transparent = void;
937
938
  template <typename T>
939
1.77k
  size_t operator()(const T& s) const {
940
1.77k
    return absl::HashOf(s.full_name());
941
1.77k
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::SymbolByFullNameHash::operator()<google::protobuf::(anonymous namespace)::FullNameQuery>(google::protobuf::(anonymous namespace)::FullNameQuery const&) const
Line
Count
Source
939
194
  size_t operator()(const T& s) const {
940
194
    return absl::HashOf(s.full_name());
941
194
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::SymbolByFullNameHash::operator()<google::protobuf::Symbol>(google::protobuf::Symbol const&) const
Line
Count
Source
939
1.58k
  size_t operator()(const T& s) const {
940
1.58k
    return absl::HashOf(s.full_name());
941
1.58k
  }
942
};
943
struct SymbolByFullNameEq {
944
  using is_transparent = void;
945
946
  template <typename T, typename U>
947
232
  bool operator()(const T& a, const U& b) const {
948
232
    return a.full_name() == b.full_name();
949
232
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::SymbolByFullNameEq::operator()<google::protobuf::Symbol, google::protobuf::(anonymous namespace)::FullNameQuery>(google::protobuf::Symbol const&, google::protobuf::(anonymous namespace)::FullNameQuery const&) const
Line
Count
Source
947
186
  bool operator()(const T& a, const U& b) const {
948
186
    return a.full_name() == b.full_name();
949
186
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::SymbolByFullNameEq::operator()<google::protobuf::Symbol, google::protobuf::Symbol>(google::protobuf::Symbol const&, google::protobuf::Symbol const&) const
Line
Count
Source
947
46
  bool operator()(const T& a, const U& b) const {
948
46
    return a.full_name() == b.full_name();
949
46
  }
950
};
951
using SymbolsByNameSet =
952
    absl::flat_hash_set<Symbol, SymbolByFullNameHash, SymbolByFullNameEq>;
953
954
struct ParentNameQuery {
955
  std::pair<const void*, absl::string_view> query;
956
290k
  std::pair<const void*, absl::string_view> parent_name_key() const {
957
290k
    return query;
958
290k
  }
959
};
960
struct SymbolByParentHash {
961
  using is_transparent = void;
962
963
  template <typename T>
964
147k
  size_t operator()(const T& s) const {
965
147k
    return absl::HashOf(s.parent_name_key());
966
147k
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::SymbolByParentHash::operator()<google::protobuf::(anonymous namespace)::ParentNameQuery>(google::protobuf::(anonymous namespace)::ParentNameQuery const&) const
Line
Count
Source
964
145k
  size_t operator()(const T& s) const {
965
145k
    return absl::HashOf(s.parent_name_key());
966
145k
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::SymbolByParentHash::operator()<google::protobuf::Symbol>(google::protobuf::Symbol const&) const
Line
Count
Source
964
1.83k
  size_t operator()(const T& s) const {
965
1.83k
    return absl::HashOf(s.parent_name_key());
966
1.83k
  }
967
};
968
struct SymbolByParentEq {
969
  using is_transparent = void;
970
971
  template <typename T, typename U>
972
145k
  bool operator()(const T& a, const U& b) const {
973
145k
    return a.parent_name_key() == b.parent_name_key();
974
145k
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::SymbolByParentEq::operator()<google::protobuf::Symbol, google::protobuf::(anonymous namespace)::ParentNameQuery>(google::protobuf::Symbol const&, google::protobuf::(anonymous namespace)::ParentNameQuery const&) const
Line
Count
Source
972
145k
  bool operator()(const T& a, const U& b) const {
973
145k
    return a.parent_name_key() == b.parent_name_key();
974
145k
  }
descriptor.cc:bool google::protobuf::(anonymous namespace)::SymbolByParentEq::operator()<google::protobuf::Symbol, google::protobuf::Symbol>(google::protobuf::Symbol const&, google::protobuf::Symbol const&) const
Line
Count
Source
972
91
  bool operator()(const T& a, const U& b) const {
973
91
    return a.parent_name_key() == b.parent_name_key();
974
91
  }
975
};
976
using SymbolsByParentSet =
977
    absl::flat_hash_set<Symbol, SymbolByParentHash, SymbolByParentEq>;
978
979
template <typename DescriptorT>
980
struct DescriptorsByNameHash {
981
  using is_transparent = void;
982
983
26
  size_t operator()(absl::string_view name) const { return absl::HashOf(name); }
descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameHash<google::protobuf::FileDescriptor>::operator()(absl::lts_20230802::string_view) const
Line
Count
Source
983
26
  size_t operator()(absl::string_view name) const { return absl::HashOf(name); }
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameHash<google::protobuf::Descriptor>::operator()(absl::lts_20230802::string_view) const
984
985
16
  size_t operator()(const DescriptorT* file) const {
986
16
    return absl::HashOf(file->name());
987
16
  }
descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameHash<google::protobuf::FileDescriptor>::operator()(google::protobuf::FileDescriptor const*) const
Line
Count
Source
985
16
  size_t operator()(const DescriptorT* file) const {
986
16
    return absl::HashOf(file->name());
987
16
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameHash<google::protobuf::Descriptor>::operator()(google::protobuf::Descriptor const*) const
988
};
989
990
template <typename DescriptorT>
991
struct DescriptorsByNameEq {
992
  using is_transparent = void;
993
994
  bool operator()(absl::string_view lhs, absl::string_view rhs) const {
995
    return lhs == rhs;
996
  }
997
  bool operator()(absl::string_view lhs, const DescriptorT* rhs) const {
998
    return lhs == rhs->name();
999
  }
1000
10
  bool operator()(const DescriptorT* lhs, absl::string_view rhs) const {
1001
10
    return lhs->name() == rhs;
1002
10
  }
descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameEq<google::protobuf::FileDescriptor>::operator()(google::protobuf::FileDescriptor const*, absl::lts_20230802::string_view) const
Line
Count
Source
1000
10
  bool operator()(const DescriptorT* lhs, absl::string_view rhs) const {
1001
10
    return lhs->name() == rhs;
1002
10
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameEq<google::protobuf::Descriptor>::operator()(google::protobuf::Descriptor const*, absl::lts_20230802::string_view) const
1003
0
  bool operator()(const DescriptorT* lhs, const DescriptorT* rhs) const {
1004
0
    return lhs == rhs || lhs->name() == rhs->name();
1005
0
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameEq<google::protobuf::FileDescriptor>::operator()(google::protobuf::FileDescriptor const*, google::protobuf::FileDescriptor const*) const
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::DescriptorsByNameEq<google::protobuf::Descriptor>::operator()(google::protobuf::Descriptor const*, google::protobuf::Descriptor const*) const
1006
};
1007
1008
template <typename DescriptorT>
1009
using DescriptorsByNameSet =
1010
    absl::flat_hash_set<const DescriptorT*, DescriptorsByNameHash<DescriptorT>,
1011
                        DescriptorsByNameEq<DescriptorT>>;
1012
1013
using FieldsByNameMap =
1014
    absl::flat_hash_map<std::pair<const void*, absl::string_view>,
1015
                        const FieldDescriptor*>;
1016
1017
struct ParentNumberQuery {
1018
  std::pair<const void*, int> query;
1019
};
1020
452
std::pair<const void*, int> ObjectToParentNumber(const FieldDescriptor* field) {
1021
452
  return {field->containing_type(), field->number()};
1022
452
}
1023
std::pair<const void*, int> ObjectToParentNumber(
1024
42
    const EnumValueDescriptor* enum_value) {
1025
42
  return {enum_value->type(), enum_value->number()};
1026
42
}
1027
0
std::pair<const void*, int> ObjectToParentNumber(ParentNumberQuery query) {
1028
0
  return query.query;
1029
0
}
1030
struct ParentNumberHash {
1031
  using is_transparent = void;
1032
1033
  template <typename T>
1034
458
  size_t operator()(const T& t) const {
1035
458
    return absl::HashOf(ObjectToParentNumber(t));
1036
458
  }
Unexecuted instantiation: descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::ParentNumberHash::operator()<google::protobuf::(anonymous namespace)::ParentNumberQuery>(google::protobuf::(anonymous namespace)::ParentNumberQuery const&) const
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::ParentNumberHash::operator()<google::protobuf::EnumValueDescriptor*>(google::protobuf::EnumValueDescriptor* const&) const
Line
Count
Source
1034
20
  size_t operator()(const T& t) const {
1035
20
    return absl::HashOf(ObjectToParentNumber(t));
1036
20
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::ParentNumberHash::operator()<google::protobuf::EnumValueDescriptor const*>(google::protobuf::EnumValueDescriptor const* const&) const
Line
Count
Source
1034
22
  size_t operator()(const T& t) const {
1035
22
    return absl::HashOf(ObjectToParentNumber(t));
1036
22
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::ParentNumberHash::operator()<google::protobuf::FieldDescriptor*>(google::protobuf::FieldDescriptor* const&) const
Line
Count
Source
1034
198
  size_t operator()(const T& t) const {
1035
198
    return absl::HashOf(ObjectToParentNumber(t));
1036
198
  }
descriptor.cc:unsigned long google::protobuf::(anonymous namespace)::ParentNumberHash::operator()<google::protobuf::FieldDescriptor const*>(google::protobuf::FieldDescriptor const* const&) const
Line
Count
Source
1034
218
  size_t operator()(const T& t) const {
1035
218
    return absl::HashOf(ObjectToParentNumber(t));
1036
218
  }
1037
};
1038
struct ParentNumberEq {
1039
  using is_transparent = void;
1040
1041
  template <typename T, typename U>
1042
18
  bool operator()(const T& a, const U& b) const {
1043
18
    return ObjectToParentNumber(a) == ObjectToParentNumber(b);
1044
18
  }
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::ParentNumberEq::operator()<google::protobuf::FieldDescriptor const*, google::protobuf::(anonymous namespace)::ParentNumberQuery>(google::protobuf::FieldDescriptor const* const&, google::protobuf::(anonymous namespace)::ParentNumberQuery const&) const
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::ParentNumberEq::operator()<google::protobuf::EnumValueDescriptor const*, google::protobuf::(anonymous namespace)::ParentNumberQuery>(google::protobuf::EnumValueDescriptor const* const&, google::protobuf::(anonymous namespace)::ParentNumberQuery const&) const
Unexecuted instantiation: descriptor.cc:bool google::protobuf::(anonymous namespace)::ParentNumberEq::operator()<google::protobuf::EnumValueDescriptor const*, google::protobuf::EnumValueDescriptor*>(google::protobuf::EnumValueDescriptor const* const&, google::protobuf::EnumValueDescriptor* const&) const
descriptor.cc:bool google::protobuf::(anonymous namespace)::ParentNumberEq::operator()<google::protobuf::FieldDescriptor const*, google::protobuf::FieldDescriptor*>(google::protobuf::FieldDescriptor const* const&, google::protobuf::FieldDescriptor* const&) const
Line
Count
Source
1042
18
  bool operator()(const T& a, const U& b) const {
1043
18
    return ObjectToParentNumber(a) == ObjectToParentNumber(b);
1044
18
  }
1045
};
1046
using FieldsByNumberSet = absl::flat_hash_set<const FieldDescriptor*,
1047
                                              ParentNumberHash, ParentNumberEq>;
1048
using EnumValuesByNumberSet =
1049
    absl::flat_hash_set<const EnumValueDescriptor*, ParentNumberHash,
1050
                        ParentNumberEq>;
1051
1052
// This is a map rather than a hash-map, since we use it to iterate
1053
// through all the extensions that extend a given Descriptor, and an
1054
// ordered data structure that implements lower_bound is convenient
1055
// for that.
1056
using ExtensionsGroupedByDescriptorMap =
1057
    absl::btree_map<std::pair<const Descriptor*, int>, const FieldDescriptor*>;
1058
using LocationsByPathMap =
1059
    absl::flat_hash_map<std::string, const SourceCodeInfo_Location*>;
1060
1061
0
absl::flat_hash_set<std::string>* NewAllowedProto3Extendee() {
1062
0
  const char* kOptionNames[] = {
1063
0
      "FileOptions",   "MessageOptions",   "FieldOptions",
1064
0
      "EnumOptions",   "EnumValueOptions", "ServiceOptions",
1065
0
      "MethodOptions", "OneofOptions",     "ExtensionRangeOptions"};
1066
0
  auto allowed_proto3_extendees = new absl::flat_hash_set<std::string>();
1067
0
  allowed_proto3_extendees->reserve(sizeof(kOptionNames) /
1068
0
                                    sizeof(kOptionNames[0]));
1069
1070
0
  for (const char* option_name : kOptionNames) {
1071
    // descriptor.proto has a different package name in opensource. We allow
1072
    // both so the opensource protocol compiler can also compile internal
1073
    // proto3 files with custom options. See: b/27567912
1074
0
    allowed_proto3_extendees->insert(std::string("google.protobuf.") +
1075
0
                                     option_name);
1076
    // Split the word to trick the opensource processing scripts so they
1077
    // will keep the original package name.
1078
0
    allowed_proto3_extendees->insert(std::string("proto2.") + option_name);
1079
0
  }
1080
0
  return allowed_proto3_extendees;
1081
0
}
1082
1083
// Checks whether the extendee type is allowed in proto3.
1084
// Only extensions to descriptor options are allowed. We use name comparison
1085
// instead of comparing the descriptor directly because the extensions may be
1086
// defined in a different pool.
1087
0
bool AllowedExtendeeInProto3(const std::string& name) {
1088
0
  static auto allowed_proto3_extendees =
1089
0
      internal::OnShutdownDelete(NewAllowedProto3Extendee());
1090
0
  return allowed_proto3_extendees->find(name) !=
1091
0
         allowed_proto3_extendees->end();
1092
0
}
1093
1094
8
const FeatureSetDefaults& GetCppFeatureSetDefaults() {
1095
8
  static const FeatureSetDefaults* default_spec =
1096
8
      internal::OnShutdownDelete([] {
1097
2
        auto* defaults = new FeatureSetDefaults();
1098
2
        internal::ParseNoReflection(
1099
2
            absl::string_view{
1100
2
                PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS,
1101
2
                sizeof(PROTOBUF_INTERNAL_CPP_EDITION_DEFAULTS) - 1},
1102
2
            *defaults);
1103
2
        return defaults;
1104
2
      }());
1105
8
  return *default_spec;
1106
8
}
1107
1108
template <typename ProtoT>
1109
0
void RestoreFeaturesToOptions(const FeatureSet* features, ProtoT* proto) {
1110
0
  if (features != &FeatureSet::default_instance()) {
1111
0
    *proto->mutable_options()->mutable_features() = *features;
1112
0
  }
1113
0
}
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::DescriptorProto_ExtensionRange>(google::protobuf::FeatureSet const*, google::protobuf::DescriptorProto_ExtensionRange*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::FileDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::FileDescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::DescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::DescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::FieldDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::FieldDescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::OneofDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::OneofDescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::EnumDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::EnumDescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::EnumValueDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::EnumValueDescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::ServiceDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::ServiceDescriptorProto*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::RestoreFeaturesToOptions<google::protobuf::MethodDescriptorProto>(google::protobuf::FeatureSet const*, google::protobuf::MethodDescriptorProto*)
1114
1115
template <typename OptionsT>
1116
bool HasFeatures(const OptionsT& options) {
1117
  if (options.has_features()) return true;
1118
1119
  for (const auto& opt : options.uninterpreted_option()) {
1120
    if (opt.name_size() > 0 && opt.name(0).name_part() == "features" &&
1121
        !opt.name(0).is_extension()) {
1122
      return true;
1123
    }
1124
  }
1125
  return false;
1126
}
1127
1128
8
const FeatureSet& GetParentFeatures(const FileDescriptor* file) {
1129
8
  return FeatureSet::default_instance();
1130
8
}
1131
1132
88
const FeatureSet& GetParentFeatures(const Descriptor* message) {
1133
88
  if (message->containing_type() == nullptr) {
1134
70
    return internal::InternalFeatureHelper::GetFeatures(*message->file());
1135
70
  }
1136
18
  return internal::InternalFeatureHelper::GetFeatures(
1137
18
      *message->containing_type());
1138
88
}
1139
1140
4
const FeatureSet& GetParentFeatures(const OneofDescriptor* oneof) {
1141
4
  return internal::InternalFeatureHelper::GetFeatures(
1142
4
      *oneof->containing_type());
1143
4
}
1144
1145
24
const FeatureSet& GetParentFeatures(const Descriptor::ExtensionRange* range) {
1146
24
  return internal::InternalFeatureHelper::GetFeatures(
1147
24
      *range->containing_type());
1148
24
}
1149
1150
396
const FeatureSet& GetParentFeatures(const FieldDescriptor* field) {
1151
396
  if (field->containing_oneof() != nullptr) {
1152
14
    return internal::InternalFeatureHelper::GetFeatures(
1153
14
        *field->containing_oneof());
1154
382
  } else if (field->is_extension()) {
1155
2
    if (field->extension_scope() == nullptr) {
1156
2
      return internal::InternalFeatureHelper::GetFeatures(*field->file());
1157
2
    }
1158
0
    return internal::InternalFeatureHelper::GetFeatures(
1159
0
        *field->extension_scope());
1160
2
  }
1161
380
  return internal::InternalFeatureHelper::GetFeatures(
1162
380
      *field->containing_type());
1163
396
}
1164
1165
34
const FeatureSet& GetParentFeatures(const EnumDescriptor* enm) {
1166
34
  if (enm->containing_type() == nullptr) {
1167
2
    return internal::InternalFeatureHelper::GetFeatures(*enm->file());
1168
2
  }
1169
32
  return internal::InternalFeatureHelper::GetFeatures(*enm->containing_type());
1170
34
}
1171
1172
158
const FeatureSet& GetParentFeatures(const EnumValueDescriptor* value) {
1173
158
  return internal::InternalFeatureHelper::GetFeatures(*value->type());
1174
158
}
1175
1176
0
const FeatureSet& GetParentFeatures(const ServiceDescriptor* service) {
1177
0
  return internal::InternalFeatureHelper::GetFeatures(*service->file());
1178
0
}
1179
1180
0
const FeatureSet& GetParentFeatures(const MethodDescriptor* method) {
1181
0
  return internal::InternalFeatureHelper::GetFeatures(*method->service());
1182
0
}
1183
}  // anonymous namespace
1184
1185
// Contains tables specific to a particular file.  These tables are not
1186
// modified once the file has been constructed, so they need not be
1187
// protected by a mutex.  This makes operations that depend only on the
1188
// contents of a single file -- e.g. Descriptor::FindFieldByName() --
1189
// lock-free.
1190
//
1191
// For historical reasons, the definitions of the methods of
1192
// FileDescriptorTables and DescriptorPool::Tables are interleaved below.
1193
// These used to be a single class.
1194
class FileDescriptorTables {
1195
 public:
1196
  FileDescriptorTables();
1197
  ~FileDescriptorTables();
1198
1199
  // Empty table, used with placeholder files.
1200
  inline static const FileDescriptorTables& GetEmptyInstance();
1201
1202
  // -----------------------------------------------------------------
1203
  // Finding items.
1204
1205
  // Returns a null Symbol (symbol.IsNull() is true) if not found.
1206
  // TODO: All callers to this function know the type they are looking
1207
  // for. If we propagate that information statically we can make the query
1208
  // faster.
1209
  inline Symbol FindNestedSymbol(const void* parent,
1210
                                 absl::string_view name) const;
1211
1212
  // These return nullptr if not found.
1213
  inline const FieldDescriptor* FindFieldByNumber(const Descriptor* parent,
1214
                                                  int number) const;
1215
  inline const FieldDescriptor* FindFieldByLowercaseName(
1216
      const void* parent, absl::string_view lowercase_name) const;
1217
  inline const FieldDescriptor* FindFieldByCamelcaseName(
1218
      const void* parent, absl::string_view camelcase_name) const;
1219
  inline const EnumValueDescriptor* FindEnumValueByNumber(
1220
      const EnumDescriptor* parent, int number) const;
1221
  // This creates a new EnumValueDescriptor if not found, in a thread-safe way.
1222
  inline const EnumValueDescriptor* FindEnumValueByNumberCreatingIfUnknown(
1223
      const EnumDescriptor* parent, int number) const;
1224
1225
  // -----------------------------------------------------------------
1226
  // Adding items.
1227
1228
  // These add items to the corresponding tables.  They return false if
1229
  // the key already exists in the table.
1230
  bool AddAliasUnderParent(const void* parent, absl::string_view name,
1231
                           Symbol symbol);
1232
  bool AddFieldByNumber(FieldDescriptor* field);
1233
  bool AddEnumValueByNumber(EnumValueDescriptor* value);
1234
1235
  // Populates p->first->locations_by_path_ from p->second.
1236
  // Unusual signature dictated by absl::call_once.
1237
  static void BuildLocationsByPath(
1238
      std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
1239
1240
  // Returns the location denoted by the specified path through info,
1241
  // or nullptr if not found.
1242
  // The value of info must be that of the corresponding FileDescriptor.
1243
  // (Conceptually a pure function, but stateful as an optimisation.)
1244
  const SourceCodeInfo_Location* GetSourceLocation(
1245
      const std::vector<int>& path, const SourceCodeInfo* info) const;
1246
1247
  // Must be called after BuildFileImpl(), even if the build failed and
1248
  // we are going to roll back to the last checkpoint.
1249
  void FinalizeTables();
1250
1251
 private:
1252
  const void* FindParentForFieldsByMap(const FieldDescriptor* field) const;
1253
  static void FieldsByLowercaseNamesLazyInitStatic(
1254
      const FileDescriptorTables* tables);
1255
  void FieldsByLowercaseNamesLazyInitInternal() const;
1256
  static void FieldsByCamelcaseNamesLazyInitStatic(
1257
      const FileDescriptorTables* tables);
1258
  void FieldsByCamelcaseNamesLazyInitInternal() const;
1259
1260
  SymbolsByParentSet symbols_by_parent_;
1261
  mutable absl::once_flag fields_by_lowercase_name_once_;
1262
  mutable absl::once_flag fields_by_camelcase_name_once_;
1263
  // Make these fields atomic to avoid race conditions with
1264
  // GetEstimatedOwnedMemoryBytesSize. Once the pointer is set the map won't
1265
  // change anymore.
1266
  mutable std::atomic<const FieldsByNameMap*> fields_by_lowercase_name_{};
1267
  mutable std::atomic<const FieldsByNameMap*> fields_by_camelcase_name_{};
1268
  FieldsByNumberSet fields_by_number_;  // Not including extensions.
1269
  EnumValuesByNumberSet enum_values_by_number_;
1270
  mutable EnumValuesByNumberSet unknown_enum_values_by_number_
1271
      PROTOBUF_GUARDED_BY(unknown_enum_values_mu_);
1272
1273
  // Populated on first request to save space, hence constness games.
1274
  mutable absl::once_flag locations_by_path_once_;
1275
  mutable LocationsByPathMap locations_by_path_;
1276
1277
  // Mutex to protect the unknown-enum-value map due to dynamic
1278
  // EnumValueDescriptor creation on unknown values.
1279
  mutable absl::Mutex unknown_enum_values_mu_;
1280
};
1281
1282
namespace internal {
1283
1284
// Small sequential allocator to be used within a single file.
1285
// Most of the memory for a single FileDescriptor and everything under it is
1286
// allocated in a single block of memory, with the FlatAllocator giving it out
1287
// in parts later.
1288
// The code first plans the total number of bytes needed by calling PlanArray
1289
// with all the allocations that will happen afterwards, then calls
1290
// FinalizePlanning passing the underlying allocator (the DescriptorPool::Tables
1291
// instance), and then proceeds to get the memory via
1292
// `AllocateArray`/`AllocateString` calls. The calls to PlanArray and
1293
// The calls have to match between planning and allocating, though not
1294
// necessarily in the same order.
1295
class FlatAllocator
1296
    : public decltype(ApplyTypeList<FlatAllocatorImpl>(
1297
          SortByAlignment<char, std::string, SourceCodeInfo,
1298
                          FileDescriptorTables, FeatureSet,
1299
                          // Option types
1300
                          MessageOptions, FieldOptions, EnumOptions,
1301
                          EnumValueOptions, ExtensionRangeOptions, OneofOptions,
1302
                          ServiceOptions, MethodOptions, FileOptions>())) {};
1303
1304
}  // namespace internal
1305
1306
// ===================================================================
1307
// DescriptorPool::Tables
1308
1309
class DescriptorPool::Tables {
1310
 public:
1311
  Tables();
1312
  ~Tables();
1313
1314
  // Record the current state of the tables to the stack of checkpoints.
1315
  // Each call to AddCheckpoint() must be paired with exactly one call to either
1316
  // ClearLastCheckpoint() or RollbackToLastCheckpoint().
1317
  //
1318
  // This is used when building files, since some kinds of validation errors
1319
  // cannot be detected until the file's descriptors have already been added to
1320
  // the tables.
1321
  //
1322
  // This supports recursive checkpoints, since building a file may trigger
1323
  // recursive building of other files. Note that recursive checkpoints are not
1324
  // normally necessary; explicit dependencies are built prior to checkpointing.
1325
  // So although we recursively build transitive imports, there is at most one
1326
  // checkpoint in the stack during dependency building.
1327
  //
1328
  // Recursive checkpoints only arise during cross-linking of the descriptors.
1329
  // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
1330
  // friends. If the pending file references an unknown symbol
1331
  // (e.g., it is not defined in the pending file's explicit dependencies), and
1332
  // the pool is using a fallback database, and that database contains a file
1333
  // defining that symbol, and that file has not yet been built by the pool,
1334
  // the pool builds the file during cross-linking, leading to another
1335
  // checkpoint.
1336
  void AddCheckpoint();
1337
1338
  // Mark the last checkpoint as having cleared successfully, removing it from
1339
  // the stack. If the stack is empty, all pending symbols will be committed.
1340
  //
1341
  // Note that this does not guarantee that the symbols added since the last
1342
  // checkpoint won't be rolled back: if a checkpoint gets rolled back,
1343
  // everything past that point gets rolled back, including symbols added after
1344
  // checkpoints that were pushed onto the stack after it and marked as cleared.
1345
  void ClearLastCheckpoint();
1346
1347
  // Roll back the Tables to the state of the checkpoint at the top of the
1348
  // stack, removing everything that was added after that point.
1349
  void RollbackToLastCheckpoint();
1350
1351
  // The stack of files which are currently being built.  Used to detect
1352
  // cyclic dependencies when loading files from a DescriptorDatabase.  Not
1353
  // used when fallback_database_ == nullptr.
1354
  std::vector<std::string> pending_files_;
1355
1356
  // A set of files which we have tried to load from the fallback database
1357
  // and encountered errors.  We will not attempt to load them again during
1358
  // execution of the current public API call, but for compatibility with
1359
  // legacy clients, this is cleared at the beginning of each public API call.
1360
  // Not used when fallback_database_ == nullptr.
1361
  absl::flat_hash_set<std::string> known_bad_files_;
1362
1363
  // A set of symbols which we have tried to load from the fallback database
1364
  // and encountered errors. We will not attempt to load them again during
1365
  // execution of the current public API call, but for compatibility with
1366
  // legacy clients, this is cleared at the beginning of each public API call.
1367
  absl::flat_hash_set<std::string> known_bad_symbols_;
1368
1369
  // The set of descriptors for which we've already loaded the full
1370
  // set of extensions numbers from fallback_database_.
1371
  absl::flat_hash_set<const Descriptor*> extensions_loaded_from_db_;
1372
1373
  // Maps type name to Descriptor::WellKnownType.  This is logically global
1374
  // and const, but we make it a member here to simplify its construction and
1375
  // destruction.  This only has 20-ish entries and is one per DescriptorPool,
1376
  // so the overhead is small.
1377
  absl::flat_hash_map<std::string, Descriptor::WellKnownType> well_known_types_;
1378
1379
  // -----------------------------------------------------------------
1380
  // Finding items.
1381
1382
  // Find symbols.  This returns a null Symbol (symbol.IsNull() is true)
1383
  // if not found.
1384
  inline Symbol FindSymbol(absl::string_view key) const;
1385
1386
  // This implements the body of DescriptorPool::Find*ByName().  It should
1387
  // really be a private method of DescriptorPool, but that would require
1388
  // declaring Symbol in descriptor.h, which would drag all kinds of other
1389
  // stuff into the header.  Yay C++.
1390
  Symbol FindByNameHelper(const DescriptorPool* pool, absl::string_view name);
1391
1392
  // These return nullptr if not found.
1393
  inline const FileDescriptor* FindFile(absl::string_view key) const;
1394
  inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
1395
                                              int number) const;
1396
  inline void FindAllExtensions(const Descriptor* extendee,
1397
                                std::vector<const FieldDescriptor*>* out) const;
1398
1399
  // -----------------------------------------------------------------
1400
  // Adding items.
1401
1402
  // These add items to the corresponding tables.  They return false if
1403
  // the key already exists in the table.  For AddSymbol(), the string passed
1404
  // in must be one that was constructed using AllocateString(), as it will
1405
  // be used as a key in the symbols_by_name_ map without copying.
1406
  bool AddSymbol(absl::string_view full_name, Symbol symbol);
1407
  bool AddFile(const FileDescriptor* file);
1408
  bool AddExtension(const FieldDescriptor* field);
1409
1410
  // Caches a feature set and returns a stable reference to the cached
1411
  // allocation owned by the pool.
1412
  const FeatureSet* InternFeatureSet(FeatureSet&& features);
1413
1414
  // -----------------------------------------------------------------
1415
  // Allocating memory.
1416
1417
  // Allocate an object which will be reclaimed when the pool is
1418
  // destroyed.  Note that the object's destructor will never be called,
1419
  // so its fields must be plain old data (primitive data types and
1420
  // pointers).  All of the descriptor types are such objects.
1421
  template <typename Type>
1422
  Type* Allocate();
1423
1424
  // Allocate some bytes which will be reclaimed when the pool is
1425
  // destroyed. Memory is aligned to 8 bytes.
1426
  void* AllocateBytes(int size);
1427
1428
  // Create a FlatAllocation for the corresponding sizes.
1429
  // All objects within it will be default constructed.
1430
  // The whole allocation, including the non-trivial objects within, will be
1431
  // destroyed with the pool.
1432
  template <typename... T>
1433
  internal::FlatAllocator::Allocation* CreateFlatAlloc(
1434
      const TypeMap<IntT, T...>& sizes);
1435
1436
1437
 private:
1438
  // All memory allocated in the pool.  Must be first as other objects can
1439
  // point into these.
1440
  struct MiscDeleter {
1441
0
    void operator()(int* p) const { internal::SizedDelete(p, *p + 8); }
1442
  };
1443
  // Miscellaneous allocations are length prefixed. The paylaod is 8 bytes after
1444
  // the `int` that contains the size. This keeps the payload aligned.
1445
  std::vector<std::unique_ptr<int, MiscDeleter>> misc_allocs_;
1446
  struct FlatAllocDeleter {
1447
0
    void operator()(internal::FlatAllocator::Allocation* p) const {
1448
0
      p->Destroy();
1449
0
    }
1450
  };
1451
  std::vector<
1452
      std::unique_ptr<internal::FlatAllocator::Allocation, FlatAllocDeleter>>
1453
      flat_allocs_;
1454
1455
  SymbolsByNameSet symbols_by_name_;
1456
  DescriptorsByNameSet<FileDescriptor> files_by_name_;
1457
  ExtensionsGroupedByDescriptorMap extensions_;
1458
1459
  // A cache of all unique feature sets seen.  Since we expect this number to be
1460
  // relatively low compared to descriptors, it's significantly cheaper to share
1461
  // these within the pool than have each file create its own feature sets.
1462
  absl::flat_hash_map<std::string, std::unique_ptr<FeatureSet>>
1463
      feature_set_cache_;
1464
1465
  struct CheckPoint {
1466
    explicit CheckPoint(const Tables* tables)
1467
        : flat_allocations_before_checkpoint(
1468
              static_cast<int>(tables->flat_allocs_.size())),
1469
          misc_allocations_before_checkpoint(
1470
              static_cast<int>(tables->misc_allocs_.size())),
1471
          pending_symbols_before_checkpoint(
1472
              tables->symbols_after_checkpoint_.size()),
1473
          pending_files_before_checkpoint(
1474
              tables->files_after_checkpoint_.size()),
1475
          pending_extensions_before_checkpoint(
1476
8
              tables->extensions_after_checkpoint_.size()) {}
1477
    int flat_allocations_before_checkpoint;
1478
    int misc_allocations_before_checkpoint;
1479
    int pending_symbols_before_checkpoint;
1480
    int pending_files_before_checkpoint;
1481
    int pending_extensions_before_checkpoint;
1482
  };
1483
  std::vector<CheckPoint> checkpoints_;
1484
  std::vector<Symbol> symbols_after_checkpoint_;
1485
  std::vector<const FileDescriptor*> files_after_checkpoint_;
1486
  std::vector<std::pair<const Descriptor*, int>> extensions_after_checkpoint_;
1487
};
1488
1489
4
DescriptorPool::Tables::Tables() {
1490
4
  well_known_types_.insert({
1491
4
      {"google.protobuf.DoubleValue", Descriptor::WELLKNOWNTYPE_DOUBLEVALUE},
1492
4
      {"google.protobuf.FloatValue", Descriptor::WELLKNOWNTYPE_FLOATVALUE},
1493
4
      {"google.protobuf.Int64Value", Descriptor::WELLKNOWNTYPE_INT64VALUE},
1494
4
      {"google.protobuf.UInt64Value", Descriptor::WELLKNOWNTYPE_UINT64VALUE},
1495
4
      {"google.protobuf.Int32Value", Descriptor::WELLKNOWNTYPE_INT32VALUE},
1496
4
      {"google.protobuf.UInt32Value", Descriptor::WELLKNOWNTYPE_UINT32VALUE},
1497
4
      {"google.protobuf.StringValue", Descriptor::WELLKNOWNTYPE_STRINGVALUE},
1498
4
      {"google.protobuf.BytesValue", Descriptor::WELLKNOWNTYPE_BYTESVALUE},
1499
4
      {"google.protobuf.BoolValue", Descriptor::WELLKNOWNTYPE_BOOLVALUE},
1500
4
      {"google.protobuf.Any", Descriptor::WELLKNOWNTYPE_ANY},
1501
4
      {"google.protobuf.FieldMask", Descriptor::WELLKNOWNTYPE_FIELDMASK},
1502
4
      {"google.protobuf.Duration", Descriptor::WELLKNOWNTYPE_DURATION},
1503
4
      {"google.protobuf.Timestamp", Descriptor::WELLKNOWNTYPE_TIMESTAMP},
1504
4
      {"google.protobuf.Value", Descriptor::WELLKNOWNTYPE_VALUE},
1505
4
      {"google.protobuf.ListValue", Descriptor::WELLKNOWNTYPE_LISTVALUE},
1506
4
      {"google.protobuf.Struct", Descriptor::WELLKNOWNTYPE_STRUCT},
1507
4
  });
1508
4
}
1509
1510
0
DescriptorPool::Tables::~Tables() { ABSL_DCHECK(checkpoints_.empty()); }
1511
1512
8
FileDescriptorTables::FileDescriptorTables() {}
1513
1514
0
FileDescriptorTables::~FileDescriptorTables() {
1515
0
  delete fields_by_lowercase_name_.load(std::memory_order_acquire);
1516
0
  delete fields_by_camelcase_name_.load(std::memory_order_acquire);
1517
0
}
1518
1519
0
inline const FileDescriptorTables& FileDescriptorTables::GetEmptyInstance() {
1520
0
  static auto file_descriptor_tables =
1521
0
      internal::OnShutdownDelete(new FileDescriptorTables());
1522
0
  return *file_descriptor_tables;
1523
0
}
1524
1525
8
void DescriptorPool::Tables::AddCheckpoint() {
1526
8
  checkpoints_.emplace_back(this);
1527
8
}
1528
1529
8
void DescriptorPool::Tables::ClearLastCheckpoint() {
1530
8
  ABSL_DCHECK(!checkpoints_.empty());
1531
8
  checkpoints_.pop_back();
1532
8
  if (checkpoints_.empty()) {
1533
    // All checkpoints have been cleared: we can now commit all of the pending
1534
    // data.
1535
8
    symbols_after_checkpoint_.clear();
1536
8
    files_after_checkpoint_.clear();
1537
8
    extensions_after_checkpoint_.clear();
1538
8
  }
1539
8
}
1540
1541
0
void DescriptorPool::Tables::RollbackToLastCheckpoint() {
1542
0
  ABSL_DCHECK(!checkpoints_.empty());
1543
0
  const CheckPoint& checkpoint = checkpoints_.back();
1544
1545
0
  for (size_t i = checkpoint.pending_symbols_before_checkpoint;
1546
0
       i < symbols_after_checkpoint_.size(); i++) {
1547
0
    symbols_by_name_.erase(symbols_after_checkpoint_[i]);
1548
0
  }
1549
0
  for (size_t i = checkpoint.pending_files_before_checkpoint;
1550
0
       i < files_after_checkpoint_.size(); i++) {
1551
0
    files_by_name_.erase(files_after_checkpoint_[i]);
1552
0
  }
1553
0
  for (size_t i = checkpoint.pending_extensions_before_checkpoint;
1554
0
       i < extensions_after_checkpoint_.size(); i++) {
1555
0
    extensions_.erase(extensions_after_checkpoint_[i]);
1556
0
  }
1557
1558
0
  symbols_after_checkpoint_.resize(
1559
0
      checkpoint.pending_symbols_before_checkpoint);
1560
0
  files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
1561
0
  extensions_after_checkpoint_.resize(
1562
0
      checkpoint.pending_extensions_before_checkpoint);
1563
1564
0
  flat_allocs_.resize(checkpoint.flat_allocations_before_checkpoint);
1565
0
  misc_allocs_.resize(checkpoint.misc_allocations_before_checkpoint);
1566
0
  checkpoints_.pop_back();
1567
0
}
1568
1569
// -------------------------------------------------------------------
1570
1571
194
inline Symbol DescriptorPool::Tables::FindSymbol(absl::string_view key) const {
1572
194
  auto it = symbols_by_name_.find(FullNameQuery{key});
1573
194
  return it == symbols_by_name_.end() ? Symbol() : *it;
1574
194
}
1575
1576
inline Symbol FileDescriptorTables::FindNestedSymbol(
1577
145k
    const void* parent, absl::string_view name) const {
1578
145k
  auto it = symbols_by_parent_.find(ParentNameQuery{{parent, name}});
1579
145k
  return it == symbols_by_parent_.end() ? Symbol() : *it;
1580
145k
}
1581
1582
Symbol DescriptorPool::Tables::FindByNameHelper(const DescriptorPool* pool,
1583
0
                                                absl::string_view name) {
1584
0
  if (pool->mutex_ != nullptr) {
1585
    // Fast path: the Symbol is already cached.  This is just a hash lookup.
1586
0
    absl::ReaderMutexLock lock(pool->mutex_);
1587
0
    if (known_bad_symbols_.empty() && known_bad_files_.empty()) {
1588
0
      Symbol result = FindSymbol(name);
1589
0
      if (!result.IsNull()) return result;
1590
0
    }
1591
0
  }
1592
0
  absl::MutexLockMaybe lock(pool->mutex_);
1593
0
  if (pool->fallback_database_ != nullptr) {
1594
0
    known_bad_symbols_.clear();
1595
0
    known_bad_files_.clear();
1596
0
  }
1597
0
  Symbol result = FindSymbol(name);
1598
1599
0
  if (result.IsNull() && pool->underlay_ != nullptr) {
1600
    // Symbol not found; check the underlay.
1601
0
    result = pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
1602
0
  }
1603
1604
0
  if (result.IsNull()) {
1605
    // Symbol still not found, so check fallback database.
1606
0
    if (pool->TryFindSymbolInFallbackDatabase(name)) {
1607
0
      result = FindSymbol(name);
1608
0
    }
1609
0
  }
1610
1611
0
  return result;
1612
0
}
1613
1614
inline const FileDescriptor* DescriptorPool::Tables::FindFile(
1615
26
    absl::string_view key) const {
1616
26
  auto it = files_by_name_.find(key);
1617
26
  if (it == files_by_name_.end()) return nullptr;
1618
10
  return *it;
1619
26
}
1620
1621
inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
1622
0
    const Descriptor* parent, int number) const {
1623
  // If `number` is within the sequential range, just index into the parent
1624
  // without doing a table lookup.
1625
0
  if (parent != nullptr &&  //
1626
0
      1 <= number && number <= parent->sequential_field_limit_) {
1627
0
    return parent->field(number - 1);
1628
0
  }
1629
1630
0
  auto it = fields_by_number_.find(ParentNumberQuery{{parent, number}});
1631
0
  return it == fields_by_number_.end() ? nullptr : *it;
1632
0
}
1633
1634
const void* FileDescriptorTables::FindParentForFieldsByMap(
1635
0
    const FieldDescriptor* field) const {
1636
0
  if (field->is_extension()) {
1637
0
    if (field->extension_scope() == nullptr) {
1638
0
      return field->file();
1639
0
    } else {
1640
0
      return field->extension_scope();
1641
0
    }
1642
0
  } else {
1643
0
    return field->containing_type();
1644
0
  }
1645
0
}
1646
1647
void FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic(
1648
0
    const FileDescriptorTables* tables) {
1649
0
  tables->FieldsByLowercaseNamesLazyInitInternal();
1650
0
}
1651
1652
0
void FileDescriptorTables::FieldsByLowercaseNamesLazyInitInternal() const {
1653
0
  auto* map = new FieldsByNameMap;
1654
0
  for (Symbol symbol : symbols_by_parent_) {
1655
0
    const FieldDescriptor* field = symbol.field_descriptor();
1656
0
    if (!field) continue;
1657
0
    (*map)[{FindParentForFieldsByMap(field), field->lowercase_name().c_str()}] =
1658
0
        field;
1659
0
  }
1660
0
  fields_by_lowercase_name_.store(map, std::memory_order_release);
1661
0
}
1662
1663
inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
1664
0
    const void* parent, absl::string_view lowercase_name) const {
1665
0
  absl::call_once(fields_by_lowercase_name_once_,
1666
0
                  &FileDescriptorTables::FieldsByLowercaseNamesLazyInitStatic,
1667
0
                  this);
1668
0
  const auto* fields =
1669
0
      fields_by_lowercase_name_.load(std::memory_order_acquire);
1670
0
  auto it = fields->find({parent, lowercase_name});
1671
0
  if (it == fields->end()) return nullptr;
1672
0
  return it->second;
1673
0
}
1674
1675
void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic(
1676
0
    const FileDescriptorTables* tables) {
1677
0
  tables->FieldsByCamelcaseNamesLazyInitInternal();
1678
0
}
1679
1680
0
void FileDescriptorTables::FieldsByCamelcaseNamesLazyInitInternal() const {
1681
0
  auto* map = new FieldsByNameMap;
1682
0
  for (Symbol symbol : symbols_by_parent_) {
1683
0
    const FieldDescriptor* field = symbol.field_descriptor();
1684
0
    if (!field) continue;
1685
0
    const void* parent = FindParentForFieldsByMap(field);
1686
    // If we already have a field with this camelCase name, keep the field with
1687
    // the smallest field number. This way we get a deterministic mapping.
1688
0
    const FieldDescriptor*& found =
1689
0
        (*map)[{parent, field->camelcase_name().c_str()}];
1690
0
    if (found == nullptr || found->number() > field->number()) {
1691
0
      found = field;
1692
0
    }
1693
0
  }
1694
0
  fields_by_camelcase_name_.store(map, std::memory_order_release);
1695
0
}
1696
1697
inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
1698
0
    const void* parent, absl::string_view camelcase_name) const {
1699
0
  absl::call_once(fields_by_camelcase_name_once_,
1700
0
                  FileDescriptorTables::FieldsByCamelcaseNamesLazyInitStatic,
1701
0
                  this);
1702
0
  auto* fields = fields_by_camelcase_name_.load(std::memory_order_acquire);
1703
0
  auto it = fields->find({parent, camelcase_name});
1704
0
  if (it == fields->end()) return nullptr;
1705
0
  return it->second;
1706
0
}
1707
1708
inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
1709
0
    const EnumDescriptor* parent, int number) const {
1710
  // If `number` is within the sequential range, just index into the parent
1711
  // without doing a table lookup.
1712
0
  const int base = parent->value(0)->number();
1713
0
  if (base <= number &&
1714
0
      number <= static_cast<int64_t>(base) + parent->sequential_value_limit_) {
1715
0
    return parent->value(number - base);
1716
0
  }
1717
1718
0
  auto it = enum_values_by_number_.find(ParentNumberQuery{{parent, number}});
1719
0
  return it == enum_values_by_number_.end() ? nullptr : *it;
1720
0
}
1721
1722
inline const EnumValueDescriptor*
1723
FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown(
1724
0
    const EnumDescriptor* parent, int number) const {
1725
  // First try, with map of compiled-in values.
1726
0
  {
1727
0
    const auto* value = FindEnumValueByNumber(parent, number);
1728
0
    if (value != nullptr) {
1729
0
      return value;
1730
0
    }
1731
0
  }
1732
1733
0
  const ParentNumberQuery query{{parent, number}};
1734
1735
  // Second try, with reader lock held on unknown enum values: common case.
1736
0
  {
1737
0
    absl::ReaderMutexLock l(&unknown_enum_values_mu_);
1738
0
    auto it = unknown_enum_values_by_number_.find(query);
1739
0
    if (it != unknown_enum_values_by_number_.end()) {
1740
0
      return *it;
1741
0
    }
1742
0
  }
1743
  // If not found, try again with writer lock held, and create new descriptor if
1744
  // necessary.
1745
0
  {
1746
0
    absl::WriterMutexLock l(&unknown_enum_values_mu_);
1747
0
    auto it = unknown_enum_values_by_number_.find(query);
1748
0
    if (it != unknown_enum_values_by_number_.end()) {
1749
0
      return *it;
1750
0
    }
1751
1752
    // Create an EnumValueDescriptor dynamically. We don't insert it into the
1753
    // EnumDescriptor (it's not a part of the enum as originally defined), but
1754
    // we do insert it into the table so that we can return the same pointer
1755
    // later.
1756
0
    std::string enum_value_name = absl::StrFormat(
1757
0
        "UNKNOWN_ENUM_VALUE_%s_%d", parent->name().c_str(), number);
1758
0
    auto* pool = DescriptorPool::generated_pool();
1759
0
    auto* tables = const_cast<DescriptorPool::Tables*>(pool->tables_.get());
1760
0
    internal::FlatAllocator alloc;
1761
0
    alloc.PlanArray<EnumValueDescriptor>(1);
1762
0
    alloc.PlanArray<std::string>(2);
1763
1764
0
    {
1765
      // Must lock the pool because we will do allocations in the shared arena.
1766
0
      absl::MutexLockMaybe l2(pool->mutex_);
1767
0
      alloc.FinalizePlanning(tables);
1768
0
    }
1769
0
    EnumValueDescriptor* result = alloc.AllocateArray<EnumValueDescriptor>(1);
1770
0
    result->all_names_ = alloc.AllocateStrings(
1771
0
        enum_value_name,
1772
0
        absl::StrCat(parent->full_name(), ".", enum_value_name));
1773
0
    result->number_ = number;
1774
0
    result->type_ = parent;
1775
0
    result->options_ = &EnumValueOptions::default_instance();
1776
0
    unknown_enum_values_by_number_.insert(result);
1777
0
    return result;
1778
0
  }
1779
0
}
1780
1781
inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
1782
0
    const Descriptor* extendee, int number) const {
1783
0
  auto it = extensions_.find({extendee, number});
1784
0
  if (it == extensions_.end()) return nullptr;
1785
0
  return it->second;
1786
0
}
1787
1788
inline void DescriptorPool::Tables::FindAllExtensions(
1789
    const Descriptor* extendee,
1790
0
    std::vector<const FieldDescriptor*>* out) const {
1791
0
  ExtensionsGroupedByDescriptorMap::const_iterator it =
1792
0
      extensions_.lower_bound(std::make_pair(extendee, 0));
1793
0
  for (; it != extensions_.end() && it->first.first == extendee; ++it) {
1794
0
    out->push_back(it->second);
1795
0
  }
1796
0
}
1797
1798
// -------------------------------------------------------------------
1799
1800
bool DescriptorPool::Tables::AddSymbol(absl::string_view full_name,
1801
690
                                       Symbol symbol) {
1802
690
  ABSL_DCHECK_EQ(full_name, symbol.full_name());
1803
690
  if (symbols_by_name_.insert(symbol).second) {
1804
690
    symbols_after_checkpoint_.push_back(symbol);
1805
690
    return true;
1806
690
  } else {
1807
0
    return false;
1808
0
  }
1809
690
}
1810
1811
bool FileDescriptorTables::AddAliasUnderParent(const void* parent,
1812
                                               absl::string_view name,
1813
838
                                               Symbol symbol) {
1814
838
  ABSL_DCHECK_EQ(name, symbol.parent_name_key().second);
1815
838
  ABSL_DCHECK_EQ(parent, symbol.parent_name_key().first);
1816
838
  return symbols_by_parent_.insert(symbol).second;
1817
838
}
1818
1819
8
bool DescriptorPool::Tables::AddFile(const FileDescriptor* file) {
1820
8
  if (files_by_name_.insert(file).second) {
1821
8
    files_after_checkpoint_.push_back(file);
1822
8
    return true;
1823
8
  } else {
1824
0
    return false;
1825
0
  }
1826
8
}
1827
1828
8
void FileDescriptorTables::FinalizeTables() {}
1829
1830
396
bool FileDescriptorTables::AddFieldByNumber(FieldDescriptor* field) {
1831
  // Skip fields that are at the start of the sequence.
1832
396
  if (field->containing_type() != nullptr && field->number() >= 1 &&
1833
396
      field->number() <= field->containing_type()->sequential_field_limit_) {
1834
198
    if (field->is_extension()) {
1835
      // Conflicts with the field that already exists in the sequential range.
1836
0
      return false;
1837
0
    }
1838
    // Only return true if the field at that index matches. Otherwise it
1839
    // conflicts with the existing field in the sequential range.
1840
198
    return field->containing_type()->field(field->number() - 1) == field;
1841
198
  }
1842
1843
198
  return fields_by_number_.insert(field).second;
1844
396
}
1845
1846
158
bool FileDescriptorTables::AddEnumValueByNumber(EnumValueDescriptor* value) {
1847
  // Skip values that are at the start of the sequence.
1848
158
  const int base = value->type()->value(0)->number();
1849
158
  if (base <= value->number() &&
1850
158
      value->number() <=
1851
158
          static_cast<int64_t>(base) + value->type()->sequential_value_limit_)
1852
138
    return true;
1853
20
  return enum_values_by_number_.insert(value).second;
1854
158
}
1855
1856
2
bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) {
1857
2
  auto it_inserted =
1858
2
      extensions_.insert({{field->containing_type(), field->number()}, field});
1859
2
  if (it_inserted.second) {
1860
2
    extensions_after_checkpoint_.push_back(it_inserted.first->first);
1861
2
    return true;
1862
2
  } else {
1863
0
    return false;
1864
0
  }
1865
2
}
1866
1867
const FeatureSet* DescriptorPool::Tables::InternFeatureSet(
1868
18
    FeatureSet&& features) {
1869
  // Use the serialized feature set as the cache key.  If multiple equivalent
1870
  // feature sets serialize to different strings, that just bloats the cache a
1871
  // little.
1872
18
  auto& result = feature_set_cache_[features.SerializeAsString()];
1873
18
  if (result == nullptr) {
1874
8
    result = absl::make_unique<FeatureSet>(std::move(features));
1875
8
  }
1876
18
  return result.get();
1877
18
}
1878
1879
// -------------------------------------------------------------------
1880
1881
template <typename Type>
1882
4
Type* DescriptorPool::Tables::Allocate() {
1883
4
  static_assert(std::is_trivially_destructible<Type>::value, "");
1884
4
  static_assert(alignof(Type) <= 8, "");
1885
4
  return ::new (AllocateBytes(sizeof(Type))) Type{};
1886
4
}
1887
1888
4
void* DescriptorPool::Tables::AllocateBytes(int size) {
1889
4
  if (size == 0) return nullptr;
1890
4
  void* p = ::operator new(size + RoundUpTo<8>(sizeof(int)));
1891
4
  int* sizep = static_cast<int*>(p);
1892
4
  misc_allocs_.emplace_back(sizep);
1893
4
  *sizep = size;
1894
4
  return static_cast<char*>(p) + RoundUpTo<8>(sizeof(int));
1895
4
}
1896
1897
template <typename... T>
1898
internal::FlatAllocator::Allocation* DescriptorPool::Tables::CreateFlatAlloc(
1899
8
    const TypeMap<IntT, T...>& sizes) {
1900
8
  auto ends = CalculateEnds(sizes);
1901
8
  using FlatAlloc = internal::FlatAllocator::Allocation;
1902
1903
8
  int last_end = ends.template Get<
1904
8
      typename std::tuple_element<sizeof...(T) - 1, std::tuple<T...>>::type>();
1905
8
  size_t total_size =
1906
8
      last_end + RoundUpTo<FlatAlloc::kMaxAlign>(sizeof(FlatAlloc));
1907
8
  char* data = static_cast<char*>(::operator new(total_size));
1908
8
  auto* res = ::new (data) FlatAlloc(ends);
1909
8
  flat_allocs_.emplace_back(res);
1910
1911
8
  return res;
1912
8
}
1913
1914
void FileDescriptorTables::BuildLocationsByPath(
1915
0
    std::pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
1916
0
  for (int i = 0, len = p->second->location_size(); i < len; ++i) {
1917
0
    const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
1918
0
    p->first->locations_by_path_[absl::StrJoin(loc->path(), ",")] = loc;
1919
0
  }
1920
0
}
1921
1922
const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
1923
0
    const std::vector<int>& path, const SourceCodeInfo* info) const {
1924
0
  std::pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
1925
0
      std::make_pair(this, info));
1926
0
  absl::call_once(locations_by_path_once_,
1927
0
                  FileDescriptorTables::BuildLocationsByPath, &p);
1928
0
  auto it = locations_by_path_.find(absl::StrJoin(path, ","));
1929
0
  if (it == locations_by_path_.end()) return nullptr;
1930
0
  return it->second;
1931
0
}
1932
1933
// ===================================================================
1934
// DescriptorPool
1935
1936
1937
0
DescriptorPool::ErrorCollector::~ErrorCollector() {}
1938
1939
absl::string_view DescriptorPool::ErrorCollector::ErrorLocationName(
1940
0
    ErrorLocation location) {
1941
0
  switch (location) {
1942
0
    case NAME:
1943
0
      return "NAME";
1944
0
    case NUMBER:
1945
0
      return "NUMBER";
1946
0
    case TYPE:
1947
0
      return "TYPE";
1948
0
    case EXTENDEE:
1949
0
      return "EXTENDEE";
1950
0
    case DEFAULT_VALUE:
1951
0
      return "DEFAULT_VALUE";
1952
0
    case OPTION_NAME:
1953
0
      return "OPTION_NAME";
1954
0
    case OPTION_VALUE:
1955
0
      return "OPTION_VALUE";
1956
0
    case INPUT_TYPE:
1957
0
      return "INPUT_TYPE";
1958
0
    case OUTPUT_TYPE:
1959
0
      return "OUTPUT_TYPE";
1960
0
    case IMPORT:
1961
0
      return "IMPORT";
1962
0
    case EDITIONS:
1963
0
      return "EDITIONS";
1964
0
    case OTHER:
1965
0
      return "OTHER";
1966
0
  }
1967
0
  return "UNKNOWN";
1968
0
}
1969
1970
DescriptorPool::DescriptorPool()
1971
    : mutex_(nullptr),
1972
      fallback_database_(nullptr),
1973
      default_error_collector_(nullptr),
1974
      underlay_(nullptr),
1975
      tables_(new Tables),
1976
      enforce_dependencies_(true),
1977
      lazily_build_dependencies_(false),
1978
      allow_unknown_(false),
1979
      enforce_weak_(false),
1980
      enforce_extension_declarations_(false),
1981
      disallow_enforce_utf8_(false),
1982
0
      deprecated_legacy_json_field_conflicts_(false) {}
1983
1984
DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database,
1985
                               ErrorCollector* error_collector)
1986
    : mutex_(new absl::Mutex),
1987
      fallback_database_(fallback_database),
1988
      default_error_collector_(error_collector),
1989
      underlay_(nullptr),
1990
      tables_(new Tables),
1991
      enforce_dependencies_(true),
1992
      lazily_build_dependencies_(false),
1993
      allow_unknown_(false),
1994
      enforce_weak_(false),
1995
      enforce_extension_declarations_(false),
1996
      disallow_enforce_utf8_(false),
1997
4
      deprecated_legacy_json_field_conflicts_(false) {}
1998
1999
DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
2000
    : mutex_(nullptr),
2001
      fallback_database_(nullptr),
2002
      default_error_collector_(nullptr),
2003
      underlay_(underlay),
2004
      tables_(new Tables),
2005
      enforce_dependencies_(true),
2006
      lazily_build_dependencies_(false),
2007
      allow_unknown_(false),
2008
      enforce_weak_(false),
2009
      enforce_extension_declarations_(false),
2010
      disallow_enforce_utf8_(false),
2011
0
      deprecated_legacy_json_field_conflicts_(false) {}
2012
2013
0
DescriptorPool::~DescriptorPool() {
2014
0
  if (mutex_ != nullptr) delete mutex_;
2015
0
}
2016
2017
// DescriptorPool::BuildFile() defined later.
2018
// DescriptorPool::BuildFileCollectingErrors() defined later.
2019
2020
4
void DescriptorPool::InternalDontEnforceDependencies() {
2021
4
  enforce_dependencies_ = false;
2022
4
}
2023
2024
void DescriptorPool::AddUnusedImportTrackFile(absl::string_view file_name,
2025
0
                                              bool is_error) {
2026
0
  unused_import_track_files_[file_name] = is_error;
2027
0
}
2028
2029
0
bool DescriptorPool::IsExtendingDescriptor(const FieldDescriptor& field) const {
2030
0
  static const auto& kDescriptorTypes = *new absl::flat_hash_set<std::string>({
2031
0
      "google.protobuf.EnumOptions",
2032
0
      "google.protobuf.EnumValueOptions",
2033
0
      "google.protobuf.ExtensionRangeOptions",
2034
0
      "google.protobuf.FieldOptions",
2035
0
      "google.protobuf.FileOptions",
2036
0
      "google.protobuf.MessageOptions",
2037
0
      "google.protobuf.MethodOptions",
2038
0
      "google.protobuf.OneofOptions",
2039
0
      "google.protobuf.ServiceOptions",
2040
0
      "google.protobuf.StreamOptions",
2041
0
  });
2042
0
  return kDescriptorTypes.contains(field.containing_type()->full_name());
2043
0
}
2044
2045
2046
0
void DescriptorPool::ClearUnusedImportTrackFiles() {
2047
0
  unused_import_track_files_.clear();
2048
0
}
2049
2050
0
bool DescriptorPool::InternalIsFileLoaded(absl::string_view filename) const {
2051
0
  absl::MutexLockMaybe lock(mutex_);
2052
0
  return tables_->FindFile(filename) != nullptr;
2053
0
}
2054
2055
// generated_pool ====================================================
2056
2057
namespace {
2058
2059
2060
16
EncodedDescriptorDatabase* GeneratedDatabase() {
2061
16
  static auto generated_database =
2062
16
      internal::OnShutdownDelete(new EncodedDescriptorDatabase());
2063
16
  return generated_database;
2064
16
}
2065
2066
4
DescriptorPool* NewGeneratedPool() {
2067
4
  auto generated_pool = new DescriptorPool(GeneratedDatabase());
2068
4
  generated_pool->InternalSetLazilyBuildDependencies();
2069
4
  return generated_pool;
2070
4
}
2071
2072
}  // anonymous namespace
2073
2074
0
DescriptorDatabase* DescriptorPool::internal_generated_database() {
2075
0
  return GeneratedDatabase();
2076
0
}
2077
2078
116
DescriptorPool* DescriptorPool::internal_generated_pool() {
2079
116
  static DescriptorPool* generated_pool =
2080
116
      internal::OnShutdownDelete(NewGeneratedPool());
2081
116
  return generated_pool;
2082
116
}
2083
2084
8
const DescriptorPool* DescriptorPool::generated_pool() {
2085
8
  const DescriptorPool* pool = internal_generated_pool();
2086
  // Ensure that descriptor.proto and cpp_features.proto get registered in the
2087
  // generated pool. They're special cases because they're included in the full
2088
  // runtime. We have to avoid registering it pre-main, because we need to
2089
  // ensure that the linker --gc-sections step can strip out the full runtime if
2090
  // it is unused.
2091
8
  DescriptorProto::descriptor();
2092
8
  pb::CppFeatures::descriptor();
2093
8
  return pool;
2094
8
}
2095
2096
2097
void DescriptorPool::InternalAddGeneratedFile(
2098
12
    const void* encoded_file_descriptor, int size) {
2099
  // So, this function is called in the process of initializing the
2100
  // descriptors for generated proto classes.  Each generated .pb.cc file
2101
  // has an internal procedure called AddDescriptors() which is called at
2102
  // process startup, and that function calls this one in order to register
2103
  // the raw bytes of the FileDescriptorProto representing the file.
2104
  //
2105
  // We do not actually construct the descriptor objects right away.  We just
2106
  // hang on to the bytes until they are actually needed.  We actually construct
2107
  // the descriptor the first time one of the following things happens:
2108
  // * Someone calls a method like descriptor(), GetDescriptor(), or
2109
  //   GetReflection() on the generated types, which requires returning the
2110
  //   descriptor or an object based on it.
2111
  // * Someone looks up the descriptor in DescriptorPool::generated_pool().
2112
  //
2113
  // Once one of these happens, the DescriptorPool actually parses the
2114
  // FileDescriptorProto and generates a FileDescriptor (and all its children)
2115
  // based on it.
2116
  //
2117
  // Note that FileDescriptorProto is itself a generated protocol message.
2118
  // Therefore, when we parse one, we have to be very careful to avoid using
2119
  // any descriptor-based operations, since this might cause infinite recursion
2120
  // or deadlock.
2121
12
  absl::MutexLockMaybe lock(internal_generated_pool()->mutex_);
2122
12
  ABSL_CHECK(GeneratedDatabase()->Add(encoded_file_descriptor, size));
2123
12
}
2124
2125
2126
// Find*By* methods ==================================================
2127
2128
// TODO:  There's a lot of repeated code here, but I'm not sure if
2129
//   there's any good way to factor it out.  Think about this some time when
2130
//   there's nothing more important to do (read: never).
2131
2132
const FileDescriptor* DescriptorPool::FindFileByName(
2133
8
    absl::string_view name) const {
2134
8
  absl::MutexLockMaybe lock(mutex_);
2135
8
  if (fallback_database_ != nullptr) {
2136
8
    tables_->known_bad_symbols_.clear();
2137
8
    tables_->known_bad_files_.clear();
2138
8
  }
2139
8
  const FileDescriptor* result = tables_->FindFile(name);
2140
8
  if (result != nullptr) return result;
2141
8
  if (underlay_ != nullptr) {
2142
0
    result = underlay_->FindFileByName(name);
2143
0
    if (result != nullptr) return result;
2144
0
  }
2145
8
  if (TryFindFileInFallbackDatabase(name)) {
2146
8
    result = tables_->FindFile(name);
2147
8
    if (result != nullptr) return result;
2148
8
  }
2149
0
  return nullptr;
2150
8
}
2151
2152
const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
2153
0
    absl::string_view symbol_name) const {
2154
0
  absl::MutexLockMaybe lock(mutex_);
2155
0
  if (fallback_database_ != nullptr) {
2156
0
    tables_->known_bad_symbols_.clear();
2157
0
    tables_->known_bad_files_.clear();
2158
0
  }
2159
0
  Symbol result = tables_->FindSymbol(symbol_name);
2160
0
  if (!result.IsNull()) return result.GetFile();
2161
0
  if (underlay_ != nullptr) {
2162
0
    const FileDescriptor* file_result =
2163
0
        underlay_->FindFileContainingSymbol(symbol_name);
2164
0
    if (file_result != nullptr) return file_result;
2165
0
  }
2166
0
  if (TryFindSymbolInFallbackDatabase(symbol_name)) {
2167
0
    result = tables_->FindSymbol(symbol_name);
2168
0
    if (!result.IsNull()) return result.GetFile();
2169
0
  }
2170
0
  return nullptr;
2171
0
}
2172
2173
const Descriptor* DescriptorPool::FindMessageTypeByName(
2174
0
    absl::string_view name) const {
2175
0
  return tables_->FindByNameHelper(this, name).descriptor();
2176
0
}
2177
2178
const FieldDescriptor* DescriptorPool::FindFieldByName(
2179
0
    absl::string_view name) const {
2180
0
  if (const FieldDescriptor* field =
2181
0
          tables_->FindByNameHelper(this, name).field_descriptor()) {
2182
0
    if (!field->is_extension()) {
2183
0
      return field;
2184
0
    }
2185
0
  }
2186
0
  return nullptr;
2187
0
}
2188
2189
const FieldDescriptor* DescriptorPool::FindExtensionByName(
2190
0
    absl::string_view name) const {
2191
0
  if (const FieldDescriptor* field =
2192
0
          tables_->FindByNameHelper(this, name).field_descriptor()) {
2193
0
    if (field->is_extension()) {
2194
0
      return field;
2195
0
    }
2196
0
  }
2197
0
  return nullptr;
2198
0
}
2199
2200
const OneofDescriptor* DescriptorPool::FindOneofByName(
2201
0
    absl::string_view name) const {
2202
0
  return tables_->FindByNameHelper(this, name).oneof_descriptor();
2203
0
}
2204
2205
const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
2206
0
    absl::string_view name) const {
2207
0
  return tables_->FindByNameHelper(this, name).enum_descriptor();
2208
0
}
2209
2210
const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
2211
0
    absl::string_view name) const {
2212
0
  return tables_->FindByNameHelper(this, name).enum_value_descriptor();
2213
0
}
2214
2215
const ServiceDescriptor* DescriptorPool::FindServiceByName(
2216
0
    absl::string_view name) const {
2217
0
  return tables_->FindByNameHelper(this, name).service_descriptor();
2218
0
}
2219
2220
const MethodDescriptor* DescriptorPool::FindMethodByName(
2221
0
    absl::string_view name) const {
2222
0
  return tables_->FindByNameHelper(this, name).method_descriptor();
2223
0
}
2224
2225
const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
2226
0
    const Descriptor* extendee, int number) const {
2227
0
  if (extendee->extension_range_count() == 0) return nullptr;
2228
  // A faster path to reduce lock contention in finding extensions, assuming
2229
  // most extensions will be cache hit.
2230
0
  if (mutex_ != nullptr) {
2231
0
    absl::ReaderMutexLock lock(mutex_);
2232
0
    const FieldDescriptor* result = tables_->FindExtension(extendee, number);
2233
0
    if (result != nullptr) {
2234
0
      return result;
2235
0
    }
2236
0
  }
2237
0
  absl::MutexLockMaybe lock(mutex_);
2238
0
  if (fallback_database_ != nullptr) {
2239
0
    tables_->known_bad_symbols_.clear();
2240
0
    tables_->known_bad_files_.clear();
2241
0
  }
2242
0
  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
2243
0
  if (result != nullptr) {
2244
0
    return result;
2245
0
  }
2246
0
  if (underlay_ != nullptr) {
2247
0
    result = underlay_->FindExtensionByNumber(extendee, number);
2248
0
    if (result != nullptr) return result;
2249
0
  }
2250
0
  if (TryFindExtensionInFallbackDatabase(extendee, number)) {
2251
0
    result = tables_->FindExtension(extendee, number);
2252
0
    if (result != nullptr) {
2253
0
      return result;
2254
0
    }
2255
0
  }
2256
0
  return nullptr;
2257
0
}
2258
2259
const FieldDescriptor* DescriptorPool::InternalFindExtensionByNumberNoLock(
2260
0
    const Descriptor* extendee, int number) const {
2261
0
  if (extendee->extension_range_count() == 0) return nullptr;
2262
2263
0
  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
2264
0
  if (result != nullptr) {
2265
0
    return result;
2266
0
  }
2267
2268
0
  if (underlay_ != nullptr) {
2269
0
    result = underlay_->InternalFindExtensionByNumberNoLock(extendee, number);
2270
0
    if (result != nullptr) return result;
2271
0
  }
2272
2273
0
  return nullptr;
2274
0
}
2275
2276
const FieldDescriptor* DescriptorPool::FindExtensionByPrintableName(
2277
0
    const Descriptor* extendee, absl::string_view printable_name) const {
2278
0
  if (extendee->extension_range_count() == 0) return nullptr;
2279
0
  const FieldDescriptor* result = FindExtensionByName(printable_name);
2280
0
  if (result != nullptr && result->containing_type() == extendee) {
2281
0
    return result;
2282
0
  }
2283
0
  if (extendee->options().message_set_wire_format()) {
2284
    // MessageSet extensions may be identified by type name.
2285
0
    const Descriptor* type = FindMessageTypeByName(printable_name);
2286
0
    if (type != nullptr) {
2287
      // Look for a matching extension in the foreign type's scope.
2288
0
      const int type_extension_count = type->extension_count();
2289
0
      for (int i = 0; i < type_extension_count; i++) {
2290
0
        const FieldDescriptor* extension = type->extension(i);
2291
0
        if (extension->containing_type() == extendee &&
2292
0
            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
2293
0
            extension->is_optional() && extension->message_type() == type) {
2294
          // Found it.
2295
0
          return extension;
2296
0
        }
2297
0
      }
2298
0
    }
2299
0
  }
2300
0
  return nullptr;
2301
0
}
2302
2303
void DescriptorPool::FindAllExtensions(
2304
    const Descriptor* extendee,
2305
0
    std::vector<const FieldDescriptor*>* out) const {
2306
0
  absl::MutexLockMaybe lock(mutex_);
2307
0
  if (fallback_database_ != nullptr) {
2308
0
    tables_->known_bad_symbols_.clear();
2309
0
    tables_->known_bad_files_.clear();
2310
0
  }
2311
2312
  // Initialize tables_->extensions_ from the fallback database first
2313
  // (but do this only once per descriptor).
2314
0
  if (fallback_database_ != nullptr &&
2315
0
      tables_->extensions_loaded_from_db_.count(extendee) == 0) {
2316
0
    std::vector<int> numbers;
2317
0
    if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
2318
0
                                                    &numbers)) {
2319
0
      for (int number : numbers) {
2320
0
        if (tables_->FindExtension(extendee, number) == nullptr) {
2321
0
          TryFindExtensionInFallbackDatabase(extendee, number);
2322
0
        }
2323
0
      }
2324
0
      tables_->extensions_loaded_from_db_.insert(extendee);
2325
0
    }
2326
0
  }
2327
2328
0
  tables_->FindAllExtensions(extendee, out);
2329
0
  if (underlay_ != nullptr) {
2330
0
    underlay_->FindAllExtensions(extendee, out);
2331
0
  }
2332
0
}
2333
2334
2335
// -------------------------------------------------------------------
2336
2337
0
const FieldDescriptor* Descriptor::FindFieldByNumber(int key) const {
2338
0
  const FieldDescriptor* result = file()->tables_->FindFieldByNumber(this, key);
2339
0
  if (result == nullptr || result->is_extension()) {
2340
0
    return nullptr;
2341
0
  } else {
2342
0
    return result;
2343
0
  }
2344
0
}
2345
2346
const FieldDescriptor* Descriptor::FindFieldByLowercaseName(
2347
0
    absl::string_view key) const {
2348
0
  const FieldDescriptor* result =
2349
0
      file()->tables_->FindFieldByLowercaseName(this, key);
2350
0
  if (result == nullptr || result->is_extension()) {
2351
0
    return nullptr;
2352
0
  } else {
2353
0
    return result;
2354
0
  }
2355
0
}
2356
2357
const FieldDescriptor* Descriptor::FindFieldByCamelcaseName(
2358
0
    absl::string_view key) const {
2359
0
  const FieldDescriptor* result =
2360
0
      file()->tables_->FindFieldByCamelcaseName(this, key);
2361
0
  if (result == nullptr || result->is_extension()) {
2362
0
    return nullptr;
2363
0
  } else {
2364
0
    return result;
2365
0
  }
2366
0
}
2367
2368
const FieldDescriptor* Descriptor::FindFieldByName(
2369
145k
    absl::string_view key) const {
2370
145k
  const FieldDescriptor* field =
2371
145k
      file()->tables_->FindNestedSymbol(this, key).field_descriptor();
2372
145k
  return field != nullptr && !field->is_extension() ? field : nullptr;
2373
145k
}
2374
2375
const OneofDescriptor* Descriptor::FindOneofByName(
2376
0
    absl::string_view key) const {
2377
0
  return file()->tables_->FindNestedSymbol(this, key).oneof_descriptor();
2378
0
}
2379
2380
const FieldDescriptor* Descriptor::FindExtensionByName(
2381
0
    absl::string_view key) const {
2382
0
  const FieldDescriptor* field =
2383
0
      file()->tables_->FindNestedSymbol(this, key).field_descriptor();
2384
0
  return field != nullptr && field->is_extension() ? field : nullptr;
2385
0
}
2386
2387
const FieldDescriptor* Descriptor::FindExtensionByLowercaseName(
2388
0
    absl::string_view key) const {
2389
0
  const FieldDescriptor* result =
2390
0
      file()->tables_->FindFieldByLowercaseName(this, key);
2391
0
  if (result == nullptr || !result->is_extension()) {
2392
0
    return nullptr;
2393
0
  } else {
2394
0
    return result;
2395
0
  }
2396
0
}
2397
2398
const FieldDescriptor* Descriptor::FindExtensionByCamelcaseName(
2399
0
    absl::string_view key) const {
2400
0
  const FieldDescriptor* result =
2401
0
      file()->tables_->FindFieldByCamelcaseName(this, key);
2402
0
  if (result == nullptr || !result->is_extension()) {
2403
0
    return nullptr;
2404
0
  } else {
2405
0
    return result;
2406
0
  }
2407
0
}
2408
2409
const Descriptor* Descriptor::FindNestedTypeByName(
2410
0
    absl::string_view key) const {
2411
0
  return file()->tables_->FindNestedSymbol(this, key).descriptor();
2412
0
}
2413
2414
const EnumDescriptor* Descriptor::FindEnumTypeByName(
2415
0
    absl::string_view key) const {
2416
0
  return file()->tables_->FindNestedSymbol(this, key).enum_descriptor();
2417
0
}
2418
2419
const EnumValueDescriptor* Descriptor::FindEnumValueByName(
2420
0
    absl::string_view key) const {
2421
0
  return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor();
2422
0
}
2423
2424
0
const FieldDescriptor* Descriptor::map_key() const {
2425
0
  if (!options().map_entry()) return nullptr;
2426
0
  ABSL_DCHECK_EQ(field_count(), 2);
2427
0
  return field(0);
2428
0
}
2429
2430
0
const FieldDescriptor* Descriptor::map_value() const {
2431
0
  if (!options().map_entry()) return nullptr;
2432
0
  ABSL_DCHECK_EQ(field_count(), 2);
2433
0
  return field(1);
2434
0
}
2435
2436
const EnumValueDescriptor* EnumDescriptor::FindValueByName(
2437
0
    absl::string_view key) const {
2438
0
  return file()->tables_->FindNestedSymbol(this, key).enum_value_descriptor();
2439
0
}
2440
2441
0
const EnumValueDescriptor* EnumDescriptor::FindValueByNumber(int key) const {
2442
0
  return file()->tables_->FindEnumValueByNumber(this, key);
2443
0
}
2444
2445
const EnumValueDescriptor* EnumDescriptor::FindValueByNumberCreatingIfUnknown(
2446
0
    int key) const {
2447
0
  return file()->tables_->FindEnumValueByNumberCreatingIfUnknown(this, key);
2448
0
}
2449
2450
const MethodDescriptor* ServiceDescriptor::FindMethodByName(
2451
0
    absl::string_view key) const {
2452
0
  return file()->tables_->FindNestedSymbol(this, key).method_descriptor();
2453
0
}
2454
2455
const Descriptor* FileDescriptor::FindMessageTypeByName(
2456
0
    absl::string_view key) const {
2457
0
  return tables_->FindNestedSymbol(this, key).descriptor();
2458
0
}
2459
2460
const EnumDescriptor* FileDescriptor::FindEnumTypeByName(
2461
0
    absl::string_view key) const {
2462
0
  return tables_->FindNestedSymbol(this, key).enum_descriptor();
2463
0
}
2464
2465
const EnumValueDescriptor* FileDescriptor::FindEnumValueByName(
2466
0
    absl::string_view key) const {
2467
0
  return tables_->FindNestedSymbol(this, key).enum_value_descriptor();
2468
0
}
2469
2470
const ServiceDescriptor* FileDescriptor::FindServiceByName(
2471
0
    absl::string_view key) const {
2472
0
  return tables_->FindNestedSymbol(this, key).service_descriptor();
2473
0
}
2474
2475
const FieldDescriptor* FileDescriptor::FindExtensionByName(
2476
0
    absl::string_view key) const {
2477
0
  const FieldDescriptor* field =
2478
0
      tables_->FindNestedSymbol(this, key).field_descriptor();
2479
0
  return field != nullptr && field->is_extension() ? field : nullptr;
2480
0
}
2481
2482
const FieldDescriptor* FileDescriptor::FindExtensionByLowercaseName(
2483
0
    absl::string_view key) const {
2484
0
  const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
2485
0
  if (result == nullptr || !result->is_extension()) {
2486
0
    return nullptr;
2487
0
  } else {
2488
0
    return result;
2489
0
  }
2490
0
}
2491
2492
const FieldDescriptor* FileDescriptor::FindExtensionByCamelcaseName(
2493
0
    absl::string_view key) const {
2494
0
  const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
2495
0
  if (result == nullptr || !result->is_extension()) {
2496
0
    return nullptr;
2497
0
  } else {
2498
0
    return result;
2499
0
  }
2500
0
}
2501
2502
void Descriptor::ExtensionRange::CopyTo(
2503
0
    DescriptorProto_ExtensionRange* proto) const {
2504
0
  proto->set_start(start_);
2505
0
  proto->set_end(end_);
2506
0
  if (options_ != &ExtensionRangeOptions::default_instance()) {
2507
0
    *proto->mutable_options() = *options_;
2508
0
  }
2509
0
  RestoreFeaturesToOptions(proto_features_, proto);
2510
0
}
2511
2512
const Descriptor::ExtensionRange*
2513
2
Descriptor::FindExtensionRangeContainingNumber(int number) const {
2514
  // Linear search should be fine because we don't expect a message to have
2515
  // more than a couple extension ranges.
2516
2
  for (int i = 0; i < extension_range_count(); i++) {
2517
2
    if (number >= extension_range(i)->start_number() &&
2518
2
        number < extension_range(i)->end_number()) {
2519
2
      return extension_range(i);
2520
2
    }
2521
2
  }
2522
0
  return nullptr;
2523
2
}
2524
2525
const Descriptor::ReservedRange* Descriptor::FindReservedRangeContainingNumber(
2526
0
    int number) const {
2527
  // TODO: Consider a non-linear search.
2528
0
  for (int i = 0; i < reserved_range_count(); i++) {
2529
0
    if (number >= reserved_range(i)->start && number < reserved_range(i)->end) {
2530
0
      return reserved_range(i);
2531
0
    }
2532
0
  }
2533
0
  return nullptr;
2534
0
}
2535
2536
const EnumDescriptor::ReservedRange*
2537
0
EnumDescriptor::FindReservedRangeContainingNumber(int number) const {
2538
  // TODO: Consider a non-linear search.
2539
0
  for (int i = 0; i < reserved_range_count(); i++) {
2540
0
    if (number >= reserved_range(i)->start &&
2541
0
        number <= reserved_range(i)->end) {
2542
0
      return reserved_range(i);
2543
0
    }
2544
0
  }
2545
0
  return nullptr;
2546
0
}
2547
2548
// -------------------------------------------------------------------
2549
2550
bool DescriptorPool::TryFindFileInFallbackDatabase(
2551
8
    absl::string_view name) const {
2552
8
  if (fallback_database_ == nullptr) return false;
2553
2554
8
  if (tables_->known_bad_files_.contains(name)) return false;
2555
2556
  // NOINLINE to reduce the stack cost of the operation in the caller.
2557
8
  const auto find_file = [](DescriptorDatabase& database,
2558
8
                            absl::string_view filename,
2559
8
                            FileDescriptorProto& output) PROTOBUF_NOINLINE {
2560
8
    return database.FindFileByName(std::string(filename), &output);
2561
8
  };
2562
2563
8
  auto file_proto = absl::make_unique<FileDescriptorProto>();
2564
8
  if (!find_file(*fallback_database_, name, *file_proto) ||
2565
8
      BuildFileFromDatabase(*file_proto) == nullptr) {
2566
0
    tables_->known_bad_files_.emplace(name);
2567
0
    return false;
2568
0
  }
2569
8
  return true;
2570
8
}
2571
2572
0
bool DescriptorPool::IsSubSymbolOfBuiltType(absl::string_view name) const {
2573
0
  for (size_t pos = name.find('.'); pos != name.npos;
2574
0
       pos = name.find('.', pos + 1)) {
2575
0
    auto prefix = name.substr(0, pos);
2576
0
    Symbol symbol = tables_->FindSymbol(prefix);
2577
0
    if (symbol.IsNull()) {
2578
0
      break;
2579
0
    }
2580
0
    if (!symbol.IsPackage()) {
2581
      // If the symbol type is anything other than PACKAGE, then its complete
2582
      // definition is already known.
2583
0
      return true;
2584
0
    }
2585
0
  }
2586
0
  if (underlay_ != nullptr) {
2587
    // Check to see if any prefix of this symbol exists in the underlay.
2588
0
    return underlay_->IsSubSymbolOfBuiltType(name);
2589
0
  }
2590
0
  return false;
2591
0
}
2592
2593
bool DescriptorPool::TryFindSymbolInFallbackDatabase(
2594
0
    absl::string_view name) const {
2595
0
  if (fallback_database_ == nullptr) return false;
2596
2597
0
  if (tables_->known_bad_symbols_.contains(name)) return false;
2598
2599
0
  std::string name_string(name);
2600
0
  auto file_proto = absl::make_unique<FileDescriptorProto>();
2601
0
  if (  // We skip looking in the fallback database if the name is a sub-symbol
2602
        // of any descriptor that already exists in the descriptor pool (except
2603
        // for package descriptors).  This is valid because all symbols except
2604
        // for packages are defined in a single file, so if the symbol exists
2605
        // then we should already have its definition.
2606
        //
2607
        // The other reason to do this is to support "overriding" type
2608
        // definitions by merging two databases that define the same type. (Yes,
2609
        // people do this.)  The main difficulty with making this work is that
2610
        // FindFileContainingSymbol() is allowed to return both false positives
2611
        // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and
2612
        // false negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
2613
        // When two such databases are merged, looking up a non-existent
2614
        // sub-symbol of a type that already exists in the descriptor pool can
2615
        // result in an attempt to load multiple definitions of the same type.
2616
        // The check below avoids this.
2617
0
      IsSubSymbolOfBuiltType(name)
2618
2619
      // Look up file containing this symbol in fallback database.
2620
0
      || !fallback_database_->FindFileContainingSymbol(name_string,
2621
0
                                                       file_proto.get())
2622
2623
      // Check if we've already built this file. If so, it apparently doesn't
2624
      // contain the symbol we're looking for.  Some DescriptorDatabases
2625
      // return false positives.
2626
0
      || tables_->FindFile(file_proto->name()) != nullptr
2627
2628
      // Build the file.
2629
0
      || BuildFileFromDatabase(*file_proto) == nullptr) {
2630
0
    tables_->known_bad_symbols_.insert(std::move(name_string));
2631
0
    return false;
2632
0
  }
2633
2634
0
  return true;
2635
0
}
2636
2637
bool DescriptorPool::TryFindExtensionInFallbackDatabase(
2638
0
    const Descriptor* containing_type, int field_number) const {
2639
0
  if (fallback_database_ == nullptr) return false;
2640
2641
0
  auto file_proto = absl::make_unique<FileDescriptorProto>();
2642
0
  if (!fallback_database_->FindFileContainingExtension(
2643
0
          containing_type->full_name(), field_number, file_proto.get())) {
2644
0
    return false;
2645
0
  }
2646
2647
0
  if (tables_->FindFile(file_proto->name()) != nullptr) {
2648
    // We've already loaded this file, and it apparently doesn't contain the
2649
    // extension we're looking for.  Some DescriptorDatabases return false
2650
    // positives.
2651
0
    return false;
2652
0
  }
2653
2654
0
  if (BuildFileFromDatabase(*file_proto) == nullptr) {
2655
0
    return false;
2656
0
  }
2657
2658
0
  return true;
2659
0
}
2660
2661
// ===================================================================
2662
2663
221k
bool FieldDescriptor::is_map_message_type() const {
2664
221k
  return type_descriptor_.message_type->options().map_entry();
2665
221k
}
2666
2667
std::string FieldDescriptor::DefaultValueAsString(
2668
0
    bool quote_string_type) const {
2669
0
  ABSL_CHECK(has_default_value()) << "No default value";
2670
0
  switch (cpp_type()) {
2671
0
    case CPPTYPE_INT32:
2672
0
      return absl::StrCat(default_value_int32_t());
2673
0
    case CPPTYPE_INT64:
2674
0
      return absl::StrCat(default_value_int64_t());
2675
0
    case CPPTYPE_UINT32:
2676
0
      return absl::StrCat(default_value_uint32_t());
2677
0
    case CPPTYPE_UINT64:
2678
0
      return absl::StrCat(default_value_uint64_t());
2679
0
    case CPPTYPE_FLOAT:
2680
0
      return io::SimpleFtoa(default_value_float());
2681
0
    case CPPTYPE_DOUBLE:
2682
0
      return io::SimpleDtoa(default_value_double());
2683
0
    case CPPTYPE_BOOL:
2684
0
      return default_value_bool() ? "true" : "false";
2685
0
    case CPPTYPE_STRING:
2686
0
      if (quote_string_type) {
2687
0
        return absl::StrCat("\"", absl::CEscape(default_value_string()), "\"");
2688
0
      } else {
2689
0
        if (type() == TYPE_BYTES) {
2690
0
          return absl::CEscape(default_value_string());
2691
0
        } else {
2692
0
          return default_value_string();
2693
0
        }
2694
0
      }
2695
0
    case CPPTYPE_ENUM:
2696
0
      return default_value_enum()->name();
2697
0
    case CPPTYPE_MESSAGE:
2698
0
      ABSL_DLOG(FATAL) << "Messages can't have default values!";
2699
0
      break;
2700
0
  }
2701
0
  ABSL_LOG(FATAL) << "Can't get here: failed to get default value as string";
2702
0
  return "";
2703
0
}
2704
2705
// Out-of-line constructor definitions ==============================
2706
// When using constructor type homing in Clang, debug info for a type
2707
// is only emitted when a constructor definition is emitted, as an
2708
// optimization. These constructors are never called, so we define them
2709
// out of line to make sure the debug info is emitted somewhere.
2710
2711
0
Descriptor::Descriptor() {}
2712
0
FieldDescriptor::FieldDescriptor() {}
2713
0
OneofDescriptor::OneofDescriptor() {}
2714
0
EnumDescriptor::EnumDescriptor() {}
2715
0
EnumValueDescriptor::EnumValueDescriptor() {}
2716
0
ServiceDescriptor::ServiceDescriptor() {}
2717
0
MethodDescriptor::MethodDescriptor() {}
2718
0
FileDescriptor::FileDescriptor() {}
2719
2720
// CopyTo methods ====================================================
2721
2722
0
void FileDescriptor::CopyTo(FileDescriptorProto* proto) const {
2723
0
  CopyHeadingTo(proto);
2724
2725
0
  for (int i = 0; i < dependency_count(); i++) {
2726
0
    proto->add_dependency(dependency(i)->name());
2727
0
  }
2728
2729
0
  for (int i = 0; i < public_dependency_count(); i++) {
2730
0
    proto->add_public_dependency(public_dependencies_[i]);
2731
0
  }
2732
2733
0
  for (int i = 0; i < weak_dependency_count(); i++) {
2734
0
    proto->add_weak_dependency(weak_dependencies_[i]);
2735
0
  }
2736
2737
0
  for (int i = 0; i < message_type_count(); i++) {
2738
0
    message_type(i)->CopyTo(proto->add_message_type());
2739
0
  }
2740
0
  for (int i = 0; i < enum_type_count(); i++) {
2741
0
    enum_type(i)->CopyTo(proto->add_enum_type());
2742
0
  }
2743
0
  for (int i = 0; i < service_count(); i++) {
2744
0
    service(i)->CopyTo(proto->add_service());
2745
0
  }
2746
0
  for (int i = 0; i < extension_count(); i++) {
2747
0
    extension(i)->CopyTo(proto->add_extension());
2748
0
  }
2749
0
}
2750
2751
0
void FileDescriptor::CopyHeadingTo(FileDescriptorProto* proto) const {
2752
0
  proto->set_name(name());
2753
0
  if (!package().empty()) {
2754
0
    proto->set_package(package());
2755
0
  }
2756
2757
  // TODO: Also populate when syntax="proto2".
2758
0
  FileDescriptorLegacy::Syntax syntax = FileDescriptorLegacy(this).syntax();
2759
0
  if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_PROTO3 ||
2760
0
      syntax == FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) {
2761
0
    proto->set_syntax(FileDescriptorLegacy::SyntaxName(syntax));
2762
0
  }
2763
0
  if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) {
2764
0
    proto->set_edition(edition());
2765
0
  }
2766
2767
0
  if (&options() != &FileOptions::default_instance()) {
2768
0
    *proto->mutable_options() = options();
2769
0
  }
2770
0
  RestoreFeaturesToOptions(proto_features_, proto);
2771
0
}
2772
2773
0
void FileDescriptor::CopyJsonNameTo(FileDescriptorProto* proto) const {
2774
0
  if (message_type_count() != proto->message_type_size() ||
2775
0
      extension_count() != proto->extension_size()) {
2776
0
    ABSL_LOG(ERROR) << "Cannot copy json_name to a proto of a different size.";
2777
0
    return;
2778
0
  }
2779
0
  for (int i = 0; i < message_type_count(); i++) {
2780
0
    message_type(i)->CopyJsonNameTo(proto->mutable_message_type(i));
2781
0
  }
2782
0
  for (int i = 0; i < extension_count(); i++) {
2783
0
    extension(i)->CopyJsonNameTo(proto->mutable_extension(i));
2784
0
  }
2785
0
}
2786
2787
0
void FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const {
2788
0
  if (source_code_info_ &&
2789
0
      source_code_info_ != &SourceCodeInfo::default_instance()) {
2790
0
    proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
2791
0
  }
2792
0
}
2793
2794
0
void Descriptor::CopyTo(DescriptorProto* proto) const {
2795
0
  proto->set_name(name());
2796
2797
0
  for (int i = 0; i < field_count(); i++) {
2798
0
    field(i)->CopyTo(proto->add_field());
2799
0
  }
2800
0
  for (int i = 0; i < oneof_decl_count(); i++) {
2801
0
    oneof_decl(i)->CopyTo(proto->add_oneof_decl());
2802
0
  }
2803
0
  for (int i = 0; i < nested_type_count(); i++) {
2804
0
    nested_type(i)->CopyTo(proto->add_nested_type());
2805
0
  }
2806
0
  for (int i = 0; i < enum_type_count(); i++) {
2807
0
    enum_type(i)->CopyTo(proto->add_enum_type());
2808
0
  }
2809
0
  for (int i = 0; i < extension_range_count(); i++) {
2810
0
    extension_range(i)->CopyTo(proto->add_extension_range());
2811
0
  }
2812
0
  for (int i = 0; i < extension_count(); i++) {
2813
0
    extension(i)->CopyTo(proto->add_extension());
2814
0
  }
2815
0
  for (int i = 0; i < reserved_range_count(); i++) {
2816
0
    DescriptorProto::ReservedRange* range = proto->add_reserved_range();
2817
0
    range->set_start(reserved_range(i)->start);
2818
0
    range->set_end(reserved_range(i)->end);
2819
0
  }
2820
0
  for (int i = 0; i < reserved_name_count(); i++) {
2821
0
    proto->add_reserved_name(reserved_name(i));
2822
0
  }
2823
2824
0
  if (&options() != &MessageOptions::default_instance()) {
2825
0
    proto->mutable_options()->CopyFrom(options());
2826
0
  }
2827
2828
0
  RestoreFeaturesToOptions(proto_features_, proto);
2829
0
}
2830
2831
0
void Descriptor::CopyJsonNameTo(DescriptorProto* proto) const {
2832
0
  if (field_count() != proto->field_size() ||
2833
0
      nested_type_count() != proto->nested_type_size() ||
2834
0
      extension_count() != proto->extension_size()) {
2835
0
    ABSL_LOG(ERROR) << "Cannot copy json_name to a proto of a different size.";
2836
0
    return;
2837
0
  }
2838
0
  for (int i = 0; i < field_count(); i++) {
2839
0
    field(i)->CopyJsonNameTo(proto->mutable_field(i));
2840
0
  }
2841
0
  for (int i = 0; i < nested_type_count(); i++) {
2842
0
    nested_type(i)->CopyJsonNameTo(proto->mutable_nested_type(i));
2843
0
  }
2844
0
  for (int i = 0; i < extension_count(); i++) {
2845
0
    extension(i)->CopyJsonNameTo(proto->mutable_extension(i));
2846
0
  }
2847
0
}
2848
2849
0
void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const {
2850
0
  proto->set_name(name());
2851
0
  proto->set_number(number());
2852
0
  if (has_json_name_) {
2853
0
    proto->set_json_name(json_name());
2854
0
  }
2855
0
  if (proto3_optional_) {
2856
0
    proto->set_proto3_optional(true);
2857
0
  }
2858
  // Some compilers do not allow static_cast directly between two enum types,
2859
  // so we must cast to int first.
2860
0
  if (is_required() && FileDescriptorLegacy(file()).syntax() ==
2861
0
                           FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) {
2862
    // Editions files have no required keyword, and we only set this label
2863
    // during descriptor build.
2864
0
    proto->set_label(static_cast<FieldDescriptorProto::Label>(
2865
0
        absl::implicit_cast<int>(LABEL_OPTIONAL)));
2866
0
  } else {
2867
0
    proto->set_label(static_cast<FieldDescriptorProto::Label>(
2868
0
        absl::implicit_cast<int>(label())));
2869
0
  }
2870
0
  if (type() == TYPE_GROUP &&
2871
0
      FileDescriptorLegacy(file()).syntax() ==
2872
0
          FileDescriptorLegacy::Syntax::SYNTAX_EDITIONS) {
2873
    // Editions files have no group keyword, and we only set this label
2874
    // during descriptor build.
2875
0
    proto->set_type(static_cast<FieldDescriptorProto::Type>(
2876
0
        absl::implicit_cast<int>(TYPE_MESSAGE)));
2877
0
  } else {
2878
0
    proto->set_type(static_cast<FieldDescriptorProto::Type>(
2879
0
        absl::implicit_cast<int>(type())));
2880
0
  }
2881
2882
0
  if (is_extension()) {
2883
0
    if (!containing_type()->is_unqualified_placeholder_) {
2884
0
      proto->set_extendee(".");
2885
0
    }
2886
0
    proto->mutable_extendee()->append(containing_type()->full_name());
2887
0
  }
2888
2889
0
  if (cpp_type() == CPPTYPE_MESSAGE) {
2890
0
    if (message_type()->is_placeholder_) {
2891
      // We don't actually know if the type is a message type.  It could be
2892
      // an enum.
2893
0
      proto->clear_type();
2894
0
    }
2895
2896
0
    if (!message_type()->is_unqualified_placeholder_) {
2897
0
      proto->set_type_name(".");
2898
0
    }
2899
0
    proto->mutable_type_name()->append(message_type()->full_name());
2900
0
  } else if (cpp_type() == CPPTYPE_ENUM) {
2901
0
    if (!enum_type()->is_unqualified_placeholder_) {
2902
0
      proto->set_type_name(".");
2903
0
    }
2904
0
    proto->mutable_type_name()->append(enum_type()->full_name());
2905
0
  }
2906
2907
0
  if (has_default_value()) {
2908
0
    proto->set_default_value(DefaultValueAsString(false));
2909
0
  }
2910
2911
0
  if (containing_oneof() != nullptr && !is_extension()) {
2912
0
    proto->set_oneof_index(containing_oneof()->index());
2913
0
  }
2914
2915
0
  if (&options() != &FieldOptions::default_instance()) {
2916
0
    proto->mutable_options()->CopyFrom(options());
2917
0
  }
2918
2919
0
  RestoreFeaturesToOptions(proto_features_, proto);
2920
0
}
2921
2922
0
void FieldDescriptor::CopyJsonNameTo(FieldDescriptorProto* proto) const {
2923
0
  proto->set_json_name(json_name());
2924
0
}
2925
2926
0
void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
2927
0
  proto->set_name(name());
2928
0
  if (&options() != &OneofOptions::default_instance()) {
2929
0
    proto->mutable_options()->CopyFrom(options());
2930
0
  }
2931
0
  RestoreFeaturesToOptions(proto_features_, proto);
2932
0
}
2933
2934
0
void EnumDescriptor::CopyTo(EnumDescriptorProto* proto) const {
2935
0
  proto->set_name(name());
2936
2937
0
  for (int i = 0; i < value_count(); i++) {
2938
0
    value(i)->CopyTo(proto->add_value());
2939
0
  }
2940
0
  for (int i = 0; i < reserved_range_count(); i++) {
2941
0
    EnumDescriptorProto::EnumReservedRange* range = proto->add_reserved_range();
2942
0
    range->set_start(reserved_range(i)->start);
2943
0
    range->set_end(reserved_range(i)->end);
2944
0
  }
2945
0
  for (int i = 0; i < reserved_name_count(); i++) {
2946
0
    proto->add_reserved_name(reserved_name(i));
2947
0
  }
2948
2949
0
  if (&options() != &EnumOptions::default_instance()) {
2950
0
    proto->mutable_options()->CopyFrom(options());
2951
0
  }
2952
0
  RestoreFeaturesToOptions(proto_features_, proto);
2953
0
}
2954
2955
0
void EnumValueDescriptor::CopyTo(EnumValueDescriptorProto* proto) const {
2956
0
  proto->set_name(name());
2957
0
  proto->set_number(number());
2958
2959
0
  if (&options() != &EnumValueOptions::default_instance()) {
2960
0
    proto->mutable_options()->CopyFrom(options());
2961
0
  }
2962
0
  RestoreFeaturesToOptions(proto_features_, proto);
2963
0
}
2964
2965
0
void ServiceDescriptor::CopyTo(ServiceDescriptorProto* proto) const {
2966
0
  proto->set_name(name());
2967
2968
0
  for (int i = 0; i < method_count(); i++) {
2969
0
    method(i)->CopyTo(proto->add_method());
2970
0
  }
2971
2972
0
  if (&options() != &ServiceOptions::default_instance()) {
2973
0
    proto->mutable_options()->CopyFrom(options());
2974
0
  }
2975
0
  RestoreFeaturesToOptions(proto_features_, proto);
2976
0
}
2977
2978
0
void MethodDescriptor::CopyTo(MethodDescriptorProto* proto) const {
2979
0
  proto->set_name(name());
2980
2981
0
  if (!input_type()->is_unqualified_placeholder_) {
2982
0
    proto->set_input_type(".");
2983
0
  }
2984
0
  proto->mutable_input_type()->append(input_type()->full_name());
2985
2986
0
  if (!output_type()->is_unqualified_placeholder_) {
2987
0
    proto->set_output_type(".");
2988
0
  }
2989
0
  proto->mutable_output_type()->append(output_type()->full_name());
2990
2991
0
  if (&options() != &MethodOptions::default_instance()) {
2992
0
    proto->mutable_options()->CopyFrom(options());
2993
0
  }
2994
2995
0
  if (client_streaming_) {
2996
0
    proto->set_client_streaming(true);
2997
0
  }
2998
0
  if (server_streaming_) {
2999
0
    proto->set_server_streaming(true);
3000
0
  }
3001
0
  RestoreFeaturesToOptions(proto_features_, proto);
3002
0
}
3003
3004
// DebugString methods ===============================================
3005
3006
namespace {
3007
3008
0
bool IsGroupSyntax(const FieldDescriptor* desc) {
3009
0
  if (FileDescriptorLegacy(desc->file()).syntax() ==
3010
0
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
3011
0
    return false;
3012
0
  }
3013
0
  return desc->type() == FieldDescriptor::TYPE_GROUP;
3014
0
}
3015
3016
template <typename OptionsT>
3017
0
void CopyFeaturesToOptions(const FeatureSet* features, OptionsT* options) {
3018
0
  if (features != &FeatureSet::default_instance()) {
3019
0
    *options->mutable_features() = *features;
3020
0
  }
3021
0
}
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::FileOptions>(google::protobuf::FeatureSet const*, google::protobuf::FileOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::MessageOptions>(google::protobuf::FeatureSet const*, google::protobuf::MessageOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::ExtensionRangeOptions>(google::protobuf::FeatureSet const*, google::protobuf::ExtensionRangeOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::FieldOptions>(google::protobuf::FeatureSet const*, google::protobuf::FieldOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::OneofOptions>(google::protobuf::FeatureSet const*, google::protobuf::OneofOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::EnumOptions>(google::protobuf::FeatureSet const*, google::protobuf::EnumOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::EnumValueOptions>(google::protobuf::FeatureSet const*, google::protobuf::EnumValueOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::ServiceOptions>(google::protobuf::FeatureSet const*, google::protobuf::ServiceOptions*)
Unexecuted instantiation: descriptor.cc:void google::protobuf::(anonymous namespace)::CopyFeaturesToOptions<google::protobuf::MethodOptions>(google::protobuf::FeatureSet const*, google::protobuf::MethodOptions*)
3022
3023
bool RetrieveOptionsAssumingRightPool(
3024
    int depth, const Message& options,
3025
0
    std::vector<std::string>* option_entries) {
3026
0
  option_entries->clear();
3027
0
  const Reflection* reflection = options.GetReflection();
3028
0
  std::vector<const FieldDescriptor*> fields;
3029
0
  reflection->ListFields(options, &fields);
3030
0
  for (const FieldDescriptor* field : fields) {
3031
0
    int count = 1;
3032
0
    bool repeated = false;
3033
0
    if (field->is_repeated()) {
3034
0
      count = reflection->FieldSize(options, field);
3035
0
      repeated = true;
3036
0
    }
3037
0
    for (int j = 0; j < count; j++) {
3038
0
      std::string fieldval;
3039
0
      if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
3040
0
        std::string tmp;
3041
0
        TextFormat::Printer printer;
3042
0
        printer.SetExpandAny(true);
3043
0
        printer.SetInitialIndentLevel(depth + 1);
3044
0
        printer.PrintFieldValueToString(options, field, repeated ? j : -1,
3045
0
                                        &tmp);
3046
0
        fieldval.append("{\n");
3047
0
        fieldval.append(tmp);
3048
0
        fieldval.append(depth * 2, ' ');
3049
0
        fieldval.append("}");
3050
0
      } else {
3051
0
        TextFormat::PrintFieldValueToString(options, field, repeated ? j : -1,
3052
0
                                            &fieldval);
3053
0
      }
3054
0
      std::string name;
3055
0
      if (field->is_extension()) {
3056
0
        name = absl::StrCat("(.", field->full_name(), ")");
3057
0
      } else {
3058
0
        name = field->name();
3059
0
      }
3060
0
      option_entries->push_back(absl::StrCat(name, " = ", fieldval));
3061
0
    }
3062
0
  }
3063
0
  return !option_entries->empty();
3064
0
}
3065
3066
// Used by each of the option formatters.
3067
bool RetrieveOptions(int depth, const Message& options,
3068
                     const DescriptorPool* pool,
3069
0
                     std::vector<std::string>* option_entries) {
3070
  // When printing custom options for a descriptor, we must use an options
3071
  // message built on top of the same DescriptorPool where the descriptor
3072
  // is coming from. This is to ensure we are interpreting custom options
3073
  // against the right pool.
3074
0
  if (options.GetDescriptor()->file()->pool() == pool) {
3075
0
    return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
3076
0
  } else {
3077
0
    const Descriptor* option_descriptor =
3078
0
        pool->FindMessageTypeByName(options.GetDescriptor()->full_name());
3079
0
    if (option_descriptor == nullptr) {
3080
      // descriptor.proto is not in the pool. This means no custom options are
3081
      // used so we are safe to proceed with the compiled options message type.
3082
0
      return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
3083
0
    }
3084
0
    DynamicMessageFactory factory;
3085
0
    std::unique_ptr<Message> dynamic_options(
3086
0
        factory.GetPrototype(option_descriptor)->New());
3087
0
    std::string serialized = options.SerializeAsString();
3088
0
    io::CodedInputStream input(
3089
0
        reinterpret_cast<const uint8_t*>(serialized.c_str()),
3090
0
        serialized.size());
3091
0
    input.SetExtensionRegistry(pool, &factory);
3092
0
    if (dynamic_options->ParseFromCodedStream(&input)) {
3093
0
      return RetrieveOptionsAssumingRightPool(depth, *dynamic_options,
3094
0
                                              option_entries);
3095
0
    } else {
3096
0
      ABSL_LOG(ERROR) << "Found invalid proto option data for: "
3097
0
                      << options.GetDescriptor()->full_name();
3098
0
      return RetrieveOptionsAssumingRightPool(depth, options, option_entries);
3099
0
    }
3100
0
  }
3101
0
}
3102
3103
// Formats options that all appear together in brackets. Does not include
3104
// brackets.
3105
bool FormatBracketedOptions(int depth, const Message& options,
3106
0
                            const DescriptorPool* pool, std::string* output) {
3107
0
  std::vector<std::string> all_options;
3108
0
  if (RetrieveOptions(depth, options, pool, &all_options)) {
3109
0
    output->append(absl::StrJoin(all_options, ", "));
3110
0
  }
3111
0
  return !all_options.empty();
3112
0
}
3113
3114
// Formats options one per line
3115
bool FormatLineOptions(int depth, const Message& options,
3116
0
                       const DescriptorPool* pool, std::string* output) {
3117
0
  std::string prefix(depth * 2, ' ');
3118
0
  std::vector<std::string> all_options;
3119
0
  if (RetrieveOptions(depth, options, pool, &all_options)) {
3120
0
    for (const std::string& option : all_options) {
3121
0
      absl::SubstituteAndAppend(output, "$0option $1;\n", prefix, option);
3122
0
    }
3123
0
  }
3124
0
  return !all_options.empty();
3125
0
}
3126
3127
class SourceLocationCommentPrinter {
3128
 public:
3129
  template <typename DescType>
3130
  SourceLocationCommentPrinter(const DescType* desc, const std::string& prefix,
3131
                               const DebugStringOptions& options)
3132
0
      : options_(options), prefix_(prefix) {
3133
    // Perform the SourceLocation lookup only if we're including user comments,
3134
    // because the lookup is fairly expensive.
3135
0
    have_source_loc_ =
3136
0
        options.include_comments && desc->GetSourceLocation(&source_loc_);
3137
0
  }
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::FileDescriptor>(google::protobuf::FileDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::Descriptor>(google::protobuf::Descriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::FieldDescriptor>(google::protobuf::FieldDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::OneofDescriptor>(google::protobuf::OneofDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::EnumDescriptor>(google::protobuf::EnumDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::EnumValueDescriptor>(google::protobuf::EnumValueDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::ServiceDescriptor>(google::protobuf::ServiceDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
Unexecuted instantiation: descriptor.cc:google::protobuf::(anonymous namespace)::SourceLocationCommentPrinter::SourceLocationCommentPrinter<google::protobuf::MethodDescriptor>(google::protobuf::MethodDescriptor const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::DebugStringOptions const&)
3138
  SourceLocationCommentPrinter(const FileDescriptor* file,
3139
                               const std::vector<int>& path,
3140
                               const std::string& prefix,
3141
                               const DebugStringOptions& options)
3142
0
      : options_(options), prefix_(prefix) {
3143
    // Perform the SourceLocation lookup only if we're including user comments,
3144
    // because the lookup is fairly expensive.
3145
0
    have_source_loc_ =
3146
0
        options.include_comments && file->GetSourceLocation(path, &source_loc_);
3147
0
  }
3148
0
  void AddPreComment(std::string* output) {
3149
0
    if (have_source_loc_) {
3150
      // Detached leading comments.
3151
0
      for (const std::string& leading_detached_comment :
3152
0
           source_loc_.leading_detached_comments) {
3153
0
        absl::StrAppend(output, FormatComment(leading_detached_comment), "\n");
3154
0
      }
3155
      // Attached leading comments.
3156
0
      if (!source_loc_.leading_comments.empty()) {
3157
0
        absl::StrAppend(output, FormatComment(source_loc_.leading_comments));
3158
0
      }
3159
0
    }
3160
0
  }
3161
0
  void AddPostComment(std::string* output) {
3162
0
    if (have_source_loc_ && source_loc_.trailing_comments.size() > 0) {
3163
0
      absl::StrAppend(output, FormatComment(source_loc_.trailing_comments));
3164
0
    }
3165
0
  }
3166
3167
  // Format comment such that each line becomes a full-line C++-style comment in
3168
  // the DebugString() output.
3169
0
  std::string FormatComment(const std::string& comment_text) {
3170
0
    std::string stripped_comment = comment_text;
3171
0
    absl::StripAsciiWhitespace(&stripped_comment);
3172
0
    std::string output;
3173
0
    for (absl::string_view line : absl::StrSplit(stripped_comment, '\n')) {
3174
0
      absl::SubstituteAndAppend(&output, "$0// $1\n", prefix_, line);
3175
0
    }
3176
0
    return output;
3177
0
  }
3178
3179
 private:
3180
3181
  bool have_source_loc_;
3182
  SourceLocation source_loc_;
3183
  DebugStringOptions options_;
3184
  std::string prefix_;
3185
};
3186
3187
}  // anonymous namespace
3188
3189
0
std::string FileDescriptor::DebugString() const {
3190
0
  DebugStringOptions options;  // default options
3191
0
  return DebugStringWithOptions(options);
3192
0
}
3193
3194
std::string FileDescriptor::DebugStringWithOptions(
3195
0
    const DebugStringOptions& debug_string_options) const {
3196
0
  std::string contents;
3197
0
  {
3198
0
    std::vector<int> path;
3199
0
    path.push_back(FileDescriptorProto::kSyntaxFieldNumber);
3200
0
    SourceLocationCommentPrinter syntax_comment(this, path, "",
3201
0
                                                debug_string_options);
3202
0
    syntax_comment.AddPreComment(&contents);
3203
0
    if (FileDescriptorLegacy(this).syntax() ==
3204
0
        FileDescriptorLegacy::SYNTAX_EDITIONS) {
3205
0
      absl::SubstituteAndAppend(&contents, "edition = \"$0\";\n\n", edition());
3206
0
    } else {
3207
0
      absl::SubstituteAndAppend(&contents, "syntax = \"$0\";\n\n",
3208
0
                                FileDescriptorLegacy::SyntaxName(
3209
0
                                    FileDescriptorLegacy(this).syntax()));
3210
0
    }
3211
0
    syntax_comment.AddPostComment(&contents);
3212
0
  }
3213
3214
0
  SourceLocationCommentPrinter comment_printer(this, "", debug_string_options);
3215
0
  comment_printer.AddPreComment(&contents);
3216
3217
0
  absl::flat_hash_set<int> public_dependencies(
3218
0
      public_dependencies_, public_dependencies_ + public_dependency_count_);
3219
0
  absl::flat_hash_set<int> weak_dependencies(
3220
0
      weak_dependencies_, weak_dependencies_ + weak_dependency_count_);
3221
3222
0
  for (int i = 0; i < dependency_count(); i++) {
3223
0
    if (public_dependencies.contains(i)) {
3224
0
      absl::SubstituteAndAppend(&contents, "import public \"$0\";\n",
3225
0
                                dependency(i)->name());
3226
0
    } else if (weak_dependencies.contains(i)) {
3227
0
      absl::SubstituteAndAppend(&contents, "import weak \"$0\";\n",
3228
0
                                dependency(i)->name());
3229
0
    } else {
3230
0
      absl::SubstituteAndAppend(&contents, "import \"$0\";\n",
3231
0
                                dependency(i)->name());
3232
0
    }
3233
0
  }
3234
3235
0
  if (!package().empty()) {
3236
0
    std::vector<int> path;
3237
0
    path.push_back(FileDescriptorProto::kPackageFieldNumber);
3238
0
    SourceLocationCommentPrinter package_comment(this, path, "",
3239
0
                                                 debug_string_options);
3240
0
    package_comment.AddPreComment(&contents);
3241
0
    absl::SubstituteAndAppend(&contents, "package $0;\n\n", package());
3242
0
    package_comment.AddPostComment(&contents);
3243
0
  }
3244
3245
0
  FileOptions full_options = options();
3246
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3247
0
  if (FormatLineOptions(0, full_options, pool(), &contents)) {
3248
0
    contents.append("\n");  // add some space if we had options
3249
0
  }
3250
3251
0
  for (int i = 0; i < enum_type_count(); i++) {
3252
0
    enum_type(i)->DebugString(0, &contents, debug_string_options);
3253
0
    contents.append("\n");
3254
0
  }
3255
3256
  // Find all the 'group' type extensions; we will not output their nested
3257
  // definitions (those will be done with their group field descriptor).
3258
0
  absl::flat_hash_set<const Descriptor*> groups;
3259
0
  for (int i = 0; i < extension_count(); i++) {
3260
0
    if (IsGroupSyntax(extension(i))) {
3261
0
      groups.insert(extension(i)->message_type());
3262
0
    }
3263
0
  }
3264
3265
0
  for (int i = 0; i < message_type_count(); i++) {
3266
0
    if (!groups.contains(message_type(i))) {
3267
0
      message_type(i)->DebugString(0, &contents, debug_string_options,
3268
0
                                   /* include_opening_clause */ true);
3269
0
      contents.append("\n");
3270
0
    }
3271
0
  }
3272
3273
0
  for (int i = 0; i < service_count(); i++) {
3274
0
    service(i)->DebugString(&contents, debug_string_options);
3275
0
    contents.append("\n");
3276
0
  }
3277
3278
0
  const Descriptor* containing_type = nullptr;
3279
0
  for (int i = 0; i < extension_count(); i++) {
3280
0
    if (extension(i)->containing_type() != containing_type) {
3281
0
      if (i > 0) contents.append("}\n\n");
3282
0
      containing_type = extension(i)->containing_type();
3283
0
      absl::SubstituteAndAppend(&contents, "extend .$0 {\n",
3284
0
                                containing_type->full_name());
3285
0
    }
3286
0
    extension(i)->DebugString(1, &contents, debug_string_options);
3287
0
  }
3288
0
  if (extension_count() > 0) contents.append("}\n\n");
3289
3290
0
  comment_printer.AddPostComment(&contents);
3291
3292
0
  return contents;
3293
0
}
3294
3295
0
std::string Descriptor::DebugString() const {
3296
0
  DebugStringOptions options;  // default options
3297
0
  return DebugStringWithOptions(options);
3298
0
}
3299
3300
std::string Descriptor::DebugStringWithOptions(
3301
0
    const DebugStringOptions& options) const {
3302
0
  std::string contents;
3303
0
  DebugString(0, &contents, options, /* include_opening_clause */ true);
3304
0
  return contents;
3305
0
}
3306
3307
void Descriptor::DebugString(int depth, std::string* contents,
3308
                             const DebugStringOptions& debug_string_options,
3309
0
                             bool include_opening_clause) const {
3310
0
  if (options().map_entry()) {
3311
    // Do not generate debug string for auto-generated map-entry type.
3312
0
    return;
3313
0
  }
3314
0
  std::string prefix(depth * 2, ' ');
3315
0
  ++depth;
3316
3317
0
  SourceLocationCommentPrinter comment_printer(this, prefix,
3318
0
                                               debug_string_options);
3319
0
  comment_printer.AddPreComment(contents);
3320
3321
0
  if (include_opening_clause) {
3322
0
    absl::SubstituteAndAppend(contents, "$0message $1", prefix, name());
3323
0
  }
3324
0
  contents->append(" {\n");
3325
3326
0
  MessageOptions full_options = options();
3327
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3328
0
  FormatLineOptions(depth, full_options, file()->pool(), contents);
3329
3330
  // Find all the 'group' types for fields and extensions; we will not output
3331
  // their nested definitions (those will be done with their group field
3332
  // descriptor).
3333
0
  absl::flat_hash_set<const Descriptor*> groups;
3334
0
  for (int i = 0; i < field_count(); i++) {
3335
0
    if (IsGroupSyntax(field(i))) {
3336
0
      groups.insert(field(i)->message_type());
3337
0
    }
3338
0
  }
3339
0
  for (int i = 0; i < extension_count(); i++) {
3340
0
    if (IsGroupSyntax(extension(i))) {
3341
0
      groups.insert(extension(i)->message_type());
3342
0
    }
3343
0
  }
3344
3345
0
  for (int i = 0; i < nested_type_count(); i++) {
3346
0
    if (!groups.contains(nested_type(i))) {
3347
0
      nested_type(i)->DebugString(depth, contents, debug_string_options,
3348
0
                                  /* include_opening_clause */ true);
3349
0
    }
3350
0
  }
3351
0
  for (int i = 0; i < enum_type_count(); i++) {
3352
0
    enum_type(i)->DebugString(depth, contents, debug_string_options);
3353
0
  }
3354
0
  for (int i = 0; i < field_count(); i++) {
3355
0
    if (field(i)->real_containing_oneof() == nullptr) {
3356
0
      field(i)->DebugString(depth, contents, debug_string_options);
3357
0
    } else if (field(i)->containing_oneof()->field(0) == field(i)) {
3358
      // This is the first field in this oneof, so print the whole oneof.
3359
0
      field(i)->containing_oneof()->DebugString(depth, contents,
3360
0
                                                debug_string_options);
3361
0
    }
3362
0
  }
3363
3364
0
  for (int i = 0; i < extension_range_count(); i++) {
3365
0
    absl::SubstituteAndAppend(contents, "$0  extensions $1", prefix,
3366
0
                              extension_range(i)->start_number());
3367
0
    if (extension_range(i)->end_number() >
3368
0
        extension_range(i)->start_number() + 1) {
3369
0
      absl::SubstituteAndAppend(contents, " to $0",
3370
0
                                extension_range(i)->end_number() - 1);
3371
0
    }
3372
0
    ExtensionRangeOptions range_options = extension_range(i)->options();
3373
0
    CopyFeaturesToOptions(extension_range(i)->proto_features_, &range_options);
3374
0
    std::string formatted_options;
3375
0
    if (FormatBracketedOptions(depth, range_options, file()->pool(),
3376
0
                               &formatted_options)) {
3377
0
      absl::StrAppend(contents, " [", formatted_options, "]");
3378
0
    }
3379
0
    absl::StrAppend(contents, ";\n");
3380
0
  }
3381
3382
  // Group extensions by what they extend, so they can be printed out together.
3383
0
  const Descriptor* containing_type = nullptr;
3384
0
  for (int i = 0; i < extension_count(); i++) {
3385
0
    if (extension(i)->containing_type() != containing_type) {
3386
0
      if (i > 0) absl::SubstituteAndAppend(contents, "$0  }\n", prefix);
3387
0
      containing_type = extension(i)->containing_type();
3388
0
      absl::SubstituteAndAppend(contents, "$0  extend .$1 {\n", prefix,
3389
0
                                containing_type->full_name());
3390
0
    }
3391
0
    extension(i)->DebugString(depth + 1, contents, debug_string_options);
3392
0
  }
3393
0
  if (extension_count() > 0)
3394
0
    absl::SubstituteAndAppend(contents, "$0  }\n", prefix);
3395
3396
0
  if (reserved_range_count() > 0) {
3397
0
    absl::SubstituteAndAppend(contents, "$0  reserved ", prefix);
3398
0
    for (int i = 0; i < reserved_range_count(); i++) {
3399
0
      const Descriptor::ReservedRange* range = reserved_range(i);
3400
0
      if (range->end == range->start + 1) {
3401
0
        absl::SubstituteAndAppend(contents, "$0, ", range->start);
3402
0
      } else if (range->end > FieldDescriptor::kMaxNumber) {
3403
0
        absl::SubstituteAndAppend(contents, "$0 to max, ", range->start);
3404
0
      } else {
3405
0
        absl::SubstituteAndAppend(contents, "$0 to $1, ", range->start,
3406
0
                                  range->end - 1);
3407
0
      }
3408
0
    }
3409
0
    contents->replace(contents->size() - 2, 2, ";\n");
3410
0
  }
3411
3412
0
  if (reserved_name_count() > 0) {
3413
0
    absl::SubstituteAndAppend(contents, "$0  reserved ", prefix);
3414
0
    for (int i = 0; i < reserved_name_count(); i++) {
3415
0
      absl::SubstituteAndAppend(contents, "\"$0\", ",
3416
0
                                absl::CEscape(reserved_name(i)));
3417
0
    }
3418
0
    contents->replace(contents->size() - 2, 2, ";\n");
3419
0
  }
3420
3421
0
  absl::SubstituteAndAppend(contents, "$0}\n", prefix);
3422
0
  comment_printer.AddPostComment(contents);
3423
0
}
3424
3425
0
std::string FieldDescriptor::DebugString() const {
3426
0
  DebugStringOptions options;  // default options
3427
0
  return DebugStringWithOptions(options);
3428
0
}
3429
3430
std::string FieldDescriptor::DebugStringWithOptions(
3431
0
    const DebugStringOptions& debug_string_options) const {
3432
0
  std::string contents;
3433
0
  int depth = 0;
3434
0
  if (is_extension()) {
3435
0
    absl::SubstituteAndAppend(&contents, "extend .$0 {\n",
3436
0
                              containing_type()->full_name());
3437
0
    depth = 1;
3438
0
  }
3439
0
  DebugString(depth, &contents, debug_string_options);
3440
0
  if (is_extension()) {
3441
0
    contents.append("}\n");
3442
0
  }
3443
0
  return contents;
3444
0
}
3445
3446
// The field type string used in FieldDescriptor::DebugString()
3447
0
std::string FieldDescriptor::FieldTypeNameDebugString() const {
3448
0
  switch (type()) {
3449
0
    case TYPE_MESSAGE:
3450
0
    case TYPE_GROUP:
3451
0
      if (IsGroupSyntax(this)) {
3452
0
        return kTypeToName[type()];
3453
0
      }
3454
0
      return absl::StrCat(".", message_type()->full_name());
3455
0
    case TYPE_ENUM:
3456
0
      return absl::StrCat(".", enum_type()->full_name());
3457
0
    default:
3458
0
      return kTypeToName[type()];
3459
0
  }
3460
0
}
3461
3462
void FieldDescriptor::DebugString(
3463
    int depth, std::string* contents,
3464
0
    const DebugStringOptions& debug_string_options) const {
3465
0
  std::string prefix(depth * 2, ' ');
3466
0
  std::string field_type;
3467
3468
  // Special case map fields.
3469
0
  if (is_map()) {
3470
0
    absl::SubstituteAndAppend(
3471
0
        &field_type, "map<$0, $1>",
3472
0
        message_type()->field(0)->FieldTypeNameDebugString(),
3473
0
        message_type()->field(1)->FieldTypeNameDebugString());
3474
0
  } else {
3475
0
    field_type = FieldTypeNameDebugString();
3476
0
  }
3477
3478
0
  std::string label = absl::StrCat(kLabelToName[this->label()], " ");
3479
3480
  // Label is omitted for maps, oneof, and plain proto3 fields.
3481
0
  if (is_map() || real_containing_oneof() ||
3482
0
      (is_optional() && !FieldDescriptorLegacy(this).has_optional_keyword())) {
3483
0
    label.clear();
3484
0
  }
3485
  // Label is omitted for optional and required fields under editions.
3486
0
  if ((is_optional() || is_required()) &&
3487
0
      FileDescriptorLegacy(file()).syntax() ==
3488
0
          FileDescriptorLegacy::SYNTAX_EDITIONS) {
3489
0
    label.clear();
3490
0
  }
3491
3492
0
  SourceLocationCommentPrinter comment_printer(this, prefix,
3493
0
                                               debug_string_options);
3494
0
  comment_printer.AddPreComment(contents);
3495
3496
0
  absl::SubstituteAndAppend(
3497
0
      contents, "$0$1$2 $3 = $4", prefix, label, field_type,
3498
0
      IsGroupSyntax(this) ? message_type()->name() : name(), number());
3499
3500
0
  bool bracketed = false;
3501
0
  if (has_default_value()) {
3502
0
    bracketed = true;
3503
0
    absl::SubstituteAndAppend(contents, " [default = $0",
3504
0
                              DefaultValueAsString(true));
3505
0
  }
3506
0
  if (has_json_name_) {
3507
0
    if (!bracketed) {
3508
0
      bracketed = true;
3509
0
      contents->append(" [");
3510
0
    } else {
3511
0
      contents->append(", ");
3512
0
    }
3513
0
    contents->append("json_name = \"");
3514
0
    contents->append(absl::CEscape(json_name()));
3515
0
    contents->append("\"");
3516
0
  }
3517
3518
0
  FieldOptions full_options = options();
3519
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3520
0
  std::string formatted_options;
3521
0
  if (FormatBracketedOptions(depth, full_options, file()->pool(),
3522
0
                             &formatted_options)) {
3523
0
    contents->append(bracketed ? ", " : " [");
3524
0
    bracketed = true;
3525
0
    contents->append(formatted_options);
3526
0
  }
3527
3528
0
  if (bracketed) {
3529
0
    contents->append("]");
3530
0
  }
3531
3532
0
  if (IsGroupSyntax(this)) {
3533
0
    if (debug_string_options.elide_group_body) {
3534
0
      contents->append(" { ... };\n");
3535
0
    } else {
3536
0
      message_type()->DebugString(depth, contents, debug_string_options,
3537
0
                                  /* include_opening_clause */ false);
3538
0
    }
3539
0
  } else {
3540
0
    contents->append(";\n");
3541
0
  }
3542
3543
0
  comment_printer.AddPostComment(contents);
3544
0
}
3545
3546
0
std::string OneofDescriptor::DebugString() const {
3547
0
  DebugStringOptions options;  // default values
3548
0
  return DebugStringWithOptions(options);
3549
0
}
3550
3551
std::string OneofDescriptor::DebugStringWithOptions(
3552
0
    const DebugStringOptions& options) const {
3553
0
  std::string contents;
3554
0
  DebugString(0, &contents, options);
3555
0
  return contents;
3556
0
}
3557
3558
void OneofDescriptor::DebugString(
3559
    int depth, std::string* contents,
3560
0
    const DebugStringOptions& debug_string_options) const {
3561
0
  std::string prefix(depth * 2, ' ');
3562
0
  ++depth;
3563
0
  SourceLocationCommentPrinter comment_printer(this, prefix,
3564
0
                                               debug_string_options);
3565
0
  comment_printer.AddPreComment(contents);
3566
0
  absl::SubstituteAndAppend(contents, "$0oneof $1 {", prefix, name());
3567
3568
0
  OneofOptions full_options = options();
3569
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3570
0
  FormatLineOptions(depth, full_options, containing_type()->file()->pool(),
3571
0
                    contents);
3572
3573
0
  if (debug_string_options.elide_oneof_body) {
3574
0
    contents->append(" ... }\n");
3575
0
  } else {
3576
0
    contents->append("\n");
3577
0
    for (int i = 0; i < field_count(); i++) {
3578
0
      field(i)->DebugString(depth, contents, debug_string_options);
3579
0
    }
3580
0
    absl::SubstituteAndAppend(contents, "$0}\n", prefix);
3581
0
  }
3582
0
  comment_printer.AddPostComment(contents);
3583
0
}
3584
3585
0
std::string EnumDescriptor::DebugString() const {
3586
0
  DebugStringOptions options;  // default values
3587
0
  return DebugStringWithOptions(options);
3588
0
}
3589
3590
std::string EnumDescriptor::DebugStringWithOptions(
3591
0
    const DebugStringOptions& options) const {
3592
0
  std::string contents;
3593
0
  DebugString(0, &contents, options);
3594
0
  return contents;
3595
0
}
3596
3597
void EnumDescriptor::DebugString(
3598
    int depth, std::string* contents,
3599
0
    const DebugStringOptions& debug_string_options) const {
3600
0
  std::string prefix(depth * 2, ' ');
3601
0
  ++depth;
3602
3603
0
  SourceLocationCommentPrinter comment_printer(this, prefix,
3604
0
                                               debug_string_options);
3605
0
  comment_printer.AddPreComment(contents);
3606
3607
0
  absl::SubstituteAndAppend(contents, "$0enum $1 {\n", prefix, name());
3608
3609
0
  EnumOptions full_options = options();
3610
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3611
0
  FormatLineOptions(depth, full_options, file()->pool(), contents);
3612
3613
0
  for (int i = 0; i < value_count(); i++) {
3614
0
    value(i)->DebugString(depth, contents, debug_string_options);
3615
0
  }
3616
3617
0
  if (reserved_range_count() > 0) {
3618
0
    absl::SubstituteAndAppend(contents, "$0  reserved ", prefix);
3619
0
    for (int i = 0; i < reserved_range_count(); i++) {
3620
0
      const EnumDescriptor::ReservedRange* range = reserved_range(i);
3621
0
      if (range->end == range->start) {
3622
0
        absl::SubstituteAndAppend(contents, "$0, ", range->start);
3623
0
      } else if (range->end == INT_MAX) {
3624
0
        absl::SubstituteAndAppend(contents, "$0 to max, ", range->start);
3625
0
      } else {
3626
0
        absl::SubstituteAndAppend(contents, "$0 to $1, ", range->start,
3627
0
                                  range->end);
3628
0
      }
3629
0
    }
3630
0
    contents->replace(contents->size() - 2, 2, ";\n");
3631
0
  }
3632
3633
0
  if (reserved_name_count() > 0) {
3634
0
    absl::SubstituteAndAppend(contents, "$0  reserved ", prefix);
3635
0
    for (int i = 0; i < reserved_name_count(); i++) {
3636
0
      absl::SubstituteAndAppend(contents, "\"$0\", ",
3637
0
                                absl::CEscape(reserved_name(i)));
3638
0
    }
3639
0
    contents->replace(contents->size() - 2, 2, ";\n");
3640
0
  }
3641
3642
0
  absl::SubstituteAndAppend(contents, "$0}\n", prefix);
3643
3644
0
  comment_printer.AddPostComment(contents);
3645
0
}
3646
3647
0
std::string EnumValueDescriptor::DebugString() const {
3648
0
  DebugStringOptions options;  // default values
3649
0
  return DebugStringWithOptions(options);
3650
0
}
3651
3652
std::string EnumValueDescriptor::DebugStringWithOptions(
3653
0
    const DebugStringOptions& options) const {
3654
0
  std::string contents;
3655
0
  DebugString(0, &contents, options);
3656
0
  return contents;
3657
0
}
3658
3659
void EnumValueDescriptor::DebugString(
3660
    int depth, std::string* contents,
3661
0
    const DebugStringOptions& debug_string_options) const {
3662
0
  std::string prefix(depth * 2, ' ');
3663
3664
0
  SourceLocationCommentPrinter comment_printer(this, prefix,
3665
0
                                               debug_string_options);
3666
0
  comment_printer.AddPreComment(contents);
3667
3668
0
  absl::SubstituteAndAppend(contents, "$0$1 = $2", prefix, name(), number());
3669
3670
0
  EnumValueOptions full_options = options();
3671
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3672
0
  std::string formatted_options;
3673
0
  if (FormatBracketedOptions(depth, full_options, type()->file()->pool(),
3674
0
                             &formatted_options)) {
3675
0
    absl::SubstituteAndAppend(contents, " [$0]", formatted_options);
3676
0
  }
3677
0
  contents->append(";\n");
3678
3679
0
  comment_printer.AddPostComment(contents);
3680
0
}
3681
3682
0
std::string ServiceDescriptor::DebugString() const {
3683
0
  DebugStringOptions options;  // default values
3684
0
  return DebugStringWithOptions(options);
3685
0
}
3686
3687
std::string ServiceDescriptor::DebugStringWithOptions(
3688
0
    const DebugStringOptions& options) const {
3689
0
  std::string contents;
3690
0
  DebugString(&contents, options);
3691
0
  return contents;
3692
0
}
3693
3694
void ServiceDescriptor::DebugString(
3695
    std::string* contents,
3696
0
    const DebugStringOptions& debug_string_options) const {
3697
0
  SourceLocationCommentPrinter comment_printer(this, /* prefix */ "",
3698
0
                                               debug_string_options);
3699
0
  comment_printer.AddPreComment(contents);
3700
3701
0
  absl::SubstituteAndAppend(contents, "service $0 {\n", name());
3702
3703
0
  ServiceOptions full_options = options();
3704
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3705
0
  FormatLineOptions(1, full_options, file()->pool(), contents);
3706
3707
0
  for (int i = 0; i < method_count(); i++) {
3708
0
    method(i)->DebugString(1, contents, debug_string_options);
3709
0
  }
3710
3711
0
  contents->append("}\n");
3712
3713
0
  comment_printer.AddPostComment(contents);
3714
0
}
3715
3716
0
std::string MethodDescriptor::DebugString() const {
3717
0
  DebugStringOptions options;  // default values
3718
0
  return DebugStringWithOptions(options);
3719
0
}
3720
3721
std::string MethodDescriptor::DebugStringWithOptions(
3722
0
    const DebugStringOptions& options) const {
3723
0
  std::string contents;
3724
0
  DebugString(0, &contents, options);
3725
0
  return contents;
3726
0
}
3727
3728
void MethodDescriptor::DebugString(
3729
    int depth, std::string* contents,
3730
0
    const DebugStringOptions& debug_string_options) const {
3731
0
  std::string prefix(depth * 2, ' ');
3732
0
  ++depth;
3733
3734
0
  SourceLocationCommentPrinter comment_printer(this, prefix,
3735
0
                                               debug_string_options);
3736
0
  comment_printer.AddPreComment(contents);
3737
3738
0
  absl::SubstituteAndAppend(
3739
0
      contents, "$0rpc $1($4.$2) returns ($5.$3)", prefix, name(),
3740
0
      input_type()->full_name(), output_type()->full_name(),
3741
0
      client_streaming() ? "stream " : "", server_streaming() ? "stream " : "");
3742
3743
0
  MethodOptions full_options = options();
3744
0
  CopyFeaturesToOptions(proto_features_, &full_options);
3745
0
  std::string formatted_options;
3746
0
  if (FormatLineOptions(depth, full_options, service()->file()->pool(),
3747
0
                        &formatted_options)) {
3748
0
    absl::SubstituteAndAppend(contents, " {\n$0$1}\n", formatted_options,
3749
0
                              prefix);
3750
0
  } else {
3751
0
    contents->append(";\n");
3752
0
  }
3753
3754
0
  comment_printer.AddPostComment(contents);
3755
0
}
3756
3757
// Feature methods ===============================================
3758
3759
0
bool EnumDescriptor::is_closed() const {
3760
0
  return features().enum_type() == FeatureSet::CLOSED;
3761
0
}
3762
3763
0
bool FieldDescriptor::is_packed() const {
3764
0
  if (!is_packable()) return false;
3765
0
  return features().repeated_field_encoding() == FeatureSet::PACKED;
3766
0
}
3767
3768
0
static bool IsStrictUtf8(const FieldDescriptor* field) {
3769
0
  return internal::InternalFeatureHelper::GetFeatures(*field)
3770
0
             .utf8_validation() == FeatureSet::VERIFY;
3771
0
}
3772
3773
0
bool FieldDescriptor::requires_utf8_validation() const {
3774
0
  return type() == TYPE_STRING && IsStrictUtf8(this);
3775
0
}
3776
3777
0
bool FieldDescriptor::has_presence() const {
3778
0
  if (is_repeated()) return false;
3779
0
  return cpp_type() == CPPTYPE_MESSAGE || containing_oneof() ||
3780
0
         features().field_presence() != FeatureSet::IMPLICIT;
3781
0
}
3782
3783
406k
bool FieldDescriptor::is_required() const {
3784
406k
  return features().field_presence() == FeatureSet::LEGACY_REQUIRED;
3785
406k
}
3786
3787
0
bool FieldDescriptor::legacy_enum_field_treated_as_closed() const {
3788
0
  return type() == TYPE_ENUM &&
3789
0
         (features().GetExtension(pb::cpp).legacy_closed_enum() ||
3790
0
          enum_type()->is_closed());
3791
0
}
3792
3793
// Location methods ===============================================
3794
3795
bool FileDescriptor::GetSourceLocation(const std::vector<int>& path,
3796
0
                                       SourceLocation* out_location) const {
3797
0
  ABSL_CHECK(out_location != nullptr);
3798
0
  if (source_code_info_) {
3799
0
    if (const SourceCodeInfo_Location* loc =
3800
0
            tables_->GetSourceLocation(path, source_code_info_)) {
3801
0
      const RepeatedField<int32_t>& span = loc->span();
3802
0
      if (span.size() == 3 || span.size() == 4) {
3803
0
        out_location->start_line = span.Get(0);
3804
0
        out_location->start_column = span.Get(1);
3805
0
        out_location->end_line = span.Get(span.size() == 3 ? 0 : 2);
3806
0
        out_location->end_column = span.Get(span.size() - 1);
3807
3808
0
        out_location->leading_comments = loc->leading_comments();
3809
0
        out_location->trailing_comments = loc->trailing_comments();
3810
0
        out_location->leading_detached_comments.assign(
3811
0
            loc->leading_detached_comments().begin(),
3812
0
            loc->leading_detached_comments().end());
3813
0
        return true;
3814
0
      }
3815
0
    }
3816
0
  }
3817
0
  return false;
3818
0
}
3819
3820
0
bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3821
0
  std::vector<int> path;  // empty path for root FileDescriptor
3822
0
  return GetSourceLocation(path, out_location);
3823
0
}
3824
3825
0
bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
3826
0
  std::vector<int> path;
3827
0
  GetLocationPath(&path);
3828
0
  return file()->GetSourceLocation(path, out_location);
3829
0
}
3830
3831
0
bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3832
0
  std::vector<int> path;
3833
0
  GetLocationPath(&path);
3834
0
  return file()->GetSourceLocation(path, out_location);
3835
0
}
3836
3837
0
bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3838
0
  std::vector<int> path;
3839
0
  GetLocationPath(&path);
3840
0
  return containing_type()->file()->GetSourceLocation(path, out_location);
3841
0
}
3842
3843
0
bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3844
0
  std::vector<int> path;
3845
0
  GetLocationPath(&path);
3846
0
  return file()->GetSourceLocation(path, out_location);
3847
0
}
3848
3849
0
bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3850
0
  std::vector<int> path;
3851
0
  GetLocationPath(&path);
3852
0
  return service()->file()->GetSourceLocation(path, out_location);
3853
0
}
3854
3855
0
bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const {
3856
0
  std::vector<int> path;
3857
0
  GetLocationPath(&path);
3858
0
  return file()->GetSourceLocation(path, out_location);
3859
0
}
3860
3861
bool EnumValueDescriptor::GetSourceLocation(
3862
0
    SourceLocation* out_location) const {
3863
0
  std::vector<int> path;
3864
0
  GetLocationPath(&path);
3865
0
  return type()->file()->GetSourceLocation(path, out_location);
3866
0
}
3867
3868
764
void Descriptor::GetLocationPath(std::vector<int>* output) const {
3869
764
  if (containing_type()) {
3870
82
    containing_type()->GetLocationPath(output);
3871
82
    output->push_back(DescriptorProto::kNestedTypeFieldNumber);
3872
82
    output->push_back(index());
3873
682
  } else {
3874
682
    output->push_back(FileDescriptorProto::kMessageTypeFieldNumber);
3875
682
    output->push_back(index());
3876
682
  }
3877
764
}
3878
3879
396
void FieldDescriptor::GetLocationPath(std::vector<int>* output) const {
3880
396
  if (is_extension()) {
3881
2
    if (extension_scope() == nullptr) {
3882
2
      output->push_back(FileDescriptorProto::kExtensionFieldNumber);
3883
2
      output->push_back(index());
3884
2
    } else {
3885
0
      extension_scope()->GetLocationPath(output);
3886
0
      output->push_back(DescriptorProto::kExtensionFieldNumber);
3887
0
      output->push_back(index());
3888
0
    }
3889
394
  } else {
3890
394
    containing_type()->GetLocationPath(output);
3891
394
    output->push_back(DescriptorProto::kFieldFieldNumber);
3892
394
    output->push_back(index());
3893
394
  }
3894
396
}
3895
3896
4
void OneofDescriptor::GetLocationPath(std::vector<int>* output) const {
3897
4
  containing_type()->GetLocationPath(output);
3898
4
  output->push_back(DescriptorProto::kOneofDeclFieldNumber);
3899
4
  output->push_back(index());
3900
4
}
3901
3902
void Descriptor::ExtensionRange::GetLocationPath(
3903
24
    std::vector<int>* output) const {
3904
24
  containing_type()->GetLocationPath(output);
3905
24
  output->push_back(DescriptorProto::kExtensionRangeFieldNumber);
3906
24
  output->push_back(index());
3907
24
}
3908
3909
192
void EnumDescriptor::GetLocationPath(std::vector<int>* output) const {
3910
192
  if (containing_type()) {
3911
172
    containing_type()->GetLocationPath(output);
3912
172
    output->push_back(DescriptorProto::kEnumTypeFieldNumber);
3913
172
    output->push_back(index());
3914
172
  } else {
3915
20
    output->push_back(FileDescriptorProto::kEnumTypeFieldNumber);
3916
20
    output->push_back(index());
3917
20
  }
3918
192
}
3919
3920
158
void EnumValueDescriptor::GetLocationPath(std::vector<int>* output) const {
3921
158
  type()->GetLocationPath(output);
3922
158
  output->push_back(EnumDescriptorProto::kValueFieldNumber);
3923
158
  output->push_back(index());
3924
158
}
3925
3926
0
void ServiceDescriptor::GetLocationPath(std::vector<int>* output) const {
3927
0
  output->push_back(FileDescriptorProto::kServiceFieldNumber);
3928
0
  output->push_back(index());
3929
0
}
3930
3931
0
void MethodDescriptor::GetLocationPath(std::vector<int>* output) const {
3932
0
  service()->GetLocationPath(output);
3933
0
  output->push_back(ServiceDescriptorProto::kMethodFieldNumber);
3934
0
  output->push_back(index());
3935
0
}
3936
3937
// ===================================================================
3938
3939
namespace {
3940
3941
// Represents an options message to interpret. Extension names in the option
3942
// name are resolved relative to name_scope. element_name and orig_opt are
3943
// used only for error reporting (since the parser records locations against
3944
// pointers in the original options, not the mutable copy). The Message must be
3945
// one of the Options messages in descriptor.proto.
3946
struct OptionsToInterpret {
3947
  OptionsToInterpret(absl::string_view ns, absl::string_view el,
3948
                     absl::Span<const int> path, const Message* orig_opt,
3949
                     Message* opt)
3950
      : name_scope(ns),
3951
        element_name(el),
3952
        element_path(path.begin(), path.end()),
3953
        original_options(orig_opt),
3954
0
        options(opt) {}
3955
  std::string name_scope;
3956
  std::string element_name;
3957
  std::vector<int> element_path;
3958
  const Message* original_options;
3959
  Message* options;
3960
};
3961
3962
}  // namespace
3963
3964
class DescriptorBuilder {
3965
 public:
3966
  static std::unique_ptr<DescriptorBuilder> New(
3967
      const DescriptorPool* pool, DescriptorPool::Tables* tables,
3968
8
      DescriptorPool::ErrorCollector* error_collector) {
3969
8
    return std::unique_ptr<DescriptorBuilder>(
3970
8
        new DescriptorBuilder(pool, tables, error_collector));
3971
8
  }
3972
3973
  ~DescriptorBuilder();
3974
3975
  const FileDescriptor* BuildFile(const FileDescriptorProto& original_proto);
3976
3977
 private:
3978
  DescriptorBuilder(const DescriptorPool* pool, DescriptorPool::Tables* tables,
3979
                    DescriptorPool::ErrorCollector* error_collector);
3980
3981
  friend class OptionInterpreter;
3982
3983
  // Non-recursive part of BuildFile functionality.
3984
  FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto,
3985
                                internal::FlatAllocator& alloc);
3986
3987
  const DescriptorPool* pool_;
3988
  DescriptorPool::Tables* tables_;  // for convenience
3989
  DescriptorPool::ErrorCollector* error_collector_;
3990
3991
  absl::optional<FeatureResolver> feature_resolver_ = absl::nullopt;
3992
3993
  // As we build descriptors we store copies of the options messages in
3994
  // them. We put pointers to those copies in this vector, as we build, so we
3995
  // can later (after cross-linking) interpret those options.
3996
  std::vector<OptionsToInterpret> options_to_interpret_;
3997
3998
  bool had_errors_;
3999
  std::string filename_;
4000
  FileDescriptor* file_;
4001
  FileDescriptorTables* file_tables_;
4002
  absl::flat_hash_set<const FileDescriptor*> dependencies_;
4003
4004
  struct MessageHints {
4005
    int fields_to_suggest = 0;
4006
    const Message* first_reason = nullptr;
4007
    DescriptorPool::ErrorCollector::ErrorLocation first_reason_location =
4008
        DescriptorPool::ErrorCollector::ErrorLocation::OTHER;
4009
4010
    void RequestHintOnFieldNumbers(
4011
        const Message& reason,
4012
        DescriptorPool::ErrorCollector::ErrorLocation reason_location,
4013
0
        int range_start = 0, int range_end = 1) {
4014
0
      auto fit = [](int value) {
4015
0
        return std::min(std::max(value, 0), FieldDescriptor::kMaxNumber);
4016
0
      };
4017
0
      fields_to_suggest =
4018
0
          fit(fields_to_suggest + fit(fit(range_end) - fit(range_start)));
4019
0
      if (first_reason) return;
4020
0
      first_reason = &reason;
4021
0
      first_reason_location = reason_location;
4022
0
    }
4023
  };
4024
4025
  absl::flat_hash_map<const Descriptor*, MessageHints> message_hints_;
4026
4027
  // unused_dependency_ is used to record the unused imported files.
4028
  // Note: public import is not considered.
4029
  absl::flat_hash_set<const FileDescriptor*> unused_dependency_;
4030
4031
  // If LookupSymbol() finds a symbol that is in a file which is not a declared
4032
  // dependency of this file, it will fail, but will set
4033
  // possible_undeclared_dependency_ to point at that file.  This is only used
4034
  // by AddNotDefinedError() to report a more useful error message.
4035
  // possible_undeclared_dependency_name_ is the name of the symbol that was
4036
  // actually found in possible_undeclared_dependency_, which may be a parent
4037
  // of the symbol actually looked for.
4038
  const FileDescriptor* possible_undeclared_dependency_;
4039
  std::string possible_undeclared_dependency_name_;
4040
4041
  // If LookupSymbol() could resolve a symbol which is not defined,
4042
  // record the resolved name.  This is only used by AddNotDefinedError()
4043
  // to report a more useful error message.
4044
  std::string undefine_resolved_name_;
4045
4046
  // Tracker for current recursion depth to implement recursion protection.
4047
  //
4048
  // Counts down to 0 when there is no depth remaining.
4049
  //
4050
  // Maximum recursion depth corresponds to 32 nested message declarations.
4051
  int recursion_depth_ = 32;
4052
4053
  // Note: Both AddError and AddWarning functions are extremely sensitive to
4054
  // the *caller* stack space used. We call these functions many times in
4055
  // complex code paths that are hot and likely to be inlined heavily. However,
4056
  // these calls themselves are cold error paths. But stack space used by the
4057
  // code that sets up the call in many cases is paid for even when the call
4058
  // isn't reached. To optimize this, we use `const std::string &` to reuse
4059
  // string objects where possible for the inputs and for the error message
4060
  // itself we use a closure to build the error message inside these routines.
4061
  // The routines themselves are marked to prevent inlining and this lets us
4062
  // move the large code sometimes required to produce a useful error message
4063
  // entirely into a helper closure rather than the immediate caller.
4064
  //
4065
  // The `const char*` overload should only be used for string literal messages
4066
  // where this is a frustrating amount of overhead and there is no harm in
4067
  // directly using the literal.
4068
  void AddError(const std::string& element_name, const Message& descriptor,
4069
                DescriptorPool::ErrorCollector::ErrorLocation location,
4070
                absl::FunctionRef<std::string()> make_error);
4071
  void AddError(const std::string& element_name, const Message& descriptor,
4072
                DescriptorPool::ErrorCollector::ErrorLocation location,
4073
                const char* error);
4074
  void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
4075
  void AddTwiceListedError(const FileDescriptorProto& proto, int index);
4076
  void AddImportError(const FileDescriptorProto& proto, int index);
4077
4078
  // Adds an error indicating that undefined_symbol was not defined.  Must
4079
  // only be called after LookupSymbol() fails.
4080
  void AddNotDefinedError(
4081
      const std::string& element_name, const Message& descriptor,
4082
      DescriptorPool::ErrorCollector::ErrorLocation location,
4083
      const std::string& undefined_symbol);
4084
4085
  void AddWarning(const std::string& element_name, const Message& descriptor,
4086
                  DescriptorPool::ErrorCollector::ErrorLocation location,
4087
                  absl::FunctionRef<std::string()> make_error);
4088
  void AddWarning(const std::string& element_name, const Message& descriptor,
4089
                  DescriptorPool::ErrorCollector::ErrorLocation location,
4090
                  const char* error);
4091
4092
  // Silly helper which determines if the given file is in the given package.
4093
  // I.e., either file->package() == package_name or file->package() is a
4094
  // nested package within package_name.
4095
  bool IsInPackage(const FileDescriptor* file, absl::string_view package_name);
4096
4097
  // Helper function which finds all public dependencies of the given file, and
4098
  // stores the them in the dependencies_ set in the builder.
4099
  void RecordPublicDependencies(const FileDescriptor* file);
4100
4101
  // Like tables_->FindSymbol(), but additionally:
4102
  // - Search the pool's underlay if not found in tables_.
4103
  // - Insure that the resulting Symbol is from one of the file's declared
4104
  //   dependencies.
4105
  Symbol FindSymbol(const std::string& name, bool build_it = true);
4106
4107
  // Like FindSymbol() but does not require that the symbol is in one of the
4108
  // file's declared dependencies.
4109
  Symbol FindSymbolNotEnforcingDeps(const std::string& name,
4110
                                    bool build_it = true);
4111
4112
  // This implements the body of FindSymbolNotEnforcingDeps().
4113
  Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
4114
                                          const std::string& name,
4115
                                          bool build_it = true);
4116
4117
  // Like FindSymbol(), but looks up the name relative to some other symbol
4118
  // name.  This first searches siblings of relative_to, then siblings of its
4119
  // parents, etc.  For example, LookupSymbol("foo.bar", "baz.moo.corge") makes
4120
  // the following calls, returning the first non-null result:
4121
  // FindSymbol("baz.moo.foo.bar"), FindSymbol("baz.foo.bar"),
4122
  // FindSymbol("foo.bar").  If AllowUnknownDependencies() has been called
4123
  // on the DescriptorPool, this will generate a placeholder type if
4124
  // the name is not found (unless the name itself is malformed).  The
4125
  // placeholder_type parameter indicates what kind of placeholder should be
4126
  // constructed in this case.  The resolve_mode parameter determines whether
4127
  // any symbol is returned, or only symbols that are types.  Note, however,
4128
  // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
4129
  // if it believes that's all it could refer to.  The caller should always
4130
  // check that it receives the type of symbol it was expecting.
4131
  enum ResolveMode { LOOKUP_ALL, LOOKUP_TYPES };
4132
  Symbol LookupSymbol(const std::string& name, const std::string& relative_to,
4133
                      DescriptorPool::PlaceholderType placeholder_type =
4134
                          DescriptorPool::PLACEHOLDER_MESSAGE,
4135
                      ResolveMode resolve_mode = LOOKUP_ALL,
4136
                      bool build_it = true);
4137
4138
  // Like LookupSymbol() but will not return a placeholder even if
4139
  // AllowUnknownDependencies() has been used.
4140
  Symbol LookupSymbolNoPlaceholder(const std::string& name,
4141
                                   const std::string& relative_to,
4142
                                   ResolveMode resolve_mode = LOOKUP_ALL,
4143
                                   bool build_it = true);
4144
4145
  // Calls tables_->AddSymbol() and records an error if it fails.  Returns
4146
  // true if successful or false if failed, though most callers can ignore
4147
  // the return value since an error has already been recorded.
4148
  bool AddSymbol(const std::string& full_name, const void* parent,
4149
                 const std::string& name, const Message& proto, Symbol symbol);
4150
4151
  // Like AddSymbol(), but succeeds if the symbol is already defined as long
4152
  // as the existing definition is also a package (because it's OK to define
4153
  // the same package in two different files).  Also adds all parents of the
4154
  // package to the symbol table (e.g. AddPackage("foo.bar", ...) will add
4155
  // "foo.bar" and "foo" to the table).
4156
  void AddPackage(const std::string& name, const Message& proto,
4157
                  FileDescriptor* file);
4158
4159
  // Checks that the symbol name contains only alphanumeric characters and
4160
  // underscores.  Records an error otherwise.
4161
  void ValidateSymbolName(const std::string& name, const std::string& full_name,
4162
                          const Message& proto);
4163
4164
  // Allocates a copy of orig_options in tables_ and stores it in the
4165
  // descriptor. Remembers its uninterpreted options, to be interpreted
4166
  // later. DescriptorT must be one of the Descriptor messages from
4167
  // descriptor.proto.
4168
  template <class DescriptorT>
4169
  void AllocateOptions(const typename DescriptorT::Proto& proto,
4170
                       DescriptorT* descriptor, int options_field_tag,
4171
                       absl::string_view option_name,
4172
                       internal::FlatAllocator& alloc);
4173
  // Specialization for FileOptions.
4174
  void AllocateOptions(const FileDescriptorProto& proto,
4175
                       FileDescriptor* descriptor,
4176
                       internal::FlatAllocator& alloc);
4177
4178
  // Implementation for AllocateOptions(). Don't call this directly.
4179
  template <class DescriptorT>
4180
  typename DescriptorT::OptionsType* AllocateOptionsImpl(
4181
      absl::string_view name_scope, absl::string_view element_name,
4182
      const typename DescriptorT::Proto& proto,
4183
      absl::Span<const int> options_path, absl::string_view option_name,
4184
      internal::FlatAllocator& alloc);
4185
4186
  // Allocates and resolves any feature sets that need to be owned by a given
4187
  // descriptor. This also strips features out of the mutable options message to
4188
  // prevent leaking of unresolved features.
4189
  // Note: This must be used during a pre-order traversal of the
4190
  // descriptor tree, so that each descriptor's parent has a fully resolved
4191
  // feature set already.
4192
  template <class DescriptorT>
4193
  void ResolveFeatures(const typename DescriptorT::Proto& proto,
4194
                       DescriptorT* descriptor,
4195
                       typename DescriptorT::OptionsType* options,
4196
                       internal::FlatAllocator& alloc);
4197
  void ResolveFeatures(const FileDescriptorProto& proto,
4198
                       FileDescriptor* descriptor, FileOptions* options,
4199
                       internal::FlatAllocator& alloc);
4200
  template <class DescriptorT>
4201
  void ResolveFeaturesImpl(
4202
      const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
4203
      typename DescriptorT::OptionsType* options,
4204
      internal::FlatAllocator& alloc,
4205
      DescriptorPool::ErrorCollector::ErrorLocation error_location,
4206
      bool force_merge = false);
4207
4208
  void PostProcessFieldFeatures(FieldDescriptor& field);
4209
4210
  // Allocates an array of two strings, the first one is a copy of
4211
  // `proto_name`, and the second one is the full name. Full proto name is
4212
  // "scope.proto_name" if scope is non-empty and "proto_name" otherwise.
4213
  const std::string* AllocateNameStrings(const std::string& scope,
4214
                                         const std::string& proto_name,
4215
                                         internal::FlatAllocator& alloc);
4216
4217
  // These methods all have the same signature for the sake of the BUILD_ARRAY
4218
  // macro, below.
4219
  void BuildMessage(const DescriptorProto& proto, const Descriptor* parent,
4220
                    Descriptor* result, internal::FlatAllocator& alloc);
4221
  void BuildFieldOrExtension(const FieldDescriptorProto& proto,
4222
                             Descriptor* parent, FieldDescriptor* result,
4223
                             bool is_extension, internal::FlatAllocator& alloc);
4224
  void BuildField(const FieldDescriptorProto& proto, Descriptor* parent,
4225
394
                  FieldDescriptor* result, internal::FlatAllocator& alloc) {
4226
394
    BuildFieldOrExtension(proto, parent, result, false, alloc);
4227
394
  }
4228
  void BuildExtension(const FieldDescriptorProto& proto, Descriptor* parent,
4229
2
                      FieldDescriptor* result, internal::FlatAllocator& alloc) {
4230
2
    BuildFieldOrExtension(proto, parent, result, true, alloc);
4231
2
  }
4232
  void BuildExtensionRange(const DescriptorProto::ExtensionRange& proto,
4233
                           const Descriptor* parent,
4234
                           Descriptor::ExtensionRange* result,
4235
                           internal::FlatAllocator& alloc);
4236
  void BuildReservedRange(const DescriptorProto::ReservedRange& proto,
4237
                          const Descriptor* parent,
4238
                          Descriptor::ReservedRange* result,
4239
                          internal::FlatAllocator& alloc);
4240
  void BuildReservedRange(const EnumDescriptorProto::EnumReservedRange& proto,
4241
                          const EnumDescriptor* parent,
4242
                          EnumDescriptor::ReservedRange* result,
4243
                          internal::FlatAllocator& alloc);
4244
  void BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent,
4245
                  OneofDescriptor* result, internal::FlatAllocator& alloc);
4246
  void BuildEnum(const EnumDescriptorProto& proto, const Descriptor* parent,
4247
                 EnumDescriptor* result, internal::FlatAllocator& alloc);
4248
  void BuildEnumValue(const EnumValueDescriptorProto& proto,
4249
                      const EnumDescriptor* parent, EnumValueDescriptor* result,
4250
                      internal::FlatAllocator& alloc);
4251
  void BuildService(const ServiceDescriptorProto& proto, const void* dummy,
4252
                    ServiceDescriptor* result, internal::FlatAllocator& alloc);
4253
  void BuildMethod(const MethodDescriptorProto& proto,
4254
                   const ServiceDescriptor* parent, MethodDescriptor* result,
4255
                   internal::FlatAllocator& alloc);
4256
4257
  void CheckFieldJsonNameUniqueness(const DescriptorProto& proto,
4258
                                    const Descriptor* result);
4259
  void CheckFieldJsonNameUniqueness(const std::string& message_name,
4260
                                    const DescriptorProto& message,
4261
                                    const Descriptor* descriptor,
4262
                                    FileDescriptorLegacy::Syntax syntax,
4263
                                    bool use_custom_names);
4264
  void CheckEnumValueUniqueness(const EnumDescriptorProto& proto,
4265
                                const EnumDescriptor* result);
4266
4267
  void LogUnusedDependency(const FileDescriptorProto& proto,
4268
                           const FileDescriptor* result);
4269
4270
  // Must be run only after building.
4271
  //
4272
  // NOTE: Options will not be available during cross-linking, as they
4273
  // have not yet been interpreted. Defer any handling of options to the
4274
  // Validate*Options methods.
4275
  void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
4276
  void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
4277
  void CrossLinkField(FieldDescriptor* field,
4278
                      const FieldDescriptorProto& proto);
4279
  void CrossLinkExtensionRange(Descriptor::ExtensionRange* range,
4280
                               const DescriptorProto::ExtensionRange& proto);
4281
  void CrossLinkEnum(EnumDescriptor* enum_type,
4282
                     const EnumDescriptorProto& proto);
4283
  void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
4284
                          const EnumValueDescriptorProto& proto);
4285
  void CrossLinkService(ServiceDescriptor* service,
4286
                        const ServiceDescriptorProto& proto);
4287
  void CrossLinkMethod(MethodDescriptor* method,
4288
                       const MethodDescriptorProto& proto);
4289
  void SuggestFieldNumbers(FileDescriptor* file,
4290
                           const FileDescriptorProto& proto);
4291
4292
  // Checks that the extension field matches what is declared.
4293
  void CheckExtensionDeclaration(const FieldDescriptor& field,
4294
                                 const FieldDescriptorProto& proto,
4295
                                 absl::string_view declared_full_name,
4296
                                 absl::string_view declared_type_name,
4297
                                 bool is_repeated);
4298
  // Checks that the extension field type matches the declared type. It also
4299
  // handles message types that look like non-message types such as "fixed64" vs
4300
  // ".fixed64".
4301
  void CheckExtensionDeclarationFieldType(const FieldDescriptor& field,
4302
                                          const FieldDescriptorProto& proto,
4303
                                          absl::string_view type);
4304
4305
  // A helper class for interpreting options.
4306
  class OptionInterpreter {
4307
   public:
4308
    // Creates an interpreter that operates in the context of the pool of the
4309
    // specified builder, which must not be nullptr. We don't take ownership of
4310
    // the builder.
4311
    explicit OptionInterpreter(DescriptorBuilder* builder);
4312
    OptionInterpreter(const OptionInterpreter&) = delete;
4313
    OptionInterpreter& operator=(const OptionInterpreter&) = delete;
4314
4315
    ~OptionInterpreter();
4316
4317
    // Interprets the uninterpreted options in the specified Options message.
4318
    // On error, calls AddError() on the underlying builder and returns false.
4319
    // Otherwise returns true.
4320
    bool InterpretOptionExtensions(OptionsToInterpret* options_to_interpret);
4321
4322
    // Interprets the uninterpreted feature options in the specified Options
4323
    // message. On error, calls AddError() on the underlying builder and returns
4324
    // false. Otherwise returns true.
4325
    bool InterpretNonExtensionOptions(OptionsToInterpret* options_to_interpret);
4326
4327
    // Updates the given source code info by re-writing uninterpreted option
4328
    // locations to refer to the corresponding interpreted option.
4329
    void UpdateSourceCodeInfo(SourceCodeInfo* info);
4330
4331
    class AggregateOptionFinder;
4332
4333
   private:
4334
    bool InterpretOptionsImpl(OptionsToInterpret* options_to_interpret,
4335
                              bool skip_extensions);
4336
4337
    // Interprets uninterpreted_option_ on the specified message, which
4338
    // must be the mutable copy of the original options message to which
4339
    // uninterpreted_option_ belongs. The given src_path is the source
4340
    // location path to the uninterpreted option, and options_path is the
4341
    // source location path to the options message. The location paths are
4342
    // recorded and then used in UpdateSourceCodeInfo.
4343
    // The features boolean controls whether or not we should only interpret
4344
    // feature options or skip them entirely.
4345
    bool InterpretSingleOption(Message* options,
4346
                               const std::vector<int>& src_path,
4347
                               const std::vector<int>& options_path,
4348
                               bool skip_extensions);
4349
4350
    // Adds the uninterpreted_option to the given options message verbatim.
4351
    // Used when AllowUnknownDependencies() is in effect and we can't find
4352
    // the option's definition.
4353
    void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
4354
                                Message* options);
4355
4356
    // A recursive helper function that drills into the intermediate fields
4357
    // in unknown_fields to check if field innermost_field is set on the
4358
    // innermost message. Returns false and sets an error if so.
4359
    bool ExamineIfOptionIsSet(
4360
        std::vector<const FieldDescriptor*>::const_iterator
4361
            intermediate_fields_iter,
4362
        std::vector<const FieldDescriptor*>::const_iterator
4363
            intermediate_fields_end,
4364
        const FieldDescriptor* innermost_field,
4365
        const std::string& debug_msg_name,
4366
        const UnknownFieldSet& unknown_fields);
4367
4368
    // Validates the value for the option field of the currently interpreted
4369
    // option and then sets it on the unknown_field.
4370
    bool SetOptionValue(const FieldDescriptor* option_field,
4371
                        UnknownFieldSet* unknown_fields);
4372
4373
    // Parses an aggregate value for a CPPTYPE_MESSAGE option and
4374
    // saves it into *unknown_fields.
4375
    bool SetAggregateOption(const FieldDescriptor* option_field,
4376
                            UnknownFieldSet* unknown_fields);
4377
4378
    // Convenience functions to set an int field the right way, depending on
4379
    // its wire type (a single int CppType can represent multiple wire types).
4380
    void SetInt32(int number, int32_t value, FieldDescriptor::Type type,
4381
                  UnknownFieldSet* unknown_fields);
4382
    void SetInt64(int number, int64_t value, FieldDescriptor::Type type,
4383
                  UnknownFieldSet* unknown_fields);
4384
    void SetUInt32(int number, uint32_t value, FieldDescriptor::Type type,
4385
                   UnknownFieldSet* unknown_fields);
4386
    void SetUInt64(int number, uint64_t value, FieldDescriptor::Type type,
4387
                   UnknownFieldSet* unknown_fields);
4388
4389
    // A helper function that adds an error at the specified location of the
4390
    // option we're currently interpreting, and returns false.
4391
    bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location,
4392
0
                        absl::FunctionRef<std::string()> make_error) {
4393
0
      builder_->AddError(options_to_interpret_->element_name,
4394
0
                         *uninterpreted_option_, location, make_error);
4395
0
      return false;
4396
0
    }
4397
4398
    // A helper function that adds an error at the location of the option name
4399
    // and returns false.
4400
0
    bool AddNameError(absl::FunctionRef<std::string()> make_error) {
4401
#ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4402
      return true;
4403
#else   // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4404
0
      return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME,
4405
0
                            make_error);
4406
0
#endif  // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_
4407
0
    }
4408
4409
    // A helper function that adds an error at the location of the option name
4410
    // and returns false.
4411
0
    bool AddValueError(absl::FunctionRef<std::string()> make_error) {
4412
0
      return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE,
4413
0
                            make_error);
4414
0
    }
4415
4416
    // We interpret against this builder's pool. Is never nullptr. We don't own
4417
    // this pointer.
4418
    DescriptorBuilder* builder_;
4419
4420
    // The options we're currently interpreting, or nullptr if we're not in a
4421
    // call to InterpretOptions.
4422
    const OptionsToInterpret* options_to_interpret_;
4423
4424
    // The option we're currently interpreting within options_to_interpret_, or
4425
    // nullptr if we're not in a call to InterpretOptions(). This points to a
4426
    // submessage of the original option, not the mutable copy. Therefore we
4427
    // can use it to find locations recorded by the parser.
4428
    const UninterpretedOption* uninterpreted_option_;
4429
4430
    // This maps the element path of uninterpreted options to the element path
4431
    // of the resulting interpreted option. This is used to modify a file's
4432
    // source code info to account for option interpretation.
4433
    absl::flat_hash_map<std::vector<int>, std::vector<int>> interpreted_paths_;
4434
4435
    // This maps the path to a repeated option field to the known number of
4436
    // elements the field contains. This is used to track the compute the
4437
    // index portion of the element path when interpreting a single option.
4438
    absl::flat_hash_map<std::vector<int>, int> repeated_option_counts_;
4439
4440
    // Factory used to create the dynamic messages we need to parse
4441
    // any aggregate option values we encounter.
4442
    DynamicMessageFactory dynamic_factory_;
4443
  };
4444
4445
  // Work-around for broken compilers:  According to the C++ standard,
4446
  // OptionInterpreter should have access to the private members of any class
4447
  // which has declared DescriptorBuilder as a friend.  Unfortunately some old
4448
  // versions of GCC and other compilers do not implement this correctly.  So,
4449
  // we have to have these intermediate methods to provide access.  We also
4450
  // redundantly declare OptionInterpreter a friend just to make things extra
4451
  // clear for these bad compilers.
4452
  friend class OptionInterpreter;
4453
  friend class OptionInterpreter::AggregateOptionFinder;
4454
4455
0
  static inline bool get_allow_unknown(const DescriptorPool* pool) {
4456
0
    return pool->allow_unknown_;
4457
0
  }
4458
0
  static inline bool get_enforce_weak(const DescriptorPool* pool) {
4459
0
    return pool->enforce_weak_;
4460
0
  }
4461
0
  static inline bool get_is_placeholder(const Descriptor* descriptor) {
4462
0
    return descriptor != nullptr && descriptor->is_placeholder_;
4463
0
  }
4464
0
  static inline void assert_mutex_held(const DescriptorPool* pool) {
4465
0
    if (pool->mutex_ != nullptr) {
4466
0
      pool->mutex_->AssertHeld();
4467
0
    }
4468
0
  }
4469
4470
  // Must be run only after options have been interpreted.
4471
  //
4472
  // NOTE: Validation code must only reference the options in the mutable
4473
  // descriptors, which are the ones that have been interpreted. The const
4474
  // proto references are passed in only so they can be provided to calls to
4475
  // AddError(). Do not look at their options, which have not been interpreted.
4476
  void ValidateOptions(const FileDescriptor* file,
4477
                       const FileDescriptorProto& proto);
4478
  void ValidateFileFeatures(const FileDescriptor* file,
4479
                            const FileDescriptorProto& proto);
4480
  void ValidateOptions(const Descriptor* message, const DescriptorProto& proto);
4481
  void ValidateOptions(const OneofDescriptor* oneof,
4482
                       const OneofDescriptorProto& proto);
4483
  void ValidateOptions(const FieldDescriptor* field,
4484
                       const FieldDescriptorProto& proto);
4485
  void ValidateFieldFeatures(const FieldDescriptor* field,
4486
                             const FieldDescriptorProto& proto);
4487
  void ValidateOptions(const EnumDescriptor* enm,
4488
                       const EnumDescriptorProto& proto);
4489
  void ValidateOptions(const EnumValueDescriptor* enum_value,
4490
                       const EnumValueDescriptorProto& proto);
4491
  void ValidateOptions(const Descriptor::ExtensionRange* range,
4492
0
                       const DescriptorProto::ExtensionRange& proto) {}
4493
  void ValidateExtensionRangeOptions(const DescriptorProto& proto,
4494
                                     const Descriptor& message);
4495
  void ValidateExtensionDeclaration(
4496
      const std::string& full_name,
4497
      const RepeatedPtrField<ExtensionRangeOptions_Declaration>& declarations,
4498
      const DescriptorProto_ExtensionRange& proto,
4499
      absl::flat_hash_set<absl::string_view>& full_name_set);
4500
  void ValidateOptions(const ServiceDescriptor* service,
4501
                       const ServiceDescriptorProto& proto);
4502
  void ValidateOptions(const MethodDescriptor* method,
4503
                       const MethodDescriptorProto& proto);
4504
  void ValidateProto3(const FileDescriptor* file,
4505
                      const FileDescriptorProto& proto);
4506
  void ValidateProto3Message(const Descriptor* message,
4507
                             const DescriptorProto& proto);
4508
  void ValidateProto3Field(const FieldDescriptor* field,
4509
                           const FieldDescriptorProto& proto);
4510
4511
  // Returns true if the map entry message is compatible with the
4512
  // auto-generated entry message from map fields syntax.
4513
  bool ValidateMapEntry(const FieldDescriptor* field,
4514
                        const FieldDescriptorProto& proto);
4515
4516
  // Recursively detects naming conflicts with map entry types for a
4517
  // better error message.
4518
  void DetectMapConflicts(const Descriptor* message,
4519
                          const DescriptorProto& proto);
4520
4521
  void ValidateJSType(const FieldDescriptor* field,
4522
                      const FieldDescriptorProto& proto);
4523
};
4524
4525
const FileDescriptor* DescriptorPool::BuildFile(
4526
0
    const FileDescriptorProto& proto) {
4527
0
  return BuildFileCollectingErrors(proto, nullptr);
4528
0
}
4529
4530
const FileDescriptor* DescriptorPool::BuildFileCollectingErrors(
4531
0
    const FileDescriptorProto& proto, ErrorCollector* error_collector) {
4532
0
  ABSL_CHECK(fallback_database_ == nullptr)
4533
0
      << "Cannot call BuildFile on a DescriptorPool that uses a "
4534
0
         "DescriptorDatabase.  You must instead find a way to get your file "
4535
0
         "into the underlying database.";
4536
0
  ABSL_CHECK(mutex_ == nullptr);  // Implied by the above ABSL_CHECK.
4537
0
  tables_->known_bad_symbols_.clear();
4538
0
  tables_->known_bad_files_.clear();
4539
0
  build_started_ = true;
4540
0
  return DescriptorBuilder::New(this, tables_.get(), error_collector)
4541
0
      ->BuildFile(proto);
4542
0
}
4543
4544
const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
4545
8
    const FileDescriptorProto& proto) const {
4546
8
  mutex_->AssertHeld();
4547
8
  build_started_ = true;
4548
8
  if (tables_->known_bad_files_.contains(proto.name())) {
4549
0
    return nullptr;
4550
0
  }
4551
8
  const FileDescriptor* result =
4552
8
      DescriptorBuilder::New(this, tables_.get(), default_error_collector_)
4553
8
          ->BuildFile(proto);
4554
8
  if (result == nullptr) {
4555
0
    tables_->known_bad_files_.insert(proto.name());
4556
0
  }
4557
8
  return result;
4558
8
}
4559
4560
0
void DescriptorPool::SetFeatureSetDefaults(FeatureSetDefaults spec) {
4561
0
  ABSL_CHECK(!build_started_)
4562
0
      << "Feature set defaults can't be changed once the pool has started "
4563
0
         "building.";
4564
0
  feature_set_defaults_spec_ =
4565
0
      absl::make_unique<FeatureSetDefaults>(std::move(spec));
4566
0
}
4567
4568
DescriptorBuilder::DescriptorBuilder(
4569
    const DescriptorPool* pool, DescriptorPool::Tables* tables,
4570
    DescriptorPool::ErrorCollector* error_collector)
4571
    : pool_(pool),
4572
      tables_(tables),
4573
      error_collector_(error_collector),
4574
      had_errors_(false),
4575
      possible_undeclared_dependency_(nullptr),
4576
8
      undefine_resolved_name_("") {
4577
  // Ensure that any lazily loaded static initializers from the generated pool
4578
  // (e.g. from bootstrapped protos) are run before building any descriptors. We
4579
  // have to avoid registering these pre-main, because we need to ensure that
4580
  // the linker --gc-sections step can strip out the full runtime if it is
4581
  // unused.
4582
8
  pb::cpp.LazyRegister();
4583
8
}
4584
4585
8
DescriptorBuilder::~DescriptorBuilder() {}
4586
4587
PROTOBUF_NOINLINE void DescriptorBuilder::AddError(
4588
    const std::string& element_name, const Message& descriptor,
4589
    DescriptorPool::ErrorCollector::ErrorLocation location,
4590
0
    absl::FunctionRef<std::string()> make_error) {
4591
0
  std::string error = make_error();
4592
0
  if (error_collector_ == nullptr) {
4593
0
    if (!had_errors_) {
4594
0
      ABSL_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_
4595
0
                      << "\":";
4596
0
    }
4597
0
    ABSL_LOG(ERROR) << "  " << element_name << ": " << error;
4598
0
  } else {
4599
0
    error_collector_->RecordError(filename_, element_name, &descriptor,
4600
0
                                  location, error);
4601
0
  }
4602
0
  had_errors_ = true;
4603
0
}
4604
4605
PROTOBUF_NOINLINE void DescriptorBuilder::AddError(
4606
    const std::string& element_name, const Message& descriptor,
4607
0
    DescriptorPool::ErrorCollector::ErrorLocation location, const char* error) {
4608
0
  AddError(element_name, descriptor, location, [error] { return error; });
4609
0
}
4610
4611
PROTOBUF_NOINLINE void DescriptorBuilder::AddNotDefinedError(
4612
    const std::string& element_name, const Message& descriptor,
4613
    DescriptorPool::ErrorCollector::ErrorLocation location,
4614
0
    const std::string& undefined_symbol) {
4615
0
  if (possible_undeclared_dependency_ == nullptr &&
4616
0
      undefine_resolved_name_.empty()) {
4617
0
    AddError(element_name, descriptor, location, [&] {
4618
0
      return absl::StrCat("\"", undefined_symbol, "\" is not defined.");
4619
0
    });
4620
0
  } else {
4621
0
    if (possible_undeclared_dependency_ != nullptr) {
4622
0
      AddError(element_name, descriptor, location, [&] {
4623
0
        return absl::StrCat("\"", possible_undeclared_dependency_name_,
4624
0
                            "\" seems to be defined in \"",
4625
0
                            possible_undeclared_dependency_->name(),
4626
0
                            "\", which is not "
4627
0
                            "imported by \"",
4628
0
                            filename_,
4629
0
                            "\".  To use it here, please "
4630
0
                            "add the necessary import.");
4631
0
      });
4632
0
    }
4633
0
    if (!undefine_resolved_name_.empty()) {
4634
0
      AddError(element_name, descriptor, location, [&] {
4635
0
        return absl::StrCat(
4636
0
            "\"", undefined_symbol, "\" is resolved to \"",
4637
0
            undefine_resolved_name_,
4638
0
            "\", which is not defined. "
4639
0
            "The innermost scope is searched first in name resolution. "
4640
0
            "Consider using a leading '.'(i.e., \".",
4641
0
            undefined_symbol, "\") to start from the outermost scope.");
4642
0
      });
4643
0
    }
4644
0
  }
4645
0
}
4646
4647
PROTOBUF_NOINLINE void DescriptorBuilder::AddWarning(
4648
    const std::string& element_name, const Message& descriptor,
4649
    DescriptorPool::ErrorCollector::ErrorLocation location,
4650
0
    absl::FunctionRef<std::string()> make_error) {
4651
0
  std::string error = make_error();
4652
0
  if (error_collector_ == nullptr) {
4653
0
    ABSL_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
4654
0
  } else {
4655
0
    error_collector_->RecordWarning(filename_, element_name, &descriptor,
4656
0
                                    location, error);
4657
0
  }
4658
0
}
4659
4660
PROTOBUF_NOINLINE void DescriptorBuilder::AddWarning(
4661
    const std::string& element_name, const Message& descriptor,
4662
0
    DescriptorPool::ErrorCollector::ErrorLocation location, const char* error) {
4663
0
  AddWarning(element_name, descriptor, location,
4664
0
             [error]() -> std::string { return error; });
4665
0
}
4666
4667
bool DescriptorBuilder::IsInPackage(const FileDescriptor* file,
4668
0
                                    absl::string_view package_name) {
4669
0
  return absl::StartsWith(file->package(), package_name) &&
4670
0
         (file->package().size() == package_name.size() ||
4671
0
          file->package()[package_name.size()] == '.');
4672
0
}
4673
4674
0
void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) {
4675
0
  if (file == nullptr || !dependencies_.insert(file).second) return;
4676
0
  for (int i = 0; file != nullptr && i < file->public_dependency_count(); i++) {
4677
0
    RecordPublicDependencies(file->public_dependency(i));
4678
0
  }
4679
0
}
4680
4681
Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper(
4682
182
    const DescriptorPool* pool, const std::string& name, bool build_it) {
4683
  // If we are looking at an underlay, we must lock its mutex_, since we are
4684
  // accessing the underlay's tables_ directly.
4685
182
  absl::MutexLockMaybe lock((pool == pool_) ? nullptr : pool->mutex_);
4686
4687
182
  Symbol result = pool->tables_->FindSymbol(name);
4688
182
  if (result.IsNull() && pool->underlay_ != nullptr) {
4689
    // Symbol not found; check the underlay.
4690
0
    result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name);
4691
0
  }
4692
4693
182
  if (result.IsNull()) {
4694
    // With lazily_build_dependencies_, a symbol lookup at cross link time is
4695
    // not guaranteed to be successful. In most cases, build_it will be false,
4696
    // which intentionally prevents us from building an import until it's
4697
    // actually needed. In some cases, like registering an extension, we want
4698
    // to build the file containing the symbol, and build_it will be set.
4699
    // Also, build_it will be true when !lazily_build_dependencies_, to provide
4700
    // better error reporting of missing dependencies.
4701
0
    if (build_it && pool->TryFindSymbolInFallbackDatabase(name)) {
4702
0
      result = pool->tables_->FindSymbol(name);
4703
0
    }
4704
0
  }
4705
4706
182
  return result;
4707
182
}
4708
4709
Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const std::string& name,
4710
182
                                                     bool build_it) {
4711
182
  Symbol result = FindSymbolNotEnforcingDepsHelper(pool_, name, build_it);
4712
  // Only find symbols which were defined in this file or one of its
4713
  // dependencies.
4714
182
  const FileDescriptor* file = result.GetFile();
4715
182
  if ((file == file_ || dependencies_.contains(file)) && !result.IsPackage()) {
4716
180
    unused_dependency_.erase(file);
4717
180
  }
4718
182
  return result;
4719
182
}
4720
4721
182
Symbol DescriptorBuilder::FindSymbol(const std::string& name, bool build_it) {
4722
182
  Symbol result = FindSymbolNotEnforcingDeps(name, build_it);
4723
4724
182
  if (result.IsNull()) return result;
4725
4726
182
  if (!pool_->enforce_dependencies_) {
4727
    // Hack for CompilerUpgrader, and also used for lazily_build_dependencies_
4728
182
    return result;
4729
182
  }
4730
4731
  // Only find symbols which were defined in this file or one of its
4732
  // dependencies.
4733
0
  const FileDescriptor* file = result.GetFile();
4734
0
  if (file == file_ || dependencies_.contains(file)) {
4735
0
    return result;
4736
0
  }
4737
4738
0
  if (result.IsPackage()) {
4739
    // Arg, this is overcomplicated.  The symbol is a package name.  It could
4740
    // be that the package was defined in multiple files.  result.GetFile()
4741
    // returns the first file we saw that used this package.  We've determined
4742
    // that that file is not a direct dependency of the file we are currently
4743
    // building, but it could be that some other file which *is* a direct
4744
    // dependency also defines the same package.  We can't really rule out this
4745
    // symbol unless none of the dependencies define it.
4746
0
    if (IsInPackage(file_, name)) return result;
4747
0
    for (const auto* dep : dependencies_) {
4748
      // Note:  A dependency may be nullptr if it was not found or had errors.
4749
0
      if (dep != nullptr && IsInPackage(dep, name)) return result;
4750
0
    }
4751
0
  }
4752
4753
0
  possible_undeclared_dependency_ = file;
4754
0
  possible_undeclared_dependency_name_ = name;
4755
0
  return Symbol();
4756
0
}
4757
4758
Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
4759
    const std::string& name, const std::string& relative_to,
4760
182
    ResolveMode resolve_mode, bool build_it) {
4761
182
  possible_undeclared_dependency_ = nullptr;
4762
182
  undefine_resolved_name_.clear();
4763
4764
182
  if (!name.empty() && name[0] == '.') {
4765
    // Fully-qualified name.
4766
172
    return FindSymbol(name.substr(1), build_it);
4767
172
  }
4768
4769
  // If name is something like "Foo.Bar.baz", and symbols named "Foo" are
4770
  // defined in multiple parent scopes, we only want to find "Bar.baz" in the
4771
  // innermost one.  E.g., the following should produce an error:
4772
  //   message Bar { message Baz {} }
4773
  //   message Foo {
4774
  //     message Bar {
4775
  //     }
4776
  //     optional Bar.Baz baz = 1;
4777
  //   }
4778
  // So, we look for just "Foo" first, then look for "Bar.baz" within it if
4779
  // found.
4780
10
  std::string::size_type name_dot_pos = name.find_first_of('.');
4781
10
  std::string first_part_of_name;
4782
10
  if (name_dot_pos == std::string::npos) {
4783
10
    first_part_of_name = name;
4784
10
  } else {
4785
0
    first_part_of_name = name.substr(0, name_dot_pos);
4786
0
  }
4787
4788
10
  std::string scope_to_try(relative_to);
4789
4790
10
  while (true) {
4791
    // Chop off the last component of the scope.
4792
10
    std::string::size_type dot_pos = scope_to_try.find_last_of('.');
4793
10
    if (dot_pos == std::string::npos) {
4794
0
      return FindSymbol(name, build_it);
4795
10
    } else {
4796
10
      scope_to_try.erase(dot_pos);
4797
10
    }
4798
4799
    // Append ".first_part_of_name" and try to find.
4800
10
    std::string::size_type old_size = scope_to_try.size();
4801
10
    scope_to_try.append(1, '.');
4802
10
    scope_to_try.append(first_part_of_name);
4803
10
    Symbol result = FindSymbol(scope_to_try, build_it);
4804
10
    if (!result.IsNull()) {
4805
10
      if (first_part_of_name.size() < name.size()) {
4806
        // name is a compound symbol, of which we only found the first part.
4807
        // Now try to look up the rest of it.
4808
0
        if (result.IsAggregate()) {
4809
0
          scope_to_try.append(name, first_part_of_name.size(),
4810
0
                              name.size() - first_part_of_name.size());
4811
0
          result = FindSymbol(scope_to_try, build_it);
4812
0
          if (result.IsNull()) {
4813
0
            undefine_resolved_name_ = scope_to_try;
4814
0
          }
4815
0
          return result;
4816
0
        } else {
4817
          // We found a symbol but it's not an aggregate.  Continue the loop.
4818
0
        }
4819
10
      } else {
4820
10
        if (resolve_mode == LOOKUP_TYPES && !result.IsType()) {
4821
          // We found a symbol but it's not a type.  Continue the loop.
4822
10
        } else {
4823
10
          return result;
4824
10
        }
4825
10
      }
4826
10
    }
4827
4828
    // Not found.  Remove the name so we can try again.
4829
0
    scope_to_try.erase(old_size);
4830
0
  }
4831
10
}
4832
4833
Symbol DescriptorBuilder::LookupSymbol(
4834
    const std::string& name, const std::string& relative_to,
4835
    DescriptorPool::PlaceholderType placeholder_type, ResolveMode resolve_mode,
4836
172
    bool build_it) {
4837
172
  Symbol result =
4838
172
      LookupSymbolNoPlaceholder(name, relative_to, resolve_mode, build_it);
4839
172
  if (result.IsNull() && pool_->allow_unknown_) {
4840
    // Not found, but AllowUnknownDependencies() is enabled.  Return a
4841
    // placeholder instead.
4842
0
    result = pool_->NewPlaceholderWithMutexHeld(name, placeholder_type);
4843
0
  }
4844
172
  return result;
4845
172
}
4846
4847
0
static bool ValidateQualifiedName(absl::string_view name) {
4848
0
  bool last_was_period = false;
4849
4850
0
  for (char character : name) {
4851
    // I don't trust isalnum() due to locales.  :(
4852
0
    if (('a' <= character && character <= 'z') ||
4853
0
        ('A' <= character && character <= 'Z') ||
4854
0
        ('0' <= character && character <= '9') || (character == '_')) {
4855
0
      last_was_period = false;
4856
0
    } else if (character == '.') {
4857
0
      if (last_was_period) return false;
4858
0
      last_was_period = true;
4859
0
    } else {
4860
0
      return false;
4861
0
    }
4862
0
  }
4863
4864
0
  return !name.empty() && !last_was_period;
4865
0
}
4866
4867
Symbol DescriptorPool::NewPlaceholder(absl::string_view name,
4868
0
                                      PlaceholderType placeholder_type) const {
4869
0
  absl::MutexLockMaybe lock(mutex_);
4870
0
  return NewPlaceholderWithMutexHeld(name, placeholder_type);
4871
0
}
4872
4873
Symbol DescriptorPool::NewPlaceholderWithMutexHeld(
4874
0
    absl::string_view name, PlaceholderType placeholder_type) const {
4875
0
  if (mutex_) {
4876
0
    mutex_->AssertHeld();
4877
0
  }
4878
  // Compute names.
4879
0
  absl::string_view placeholder_full_name;
4880
0
  absl::string_view placeholder_name;
4881
0
  const std::string* placeholder_package;
4882
4883
0
  if (!ValidateQualifiedName(name)) return Symbol();
4884
0
  if (name[0] == '.') {
4885
    // Fully-qualified.
4886
0
    placeholder_full_name = name.substr(1);
4887
0
  } else {
4888
0
    placeholder_full_name = name;
4889
0
  }
4890
4891
  // Create the placeholders.
4892
0
  internal::FlatAllocator alloc;
4893
0
  alloc.PlanArray<FileDescriptor>(1);
4894
0
  alloc.PlanArray<std::string>(2);
4895
0
  if (placeholder_type == PLACEHOLDER_ENUM) {
4896
0
    alloc.PlanArray<EnumDescriptor>(1);
4897
0
    alloc.PlanArray<EnumValueDescriptor>(1);
4898
0
    alloc.PlanArray<std::string>(2);  // names for the descriptor.
4899
0
    alloc.PlanArray<std::string>(2);  // names for the value.
4900
0
  } else {
4901
0
    alloc.PlanArray<Descriptor>(1);
4902
0
    alloc.PlanArray<std::string>(2);  // names for the descriptor.
4903
0
    if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
4904
0
      alloc.PlanArray<Descriptor::ExtensionRange>(1);
4905
0
    }
4906
0
  }
4907
0
  alloc.FinalizePlanning(tables_);
4908
4909
0
  const std::string::size_type dotpos = placeholder_full_name.find_last_of('.');
4910
0
  if (dotpos != std::string::npos) {
4911
0
    placeholder_package =
4912
0
        alloc.AllocateStrings(placeholder_full_name.substr(0, dotpos));
4913
0
    placeholder_name = placeholder_full_name.substr(dotpos + 1);
4914
0
  } else {
4915
0
    placeholder_package = alloc.AllocateStrings("");
4916
0
    placeholder_name = placeholder_full_name;
4917
0
  }
4918
4919
0
  FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld(
4920
0
      absl::StrCat(placeholder_full_name, ".placeholder.proto"), alloc);
4921
0
  placeholder_file->package_ = placeholder_package;
4922
4923
0
  if (placeholder_type == PLACEHOLDER_ENUM) {
4924
0
    placeholder_file->enum_type_count_ = 1;
4925
0
    placeholder_file->enum_types_ = alloc.AllocateArray<EnumDescriptor>(1);
4926
4927
0
    EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
4928
0
    memset(static_cast<void*>(placeholder_enum), 0, sizeof(*placeholder_enum));
4929
4930
0
    placeholder_enum->all_names_ =
4931
0
        alloc.AllocateStrings(placeholder_name, placeholder_full_name);
4932
0
    placeholder_enum->file_ = placeholder_file;
4933
0
    placeholder_enum->options_ = &EnumOptions::default_instance();
4934
0
    placeholder_enum->proto_features_ = &FeatureSet::default_instance();
4935
0
    placeholder_enum->merged_features_ = &FeatureSet::default_instance();
4936
0
    placeholder_enum->is_placeholder_ = true;
4937
0
    placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
4938
4939
    // Enums must have at least one value.
4940
0
    placeholder_enum->value_count_ = 1;
4941
0
    placeholder_enum->values_ = alloc.AllocateArray<EnumValueDescriptor>(1);
4942
    // Disable fast-path lookup for this enum.
4943
0
    placeholder_enum->sequential_value_limit_ = -1;
4944
4945
0
    EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
4946
0
    memset(static_cast<void*>(placeholder_value), 0,
4947
0
           sizeof(*placeholder_value));
4948
4949
    // Note that enum value names are siblings of their type, not children.
4950
0
    placeholder_value->all_names_ = alloc.AllocateStrings(
4951
0
        "PLACEHOLDER_VALUE",
4952
0
        placeholder_package->empty()
4953
0
            ? "PLACEHOLDER_VALUE"
4954
0
            : absl::StrCat(*placeholder_package, ".PLACEHOLDER_VALUE"));
4955
4956
0
    placeholder_value->number_ = 0;
4957
0
    placeholder_value->type_ = placeholder_enum;
4958
0
    placeholder_value->options_ = &EnumValueOptions::default_instance();
4959
4960
0
    return Symbol(placeholder_enum);
4961
0
  } else {
4962
0
    placeholder_file->message_type_count_ = 1;
4963
0
    placeholder_file->message_types_ = alloc.AllocateArray<Descriptor>(1);
4964
4965
0
    Descriptor* placeholder_message = &placeholder_file->message_types_[0];
4966
0
    memset(static_cast<void*>(placeholder_message), 0,
4967
0
           sizeof(*placeholder_message));
4968
4969
0
    placeholder_message->all_names_ =
4970
0
        alloc.AllocateStrings(placeholder_name, placeholder_full_name);
4971
0
    placeholder_message->file_ = placeholder_file;
4972
0
    placeholder_message->options_ = &MessageOptions::default_instance();
4973
0
    placeholder_message->proto_features_ = &FeatureSet::default_instance();
4974
0
    placeholder_message->merged_features_ = &FeatureSet::default_instance();
4975
0
    placeholder_message->is_placeholder_ = true;
4976
0
    placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
4977
4978
0
    if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
4979
0
      placeholder_message->extension_range_count_ = 1;
4980
0
      placeholder_message->extension_ranges_ =
4981
0
          alloc.AllocateArray<Descriptor::ExtensionRange>(1);
4982
0
      placeholder_message->extension_ranges_[0].start_ = 1;
4983
      // kMaxNumber + 1 because ExtensionRange::end is exclusive.
4984
0
      placeholder_message->extension_ranges_[0].end_ =
4985
0
          FieldDescriptor::kMaxNumber + 1;
4986
0
      placeholder_message->extension_ranges_[0].options_ = nullptr;
4987
0
      placeholder_message->extension_ranges_[0].proto_features_ =
4988
0
          &FeatureSet::default_instance();
4989
0
      placeholder_message->extension_ranges_[0].merged_features_ =
4990
0
          &FeatureSet::default_instance();
4991
0
    }
4992
4993
0
    return Symbol(placeholder_message);
4994
0
  }
4995
0
}
4996
4997
FileDescriptor* DescriptorPool::NewPlaceholderFile(
4998
0
    absl::string_view name) const {
4999
0
  absl::MutexLockMaybe lock(mutex_);
5000
0
  internal::FlatAllocator alloc;
5001
0
  alloc.PlanArray<FileDescriptor>(1);
5002
0
  alloc.PlanArray<std::string>(1);
5003
0
  alloc.FinalizePlanning(tables_);
5004
5005
0
  return NewPlaceholderFileWithMutexHeld(name, alloc);
5006
0
}
5007
5008
FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld(
5009
0
    absl::string_view name, internal::FlatAllocator& alloc) const {
5010
0
  if (mutex_) {
5011
0
    mutex_->AssertHeld();
5012
0
  }
5013
0
  FileDescriptor* placeholder = alloc.AllocateArray<FileDescriptor>(1);
5014
0
  memset(static_cast<void*>(placeholder), 0, sizeof(*placeholder));
5015
5016
0
  placeholder->name_ = alloc.AllocateStrings(name);
5017
0
  placeholder->package_ = &internal::GetEmptyString();
5018
0
  placeholder->pool_ = this;
5019
0
  placeholder->options_ = &FileOptions::default_instance();
5020
0
  placeholder->proto_features_ = &FeatureSet::default_instance();
5021
0
  placeholder->merged_features_ = &FeatureSet::default_instance();
5022
0
  placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance();
5023
0
  placeholder->source_code_info_ = &SourceCodeInfo::default_instance();
5024
0
  placeholder->is_placeholder_ = true;
5025
0
  placeholder->syntax_ = FileDescriptorLegacy::SYNTAX_UNKNOWN;
5026
0
  placeholder->finished_building_ = true;
5027
  // All other fields are zero or nullptr.
5028
5029
0
  return placeholder;
5030
0
}
5031
5032
bool DescriptorBuilder::AddSymbol(const std::string& full_name,
5033
                                  const void* parent, const std::string& name,
5034
680
                                  const Message& proto, Symbol symbol) {
5035
  // If the caller passed nullptr for the parent, the symbol is at file scope.
5036
  // Use its file as the parent instead.
5037
680
  if (parent == nullptr) parent = file_;
5038
5039
680
  if (absl::StrContains(full_name, '\0')) {
5040
0
    AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5041
0
      return absl::StrCat("\"", full_name, "\" contains null character.");
5042
0
    });
5043
0
    return false;
5044
0
  }
5045
680
  if (tables_->AddSymbol(full_name, symbol)) {
5046
680
    if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) {
5047
      // This is only possible if there was already an error adding something of
5048
      // the same name.
5049
0
      if (!had_errors_) {
5050
0
        ABSL_DLOG(FATAL) << "\"" << full_name
5051
0
                         << "\" not previously defined in "
5052
0
                            "symbols_by_name_, but was defined in "
5053
0
                            "symbols_by_parent_; this shouldn't be possible.";
5054
0
      }
5055
0
      return false;
5056
0
    }
5057
680
    return true;
5058
680
  } else {
5059
0
    const FileDescriptor* other_file = tables_->FindSymbol(full_name).GetFile();
5060
0
    if (other_file == file_) {
5061
0
      std::string::size_type dot_pos = full_name.find_last_of('.');
5062
0
      if (dot_pos == std::string::npos) {
5063
0
        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5064
0
          return absl::StrCat("\"", full_name, "\" is already defined.");
5065
0
        });
5066
0
      } else {
5067
0
        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5068
0
          return absl::StrCat("\"", full_name.substr(dot_pos + 1),
5069
0
                              "\" is already defined in \"",
5070
0
                              full_name.substr(0, dot_pos), "\".");
5071
0
        });
5072
0
      }
5073
0
    } else {
5074
      // Symbol seems to have been defined in a different file.
5075
0
      AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5076
0
        return absl::StrCat(
5077
0
            "\"", full_name, "\" is already defined in file \"",
5078
0
            (other_file == nullptr ? "null" : other_file->name()), "\".");
5079
0
      });
5080
0
    }
5081
0
    return false;
5082
0
  }
5083
680
}
5084
5085
void DescriptorBuilder::AddPackage(const std::string& name,
5086
12
                                   const Message& proto, FileDescriptor* file) {
5087
12
  if (name.find('\0') != std::string::npos) {
5088
0
    AddError(name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5089
0
      return absl::StrCat("\"", name, "\" contains null character.");
5090
0
    });
5091
0
    return;
5092
0
  }
5093
5094
12
  Symbol existing_symbol = tables_->FindSymbol(name);
5095
  // It's OK to redefine a package.
5096
12
  if (existing_symbol.IsNull()) {
5097
10
    if (name.data() == file->package().data()) {
5098
      // It is the toplevel package name, so insert the descriptor directly.
5099
6
      tables_->AddSymbol(file->package(), Symbol(file));
5100
6
    } else {
5101
4
      auto* package = tables_->Allocate<Symbol::Subpackage>();
5102
      // If the name is the package name, then it is already in the arena.
5103
      // If not, copy it there. It came from the call to AddPackage below.
5104
4
      package->name_size = static_cast<int>(name.size());
5105
4
      package->file = file;
5106
4
      tables_->AddSymbol(name, Symbol(package));
5107
4
    }
5108
    // Also add parent package, if any.
5109
10
    std::string::size_type dot_pos = name.find_last_of('.');
5110
10
    if (dot_pos == std::string::npos) {
5111
      // No parents.
5112
6
      ValidateSymbolName(name, name, proto);
5113
6
    } else {
5114
      // Has parent.
5115
4
      AddPackage(name.substr(0, dot_pos), proto, file);
5116
4
      ValidateSymbolName(name.substr(dot_pos + 1), name, proto);
5117
4
    }
5118
10
  } else if (!existing_symbol.IsPackage()) {
5119
    // Symbol seems to have been defined in a different file.
5120
0
    const FileDescriptor* other_file = existing_symbol.GetFile();
5121
0
    AddError(name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5122
0
      return absl::StrCat("\"", name,
5123
0
                          "\" is already defined (as something other than "
5124
0
                          "a package) in file \"",
5125
0
                          (other_file == nullptr ? "null" : other_file->name()),
5126
0
                          "\".");
5127
0
    });
5128
0
  }
5129
12
}
5130
5131
void DescriptorBuilder::ValidateSymbolName(const std::string& name,
5132
                                           const std::string& full_name,
5133
690
                                           const Message& proto) {
5134
690
  if (name.empty()) {
5135
0
    AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
5136
0
             "Missing name.");
5137
690
  } else {
5138
7.84k
    for (char character : name) {
5139
      // I don't trust isalnum() due to locales.  :(
5140
7.84k
      if ((character < 'a' || 'z' < character) &&
5141
7.84k
          (character < 'A' || 'Z' < character) &&
5142
7.84k
          (character < '0' || '9' < character) && (character != '_')) {
5143
0
        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
5144
0
          return absl::StrCat("\"", name, "\" is not a valid identifier.");
5145
0
        });
5146
0
        return;
5147
0
      }
5148
7.84k
    }
5149
690
  }
5150
690
}
5151
5152
// -------------------------------------------------------------------
5153
5154
// This generic implementation is good for all descriptors except
5155
// FileDescriptor.
5156
template <class DescriptorT>
5157
void DescriptorBuilder::AllocateOptions(
5158
    const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
5159
    int options_field_tag, absl::string_view option_name,
5160
704
    internal::FlatAllocator& alloc) {
5161
704
  std::vector<int> options_path;
5162
704
  descriptor->GetLocationPath(&options_path);
5163
704
  options_path.push_back(options_field_tag);
5164
704
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
704
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
704
      option_name, alloc);
5167
704
  descriptor->options_ = options;
5168
704
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
704
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
704
}
void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::Descriptor>(google::protobuf::Descriptor::Proto const&, google::protobuf::Descriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5160
88
    internal::FlatAllocator& alloc) {
5161
88
  std::vector<int> options_path;
5162
88
  descriptor->GetLocationPath(&options_path);
5163
88
  options_path.push_back(options_field_tag);
5164
88
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
88
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
88
      option_name, alloc);
5167
88
  descriptor->options_ = options;
5168
88
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
88
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
88
}
void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::FieldDescriptor>(google::protobuf::FieldDescriptor::Proto const&, google::protobuf::FieldDescriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5160
396
    internal::FlatAllocator& alloc) {
5161
396
  std::vector<int> options_path;
5162
396
  descriptor->GetLocationPath(&options_path);
5163
396
  options_path.push_back(options_field_tag);
5164
396
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
396
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
396
      option_name, alloc);
5167
396
  descriptor->options_ = options;
5168
396
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
396
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
396
}
void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::Descriptor::ExtensionRange>(google::protobuf::Descriptor::ExtensionRange::Proto const&, google::protobuf::Descriptor::ExtensionRange*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5160
24
    internal::FlatAllocator& alloc) {
5161
24
  std::vector<int> options_path;
5162
24
  descriptor->GetLocationPath(&options_path);
5163
24
  options_path.push_back(options_field_tag);
5164
24
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
24
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
24
      option_name, alloc);
5167
24
  descriptor->options_ = options;
5168
24
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
24
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
24
}
void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::OneofDescriptor>(google::protobuf::OneofDescriptor::Proto const&, google::protobuf::OneofDescriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5160
4
    internal::FlatAllocator& alloc) {
5161
4
  std::vector<int> options_path;
5162
4
  descriptor->GetLocationPath(&options_path);
5163
4
  options_path.push_back(options_field_tag);
5164
4
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
4
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
4
      option_name, alloc);
5167
4
  descriptor->options_ = options;
5168
4
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
4
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
4
}
void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::EnumDescriptor>(google::protobuf::EnumDescriptor::Proto const&, google::protobuf::EnumDescriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5160
34
    internal::FlatAllocator& alloc) {
5161
34
  std::vector<int> options_path;
5162
34
  descriptor->GetLocationPath(&options_path);
5163
34
  options_path.push_back(options_field_tag);
5164
34
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
34
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
34
      option_name, alloc);
5167
34
  descriptor->options_ = options;
5168
34
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
34
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
34
}
void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::EnumValueDescriptor>(google::protobuf::EnumValueDescriptor::Proto const&, google::protobuf::EnumValueDescriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5160
158
    internal::FlatAllocator& alloc) {
5161
158
  std::vector<int> options_path;
5162
158
  descriptor->GetLocationPath(&options_path);
5163
158
  options_path.push_back(options_field_tag);
5164
158
  auto options = AllocateOptionsImpl<DescriptorT>(
5165
158
      descriptor->full_name(), descriptor->full_name(), proto, options_path,
5166
158
      option_name, alloc);
5167
158
  descriptor->options_ = options;
5168
158
  descriptor->proto_features_ = &FeatureSet::default_instance();
5169
158
  descriptor->merged_features_ = &FeatureSet::default_instance();
5170
158
}
Unexecuted instantiation: void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::ServiceDescriptor>(google::protobuf::ServiceDescriptor::Proto const&, google::protobuf::ServiceDescriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Unexecuted instantiation: void google::protobuf::DescriptorBuilder::AllocateOptions<google::protobuf::MethodDescriptor>(google::protobuf::MethodDescriptor::Proto const&, google::protobuf::MethodDescriptor*, int, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
5171
5172
// We specialize for FileDescriptor.
5173
void DescriptorBuilder::AllocateOptions(const FileDescriptorProto& proto,
5174
                                        FileDescriptor* descriptor,
5175
8
                                        internal::FlatAllocator& alloc) {
5176
8
  std::vector<int> options_path;
5177
8
  options_path.push_back(FileDescriptorProto::kOptionsFieldNumber);
5178
  // We add the dummy token so that LookupSymbol does the right thing.
5179
8
  auto options = AllocateOptionsImpl<FileDescriptor>(
5180
8
      absl::StrCat(descriptor->package(), ".dummy"), descriptor->name(), proto,
5181
8
      options_path, "google.protobuf.FileOptions", alloc);
5182
8
  descriptor->options_ = options;
5183
8
  descriptor->proto_features_ = &FeatureSet::default_instance();
5184
8
  descriptor->merged_features_ = &FeatureSet::default_instance();
5185
8
}
5186
5187
template <class DescriptorT>
5188
typename DescriptorT::OptionsType* DescriptorBuilder::AllocateOptionsImpl(
5189
    absl::string_view name_scope, absl::string_view element_name,
5190
    const typename DescriptorT::Proto& proto,
5191
    absl::Span<const int> options_path, absl::string_view option_name,
5192
712
    internal::FlatAllocator& alloc) {
5193
712
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
680
    return nullptr;
5196
680
  }
5197
32
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
32
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
32
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
32
  const bool parse_success =
5209
32
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
32
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
32
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
32
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
32
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
32
  return options;
5243
32
}
google::protobuf::FileDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::FileDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::FileDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
8
    internal::FlatAllocator& alloc) {
5193
8
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
4
    return nullptr;
5196
4
  }
5197
4
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
4
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
4
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
4
  const bool parse_success =
5209
4
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
4
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
4
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
4
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
4
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
4
  return options;
5243
4
}
google::protobuf::Descriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::Descriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::Descriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
88
    internal::FlatAllocator& alloc) {
5193
88
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
88
    return nullptr;
5196
88
  }
5197
0
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
0
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
0
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
0
  const bool parse_success =
5209
0
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
0
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
0
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
0
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
0
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
0
  return options;
5243
0
}
google::protobuf::FieldDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::FieldDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::FieldDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
396
    internal::FlatAllocator& alloc) {
5193
396
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
368
    return nullptr;
5196
368
  }
5197
28
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
28
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
28
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
28
  const bool parse_success =
5209
28
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
28
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
28
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
28
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
28
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
28
  return options;
5243
28
}
google::protobuf::Descriptor::ExtensionRange::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::Descriptor::ExtensionRange>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::Descriptor::ExtensionRange::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
24
    internal::FlatAllocator& alloc) {
5193
24
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
24
    return nullptr;
5196
24
  }
5197
0
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
0
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
0
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
0
  const bool parse_success =
5209
0
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
0
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
0
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
0
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
0
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
0
  return options;
5243
0
}
google::protobuf::OneofDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::OneofDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::OneofDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
4
    internal::FlatAllocator& alloc) {
5193
4
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
4
    return nullptr;
5196
4
  }
5197
0
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
0
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
0
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
0
  const bool parse_success =
5209
0
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
0
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
0
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
0
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
0
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
0
  return options;
5243
0
}
google::protobuf::EnumDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::EnumDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::EnumDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
34
    internal::FlatAllocator& alloc) {
5193
34
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
34
    return nullptr;
5196
34
  }
5197
0
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
0
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
0
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
0
  const bool parse_success =
5209
0
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
0
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
0
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
0
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
0
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
0
  return options;
5243
0
}
google::protobuf::EnumValueDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::EnumValueDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::EnumValueDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5192
158
    internal::FlatAllocator& alloc) {
5193
158
  if (!proto.has_options()) {
5194
    // Set to default_instance later if necessary.
5195
158
    return nullptr;
5196
158
  }
5197
0
  const typename DescriptorT::OptionsType& orig_options = proto.options();
5198
5199
0
  auto* options = alloc.AllocateArray<typename DescriptorT::OptionsType>(1);
5200
5201
0
  if (!orig_options.IsInitialized()) {
5202
0
    AddError(absl::StrCat(name_scope, ".", element_name), orig_options,
5203
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
5204
0
             "Uninterpreted option is missing name or value.");
5205
0
    return nullptr;
5206
0
  }
5207
5208
0
  const bool parse_success =
5209
0
      internal::ParseNoReflection(orig_options.SerializeAsString(), *options);
5210
0
  ABSL_DCHECK(parse_success);
5211
5212
  // Don't add to options_to_interpret_ unless there were uninterpreted
5213
  // options.  This not only avoids unnecessary work, but prevents a
5214
  // bootstrapping problem when building descriptors for descriptor.proto.
5215
  // descriptor.proto does not contain any uninterpreted options, but
5216
  // attempting to interpret options anyway will cause
5217
  // OptionsType::GetDescriptor() to be called which may then deadlock since
5218
  // we're still trying to build it.
5219
0
  if (options->uninterpreted_option_size() > 0) {
5220
0
    options_to_interpret_.push_back(OptionsToInterpret(
5221
0
        name_scope, element_name, options_path, &orig_options, options));
5222
0
  }
5223
5224
  // If the custom option is in unknown fields, no need to interpret it.
5225
  // Remove the dependency file from unused_dependency.
5226
0
  const UnknownFieldSet& unknown_fields = orig_options.unknown_fields();
5227
0
  if (!unknown_fields.empty()) {
5228
    // Can not use options->GetDescriptor() which may case deadlock.
5229
0
    Symbol msg_symbol = tables_->FindSymbol(option_name);
5230
0
    if (msg_symbol.type() == Symbol::MESSAGE) {
5231
0
      for (int i = 0; i < unknown_fields.field_count(); ++i) {
5232
0
        assert_mutex_held(pool_);
5233
0
        const FieldDescriptor* field =
5234
0
            pool_->InternalFindExtensionByNumberNoLock(
5235
0
                msg_symbol.descriptor(), unknown_fields.field(i).number());
5236
0
        if (field) {
5237
0
          unused_dependency_.erase(field->file());
5238
0
        }
5239
0
      }
5240
0
    }
5241
0
  }
5242
0
  return options;
5243
0
}
Unexecuted instantiation: google::protobuf::ServiceDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::ServiceDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::ServiceDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
Unexecuted instantiation: google::protobuf::MethodDescriptor::OptionsType* google::protobuf::DescriptorBuilder::AllocateOptionsImpl<google::protobuf::MethodDescriptor>(absl::lts_20230802::string_view, absl::lts_20230802::string_view, google::protobuf::MethodDescriptor::Proto const&, absl::lts_20230802::Span<int const>, absl::lts_20230802::string_view, google::protobuf::internal::FlatAllocator&)
5244
5245
template <class ProtoT, class OptionsT>
5246
static void InferLegacyProtoFeatures(const ProtoT& proto,
5247
                                     const OptionsT& options,
5248
                                     FileDescriptorLegacy::Syntax syntax,
5249
316
                                     FeatureSet& features) {}
descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::FileDescriptorProto, google::protobuf::FileOptions>(google::protobuf::FileDescriptorProto const&, google::protobuf::FileOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Line
Count
Source
5249
8
                                     FeatureSet& features) {}
descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::DescriptorProto, google::protobuf::MessageOptions>(google::protobuf::DescriptorProto const&, google::protobuf::MessageOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Line
Count
Source
5249
88
                                     FeatureSet& features) {}
descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::OneofDescriptorProto, google::protobuf::OneofOptions>(google::protobuf::OneofDescriptorProto const&, google::protobuf::OneofOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Line
Count
Source
5249
4
                                     FeatureSet& features) {}
descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::DescriptorProto_ExtensionRange, google::protobuf::ExtensionRangeOptions>(google::protobuf::DescriptorProto_ExtensionRange const&, google::protobuf::ExtensionRangeOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Line
Count
Source
5249
24
                                     FeatureSet& features) {}
descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::EnumDescriptorProto, google::protobuf::EnumOptions>(google::protobuf::EnumDescriptorProto const&, google::protobuf::EnumOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Line
Count
Source
5249
34
                                     FeatureSet& features) {}
descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::EnumValueDescriptorProto, google::protobuf::EnumValueOptions>(google::protobuf::EnumValueDescriptorProto const&, google::protobuf::EnumValueOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Line
Count
Source
5249
158
                                     FeatureSet& features) {}
Unexecuted instantiation: descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::ServiceDescriptorProto, google::protobuf::ServiceOptions>(google::protobuf::ServiceDescriptorProto const&, google::protobuf::ServiceOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
Unexecuted instantiation: descriptor.cc:void google::protobuf::InferLegacyProtoFeatures<google::protobuf::MethodDescriptorProto, google::protobuf::MethodOptions>(google::protobuf::MethodDescriptorProto const&, google::protobuf::MethodOptions const&, google::protobuf::FileDescriptorLegacy::Syntax, google::protobuf::FeatureSet&)
5250
5251
static void InferLegacyProtoFeatures(const FieldDescriptorProto& proto,
5252
                                     const FieldOptions& options,
5253
                                     FileDescriptorLegacy::Syntax syntax,
5254
396
                                     FeatureSet& features) {
5255
396
  if (proto.label() == FieldDescriptorProto::LABEL_REQUIRED) {
5256
4
    features.set_field_presence(FeatureSet::LEGACY_REQUIRED);
5257
4
  }
5258
396
  if (proto.type() == FieldDescriptorProto::TYPE_GROUP) {
5259
0
    features.set_message_encoding(FeatureSet::DELIMITED);
5260
0
  }
5261
396
  if (options.packed()) {
5262
6
    features.set_repeated_field_encoding(FeatureSet::PACKED);
5263
6
  }
5264
396
  if (syntax == FileDescriptorLegacy::SYNTAX_PROTO3) {
5265
4
    if (options.has_packed() && !options.packed()) {
5266
0
      features.set_repeated_field_encoding(FeatureSet::EXPANDED);
5267
0
    }
5268
4
  }
5269
396
}
5270
5271
template <class DescriptorT>
5272
FileDescriptorLegacy::Syntax GetDescriptorSyntax(
5273
1.40k
    const DescriptorT* descriptor) {
5274
1.40k
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
1.40k
}
google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::Descriptor>(google::protobuf::Descriptor const*)
Line
Count
Source
5273
176
    const DescriptorT* descriptor) {
5274
176
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
176
}
google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::OneofDescriptor>(google::protobuf::OneofDescriptor const*)
Line
Count
Source
5273
8
    const DescriptorT* descriptor) {
5274
8
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
8
}
google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::Descriptor::ExtensionRange>(google::protobuf::Descriptor::ExtensionRange const*)
Line
Count
Source
5273
48
    const DescriptorT* descriptor) {
5274
48
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
48
}
google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::EnumDescriptor>(google::protobuf::EnumDescriptor const*)
Line
Count
Source
5273
68
    const DescriptorT* descriptor) {
5274
68
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
68
}
google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::EnumValueDescriptor>(google::protobuf::EnumValueDescriptor const*)
Line
Count
Source
5273
316
    const DescriptorT* descriptor) {
5274
316
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
316
}
google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::FieldDescriptor>(google::protobuf::FieldDescriptor const*)
Line
Count
Source
5273
792
    const DescriptorT* descriptor) {
5274
792
  return FileDescriptorLegacy(descriptor->file()).syntax();
5275
792
}
Unexecuted instantiation: google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::ServiceDescriptor>(google::protobuf::ServiceDescriptor const*)
Unexecuted instantiation: google::protobuf::FileDescriptorLegacy::Syntax google::protobuf::GetDescriptorSyntax<google::protobuf::MethodDescriptor>(google::protobuf::MethodDescriptor const*)
5276
5277
template <>
5278
FileDescriptorLegacy::Syntax GetDescriptorSyntax(
5279
16
    const FileDescriptor* descriptor) {
5280
16
  return FileDescriptorLegacy(descriptor).syntax();
5281
16
}
5282
5283
template <class DescriptorT>
5284
void DescriptorBuilder::ResolveFeaturesImpl(
5285
    const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
5286
    typename DescriptorT::OptionsType* options, internal::FlatAllocator& alloc,
5287
    DescriptorPool::ErrorCollector::ErrorLocation error_location,
5288
712
    bool force_merge) {
5289
712
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
712
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
712
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
712
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
712
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
712
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
712
  if (GetDescriptorSyntax(descriptor) !=
5307
712
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
712
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
712
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
712
                             base_features);
5314
712
  }
5315
5316
712
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
694
    descriptor->merged_features_ = &parent_features;
5319
694
    return;
5320
694
  }
5321
5322
  // Calculate the merged features for this target.
5323
18
  absl::StatusOr<FeatureSet> merged =
5324
18
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
18
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::FileDescriptor>(google::protobuf::FileDescriptor::Proto const&, google::protobuf::FileDescriptor*, google::protobuf::FileDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::Descriptor>(google::protobuf::Descriptor::Proto const&, google::protobuf::Descriptor*, google::protobuf::Descriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::OneofDescriptor>(google::protobuf::OneofDescriptor::Proto const&, google::protobuf::OneofDescriptor*, google::protobuf::OneofDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::Descriptor::ExtensionRange>(google::protobuf::Descriptor::ExtensionRange::Proto const&, google::protobuf::Descriptor::ExtensionRange*, google::protobuf::Descriptor::ExtensionRange::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::EnumDescriptor>(google::protobuf::EnumDescriptor::Proto const&, google::protobuf::EnumDescriptor*, google::protobuf::EnumDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::EnumValueDescriptor>(google::protobuf::EnumValueDescriptor::Proto const&, google::protobuf::EnumValueDescriptor*, google::protobuf::EnumValueDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::FieldDescriptor>(google::protobuf::FieldDescriptor::Proto const&, google::protobuf::FieldDescriptor*, google::protobuf::FieldDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::ServiceDescriptor>(google::protobuf::ServiceDescriptor::Proto const&, google::protobuf::ServiceDescriptor*, google::protobuf::ServiceDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
Unexecuted instantiation: google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::MethodDescriptor>(google::protobuf::MethodDescriptor::Proto const&, google::protobuf::MethodDescriptor*, google::protobuf::MethodDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)::{lambda()#1}::operator()() const
5328
0
    return;
5329
0
  }
5330
5331
18
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
18
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::FileDescriptor>(google::protobuf::FileDescriptor::Proto const&, google::protobuf::FileDescriptor*, google::protobuf::FileDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
8
    bool force_merge) {
5289
8
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
8
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
8
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
8
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
8
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
8
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
8
  if (GetDescriptorSyntax(descriptor) !=
5307
8
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
8
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
8
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
8
                             base_features);
5314
8
  }
5315
5316
8
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
0
    descriptor->merged_features_ = &parent_features;
5319
0
    return;
5320
0
  }
5321
5322
  // Calculate the merged features for this target.
5323
8
  absl::StatusOr<FeatureSet> merged =
5324
8
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
8
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
8
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
8
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::Descriptor>(google::protobuf::Descriptor::Proto const&, google::protobuf::Descriptor*, google::protobuf::Descriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
88
    bool force_merge) {
5289
88
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
88
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
88
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
88
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
88
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
88
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
88
  if (GetDescriptorSyntax(descriptor) !=
5307
88
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
88
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
88
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
88
                             base_features);
5314
88
  }
5315
5316
88
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
88
    descriptor->merged_features_ = &parent_features;
5319
88
    return;
5320
88
  }
5321
5322
  // Calculate the merged features for this target.
5323
0
  absl::StatusOr<FeatureSet> merged =
5324
0
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
0
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
0
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
0
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::OneofDescriptor>(google::protobuf::OneofDescriptor::Proto const&, google::protobuf::OneofDescriptor*, google::protobuf::OneofDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
4
    bool force_merge) {
5289
4
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
4
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
4
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
4
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
4
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
4
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
4
  if (GetDescriptorSyntax(descriptor) !=
5307
4
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
4
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
4
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
4
                             base_features);
5314
4
  }
5315
5316
4
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
4
    descriptor->merged_features_ = &parent_features;
5319
4
    return;
5320
4
  }
5321
5322
  // Calculate the merged features for this target.
5323
0
  absl::StatusOr<FeatureSet> merged =
5324
0
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
0
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
0
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
0
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::Descriptor::ExtensionRange>(google::protobuf::Descriptor::ExtensionRange::Proto const&, google::protobuf::Descriptor::ExtensionRange*, google::protobuf::Descriptor::ExtensionRange::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
24
    bool force_merge) {
5289
24
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
24
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
24
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
24
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
24
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
24
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
24
  if (GetDescriptorSyntax(descriptor) !=
5307
24
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
24
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
24
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
24
                             base_features);
5314
24
  }
5315
5316
24
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
24
    descriptor->merged_features_ = &parent_features;
5319
24
    return;
5320
24
  }
5321
5322
  // Calculate the merged features for this target.
5323
0
  absl::StatusOr<FeatureSet> merged =
5324
0
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
0
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
0
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
0
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::EnumDescriptor>(google::protobuf::EnumDescriptor::Proto const&, google::protobuf::EnumDescriptor*, google::protobuf::EnumDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
34
    bool force_merge) {
5289
34
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
34
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
34
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
34
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
34
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
34
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
34
  if (GetDescriptorSyntax(descriptor) !=
5307
34
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
34
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
34
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
34
                             base_features);
5314
34
  }
5315
5316
34
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
34
    descriptor->merged_features_ = &parent_features;
5319
34
    return;
5320
34
  }
5321
5322
  // Calculate the merged features for this target.
5323
0
  absl::StatusOr<FeatureSet> merged =
5324
0
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
0
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
0
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
0
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::EnumValueDescriptor>(google::protobuf::EnumValueDescriptor::Proto const&, google::protobuf::EnumValueDescriptor*, google::protobuf::EnumValueDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
158
    bool force_merge) {
5289
158
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
158
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
158
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
158
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
158
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
158
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
158
  if (GetDescriptorSyntax(descriptor) !=
5307
158
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
158
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
158
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
158
                             base_features);
5314
158
  }
5315
5316
158
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
158
    descriptor->merged_features_ = &parent_features;
5319
158
    return;
5320
158
  }
5321
5322
  // Calculate the merged features for this target.
5323
0
  absl::StatusOr<FeatureSet> merged =
5324
0
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
0
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
0
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
0
}
void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::FieldDescriptor>(google::protobuf::FieldDescriptor::Proto const&, google::protobuf::FieldDescriptor*, google::protobuf::FieldDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Line
Count
Source
5288
396
    bool force_merge) {
5289
396
  const FeatureSet& parent_features = GetParentFeatures(descriptor);
5290
396
  descriptor->proto_features_ = &FeatureSet::default_instance();
5291
396
  descriptor->merged_features_ = &FeatureSet::default_instance();
5292
5293
396
  ABSL_CHECK(feature_resolver_.has_value());
5294
5295
396
  if (options != nullptr && options->has_features()) {
5296
    // Remove the features from the child's options proto to avoid leaking
5297
    // internal details.
5298
0
    descriptor->proto_features_ =
5299
0
        tables_->InternFeatureSet(std::move(*options->mutable_features()));
5300
0
    options->clear_features();
5301
0
  }
5302
5303
396
  FeatureSet base_features = *descriptor->proto_features_;
5304
5305
  // Handle feature inference from proto2/proto3.
5306
396
  if (GetDescriptorSyntax(descriptor) !=
5307
396
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
5308
396
    if (descriptor->proto_features_ != &FeatureSet::default_instance()) {
5309
0
      AddError(descriptor->name(), proto, error_location,
5310
0
               "Features are only valid under editions.");
5311
0
    }
5312
396
    InferLegacyProtoFeatures(proto, *options, GetDescriptorSyntax(descriptor),
5313
396
                             base_features);
5314
396
  }
5315
5316
396
  if (base_features.ByteSizeLong() == 0 && !force_merge) {
5317
    // Nothing to merge, and we aren't forcing it.
5318
386
    descriptor->merged_features_ = &parent_features;
5319
386
    return;
5320
386
  }
5321
5322
  // Calculate the merged features for this target.
5323
10
  absl::StatusOr<FeatureSet> merged =
5324
10
      feature_resolver_->MergeFeatures(parent_features, base_features);
5325
10
  if (!merged.ok()) {
5326
0
    AddError(descriptor->name(), proto, error_location,
5327
0
             [&] { return std::string(merged.status().message()); });
5328
0
    return;
5329
0
  }
5330
5331
10
  descriptor->merged_features_ = tables_->InternFeatureSet(*std::move(merged));
5332
10
}
Unexecuted instantiation: void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::ServiceDescriptor>(google::protobuf::ServiceDescriptor::Proto const&, google::protobuf::ServiceDescriptor*, google::protobuf::ServiceDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
Unexecuted instantiation: void google::protobuf::DescriptorBuilder::ResolveFeaturesImpl<google::protobuf::MethodDescriptor>(google::protobuf::MethodDescriptor::Proto const&, google::protobuf::MethodDescriptor*, google::protobuf::MethodDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&, google::protobuf::DescriptorPool::ErrorCollector::ErrorLocation, bool)
5333
5334
template <class DescriptorT>
5335
void DescriptorBuilder::ResolveFeatures(
5336
    const typename DescriptorT::Proto& proto, DescriptorT* descriptor,
5337
    typename DescriptorT::OptionsType* options,
5338
704
    internal::FlatAllocator& alloc) {
5339
704
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
704
                      DescriptorPool::ErrorCollector::NAME);
5341
704
}
void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::Descriptor>(google::protobuf::Descriptor::Proto const&, google::protobuf::Descriptor*, google::protobuf::Descriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5338
88
    internal::FlatAllocator& alloc) {
5339
88
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
88
                      DescriptorPool::ErrorCollector::NAME);
5341
88
}
void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::OneofDescriptor>(google::protobuf::OneofDescriptor::Proto const&, google::protobuf::OneofDescriptor*, google::protobuf::OneofDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5338
4
    internal::FlatAllocator& alloc) {
5339
4
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
4
                      DescriptorPool::ErrorCollector::NAME);
5341
4
}
void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::Descriptor::ExtensionRange>(google::protobuf::Descriptor::ExtensionRange::Proto const&, google::protobuf::Descriptor::ExtensionRange*, google::protobuf::Descriptor::ExtensionRange::OptionsType*, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5338
24
    internal::FlatAllocator& alloc) {
5339
24
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
24
                      DescriptorPool::ErrorCollector::NAME);
5341
24
}
void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::EnumDescriptor>(google::protobuf::EnumDescriptor::Proto const&, google::protobuf::EnumDescriptor*, google::protobuf::EnumDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5338
34
    internal::FlatAllocator& alloc) {
5339
34
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
34
                      DescriptorPool::ErrorCollector::NAME);
5341
34
}
void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::EnumValueDescriptor>(google::protobuf::EnumValueDescriptor::Proto const&, google::protobuf::EnumValueDescriptor*, google::protobuf::EnumValueDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5338
158
    internal::FlatAllocator& alloc) {
5339
158
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
158
                      DescriptorPool::ErrorCollector::NAME);
5341
158
}
void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::FieldDescriptor>(google::protobuf::FieldDescriptor::Proto const&, google::protobuf::FieldDescriptor*, google::protobuf::FieldDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
Line
Count
Source
5338
396
    internal::FlatAllocator& alloc) {
5339
396
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5340
396
                      DescriptorPool::ErrorCollector::NAME);
5341
396
}
Unexecuted instantiation: void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::ServiceDescriptor>(google::protobuf::ServiceDescriptor::Proto const&, google::protobuf::ServiceDescriptor*, google::protobuf::ServiceDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
Unexecuted instantiation: void google::protobuf::DescriptorBuilder::ResolveFeatures<google::protobuf::MethodDescriptor>(google::protobuf::MethodDescriptor::Proto const&, google::protobuf::MethodDescriptor*, google::protobuf::MethodDescriptor::OptionsType*, google::protobuf::internal::FlatAllocator&)
5342
5343
void DescriptorBuilder::ResolveFeatures(const FileDescriptorProto& proto,
5344
                                        FileDescriptor* descriptor,
5345
                                        FileOptions* options,
5346
8
                                        internal::FlatAllocator& alloc) {
5347
  // File descriptors always need their own merged feature set, even without
5348
  // any explicit features.
5349
8
  ResolveFeaturesImpl(proto, descriptor, options, alloc,
5350
8
                      DescriptorPool::ErrorCollector::EDITIONS,
5351
8
                      /*force_merge=*/true);
5352
8
}
5353
5354
396
void DescriptorBuilder::PostProcessFieldFeatures(FieldDescriptor& field) {
5355
  // TODO This can be replace by a runtime check in `is_required`
5356
  // once the `label` getter is hidden.
5357
396
  if (field.features().field_presence() == FeatureSet::LEGACY_REQUIRED &&
5358
396
      field.label_ == FieldDescriptor::LABEL_OPTIONAL) {
5359
0
    field.label_ = FieldDescriptor::LABEL_REQUIRED;
5360
0
  }
5361
  // TODO This can be replace by a runtime check of `is_delimited`
5362
  // once the `TYPE_GROUP` value is removed.
5363
396
  if (field.type_ == FieldDescriptor::TYPE_MESSAGE &&
5364
396
      field.features().message_encoding() == FeatureSet::DELIMITED) {
5365
0
    field.type_ = FieldDescriptor::TYPE_GROUP;
5366
0
  }
5367
396
}
5368
5369
// A common pattern:  We want to convert a repeated field in the descriptor
5370
// to an array of values, calling some method to build each value.
5371
#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT)               \
5372
716
  OUTPUT->NAME##_count_ = INPUT.NAME##_size();                         \
5373
716
  OUTPUT->NAME##s_ = alloc.AllocateArray<                              \
5374
716
      typename std::remove_pointer<decltype(OUTPUT->NAME##s_)>::type>( \
5375
716
      INPUT.NAME##_size());                                            \
5376
1.44k
  for (int i = 0; i < INPUT.NAME##_size(); i++) {                      \
5377
726
    METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i, alloc);        \
5378
726
  }
5379
5380
PROTOBUF_NOINLINE void DescriptorBuilder::AddRecursiveImportError(
5381
0
    const FileDescriptorProto& proto, int from_here) {
5382
0
  auto make_error = [&] {
5383
0
    std::string error_message("File recursively imports itself: ");
5384
0
    for (size_t i = from_here; i < tables_->pending_files_.size(); i++) {
5385
0
      error_message.append(tables_->pending_files_[i]);
5386
0
      error_message.append(" -> ");
5387
0
    }
5388
0
    error_message.append(proto.name());
5389
0
    return error_message;
5390
0
  };
5391
5392
0
  if (static_cast<size_t>(from_here) < tables_->pending_files_.size() - 1) {
5393
0
    AddError(tables_->pending_files_[from_here + 1], proto,
5394
0
             DescriptorPool::ErrorCollector::IMPORT, make_error);
5395
0
  } else {
5396
0
    AddError(proto.name(), proto, DescriptorPool::ErrorCollector::IMPORT,
5397
0
             make_error);
5398
0
  }
5399
0
}
5400
5401
void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto,
5402
0
                                            int index) {
5403
0
  AddError(proto.dependency(index), proto,
5404
0
           DescriptorPool::ErrorCollector::IMPORT, [&] {
5405
0
             return absl::StrCat("Import \"", proto.dependency(index),
5406
0
                                 "\" was listed twice.");
5407
0
           });
5408
0
}
5409
5410
void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto,
5411
0
                                       int index) {
5412
0
  auto make_error = [&] {
5413
0
    if (pool_->fallback_database_ == nullptr) {
5414
0
      return absl::StrCat("Import \"", proto.dependency(index),
5415
0
                          "\" has not been loaded.");
5416
0
    }
5417
0
    return absl::StrCat("Import \"", proto.dependency(index),
5418
0
                        "\" was not found or had errors.");
5419
0
  };
5420
0
  AddError(proto.dependency(index), proto,
5421
0
           DescriptorPool::ErrorCollector::IMPORT, make_error);
5422
0
}
5423
5424
PROTOBUF_NOINLINE static bool ExistingFileMatchesProto(
5425
0
    const FileDescriptor* existing_file, const FileDescriptorProto& proto) {
5426
0
  FileDescriptorProto existing_proto;
5427
0
  existing_file->CopyTo(&existing_proto);
5428
  // TODO: Remove it when CopyTo supports copying syntax params when
5429
  // syntax="proto2".
5430
0
  if (FileDescriptorLegacy(existing_file).syntax() ==
5431
0
          FileDescriptorLegacy::Syntax::SYNTAX_PROTO2 &&
5432
0
      proto.has_syntax()) {
5433
0
    existing_proto.set_syntax(FileDescriptorLegacy::SyntaxName(
5434
0
        FileDescriptorLegacy(existing_file).syntax()));
5435
0
  }
5436
5437
0
  return existing_proto.SerializeAsString() == proto.SerializeAsString();
5438
0
}
5439
5440
// These PlanAllocationSize functions will gather into the FlatAllocator all the
5441
// necessary memory allocations that BuildXXX functions below will do on the
5442
// Tables object.
5443
// They *must* be kept in sync. If we miss some PlanArray call we won't have
5444
// enough memory and will ABSL_CHECK-fail.
5445
static void PlanAllocationSize(
5446
    const RepeatedPtrField<EnumValueDescriptorProto>& values,
5447
34
    internal::FlatAllocator& alloc) {
5448
34
  alloc.PlanArray<EnumValueDescriptor>(values.size());
5449
34
  alloc.PlanArray<std::string>(2 * values.size());  // name + full_name
5450
158
  for (const auto& v : values) {
5451
158
    if (v.has_options()) alloc.PlanArray<EnumValueOptions>(1);
5452
158
  }
5453
34
}
5454
5455
static void PlanAllocationSize(
5456
    const RepeatedPtrField<EnumDescriptorProto>& enums,
5457
96
    internal::FlatAllocator& alloc) {
5458
96
  alloc.PlanArray<EnumDescriptor>(enums.size());
5459
96
  alloc.PlanArray<std::string>(2 * enums.size());  // name + full_name
5460
96
  for (const auto& e : enums) {
5461
34
    if (e.has_options()) alloc.PlanArray<EnumOptions>(1);
5462
34
    PlanAllocationSize(e.value(), alloc);
5463
34
    alloc.PlanArray<EnumDescriptor::ReservedRange>(e.reserved_range_size());
5464
34
    alloc.PlanArray<const std::string*>(e.reserved_name_size());
5465
34
    alloc.PlanArray<std::string>(e.reserved_name_size());
5466
34
  }
5467
96
}
5468
5469
static void PlanAllocationSize(
5470
    const RepeatedPtrField<OneofDescriptorProto>& oneofs,
5471
88
    internal::FlatAllocator& alloc) {
5472
88
  alloc.PlanArray<OneofDescriptor>(oneofs.size());
5473
88
  alloc.PlanArray<std::string>(2 * oneofs.size());  // name + full_name
5474
88
  for (const auto& oneof : oneofs) {
5475
4
    if (oneof.has_options()) alloc.PlanArray<OneofOptions>(1);
5476
4
  }
5477
88
}
5478
5479
static void PlanAllocationSize(
5480
    const RepeatedPtrField<FieldDescriptorProto>& fields,
5481
184
    internal::FlatAllocator& alloc) {
5482
184
  alloc.PlanArray<FieldDescriptor>(fields.size());
5483
396
  for (const auto& field : fields) {
5484
396
    if (field.has_options()) alloc.PlanArray<FieldOptions>(1);
5485
396
    alloc.PlanFieldNames(field.name(),
5486
396
                         field.has_json_name() ? &field.json_name() : nullptr);
5487
396
    if (field.has_default_value() && field.has_type() &&
5488
396
        (field.type() == FieldDescriptorProto::TYPE_STRING ||
5489
56
         field.type() == FieldDescriptorProto::TYPE_BYTES)) {
5490
      // For the default string value.
5491
0
      alloc.PlanArray<std::string>(1);
5492
0
    }
5493
396
  }
5494
184
}
5495
5496
static void PlanAllocationSize(
5497
    const RepeatedPtrField<DescriptorProto::ExtensionRange>& ranges,
5498
88
    internal::FlatAllocator& alloc) {
5499
88
  alloc.PlanArray<Descriptor::ExtensionRange>(ranges.size());
5500
88
  for (const auto& r : ranges) {
5501
24
    if (r.has_options()) alloc.PlanArray<ExtensionRangeOptions>(1);
5502
24
  }
5503
88
}
5504
5505
static void PlanAllocationSize(
5506
    const RepeatedPtrField<DescriptorProto>& messages,
5507
96
    internal::FlatAllocator& alloc) {
5508
96
  alloc.PlanArray<Descriptor>(messages.size());
5509
96
  alloc.PlanArray<std::string>(2 * messages.size());  // name + full_name
5510
5511
96
  for (const auto& message : messages) {
5512
88
    if (message.has_options()) alloc.PlanArray<MessageOptions>(1);
5513
88
    PlanAllocationSize(message.nested_type(), alloc);
5514
88
    PlanAllocationSize(message.field(), alloc);
5515
88
    PlanAllocationSize(message.extension(), alloc);
5516
88
    PlanAllocationSize(message.extension_range(), alloc);
5517
88
    alloc.PlanArray<Descriptor::ReservedRange>(message.reserved_range_size());
5518
88
    alloc.PlanArray<const std::string*>(message.reserved_name_size());
5519
88
    alloc.PlanArray<std::string>(message.reserved_name_size());
5520
88
    PlanAllocationSize(message.enum_type(), alloc);
5521
88
    PlanAllocationSize(message.oneof_decl(), alloc);
5522
88
  }
5523
96
}
5524
5525
static void PlanAllocationSize(
5526
    const RepeatedPtrField<MethodDescriptorProto>& methods,
5527
0
    internal::FlatAllocator& alloc) {
5528
0
  alloc.PlanArray<MethodDescriptor>(methods.size());
5529
0
  alloc.PlanArray<std::string>(2 * methods.size());  // name + full_name
5530
0
  for (const auto& m : methods) {
5531
0
    if (m.has_options()) alloc.PlanArray<MethodOptions>(1);
5532
0
  }
5533
0
}
5534
5535
static void PlanAllocationSize(
5536
    const RepeatedPtrField<ServiceDescriptorProto>& services,
5537
8
    internal::FlatAllocator& alloc) {
5538
8
  alloc.PlanArray<ServiceDescriptor>(services.size());
5539
8
  alloc.PlanArray<std::string>(2 * services.size());  // name + full_name
5540
8
  for (const auto& service : services) {
5541
0
    if (service.has_options()) alloc.PlanArray<ServiceOptions>(1);
5542
0
    PlanAllocationSize(service.method(), alloc);
5543
0
  }
5544
8
}
5545
5546
static void PlanAllocationSize(const FileDescriptorProto& proto,
5547
8
                               internal::FlatAllocator& alloc) {
5548
8
  alloc.PlanArray<FileDescriptor>(1);
5549
8
  alloc.PlanArray<FileDescriptorTables>(1);
5550
8
  alloc.PlanArray<std::string>(2);  // name + package
5551
8
  if (proto.has_options()) alloc.PlanArray<FileOptions>(1);
5552
8
  if (proto.has_source_code_info()) alloc.PlanArray<SourceCodeInfo>(1);
5553
5554
8
  PlanAllocationSize(proto.service(), alloc);
5555
8
  PlanAllocationSize(proto.message_type(), alloc);
5556
8
  PlanAllocationSize(proto.enum_type(), alloc);
5557
8
  PlanAllocationSize(proto.extension(), alloc);
5558
5559
8
  alloc.PlanArray<int>(proto.weak_dependency_size());
5560
8
  alloc.PlanArray<int>(proto.public_dependency_size());
5561
8
  alloc.PlanArray<const FileDescriptor*>(proto.dependency_size());
5562
8
}
5563
5564
const FileDescriptor* DescriptorBuilder::BuildFile(
5565
8
    const FileDescriptorProto& original_proto) {
5566
8
  filename_ = original_proto.name();
5567
5568
8
  const FileDescriptorProto& proto = original_proto;
5569
5570
  // Check if the file already exists and is identical to the one being built.
5571
  // Note:  This only works if the input is canonical -- that is, it
5572
  //   fully-qualifies all type names, has no UninterpretedOptions, etc.
5573
  //   This is fine, because this idempotency "feature" really only exists to
5574
  //   accommodate one hack in the proto1->proto2 migration layer.
5575
8
  const FileDescriptor* existing_file = tables_->FindFile(filename_);
5576
8
  if (existing_file != nullptr) {
5577
    // File already in pool.  Compare the existing one to the input.
5578
0
    if (ExistingFileMatchesProto(existing_file, proto)) {
5579
      // They're identical.  Return the existing descriptor.
5580
0
      return existing_file;
5581
0
    }
5582
5583
    // Not a match.  The error will be detected and handled later.
5584
0
  }
5585
5586
  // Check to see if this file is already on the pending files list.
5587
  // TODO:  Allow recursive imports?  It may not work with some
5588
  //   (most?) programming languages.  E.g., in C++, a forward declaration
5589
  //   of a type is not sufficient to allow it to be used even in a
5590
  //   generated header file due to inlining.  This could perhaps be
5591
  //   worked around using tricks involving inserting #include statements
5592
  //   mid-file, but that's pretty ugly, and I'm pretty sure there are
5593
  //   some languages out there that do not allow recursive dependencies
5594
  //   at all.
5595
8
  for (size_t i = 0; i < tables_->pending_files_.size(); i++) {
5596
0
    if (tables_->pending_files_[i] == proto.name()) {
5597
0
      AddRecursiveImportError(proto, i);
5598
0
      return nullptr;
5599
0
    }
5600
0
  }
5601
5602
8
  static const int kMaximumPackageLength = 511;
5603
8
  if (proto.package().size() > kMaximumPackageLength) {
5604
0
    AddError(proto.package(), proto, DescriptorPool::ErrorCollector::NAME,
5605
0
             "Package name is too long");
5606
0
    return nullptr;
5607
0
  }
5608
5609
  // If we have a fallback_database_, and we aren't doing lazy import building,
5610
  // attempt to load all dependencies now, before checkpointing tables_.  This
5611
  // avoids confusion with recursive checkpoints.
5612
8
  if (!pool_->lazily_build_dependencies_) {
5613
0
    if (pool_->fallback_database_ != nullptr) {
5614
0
      tables_->pending_files_.push_back(proto.name());
5615
0
      for (int i = 0; i < proto.dependency_size(); i++) {
5616
0
        if (tables_->FindFile(proto.dependency(i)) == nullptr &&
5617
0
            (pool_->underlay_ == nullptr ||
5618
0
             pool_->underlay_->FindFileByName(proto.dependency(i)) ==
5619
0
                 nullptr)) {
5620
          // We don't care what this returns since we'll find out below anyway.
5621
0
          pool_->TryFindFileInFallbackDatabase(proto.dependency(i));
5622
0
        }
5623
0
      }
5624
0
      tables_->pending_files_.pop_back();
5625
0
    }
5626
0
  }
5627
5628
  // Checkpoint the tables so that we can roll back if something goes wrong.
5629
8
  tables_->AddCheckpoint();
5630
5631
8
  auto alloc = absl::make_unique<internal::FlatAllocator>();
5632
8
  PlanAllocationSize(proto, *alloc);
5633
8
  alloc->FinalizePlanning(tables_);
5634
8
  FileDescriptor* result = BuildFileImpl(proto, *alloc);
5635
5636
8
  file_tables_->FinalizeTables();
5637
8
  if (result) {
5638
8
    tables_->ClearLastCheckpoint();
5639
8
    result->finished_building_ = true;
5640
8
    alloc->ExpectConsumed();
5641
8
  } else {
5642
0
    tables_->RollbackToLastCheckpoint();
5643
0
  }
5644
5645
8
  return result;
5646
8
}
5647
5648
FileDescriptor* DescriptorBuilder::BuildFileImpl(
5649
8
    const FileDescriptorProto& proto, internal::FlatAllocator& alloc) {
5650
8
  FileDescriptor* result = alloc.AllocateArray<FileDescriptor>(1);
5651
8
  file_ = result;
5652
5653
  // TODO: Report error when the syntax is empty after all the protos
5654
  // have added the syntax statement.
5655
8
  if (proto.syntax().empty() || proto.syntax() == "proto2") {
5656
6
    file_->syntax_ = FileDescriptorLegacy::SYNTAX_PROTO2;
5657
6
    file_->edition_ = Edition::EDITION_PROTO2;
5658
6
  } else if (proto.syntax() == "proto3") {
5659
2
    file_->syntax_ = FileDescriptorLegacy::SYNTAX_PROTO3;
5660
2
    file_->edition_ = Edition::EDITION_PROTO3;
5661
2
  } else if (proto.syntax() == "editions") {
5662
0
    file_->syntax_ = FileDescriptorLegacy::SYNTAX_EDITIONS;
5663
0
    file_->edition_ = proto.edition();
5664
0
  } else {
5665
0
    file_->syntax_ = FileDescriptorLegacy::SYNTAX_UNKNOWN;
5666
0
    file_->edition_ = Edition::EDITION_UNKNOWN;
5667
0
    AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, [&] {
5668
0
      return absl::StrCat("Unrecognized syntax: ", proto.syntax());
5669
0
    });
5670
0
  }
5671
5672
8
  const FeatureSetDefaults& defaults =
5673
8
      pool_->feature_set_defaults_spec_ == nullptr
5674
8
          ? GetCppFeatureSetDefaults()
5675
8
          : *pool_->feature_set_defaults_spec_;
5676
5677
8
  absl::StatusOr<FeatureResolver> feature_resolver =
5678
8
      FeatureResolver::Create(file_->edition_, defaults);
5679
8
  if (!feature_resolver.ok()) {
5680
0
    AddError(proto.name(), proto, DescriptorPool::ErrorCollector::EDITIONS,
5681
0
             [&] { return std::string(feature_resolver.status().message()); });
5682
8
  } else {
5683
8
    feature_resolver_.emplace(std::move(feature_resolver).value());
5684
8
  }
5685
5686
8
  result->is_placeholder_ = false;
5687
8
  result->finished_building_ = false;
5688
8
  SourceCodeInfo* info = nullptr;
5689
8
  if (proto.has_source_code_info()) {
5690
0
    info = alloc.AllocateArray<SourceCodeInfo>(1);
5691
0
    info->CopyFrom(proto.source_code_info());
5692
0
    result->source_code_info_ = info;
5693
8
  } else {
5694
8
    result->source_code_info_ = &SourceCodeInfo::default_instance();
5695
8
  }
5696
5697
8
  file_tables_ = alloc.AllocateArray<FileDescriptorTables>(1);
5698
8
  file_->tables_ = file_tables_;
5699
5700
8
  if (!proto.has_name()) {
5701
0
    AddError("", proto, DescriptorPool::ErrorCollector::OTHER,
5702
0
             "Missing field: FileDescriptorProto.name.");
5703
0
  }
5704
5705
8
  result->name_ = alloc.AllocateStrings(proto.name());
5706
8
  if (proto.has_package()) {
5707
8
    result->package_ = alloc.AllocateStrings(proto.package());
5708
8
  } else {
5709
    // We cannot rely on proto.package() returning a valid string if
5710
    // proto.has_package() is false, because we might be running at static
5711
    // initialization time, in which case default values have not yet been
5712
    // initialized.
5713
0
    result->package_ = alloc.AllocateStrings("");
5714
0
  }
5715
8
  result->pool_ = pool_;
5716
5717
8
  if (result->name().find('\0') != std::string::npos) {
5718
0
    AddError(result->name(), proto, DescriptorPool::ErrorCollector::NAME, [&] {
5719
0
      return absl::StrCat("\"", result->name(), "\" contains null character.");
5720
0
    });
5721
0
    return nullptr;
5722
0
  }
5723
5724
  // Add to tables.
5725
8
  if (!tables_->AddFile(result)) {
5726
0
    AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
5727
0
             "A file with this name is already in the pool.");
5728
    // Bail out early so that if this is actually the exact same file, we
5729
    // don't end up reporting that every single symbol is already defined.
5730
0
    return nullptr;
5731
0
  }
5732
8
  if (!result->package().empty()) {
5733
8
    if (std::count(result->package().begin(), result->package().end(), '.') >
5734
8
        kPackageLimit) {
5735
0
      AddError(result->package(), proto, DescriptorPool::ErrorCollector::NAME,
5736
0
               "Exceeds Maximum Package Depth");
5737
0
      return nullptr;
5738
0
    }
5739
8
    AddPackage(result->package(), proto, result);
5740
8
  }
5741
5742
  // Make sure all dependencies are loaded.
5743
8
  absl::flat_hash_set<absl::string_view> seen_dependencies;
5744
8
  result->dependency_count_ = proto.dependency_size();
5745
8
  result->dependencies_ =
5746
8
      alloc.AllocateArray<const FileDescriptor*>(proto.dependency_size());
5747
8
  result->dependencies_once_ = nullptr;
5748
8
  unused_dependency_.clear();
5749
8
  absl::flat_hash_set<int> weak_deps;
5750
8
  for (int i = 0; i < proto.weak_dependency_size(); ++i) {
5751
0
    weak_deps.insert(proto.weak_dependency(i));
5752
0
  }
5753
5754
8
  bool need_lazy_deps = false;
5755
10
  for (int i = 0; i < proto.dependency_size(); i++) {
5756
2
    if (!seen_dependencies.insert(proto.dependency(i)).second) {
5757
0
      AddTwiceListedError(proto, i);
5758
0
    }
5759
5760
2
    const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
5761
2
    if (dependency == nullptr && pool_->underlay_ != nullptr) {
5762
0
      dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
5763
0
    }
5764
5765
2
    if (dependency == result) {
5766
      // Recursive import.  dependency/result is not fully initialized, and it's
5767
      // dangerous to try to do anything with it.  The recursive import error
5768
      // will be detected and reported in DescriptorBuilder::BuildFile().
5769
0
      return nullptr;
5770
0
    }
5771
5772
2
    if (dependency == nullptr) {
5773
0
      if (!pool_->lazily_build_dependencies_) {
5774
0
        if (pool_->allow_unknown_ ||
5775
0
            (!pool_->enforce_weak_ && weak_deps.contains(i))) {
5776
0
          internal::FlatAllocator lazy_dep_alloc;
5777
0
          lazy_dep_alloc.PlanArray<FileDescriptor>(1);
5778
0
          lazy_dep_alloc.PlanArray<std::string>(1);
5779
0
          lazy_dep_alloc.FinalizePlanning(tables_);
5780
0
          dependency = pool_->NewPlaceholderFileWithMutexHeld(
5781
0
              proto.dependency(i), lazy_dep_alloc);
5782
0
        } else {
5783
0
          AddImportError(proto, i);
5784
0
        }
5785
0
      }
5786
2
    } else {
5787
      // Add to unused_dependency_ to track unused imported files.
5788
      // Note: do not track unused imported files for public import.
5789
2
      if (pool_->enforce_dependencies_ &&
5790
2
          (pool_->unused_import_track_files_.find(proto.name()) !=
5791
0
           pool_->unused_import_track_files_.end()) &&
5792
2
          (dependency->public_dependency_count() == 0)) {
5793
0
        unused_dependency_.insert(dependency);
5794
0
      }
5795
2
    }
5796
5797
2
    result->dependencies_[i] = dependency;
5798
2
    if (pool_->lazily_build_dependencies_ && !dependency) {
5799
0
      need_lazy_deps = true;
5800
0
    }
5801
2
  }
5802
8
  if (need_lazy_deps) {
5803
0
    int total_char_size = 0;
5804
0
    for (int i = 0; i < proto.dependency_size(); i++) {
5805
0
      if (result->dependencies_[i] == nullptr) {
5806
0
        total_char_size += static_cast<int>(proto.dependency(i).size());
5807
0
      }
5808
0
      ++total_char_size;  // For NUL char
5809
0
    }
5810
5811
0
    void* data = tables_->AllocateBytes(
5812
0
        static_cast<int>(sizeof(absl::once_flag)) + total_char_size);
5813
0
    result->dependencies_once_ = ::new (data) absl::once_flag{};
5814
0
    char* name_data = reinterpret_cast<char*>(result->dependencies_once_ + 1);
5815
5816
0
    for (int i = 0; i < proto.dependency_size(); i++) {
5817
0
      if (result->dependencies_[i] == nullptr) {
5818
0
        memcpy(name_data, proto.dependency(i).c_str(),
5819
0
               proto.dependency(i).size());
5820
0
        name_data += proto.dependency(i).size();
5821
0
      }
5822
0
      *name_data++ = '\0';
5823
0
    }
5824
0
  }
5825
5826
  // Check public dependencies.
5827
8
  int public_dependency_count = 0;
5828
8
  result->public_dependencies_ =
5829
8
      alloc.AllocateArray<int>(proto.public_dependency_size());
5830
8
  for (int i = 0; i < proto.public_dependency_size(); i++) {
5831
    // Only put valid public dependency indexes.
5832
0
    int index = proto.public_dependency(i);
5833
0
    if (index >= 0 && index < proto.dependency_size()) {
5834
0
      result->public_dependencies_[public_dependency_count++] = index;
5835
      // Do not track unused imported files for public import.
5836
      // Calling dependency(i) builds that file when doing lazy imports,
5837
      // need to avoid doing this. Unused dependency detection isn't done
5838
      // when building lazily, anyways.
5839
0
      if (!pool_->lazily_build_dependencies_) {
5840
0
        unused_dependency_.erase(result->dependency(index));
5841
0
      }
5842
0
    } else {
5843
0
      AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
5844
0
               "Invalid public dependency index.");
5845
0
    }
5846
0
  }
5847
8
  result->public_dependency_count_ = public_dependency_count;
5848
5849
  // Build dependency set
5850
8
  dependencies_.clear();
5851
  // We don't/can't do proper dependency error checking when
5852
  // lazily_build_dependencies_, and calling dependency(i) will force
5853
  // a dependency to be built, which we don't want.
5854
8
  if (!pool_->lazily_build_dependencies_) {
5855
0
    for (int i = 0; i < result->dependency_count(); i++) {
5856
0
      RecordPublicDependencies(result->dependency(i));
5857
0
    }
5858
0
  }
5859
5860
  // Check weak dependencies.
5861
8
  int weak_dependency_count = 0;
5862
8
  result->weak_dependencies_ =
5863
8
      alloc.AllocateArray<int>(proto.weak_dependency_size());
5864
8
  for (int i = 0; i < proto.weak_dependency_size(); i++) {
5865
0
    int index = proto.weak_dependency(i);
5866
0
    if (index >= 0 && index < proto.dependency_size()) {
5867
0
      result->weak_dependencies_[weak_dependency_count++] = index;
5868
0
    } else {
5869
0
      AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
5870
0
               "Invalid weak dependency index.");
5871
0
    }
5872
0
  }
5873
8
  result->weak_dependency_count_ = weak_dependency_count;
5874
5875
  // Convert children.
5876
8
  BUILD_ARRAY(proto, result, message_type, BuildMessage, nullptr);
5877
8
  BUILD_ARRAY(proto, result, enum_type, BuildEnum, nullptr);
5878
8
  BUILD_ARRAY(proto, result, service, BuildService, nullptr);
5879
8
  BUILD_ARRAY(proto, result, extension, BuildExtension, nullptr);
5880
5881
  // Copy options.
5882
8
  AllocateOptions(proto, result, alloc);
5883
5884
  // Note that the following steps must occur in exactly the specified order.
5885
5886
  // Cross-link.
5887
8
  CrossLinkFile(result, proto);
5888
5889
8
  if (!message_hints_.empty()) {
5890
0
    SuggestFieldNumbers(result, proto);
5891
0
  }
5892
5893
  // Interpret only the non-extension options first, including features and
5894
  // their extensions.  This has to be done in two passes, since option
5895
  // extensions defined in this file may have features attached to them.
5896
8
  if (!had_errors_) {
5897
8
    OptionInterpreter option_interpreter(this);
5898
8
    for (std::vector<OptionsToInterpret>::iterator iter =
5899
8
             options_to_interpret_.begin();
5900
8
         iter != options_to_interpret_.end(); ++iter) {
5901
0
      option_interpreter.InterpretNonExtensionOptions(&(*iter));
5902
0
    }
5903
    // Handle feature resolution.  This must occur after option interpretation,
5904
    // but before validation.
5905
8
    internal::VisitDescriptors(
5906
712
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
712
          using OptionsT =
5908
712
              typename std::remove_const<typename std::remove_pointer<
5909
712
                  decltype(descriptor.options_)>::type>::type;
5910
712
          using DescriptorT = typename std::remove_const<
5911
712
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
712
          ResolveFeatures(
5914
712
              proto, const_cast<DescriptorT*>(&descriptor),
5915
712
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
712
                  OptionsT*>(descriptor.options_),
5917
712
              alloc);
5918
712
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::FileDescriptor, google::protobuf::FileDescriptorProto>(google::protobuf::FileDescriptor const&, google::protobuf::FileDescriptorProto const&) const
Line
Count
Source
5906
8
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
8
          using OptionsT =
5908
8
              typename std::remove_const<typename std::remove_pointer<
5909
8
                  decltype(descriptor.options_)>::type>::type;
5910
8
          using DescriptorT = typename std::remove_const<
5911
8
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
8
          ResolveFeatures(
5914
8
              proto, const_cast<DescriptorT*>(&descriptor),
5915
8
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
8
                  OptionsT*>(descriptor.options_),
5917
8
              alloc);
5918
8
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::Descriptor, google::protobuf::DescriptorProto>(google::protobuf::Descriptor const&, google::protobuf::DescriptorProto const&) const
Line
Count
Source
5906
88
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
88
          using OptionsT =
5908
88
              typename std::remove_const<typename std::remove_pointer<
5909
88
                  decltype(descriptor.options_)>::type>::type;
5910
88
          using DescriptorT = typename std::remove_const<
5911
88
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
88
          ResolveFeatures(
5914
88
              proto, const_cast<DescriptorT*>(&descriptor),
5915
88
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
88
                  OptionsT*>(descriptor.options_),
5917
88
              alloc);
5918
88
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::OneofDescriptor, google::protobuf::OneofDescriptorProto>(google::protobuf::OneofDescriptor const&, google::protobuf::OneofDescriptorProto const&) const
Line
Count
Source
5906
4
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
4
          using OptionsT =
5908
4
              typename std::remove_const<typename std::remove_pointer<
5909
4
                  decltype(descriptor.options_)>::type>::type;
5910
4
          using DescriptorT = typename std::remove_const<
5911
4
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
4
          ResolveFeatures(
5914
4
              proto, const_cast<DescriptorT*>(&descriptor),
5915
4
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
4
                  OptionsT*>(descriptor.options_),
5917
4
              alloc);
5918
4
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::Descriptor::ExtensionRange, google::protobuf::DescriptorProto_ExtensionRange>(google::protobuf::Descriptor::ExtensionRange const&, google::protobuf::DescriptorProto_ExtensionRange const&) const
Line
Count
Source
5906
24
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
24
          using OptionsT =
5908
24
              typename std::remove_const<typename std::remove_pointer<
5909
24
                  decltype(descriptor.options_)>::type>::type;
5910
24
          using DescriptorT = typename std::remove_const<
5911
24
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
24
          ResolveFeatures(
5914
24
              proto, const_cast<DescriptorT*>(&descriptor),
5915
24
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
24
                  OptionsT*>(descriptor.options_),
5917
24
              alloc);
5918
24
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::EnumDescriptor, google::protobuf::EnumDescriptorProto>(google::protobuf::EnumDescriptor const&, google::protobuf::EnumDescriptorProto const&) const
Line
Count
Source
5906
34
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
34
          using OptionsT =
5908
34
              typename std::remove_const<typename std::remove_pointer<
5909
34
                  decltype(descriptor.options_)>::type>::type;
5910
34
          using DescriptorT = typename std::remove_const<
5911
34
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
34
          ResolveFeatures(
5914
34
              proto, const_cast<DescriptorT*>(&descriptor),
5915
34
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
34
                  OptionsT*>(descriptor.options_),
5917
34
              alloc);
5918
34
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::EnumValueDescriptor, google::protobuf::EnumValueDescriptorProto>(google::protobuf::EnumValueDescriptor const&, google::protobuf::EnumValueDescriptorProto const&) const
Line
Count
Source
5906
158
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
158
          using OptionsT =
5908
158
              typename std::remove_const<typename std::remove_pointer<
5909
158
                  decltype(descriptor.options_)>::type>::type;
5910
158
          using DescriptorT = typename std::remove_const<
5911
158
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
158
          ResolveFeatures(
5914
158
              proto, const_cast<DescriptorT*>(&descriptor),
5915
158
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
158
                  OptionsT*>(descriptor.options_),
5917
158
              alloc);
5918
158
        });
descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::FieldDescriptor, google::protobuf::FieldDescriptorProto>(google::protobuf::FieldDescriptor const&, google::protobuf::FieldDescriptorProto const&) const
Line
Count
Source
5906
396
        *result, proto, [&](const auto& descriptor, const auto& proto) {
5907
396
          using OptionsT =
5908
396
              typename std::remove_const<typename std::remove_pointer<
5909
396
                  decltype(descriptor.options_)>::type>::type;
5910
396
          using DescriptorT = typename std::remove_const<
5911
396
              typename std::remove_reference<decltype(descriptor)>::type>::type;
5912
5913
396
          ResolveFeatures(
5914
396
              proto, const_cast<DescriptorT*>(&descriptor),
5915
396
              const_cast<  // NOLINT(google3-runtime-proto-const-cast)
5916
396
                  OptionsT*>(descriptor.options_),
5917
396
              alloc);
5918
396
        });
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::ServiceDescriptor, google::protobuf::ServiceDescriptorProto>(google::protobuf::ServiceDescriptor const&, google::protobuf::ServiceDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_19::operator()<google::protobuf::MethodDescriptor, google::protobuf::MethodDescriptorProto>(google::protobuf::MethodDescriptor const&, google::protobuf::MethodDescriptorProto const&) const
5919
5920
    // Post-process cleanup for field features.
5921
396
    internal::VisitDescriptors(*result, [&](const FieldDescriptor& field) {
5922
396
      PostProcessFieldFeatures(const_cast<FieldDescriptor&>(field));
5923
396
    });
5924
5925
    // Interpret any remaining uninterpreted options gathered into
5926
    // options_to_interpret_ during descriptor building.  Cross-linking has made
5927
    // extension options known, so all interpretations should now succeed.
5928
8
    for (std::vector<OptionsToInterpret>::iterator iter =
5929
8
             options_to_interpret_.begin();
5930
8
         iter != options_to_interpret_.end(); ++iter) {
5931
0
      option_interpreter.InterpretOptionExtensions(&(*iter));
5932
0
    }
5933
8
    options_to_interpret_.clear();
5934
8
    if (info != nullptr) {
5935
0
      option_interpreter.UpdateSourceCodeInfo(info);
5936
0
    }
5937
8
  }
5938
5939
  // Validate options. See comments at InternalSetLazilyBuildDependencies about
5940
  // error checking and lazy import building.
5941
8
  if (!had_errors_ && !pool_->lazily_build_dependencies_) {
5942
0
    internal::VisitDescriptors(*result, proto,
5943
0
                               [&](const auto& descriptor, const auto& proto) {
5944
0
                                 ValidateOptions(&descriptor, proto);
5945
0
                               });
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::FileDescriptor, google::protobuf::FileDescriptorProto>(google::protobuf::FileDescriptor const&, google::protobuf::FileDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::Descriptor, google::protobuf::DescriptorProto>(google::protobuf::Descriptor const&, google::protobuf::DescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::OneofDescriptor, google::protobuf::OneofDescriptorProto>(google::protobuf::OneofDescriptor const&, google::protobuf::OneofDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::Descriptor::ExtensionRange, google::protobuf::DescriptorProto_ExtensionRange>(google::protobuf::Descriptor::ExtensionRange const&, google::protobuf::DescriptorProto_ExtensionRange const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::EnumDescriptor, google::protobuf::EnumDescriptorProto>(google::protobuf::EnumDescriptor const&, google::protobuf::EnumDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::EnumValueDescriptor, google::protobuf::EnumValueDescriptorProto>(google::protobuf::EnumValueDescriptor const&, google::protobuf::EnumValueDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::FieldDescriptor, google::protobuf::FieldDescriptorProto>(google::protobuf::FieldDescriptor const&, google::protobuf::FieldDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::ServiceDescriptor, google::protobuf::ServiceDescriptorProto>(google::protobuf::ServiceDescriptor const&, google::protobuf::ServiceDescriptorProto const&) const
Unexecuted instantiation: descriptor.cc:auto google::protobuf::DescriptorBuilder::BuildFileImpl(google::protobuf::FileDescriptorProto const&, google::protobuf::internal::FlatAllocator&)::$_21::operator()<google::protobuf::MethodDescriptor, google::protobuf::MethodDescriptorProto>(google::protobuf::MethodDescriptor const&, google::protobuf::MethodDescriptorProto const&) const
5946
0
  }
5947
5948
  // Additional naming conflict check for map entry types. Only need to check
5949
  // this if there are already errors.
5950
8
  if (had_errors_) {
5951
0
    for (int i = 0; i < proto.message_type_size(); ++i) {
5952
0
      DetectMapConflicts(result->message_type(i), proto.message_type(i));
5953
0
    }
5954
0
  }
5955
5956
5957
  // Again, see comments at InternalSetLazilyBuildDependencies about error
5958
  // checking. Also, don't log unused dependencies if there were previous
5959
  // errors, since the results might be inaccurate.
5960
8
  if (!had_errors_ && !unused_dependency_.empty() &&
5961
8
      !pool_->lazily_build_dependencies_) {
5962
0
    LogUnusedDependency(proto, result);
5963
0
  }
5964
5965
8
  if (had_errors_) {
5966
0
    return nullptr;
5967
8
  } else {
5968
8
    return result;
5969
8
  }
5970
8
}
5971
5972
5973
const std::string* DescriptorBuilder::AllocateNameStrings(
5974
    const std::string& scope, const std::string& proto_name,
5975
126
    internal::FlatAllocator& alloc) {
5976
126
  if (scope.empty()) {
5977
0
    return alloc.AllocateStrings(proto_name, proto_name);
5978
126
  } else {
5979
126
    return alloc.AllocateStrings(proto_name,
5980
126
                                 absl::StrCat(scope, ".", proto_name));
5981
126
  }
5982
126
}
5983
5984
namespace {
5985
5986
// Helper for BuildMessage below.
5987
struct IncrementWhenDestroyed {
5988
88
  ~IncrementWhenDestroyed() { ++to_increment; }
5989
  int& to_increment;
5990
};
5991
5992
}  // namespace
5993
5994
namespace {
5995
0
bool IsNonMessageType(absl::string_view type) {
5996
0
  static const auto* non_message_types =
5997
0
      new absl::flat_hash_set<absl::string_view>(
5998
0
          {"double", "float", "int64", "uint64", "int32", "fixed32", "fixed64",
5999
0
           "bool", "string", "bytes", "uint32", "enum", "sfixed32", "sfixed64",
6000
0
           "sint32", "sint64"});
6001
0
  return non_message_types->contains(type);
6002
0
}
6003
}  // namespace
6004
6005
6006
void DescriptorBuilder::BuildMessage(const DescriptorProto& proto,
6007
                                     const Descriptor* parent,
6008
                                     Descriptor* result,
6009
88
                                     internal::FlatAllocator& alloc) {
6010
88
  const std::string& scope =
6011
88
      (parent == nullptr) ? file_->package() : parent->full_name();
6012
88
  result->all_names_ = AllocateNameStrings(scope, proto.name(), alloc);
6013
88
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6014
6015
88
  result->file_ = file_;
6016
88
  result->containing_type_ = parent;
6017
88
  result->is_placeholder_ = false;
6018
88
  result->is_unqualified_placeholder_ = false;
6019
88
  result->well_known_type_ = Descriptor::WELLKNOWNTYPE_UNSPECIFIED;
6020
88
  result->options_ = nullptr;  // Set to default_instance later if necessary.
6021
6022
88
  auto it = pool_->tables_->well_known_types_.find(result->full_name());
6023
88
  if (it != pool_->tables_->well_known_types_.end()) {
6024
2
    result->well_known_type_ = it->second;
6025
2
  }
6026
6027
  // Calculate the continuous sequence of fields.
6028
  // These can be fast-path'd during lookup and don't need to be added to the
6029
  // tables.
6030
  // We use uint16_t to save space for sequential_field_limit_, so stop before
6031
  // overflowing it. Worst case, we are not taking full advantage on huge
6032
  // messages, but it is unlikely.
6033
88
  result->sequential_field_limit_ = 0;
6034
286
  for (int i = 0; i < std::numeric_limits<uint16_t>::max() &&
6035
286
                  i < proto.field_size() && proto.field(i).number() == i + 1;
6036
198
       ++i) {
6037
198
    result->sequential_field_limit_ = i + 1;
6038
198
  }
6039
6040
  // Build oneofs first so that fields and extension ranges can refer to them.
6041
88
  BUILD_ARRAY(proto, result, oneof_decl, BuildOneof, result);
6042
88
  BUILD_ARRAY(proto, result, field, BuildField, result);
6043
88
  BUILD_ARRAY(proto, result, enum_type, BuildEnum, result);
6044
88
  BUILD_ARRAY(proto, result, extension_range, BuildExtensionRange, result);
6045
88
  BUILD_ARRAY(proto, result, extension, BuildExtension, result);
6046
88
  BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result);
6047
6048
  // Before building submessages, check recursion limit.
6049
88
  --recursion_depth_;
6050
88
  IncrementWhenDestroyed revert{recursion_depth_};
6051
88
  if (recursion_depth_ <= 0) {
6052
0
    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::OTHER,
6053
0
             "Reached maximum recursion limit for nested messages.");
6054
0
    result->nested_types_ = nullptr;
6055
0
    result->nested_type_count_ = 0;
6056
0
    return;
6057
0
  }
6058
88
  BUILD_ARRAY(proto, result, nested_type, BuildMessage, result);
6059
6060
  // Copy reserved names.
6061
88
  int reserved_name_count = proto.reserved_name_size();
6062
88
  result->reserved_name_count_ = reserved_name_count;
6063
88
  result->reserved_names_ =
6064
88
      alloc.AllocateArray<const std::string*>(reserved_name_count);
6065
88
  for (int i = 0; i < reserved_name_count; ++i) {
6066
0
    result->reserved_names_[i] = alloc.AllocateStrings(proto.reserved_name(i));
6067
0
  }
6068
6069
  // Copy options.
6070
88
  AllocateOptions(proto, result, DescriptorProto::kOptionsFieldNumber,
6071
88
                  "google.protobuf.MessageOptions", alloc);
6072
6073
88
  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
6074
6075
110
  for (int i = 0; i < proto.reserved_range_size(); i++) {
6076
22
    const DescriptorProto_ReservedRange& range1 = proto.reserved_range(i);
6077
44
    for (int j = i + 1; j < proto.reserved_range_size(); j++) {
6078
22
      const DescriptorProto_ReservedRange& range2 = proto.reserved_range(j);
6079
22
      if (range1.end() > range2.start() && range2.end() > range1.start()) {
6080
0
        AddError(result->full_name(), proto.reserved_range(i),
6081
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6082
0
                   return absl::Substitute(
6083
0
                       "Reserved range $0 to $1 overlaps with "
6084
0
                       "already-defined range $2 to $3.",
6085
0
                       range2.start(), range2.end() - 1, range1.start(),
6086
0
                       range1.end() - 1);
6087
0
                 });
6088
0
      }
6089
22
    }
6090
22
  }
6091
6092
88
  absl::flat_hash_set<absl::string_view> reserved_name_set;
6093
88
  for (const std::string& name : proto.reserved_name()) {
6094
0
    if (!reserved_name_set.insert(name).second) {
6095
0
      AddError(name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
6096
0
        return absl::Substitute("Field name \"$0\" is reserved multiple times.",
6097
0
                                name);
6098
0
      });
6099
0
    }
6100
0
  }
6101
  // Check that fields aren't using reserved names or numbers and that they
6102
  // aren't using extension numbers.
6103
482
  for (int i = 0; i < result->field_count(); i++) {
6104
394
    const FieldDescriptor* field = result->field(i);
6105
558
    for (int j = 0; j < result->extension_range_count(); j++) {
6106
164
      const Descriptor::ExtensionRange* range = result->extension_range(j);
6107
164
      if (range->start_number() <= field->number() &&
6108
164
          field->number() < range->end_number()) {
6109
0
        message_hints_[result].RequestHintOnFieldNumbers(
6110
0
            proto.extension_range(j), DescriptorPool::ErrorCollector::NUMBER);
6111
0
        AddError(field->full_name(), proto.extension_range(j),
6112
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6113
0
                   return absl::Substitute(
6114
0
                       "Extension range $0 to $1 includes field \"$2\" ($3).",
6115
0
                       range->start_number(), range->end_number() - 1,
6116
0
                       field->name(), field->number());
6117
0
                 });
6118
0
      }
6119
164
    }
6120
592
    for (int j = 0; j < result->reserved_range_count(); j++) {
6121
198
      const Descriptor::ReservedRange* range = result->reserved_range(j);
6122
198
      if (range->start <= field->number() && field->number() < range->end) {
6123
0
        message_hints_[result].RequestHintOnFieldNumbers(
6124
0
            proto.reserved_range(j), DescriptorPool::ErrorCollector::NUMBER);
6125
0
        AddError(field->full_name(), proto.reserved_range(j),
6126
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6127
0
                   return absl::Substitute(
6128
0
                       "Field \"$0\" uses reserved number $1.", field->name(),
6129
0
                       field->number());
6130
0
                 });
6131
0
      }
6132
198
    }
6133
394
    if (reserved_name_set.contains(field->name())) {
6134
0
      AddError(field->full_name(), proto.field(i),
6135
0
               DescriptorPool::ErrorCollector::NAME, [&] {
6136
0
                 return absl::Substitute("Field name \"$0\" is reserved.",
6137
0
                                         field->name());
6138
0
               });
6139
0
    }
6140
394
  }
6141
6142
  // Check that extension ranges don't overlap and don't include
6143
  // reserved field numbers or names.
6144
112
  for (int i = 0; i < result->extension_range_count(); i++) {
6145
24
    const Descriptor::ExtensionRange* range1 = result->extension_range(i);
6146
48
    for (int j = 0; j < result->reserved_range_count(); j++) {
6147
24
      const Descriptor::ReservedRange* range2 = result->reserved_range(j);
6148
24
      if (range1->end_number() > range2->start &&
6149
24
          range2->end > range1->start_number()) {
6150
0
        AddError(result->full_name(), proto.extension_range(i),
6151
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6152
0
                   return absl::Substitute(
6153
0
                       "Extension range $0 to $1 overlaps with "
6154
0
                       "reserved range $2 to $3.",
6155
0
                       range1->start_number(), range1->end_number() - 1,
6156
0
                       range2->start, range2->end - 1);
6157
0
                 });
6158
0
      }
6159
24
    }
6160
30
    for (int j = i + 1; j < result->extension_range_count(); j++) {
6161
6
      const Descriptor::ExtensionRange* range2 = result->extension_range(j);
6162
6
      if (range1->end_number() > range2->start_number() &&
6163
6
          range2->end_number() > range1->start_number()) {
6164
0
        AddError(result->full_name(), proto.extension_range(i),
6165
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6166
0
                   return absl::Substitute(
6167
0
                       "Extension range $0 to $1 overlaps with "
6168
0
                       "already-defined range $2 to $3.",
6169
0
                       range2->start_number(), range2->end_number() - 1,
6170
0
                       range1->start_number(), range1->end_number() - 1);
6171
0
                 });
6172
0
      }
6173
6
    }
6174
24
  }
6175
88
}
6176
6177
void DescriptorBuilder::CheckFieldJsonNameUniqueness(
6178
0
    const DescriptorProto& proto, const Descriptor* result) {
6179
0
  FileDescriptorLegacy::Syntax syntax =
6180
0
      FileDescriptorLegacy(result->file()).syntax();
6181
0
  std::string message_name = result->full_name();
6182
0
  if (pool_->deprecated_legacy_json_field_conflicts_ ||
6183
0
      IsLegacyJsonFieldConflictEnabled(result->options())) {
6184
0
    if (syntax == FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) {
6185
      // Only check default JSON names for conflicts in proto3.  This is legacy
6186
      // behavior that will be removed in a later version.
6187
0
      CheckFieldJsonNameUniqueness(message_name, proto, result, syntax, false);
6188
0
    }
6189
0
  } else {
6190
    // Check both with and without taking json_name into consideration.  This is
6191
    // needed for field masks, which don't use json_name.
6192
0
    CheckFieldJsonNameUniqueness(message_name, proto, result, syntax, false);
6193
0
    CheckFieldJsonNameUniqueness(message_name, proto, result, syntax, true);
6194
0
  }
6195
0
}
6196
6197
namespace {
6198
// Helpers for function below
6199
6200
struct JsonNameDetails {
6201
  const FieldDescriptorProto* field;
6202
  std::string orig_name;
6203
  bool is_custom;
6204
};
6205
6206
JsonNameDetails GetJsonNameDetails(const FieldDescriptorProto* field,
6207
0
                                   bool use_custom) {
6208
0
  std::string default_json_name = ToJsonName(field->name());
6209
0
  if (use_custom && field->has_json_name() &&
6210
0
      field->json_name() != default_json_name) {
6211
0
    return {field, field->json_name(), true};
6212
0
  }
6213
0
  return {field, default_json_name, false};
6214
0
}
6215
6216
0
bool JsonNameLooksLikeExtension(std::string name) {
6217
0
  return !name.empty() && name.front() == '[' && name.back() == ']';
6218
0
}
6219
6220
}  // namespace
6221
6222
void DescriptorBuilder::CheckFieldJsonNameUniqueness(
6223
    const std::string& message_name, const DescriptorProto& message,
6224
    const Descriptor* descriptor, FileDescriptorLegacy::Syntax syntax,
6225
0
    bool use_custom_names) {
6226
0
  absl::flat_hash_map<std::string, JsonNameDetails> name_to_field;
6227
0
  for (const FieldDescriptorProto& field : message.field()) {
6228
0
    JsonNameDetails details = GetJsonNameDetails(&field, use_custom_names);
6229
0
    if (details.is_custom && JsonNameLooksLikeExtension(details.orig_name)) {
6230
0
      auto make_error = [&] {
6231
0
        return absl::StrFormat(
6232
0
            "The custom JSON name of field \"%s\" (\"%s\") is invalid: "
6233
0
            "JSON names may not start with '[' and end with ']'.",
6234
0
            field.name(), details.orig_name);
6235
0
      };
6236
0
      AddError(message_name, field, DescriptorPool::ErrorCollector::NAME,
6237
0
               make_error);
6238
0
      continue;
6239
0
    }
6240
0
    auto it_inserted = name_to_field.try_emplace(details.orig_name, details);
6241
0
    if (it_inserted.second) {
6242
0
      continue;
6243
0
    }
6244
0
    JsonNameDetails& match = it_inserted.first->second;
6245
0
    if (use_custom_names && !details.is_custom && !match.is_custom) {
6246
      // if this pass is considering custom JSON names, but neither of the
6247
      // names involved in the conflict are custom, don't bother with a
6248
      // message. That will have been reported from other pass (non-custom
6249
      // JSON names).
6250
0
      continue;
6251
0
    }
6252
0
    auto make_error = [&] {
6253
0
      absl::string_view this_type = details.is_custom ? "custom" : "default";
6254
0
      absl::string_view existing_type = match.is_custom ? "custom" : "default";
6255
      // If the matched name differs (which it can only differ in case), include
6256
      // it in the error message, for maximum clarity to user.
6257
0
      std::string name_suffix = "";
6258
0
      if (details.orig_name != match.orig_name) {
6259
0
        name_suffix = absl::StrCat(" (\"", match.orig_name, "\")");
6260
0
      }
6261
0
      return absl::StrFormat(
6262
0
          "The %s JSON name of field \"%s\" (\"%s\") conflicts "
6263
0
          "with the %s JSON name of field \"%s\"%s.",
6264
0
          this_type, field.name(), details.orig_name, existing_type,
6265
0
          match.field->name(), name_suffix);
6266
0
    };
6267
6268
0
    bool involves_default = !details.is_custom || !match.is_custom;
6269
0
    if (descriptor->features().json_format() ==
6270
0
            FeatureSet::LEGACY_BEST_EFFORT &&
6271
0
        involves_default) {
6272
      // TODO Upgrade this to an error once downstream protos
6273
      // have been fixed.
6274
0
      AddWarning(message_name, field, DescriptorPool::ErrorCollector::NAME,
6275
0
                 make_error);
6276
0
    } else {
6277
0
      AddError(message_name, field, DescriptorPool::ErrorCollector::NAME,
6278
0
               make_error);
6279
0
    }
6280
0
  }
6281
0
}
6282
6283
void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto,
6284
                                              Descriptor* parent,
6285
                                              FieldDescriptor* result,
6286
                                              bool is_extension,
6287
396
                                              internal::FlatAllocator& alloc) {
6288
396
  const std::string& scope =
6289
396
      (parent == nullptr) ? file_->package() : parent->full_name();
6290
6291
  // We allocate all names in a single array, and dedup them.
6292
  // We remember the indices for the potentially deduped values.
6293
396
  auto all_names = alloc.AllocateFieldNames(
6294
396
      proto.name(), scope,
6295
396
      proto.has_json_name() ? &proto.json_name() : nullptr);
6296
396
  result->all_names_ = all_names.array;
6297
396
  result->lowercase_name_index_ = all_names.lowercase_index;
6298
396
  result->camelcase_name_index_ = all_names.camelcase_index;
6299
396
  result->json_name_index_ = all_names.json_index;
6300
6301
396
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6302
6303
396
  result->file_ = file_;
6304
396
  result->number_ = proto.number();
6305
396
  result->is_extension_ = is_extension;
6306
396
  result->is_oneof_ = false;
6307
396
  result->proto3_optional_ = proto.proto3_optional();
6308
6309
396
  if (proto.proto3_optional() &&
6310
396
      FileDescriptorLegacy(file_).syntax() !=
6311
0
          FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) {
6312
0
    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
6313
0
             [&] {
6314
0
               return absl::StrCat(
6315
0
                   "The [proto3_optional=true] option may only be set on proto3"
6316
0
                   "fields, not ",
6317
0
                   result->full_name());
6318
0
             });
6319
0
  }
6320
6321
396
  result->has_json_name_ = proto.has_json_name();
6322
6323
  // Some compilers do not allow static_cast directly between two enum types,
6324
  // so we must cast to int first.
6325
396
  result->type_ = static_cast<FieldDescriptor::Type>(
6326
396
      absl::implicit_cast<int>(proto.type()));
6327
396
  result->label_ = static_cast<FieldDescriptor::Label>(
6328
396
      absl::implicit_cast<int>(proto.label()));
6329
6330
396
  if (result->label() == FieldDescriptor::LABEL_REQUIRED) {
6331
    // An extension cannot have a required field (b/13365836).
6332
4
    if (result->is_extension_) {
6333
0
      AddError(result->full_name(), proto,
6334
               // Error location `TYPE`: we would really like to indicate
6335
               // `LABEL`, but the `ErrorLocation` enum has no entry for this,
6336
               // and we don't necessarily know about all implementations of the
6337
               // `ErrorCollector` interface to extend them to handle the new
6338
               // error location type properly.
6339
0
               DescriptorPool::ErrorCollector::TYPE, [&] {
6340
0
                 return absl::StrCat("The extension ", result->full_name(),
6341
0
                                     " cannot be required.");
6342
0
               });
6343
0
    }
6344
4
  }
6345
6346
  // Some of these may be filled in when cross-linking.
6347
396
  result->containing_type_ = nullptr;
6348
396
  result->type_once_ = nullptr;
6349
396
  result->default_value_enum_ = nullptr;
6350
6351
396
  result->has_default_value_ = proto.has_default_value();
6352
396
  if (proto.has_default_value() && result->is_repeated()) {
6353
0
    AddError(result->full_name(), proto,
6354
0
             DescriptorPool::ErrorCollector::DEFAULT_VALUE,
6355
0
             "Repeated fields can't have default values.");
6356
0
  }
6357
6358
396
  if (proto.has_type()) {
6359
396
    if (proto.has_default_value()) {
6360
56
      char* end_pos = nullptr;
6361
56
      switch (result->cpp_type()) {
6362
0
        case FieldDescriptor::CPPTYPE_INT32:
6363
0
          result->default_value_int32_t_ =
6364
0
              std::strtol(proto.default_value().c_str(), &end_pos, 0);
6365
0
          break;
6366
0
        case FieldDescriptor::CPPTYPE_INT64:
6367
0
          static_assert(sizeof(int64_t) == sizeof(long long),
6368
0
                        "sizeof int64_t is not sizeof long long");
6369
0
          result->default_value_int64_t_ =
6370
0
              std::strtoll(proto.default_value().c_str(), &end_pos, 0);
6371
0
          break;
6372
0
        case FieldDescriptor::CPPTYPE_UINT32:
6373
0
          result->default_value_uint32_t_ =
6374
0
              std::strtoul(proto.default_value().c_str(), &end_pos, 0);
6375
0
          break;
6376
0
        case FieldDescriptor::CPPTYPE_UINT64:
6377
0
          static_assert(sizeof(uint64_t) == sizeof(unsigned long long),
6378
0
                        "sizeof uint64_t is not sizeof unsigned long long");
6379
0
          result->default_value_uint64_t_ =
6380
0
              std::strtoull(proto.default_value().c_str(), &end_pos, 0);
6381
0
          break;
6382
0
        case FieldDescriptor::CPPTYPE_FLOAT:
6383
0
          if (proto.default_value() == "inf") {
6384
0
            result->default_value_float_ =
6385
0
                std::numeric_limits<float>::infinity();
6386
0
          } else if (proto.default_value() == "-inf") {
6387
0
            result->default_value_float_ =
6388
0
                -std::numeric_limits<float>::infinity();
6389
0
          } else if (proto.default_value() == "nan") {
6390
0
            result->default_value_float_ =
6391
0
                std::numeric_limits<float>::quiet_NaN();
6392
0
          } else {
6393
0
            result->default_value_float_ = io::SafeDoubleToFloat(
6394
0
                io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos));
6395
0
          }
6396
0
          break;
6397
0
        case FieldDescriptor::CPPTYPE_DOUBLE:
6398
0
          if (proto.default_value() == "inf") {
6399
0
            result->default_value_double_ =
6400
0
                std::numeric_limits<double>::infinity();
6401
0
          } else if (proto.default_value() == "-inf") {
6402
0
            result->default_value_double_ =
6403
0
                -std::numeric_limits<double>::infinity();
6404
0
          } else if (proto.default_value() == "nan") {
6405
0
            result->default_value_double_ =
6406
0
                std::numeric_limits<double>::quiet_NaN();
6407
0
          } else {
6408
0
            result->default_value_double_ =
6409
0
                io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
6410
0
          }
6411
0
          break;
6412
46
        case FieldDescriptor::CPPTYPE_BOOL:
6413
46
          if (proto.default_value() == "true") {
6414
2
            result->default_value_bool_ = true;
6415
44
          } else if (proto.default_value() == "false") {
6416
44
            result->default_value_bool_ = false;
6417
44
          } else {
6418
0
            AddError(result->full_name(), proto,
6419
0
                     DescriptorPool::ErrorCollector::DEFAULT_VALUE,
6420
0
                     "Boolean default must be true or false.");
6421
0
          }
6422
46
          break;
6423
10
        case FieldDescriptor::CPPTYPE_ENUM:
6424
          // This will be filled in when cross-linking.
6425
10
          result->default_value_enum_ = nullptr;
6426
10
          break;
6427
0
        case FieldDescriptor::CPPTYPE_STRING:
6428
0
          if (result->type() == FieldDescriptor::TYPE_BYTES) {
6429
0
            std::string value;
6430
0
            if (absl::CUnescape(proto.default_value(), &value)) {
6431
0
              result->default_value_string_ = alloc.AllocateStrings(value);
6432
0
            } else {
6433
0
              AddError(result->full_name(), proto,
6434
0
                       DescriptorPool::ErrorCollector::DEFAULT_VALUE,
6435
0
                       "Invalid escaping in default value.");
6436
0
            }
6437
0
          } else {
6438
0
            result->default_value_string_ =
6439
0
                alloc.AllocateStrings(proto.default_value());
6440
0
          }
6441
0
          break;
6442
0
        case FieldDescriptor::CPPTYPE_MESSAGE:
6443
0
          AddError(result->full_name(), proto,
6444
0
                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
6445
0
                   "Messages can't have default values.");
6446
0
          result->has_default_value_ = false;
6447
0
          result->default_generated_instance_ = nullptr;
6448
0
          break;
6449
56
      }
6450
6451
56
      if (end_pos != nullptr) {
6452
        // end_pos is only set non-null by the parsers for numeric types,
6453
        // above. This checks that the default was non-empty and had no extra
6454
        // junk after the end of the number.
6455
0
        if (proto.default_value().empty() || *end_pos != '\0') {
6456
0
          AddError(result->full_name(), proto,
6457
0
                   DescriptorPool::ErrorCollector::DEFAULT_VALUE, [&] {
6458
0
                     return absl::StrCat("Couldn't parse default value \"",
6459
0
                                         proto.default_value(), "\".");
6460
0
                   });
6461
0
        }
6462
0
      }
6463
340
    } else {
6464
      // No explicit default value
6465
340
      switch (result->cpp_type()) {
6466
34
        case FieldDescriptor::CPPTYPE_INT32:
6467
34
          result->default_value_int32_t_ = 0;
6468
34
          break;
6469
2
        case FieldDescriptor::CPPTYPE_INT64:
6470
2
          result->default_value_int64_t_ = 0;
6471
2
          break;
6472
2
        case FieldDescriptor::CPPTYPE_UINT32:
6473
2
          result->default_value_uint32_t_ = 0;
6474
2
          break;
6475
2
        case FieldDescriptor::CPPTYPE_UINT64:
6476
2
          result->default_value_uint64_t_ = 0;
6477
2
          break;
6478
0
        case FieldDescriptor::CPPTYPE_FLOAT:
6479
0
          result->default_value_float_ = 0.0f;
6480
0
          break;
6481
2
        case FieldDescriptor::CPPTYPE_DOUBLE:
6482
2
          result->default_value_double_ = 0.0;
6483
2
          break;
6484
26
        case FieldDescriptor::CPPTYPE_BOOL:
6485
26
          result->default_value_bool_ = false;
6486
26
          break;
6487
32
        case FieldDescriptor::CPPTYPE_ENUM:
6488
          // This will be filled in when cross-linking.
6489
32
          result->default_value_enum_ = nullptr;
6490
32
          break;
6491
112
        case FieldDescriptor::CPPTYPE_STRING:
6492
112
          result->default_value_string_ = &internal::GetEmptyString();
6493
112
          break;
6494
128
        case FieldDescriptor::CPPTYPE_MESSAGE:
6495
128
          result->default_generated_instance_ = nullptr;
6496
128
          break;
6497
340
      }
6498
340
    }
6499
396
  }
6500
6501
396
  if (result->number() <= 0) {
6502
0
    message_hints_[parent].RequestHintOnFieldNumbers(
6503
0
        proto, DescriptorPool::ErrorCollector::NUMBER);
6504
0
    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6505
0
             "Field numbers must be positive integers.");
6506
396
  } else if (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
6507
    // Only validate that the number is within the valid field range if it is
6508
    // not an extension. Since extension numbers are validated with the
6509
    // extendee's valid set of extension numbers, and those are in turn
6510
    // validated against the max allowed number, the check is unnecessary for
6511
    // extension fields.
6512
    // This avoids cross-linking issues that arise when attempting to check if
6513
    // the extendee is a message_set_wire_format message, which has a higher max
6514
    // on extension numbers.
6515
0
    message_hints_[parent].RequestHintOnFieldNumbers(
6516
0
        proto, DescriptorPool::ErrorCollector::NUMBER);
6517
0
    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6518
0
             [&] {
6519
0
               return absl::Substitute(
6520
0
                   "Field numbers cannot be greater than $0.",
6521
0
                   FieldDescriptor::kMaxNumber);
6522
0
             });
6523
0
  }
6524
6525
396
  if (is_extension) {
6526
2
    if (!proto.has_extendee()) {
6527
0
      AddError(result->full_name(), proto,
6528
0
               DescriptorPool::ErrorCollector::EXTENDEE,
6529
0
               "FieldDescriptorProto.extendee not set for extension field.");
6530
0
    }
6531
6532
2
    result->scope_.extension_scope = parent;
6533
6534
2
    if (proto.has_oneof_index()) {
6535
0
      AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
6536
0
               "FieldDescriptorProto.oneof_index should not be set for "
6537
0
               "extensions.");
6538
0
    }
6539
394
  } else {
6540
394
    if (proto.has_extendee()) {
6541
0
      AddError(result->full_name(), proto,
6542
0
               DescriptorPool::ErrorCollector::EXTENDEE,
6543
0
               "FieldDescriptorProto.extendee set for non-extension field.");
6544
0
    }
6545
6546
394
    result->containing_type_ = parent;
6547
6548
394
    if (proto.has_oneof_index()) {
6549
14
      if (proto.oneof_index() < 0 ||
6550
14
          proto.oneof_index() >= parent->oneof_decl_count()) {
6551
0
        AddError(result->full_name(), proto,
6552
0
                 DescriptorPool::ErrorCollector::TYPE, [&] {
6553
0
                   return absl::Substitute(
6554
0
                       "FieldDescriptorProto.oneof_index $0 is "
6555
0
                       "out of range for type \"$1\".",
6556
0
                       proto.oneof_index(), parent->name());
6557
0
                 });
6558
14
      } else {
6559
14
        result->is_oneof_ = true;
6560
14
        result->scope_.containing_oneof =
6561
14
            parent->oneof_decl(proto.oneof_index());
6562
14
      }
6563
14
    }
6564
394
  }
6565
6566
  // Copy options.
6567
396
  AllocateOptions(proto, result, FieldDescriptorProto::kOptionsFieldNumber,
6568
396
                  "google.protobuf.FieldOptions", alloc);
6569
6570
396
  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
6571
396
}
6572
6573
void DescriptorBuilder::BuildExtensionRange(
6574
    const DescriptorProto::ExtensionRange& proto, const Descriptor* parent,
6575
24
    Descriptor::ExtensionRange* result, internal::FlatAllocator& alloc) {
6576
24
  result->start_ = proto.start();
6577
24
  result->end_ = proto.end();
6578
24
  result->containing_type_ = parent;
6579
6580
24
  if (result->start_number() <= 0) {
6581
0
    message_hints_[parent].RequestHintOnFieldNumbers(
6582
0
        proto, DescriptorPool::ErrorCollector::NUMBER, result->start_number(),
6583
0
        result->end_number());
6584
0
    AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6585
0
             "Extension numbers must be positive integers.");
6586
0
  }
6587
6588
  // Checking of the upper bound of the extension range is deferred until after
6589
  // options interpreting. This allows messages with message_set_wire_format to
6590
  // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
6591
  // numbers are actually used as int32s in the message_set_wire_format.
6592
6593
24
  if (result->start_number() >= result->end_number()) {
6594
0
    AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6595
0
             "Extension range end number must be greater than start number.");
6596
0
  }
6597
6598
  // Copy options
6599
24
  AllocateOptions(proto, result,
6600
24
                  DescriptorProto_ExtensionRange::kOptionsFieldNumber,
6601
24
                  "google.protobuf.ExtensionRangeOptions", alloc);
6602
24
}
6603
6604
void DescriptorBuilder::BuildReservedRange(
6605
    const DescriptorProto::ReservedRange& proto, const Descriptor* parent,
6606
22
    Descriptor::ReservedRange* result, internal::FlatAllocator&) {
6607
22
  result->start = proto.start();
6608
22
  result->end = proto.end();
6609
22
  if (result->start <= 0) {
6610
0
    message_hints_[parent].RequestHintOnFieldNumbers(
6611
0
        proto, DescriptorPool::ErrorCollector::NUMBER, result->start,
6612
0
        result->end);
6613
0
    AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6614
0
             "Reserved numbers must be positive integers.");
6615
0
  }
6616
22
  if (result->start >= result->end) {
6617
0
    AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6618
0
             "Reserved range end number must be greater than start number.");
6619
0
  }
6620
22
}
6621
6622
void DescriptorBuilder::BuildReservedRange(
6623
    const EnumDescriptorProto::EnumReservedRange& proto,
6624
    const EnumDescriptor* parent, EnumDescriptor::ReservedRange* result,
6625
0
    internal::FlatAllocator&) {
6626
0
  result->start = proto.start();
6627
0
  result->end = proto.end();
6628
6629
0
  if (result->start > result->end) {
6630
0
    AddError(parent->full_name(), proto, DescriptorPool::ErrorCollector::NUMBER,
6631
0
             "Reserved range end number must be greater than start number.");
6632
0
  }
6633
0
}
6634
6635
void DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto,
6636
                                   Descriptor* parent, OneofDescriptor* result,
6637
4
                                   internal::FlatAllocator& alloc) {
6638
4
  result->all_names_ =
6639
4
      AllocateNameStrings(parent->full_name(), proto.name(), alloc);
6640
4
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6641
6642
4
  result->containing_type_ = parent;
6643
6644
  // We need to fill these in later.
6645
4
  result->field_count_ = 0;
6646
4
  result->fields_ = nullptr;
6647
6648
  // Copy options.
6649
4
  AllocateOptions(proto, result, OneofDescriptorProto::kOptionsFieldNumber,
6650
4
                  "google.protobuf.OneofOptions", alloc);
6651
6652
4
  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
6653
4
}
6654
6655
void DescriptorBuilder::CheckEnumValueUniqueness(
6656
0
    const EnumDescriptorProto& proto, const EnumDescriptor* result) {
6657
6658
  // Check that enum labels are still unique when we remove the enum prefix from
6659
  // values that have it.
6660
  //
6661
  // This will fail for something like:
6662
  //
6663
  //   enum MyEnum {
6664
  //     MY_ENUM_FOO = 0;
6665
  //     FOO = 1;
6666
  //   }
6667
  //
6668
  // By enforcing this reasonable constraint, we allow code generators to strip
6669
  // the prefix and/or PascalCase it without creating conflicts.  This can lead
6670
  // to much nicer language-specific enums like:
6671
  //
6672
  //   enum NameType {
6673
  //     FirstName = 1,
6674
  //     LastName = 2,
6675
  //   }
6676
  //
6677
  // Instead of:
6678
  //
6679
  //   enum NameType {
6680
  //     NAME_TYPE_FIRST_NAME = 1,
6681
  //     NAME_TYPE_LAST_NAME = 2,
6682
  //   }
6683
0
  PrefixRemover remover(result->name());
6684
0
  absl::flat_hash_map<std::string, const EnumValueDescriptor*> values;
6685
0
  for (int i = 0; i < result->value_count(); i++) {
6686
0
    const EnumValueDescriptor* value = result->value(i);
6687
0
    std::string stripped =
6688
0
        EnumValueToPascalCase(remover.MaybeRemove(value->name()));
6689
0
    auto insert_result = values.try_emplace(stripped, value);
6690
0
    bool inserted = insert_result.second;
6691
6692
    // We don't throw the error if the two conflicting symbols are identical, or
6693
    // if they map to the same number.  In the former case, the normal symbol
6694
    // duplication error will fire so we don't need to (and its error message
6695
    // will make more sense). We allow the latter case so users can create
6696
    // aliases which add or remove the prefix (code generators that do prefix
6697
    // stripping should de-dup the labels in this case).
6698
0
    if (!inserted && insert_result.first->second->name() != value->name() &&
6699
0
        insert_result.first->second->number() != value->number()) {
6700
0
      auto make_error = [&] {
6701
0
        return absl::StrFormat(
6702
0
            "Enum name %s has the same name as %s if you ignore case and strip "
6703
0
            "out the enum name prefix (if any). (If you are using allow_alias, "
6704
0
            "please assign the same numeric value to both enums.)",
6705
0
            value->name(), insert_result.first->second->name());
6706
0
      };
6707
      // There are proto2 enums out there with conflicting names, so to preserve
6708
      // compatibility we issue only a warning for proto2.
6709
0
      if ((pool_->deprecated_legacy_json_field_conflicts_ ||
6710
0
           IsLegacyJsonFieldConflictEnabled(result->options())) &&
6711
0
          FileDescriptorLegacy(result->file()).syntax() ==
6712
0
              FileDescriptorLegacy::Syntax::SYNTAX_PROTO2) {
6713
0
        AddWarning(value->full_name(), proto.value(i),
6714
0
                   DescriptorPool::ErrorCollector::NAME, make_error);
6715
0
        continue;
6716
0
      }
6717
0
      AddError(value->full_name(), proto.value(i),
6718
0
               DescriptorPool::ErrorCollector::NAME, make_error);
6719
0
    }
6720
0
  }
6721
0
}
6722
6723
void DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto,
6724
                                  const Descriptor* parent,
6725
                                  EnumDescriptor* result,
6726
34
                                  internal::FlatAllocator& alloc) {
6727
34
  const std::string& scope =
6728
34
      (parent == nullptr) ? file_->package() : parent->full_name();
6729
6730
34
  result->all_names_ = AllocateNameStrings(scope, proto.name(), alloc);
6731
34
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6732
34
  result->file_ = file_;
6733
34
  result->containing_type_ = parent;
6734
34
  result->is_placeholder_ = false;
6735
34
  result->is_unqualified_placeholder_ = false;
6736
6737
34
  if (proto.value_size() == 0) {
6738
    // We cannot allow enums with no values because this would mean there
6739
    // would be no valid default value for fields of this type.
6740
0
    AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
6741
0
             "Enums must contain at least one value.");
6742
0
  }
6743
6744
  // Calculate the continuous sequence of the labels.
6745
  // These can be fast-path'd during lookup and don't need to be added to the
6746
  // tables.
6747
  // We use uint16_t to save space for sequential_value_limit_, so stop before
6748
  // overflowing it. Worst case, we are not taking full advantage on huge
6749
  // enums, but it is unlikely.
6750
34
  for (int i = 0;
6751
172
       i < std::numeric_limits<uint16_t>::max() && i < proto.value_size() &&
6752
       // We do the math in int64_t to avoid overflows.
6753
172
       proto.value(i).number() ==
6754
142
           static_cast<int64_t>(i) + proto.value(0).number();
6755
138
       ++i) {
6756
138
    result->sequential_value_limit_ = i;
6757
138
  }
6758
6759
34
  BUILD_ARRAY(proto, result, value, BuildEnumValue, result);
6760
34
  BUILD_ARRAY(proto, result, reserved_range, BuildReservedRange, result);
6761
6762
  // Copy reserved names.
6763
34
  int reserved_name_count = proto.reserved_name_size();
6764
34
  result->reserved_name_count_ = reserved_name_count;
6765
34
  result->reserved_names_ =
6766
34
      alloc.AllocateArray<const std::string*>(reserved_name_count);
6767
34
  for (int i = 0; i < reserved_name_count; ++i) {
6768
0
    result->reserved_names_[i] = alloc.AllocateStrings(proto.reserved_name(i));
6769
0
  }
6770
6771
  // Copy options.
6772
34
  AllocateOptions(proto, result, EnumDescriptorProto::kOptionsFieldNumber,
6773
34
                  "google.protobuf.EnumOptions", alloc);
6774
6775
34
  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
6776
6777
34
  for (int i = 0; i < proto.reserved_range_size(); i++) {
6778
0
    const EnumDescriptorProto_EnumReservedRange& range1 =
6779
0
        proto.reserved_range(i);
6780
0
    for (int j = i + 1; j < proto.reserved_range_size(); j++) {
6781
0
      const EnumDescriptorProto_EnumReservedRange& range2 =
6782
0
          proto.reserved_range(j);
6783
0
      if (range1.end() >= range2.start() && range2.end() >= range1.start()) {
6784
0
        AddError(result->full_name(), proto.reserved_range(i),
6785
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6786
0
                   return absl::Substitute(
6787
0
                       "Reserved range $0 to $1 overlaps with "
6788
0
                       "already-defined range $2 to $3.",
6789
0
                       range2.start(), range2.end(), range1.start(),
6790
0
                       range1.end());
6791
0
                 });
6792
0
      }
6793
0
    }
6794
0
  }
6795
6796
34
  absl::flat_hash_set<absl::string_view> reserved_name_set;
6797
34
  for (const std::string& name : proto.reserved_name()) {
6798
0
    if (!reserved_name_set.insert(name).second) {
6799
0
      AddError(name, proto, DescriptorPool::ErrorCollector::NAME, [&] {
6800
0
        return absl::Substitute("Enum value \"$0\" is reserved multiple times.",
6801
0
                                name);
6802
0
      });
6803
0
    }
6804
0
  }
6805
6806
192
  for (int i = 0; i < result->value_count(); i++) {
6807
158
    const EnumValueDescriptor* value = result->value(i);
6808
158
    for (int j = 0; j < result->reserved_range_count(); j++) {
6809
0
      const EnumDescriptor::ReservedRange* range = result->reserved_range(j);
6810
0
      if (range->start <= value->number() && value->number() <= range->end) {
6811
0
        AddError(value->full_name(), proto.reserved_range(j),
6812
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
6813
0
                   return absl::Substitute(
6814
0
                       "Enum value \"$0\" uses reserved number $1.",
6815
0
                       value->name(), value->number());
6816
0
                 });
6817
0
      }
6818
0
    }
6819
158
    if (reserved_name_set.contains(value->name())) {
6820
0
      AddError(value->full_name(), proto.value(i),
6821
0
               DescriptorPool::ErrorCollector::NAME, [&] {
6822
0
                 return absl::Substitute("Enum value \"$0\" is reserved.",
6823
0
                                         value->name());
6824
0
               });
6825
0
    }
6826
158
  }
6827
34
}
6828
6829
void DescriptorBuilder::BuildEnumValue(const EnumValueDescriptorProto& proto,
6830
                                       const EnumDescriptor* parent,
6831
                                       EnumValueDescriptor* result,
6832
158
                                       internal::FlatAllocator& alloc) {
6833
  // Note:  full_name for enum values is a sibling to the parent's name, not a
6834
  //   child of it.
6835
158
  std::string full_name;
6836
158
  size_t scope_len = parent->full_name().size() - parent->name().size();
6837
158
  full_name.reserve(scope_len + proto.name().size());
6838
158
  full_name.append(parent->full_name().data(), scope_len);
6839
158
  full_name.append(proto.name());
6840
6841
158
  result->all_names_ =
6842
158
      alloc.AllocateStrings(proto.name(), std::move(full_name));
6843
158
  result->number_ = proto.number();
6844
158
  result->type_ = parent;
6845
6846
158
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6847
6848
  // Copy options.
6849
158
  AllocateOptions(proto, result, EnumValueDescriptorProto::kOptionsFieldNumber,
6850
158
                  "google.protobuf.EnumValueOptions", alloc);
6851
6852
  // Again, enum values are weird because we makes them appear as siblings
6853
  // of the enum type instead of children of it.  So, we use
6854
  // parent->containing_type() as the value's parent.
6855
158
  bool added_to_outer_scope =
6856
158
      AddSymbol(result->full_name(), parent->containing_type(), result->name(),
6857
158
                proto, Symbol::EnumValue(result, 0));
6858
6859
  // However, we also want to be able to search for values within a single
6860
  // enum type, so we add it as a child of the enum type itself, too.
6861
  // Note:  This could fail, but if it does, the error has already been
6862
  //   reported by the above AddSymbol() call, so we ignore the return code.
6863
158
  bool added_to_inner_scope = file_tables_->AddAliasUnderParent(
6864
158
      parent, result->name(), Symbol::EnumValue(result, 1));
6865
6866
158
  if (added_to_inner_scope && !added_to_outer_scope) {
6867
    // This value did not conflict with any values defined in the same enum,
6868
    // but it did conflict with some other symbol defined in the enum type's
6869
    // scope.  Let's print an additional error to explain this.
6870
0
    std::string outer_scope;
6871
0
    if (parent->containing_type() == nullptr) {
6872
0
      outer_scope = file_->package();
6873
0
    } else {
6874
0
      outer_scope = parent->containing_type()->full_name();
6875
0
    }
6876
6877
0
    if (outer_scope.empty()) {
6878
0
      outer_scope = "the global scope";
6879
0
    } else {
6880
0
      outer_scope = absl::StrCat("\"", outer_scope, "\"");
6881
0
    }
6882
6883
0
    AddError(
6884
0
        result->full_name(), proto, DescriptorPool::ErrorCollector::NAME, [&] {
6885
0
          return absl::StrCat(
6886
0
              "Note that enum values use C++ scoping rules, meaning that "
6887
0
              "enum values are siblings of their type, not children of it.  "
6888
0
              "Therefore, \"",
6889
0
              result->name(), "\" must be unique within ", outer_scope,
6890
0
              ", not just within \"", parent->name(), "\".");
6891
0
        });
6892
0
  }
6893
6894
  // An enum is allowed to define two numbers that refer to the same value.
6895
  // FindValueByNumber() should return the first such value, so we simply
6896
  // ignore AddEnumValueByNumber()'s return code.
6897
158
  file_tables_->AddEnumValueByNumber(result);
6898
158
}
6899
6900
void DescriptorBuilder::BuildService(const ServiceDescriptorProto& proto,
6901
                                     const void* /* dummy */,
6902
                                     ServiceDescriptor* result,
6903
0
                                     internal::FlatAllocator& alloc) {
6904
0
  result->all_names_ =
6905
0
      AllocateNameStrings(file_->package(), proto.name(), alloc);
6906
0
  result->file_ = file_;
6907
0
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6908
6909
0
  BUILD_ARRAY(proto, result, method, BuildMethod, result);
6910
6911
  // Copy options.
6912
0
  AllocateOptions(proto, result, ServiceDescriptorProto::kOptionsFieldNumber,
6913
0
                  "google.protobuf.ServiceOptions", alloc);
6914
6915
0
  AddSymbol(result->full_name(), nullptr, result->name(), proto,
6916
0
            Symbol(result));
6917
0
}
6918
6919
void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto,
6920
                                    const ServiceDescriptor* parent,
6921
                                    MethodDescriptor* result,
6922
0
                                    internal::FlatAllocator& alloc) {
6923
0
  result->service_ = parent;
6924
0
  result->all_names_ =
6925
0
      AllocateNameStrings(parent->full_name(), proto.name(), alloc);
6926
6927
0
  ValidateSymbolName(proto.name(), result->full_name(), proto);
6928
6929
  // These will be filled in when cross-linking.
6930
0
  result->input_type_.Init();
6931
0
  result->output_type_.Init();
6932
6933
  // Copy options.
6934
0
  AllocateOptions(proto, result, MethodDescriptorProto::kOptionsFieldNumber,
6935
0
                  "google.protobuf.MethodOptions", alloc);
6936
6937
0
  result->client_streaming_ = proto.client_streaming();
6938
0
  result->server_streaming_ = proto.server_streaming();
6939
6940
0
  AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result));
6941
0
}
6942
6943
#undef BUILD_ARRAY
6944
6945
// -------------------------------------------------------------------
6946
6947
void DescriptorBuilder::CrossLinkFile(FileDescriptor* file,
6948
8
                                      const FileDescriptorProto& proto) {
6949
8
  if (file->options_ == nullptr) {
6950
4
    file->options_ = &FileOptions::default_instance();
6951
4
  }
6952
6953
78
  for (int i = 0; i < file->message_type_count(); i++) {
6954
70
    CrossLinkMessage(&file->message_types_[i], proto.message_type(i));
6955
70
  }
6956
6957
10
  for (int i = 0; i < file->extension_count(); i++) {
6958
2
    CrossLinkField(&file->extensions_[i], proto.extension(i));
6959
2
  }
6960
6961
10
  for (int i = 0; i < file->enum_type_count(); i++) {
6962
2
    CrossLinkEnum(&file->enum_types_[i], proto.enum_type(i));
6963
2
  }
6964
6965
8
  for (int i = 0; i < file->service_count(); i++) {
6966
0
    CrossLinkService(&file->services_[i], proto.service(i));
6967
0
  }
6968
8
}
6969
6970
void DescriptorBuilder::CrossLinkMessage(Descriptor* message,
6971
88
                                         const DescriptorProto& proto) {
6972
88
  if (message->options_ == nullptr) {
6973
88
    message->options_ = &MessageOptions::default_instance();
6974
88
  }
6975
6976
106
  for (int i = 0; i < message->nested_type_count(); i++) {
6977
18
    CrossLinkMessage(&message->nested_types_[i], proto.nested_type(i));
6978
18
  }
6979
6980
120
  for (int i = 0; i < message->enum_type_count(); i++) {
6981
32
    CrossLinkEnum(&message->enum_types_[i], proto.enum_type(i));
6982
32
  }
6983
6984
482
  for (int i = 0; i < message->field_count(); i++) {
6985
394
    CrossLinkField(&message->fields_[i], proto.field(i));
6986
394
  }
6987
6988
88
  for (int i = 0; i < message->extension_count(); i++) {
6989
0
    CrossLinkField(&message->extensions_[i], proto.extension(i));
6990
0
  }
6991
6992
112
  for (int i = 0; i < message->extension_range_count(); i++) {
6993
24
    CrossLinkExtensionRange(&message->extension_ranges_[i],
6994
24
                            proto.extension_range(i));
6995
24
  }
6996
6997
  // Set up field array for each oneof.
6998
6999
  // First count the number of fields per oneof.
7000
482
  for (int i = 0; i < message->field_count(); i++) {
7001
394
    const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
7002
394
    if (oneof_decl != nullptr) {
7003
      // Make sure fields belonging to the same oneof are defined consecutively.
7004
      // This enables optimizations in codegens and reflection libraries to
7005
      // skip fields in the oneof group, as only one of the field can be set.
7006
      // Note that field_count() returns how many fields in this oneof we have
7007
      // seen so far. field_count() > 0 guarantees that i > 0, so field(i-1) is
7008
      // safe.
7009
14
      if (oneof_decl->field_count() > 0 &&
7010
14
          message->field(i - 1)->containing_oneof() != oneof_decl) {
7011
0
        AddError(
7012
0
            absl::StrCat(message->full_name(), ".",
7013
0
                         message->field(i - 1)->name()),
7014
0
            proto.field(i - 1), DescriptorPool::ErrorCollector::TYPE, [&] {
7015
0
              return absl::Substitute(
7016
0
                  "Fields in the same oneof must be defined consecutively. "
7017
0
                  "\"$0\" cannot be defined before the completion of the "
7018
0
                  "\"$1\" oneof definition.",
7019
0
                  message->field(i - 1)->name(), oneof_decl->name());
7020
0
            });
7021
0
      }
7022
      // Must go through oneof_decls_ array to get a non-const version of the
7023
      // OneofDescriptor.
7024
14
      auto& out_oneof_decl = message->oneof_decls_[oneof_decl->index()];
7025
14
      if (out_oneof_decl.field_count_ == 0) {
7026
4
        out_oneof_decl.fields_ = message->field(i);
7027
4
      }
7028
7029
14
      if (!had_errors_) {
7030
        // Verify that they are contiguous.
7031
        // This is assumed by OneofDescriptor::field(i).
7032
        // But only if there are no errors.
7033
14
        ABSL_CHECK_EQ(out_oneof_decl.fields_ + out_oneof_decl.field_count_,
7034
14
                      message->field(i));
7035
14
      }
7036
14
      ++out_oneof_decl.field_count_;
7037
14
    }
7038
394
  }
7039
7040
  // Then verify the sizes.
7041
92
  for (int i = 0; i < message->oneof_decl_count(); i++) {
7042
4
    OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
7043
7044
4
    if (oneof_decl->field_count() == 0) {
7045
0
      AddError(absl::StrCat(message->full_name(), ".", oneof_decl->name()),
7046
0
               proto.oneof_decl(i), DescriptorPool::ErrorCollector::NAME,
7047
0
               "Oneof must have at least one field.");
7048
0
    }
7049
7050
4
    if (oneof_decl->options_ == nullptr) {
7051
4
      oneof_decl->options_ = &OneofOptions::default_instance();
7052
4
    }
7053
4
  }
7054
7055
482
  for (int i = 0; i < message->field_count(); i++) {
7056
394
    const FieldDescriptor* field = message->field(i);
7057
394
    if (field->proto3_optional_) {
7058
0
      if (!field->containing_oneof() ||
7059
0
          !OneofDescriptorLegacy(field->containing_oneof()).is_synthetic()) {
7060
0
        AddError(message->full_name(), proto.field(i),
7061
0
                 DescriptorPool::ErrorCollector::OTHER,
7062
0
                 "Fields with proto3_optional set must be "
7063
0
                 "a member of a one-field oneof");
7064
0
      }
7065
0
    }
7066
394
  }
7067
7068
  // Synthetic oneofs must be last.
7069
88
  int first_synthetic = -1;
7070
92
  for (int i = 0; i < message->oneof_decl_count(); i++) {
7071
4
    const OneofDescriptor* oneof = message->oneof_decl(i);
7072
4
    if (OneofDescriptorLegacy(oneof).is_synthetic()) {
7073
0
      if (first_synthetic == -1) {
7074
0
        first_synthetic = i;
7075
0
      }
7076
4
    } else {
7077
4
      if (first_synthetic != -1) {
7078
0
        AddError(message->full_name(), proto.oneof_decl(i),
7079
0
                 DescriptorPool::ErrorCollector::OTHER,
7080
0
                 "Synthetic oneofs must be after all other oneofs");
7081
0
      }
7082
4
    }
7083
4
  }
7084
7085
88
  if (first_synthetic == -1) {
7086
88
    message->real_oneof_decl_count_ = message->oneof_decl_count_;
7087
88
  } else {
7088
0
    message->real_oneof_decl_count_ = first_synthetic;
7089
0
  }
7090
88
}
7091
7092
void DescriptorBuilder::CrossLinkExtensionRange(
7093
    Descriptor::ExtensionRange* range,
7094
24
    const DescriptorProto::ExtensionRange& /*proto*/) {
7095
24
  if (range->options_ == nullptr) {
7096
24
    range->options_ = &ExtensionRangeOptions::default_instance();
7097
24
  }
7098
24
}
7099
7100
void DescriptorBuilder::CheckExtensionDeclarationFieldType(
7101
    const FieldDescriptor& field, const FieldDescriptorProto& proto,
7102
0
    absl::string_view type) {
7103
0
  if (had_errors_) return;
7104
0
  std::string actual_type = field.type_name();
7105
0
  std::string expected_type(type);
7106
0
  if (field.message_type() || field.enum_type()) {
7107
    // Field message type descriptor can be in a partial state which will cause
7108
    // segmentation fault if it is being accessed.
7109
0
    if (had_errors_) return;
7110
0
    absl::string_view full_name = field.message_type() != nullptr
7111
0
                                      ? field.message_type()->full_name()
7112
0
                                      : field.enum_type()->full_name();
7113
0
    actual_type = absl::StrCat(".", full_name);
7114
0
  }
7115
0
  if (!IsNonMessageType(type) && !absl::StartsWith(type, ".")) {
7116
0
    expected_type = absl::StrCat(".", type);
7117
0
  }
7118
0
  if (expected_type != actual_type) {
7119
0
    AddError(field.full_name(), proto, DescriptorPool::ErrorCollector::EXTENDEE,
7120
0
             [&] {
7121
0
               return absl::Substitute(
7122
0
                   "\"$0\" extension field $1 is expected to be type "
7123
0
                   "\"$2\", not \"$3\".",
7124
0
                   field.containing_type()->full_name(), field.number(),
7125
0
                   expected_type, actual_type);
7126
0
             });
7127
0
  }
7128
0
}
7129
7130
7131
void DescriptorBuilder::CheckExtensionDeclaration(
7132
    const FieldDescriptor& field, const FieldDescriptorProto& proto,
7133
    absl::string_view declared_full_name, absl::string_view declared_type_name,
7134
0
    bool is_repeated) {
7135
0
  if (!declared_type_name.empty()) {
7136
0
    CheckExtensionDeclarationFieldType(field, proto, declared_type_name);
7137
0
  }
7138
0
  if (!declared_full_name.empty()) {
7139
0
    std::string actual_full_name = absl::StrCat(".", field.full_name());
7140
0
    if (declared_full_name != actual_full_name) {
7141
0
      AddError(field.full_name(), proto,
7142
0
               DescriptorPool::ErrorCollector::EXTENDEE, [&] {
7143
0
                 return absl::Substitute(
7144
0
                     "\"$0\" extension field $1 is expected to have field name "
7145
0
                     "\"$2\", not \"$3\".",
7146
0
                     field.containing_type()->full_name(), field.number(),
7147
0
                     declared_full_name, actual_full_name);
7148
0
               });
7149
0
    }
7150
0
  }
7151
7152
0
  if (is_repeated != field.is_repeated()) {
7153
0
    AddError(field.full_name(), proto, DescriptorPool::ErrorCollector::EXTENDEE,
7154
0
             [&] {
7155
0
               return absl::Substitute(
7156
0
                   "\"$0\" extension field $1 is expected to be $2.",
7157
0
                   field.containing_type()->full_name(), field.number(),
7158
0
                   is_repeated ? "repeated" : "optional");
7159
0
             });
7160
0
  }
7161
0
}
7162
7163
void DescriptorBuilder::CrossLinkField(FieldDescriptor* field,
7164
396
                                       const FieldDescriptorProto& proto) {
7165
396
  if (field->options_ == nullptr) {
7166
368
    field->options_ = &FieldOptions::default_instance();
7167
368
  }
7168
7169
396
  if (proto.has_extendee()) {
7170
2
    Symbol extendee =
7171
2
        LookupSymbol(proto.extendee(), field->full_name(),
7172
2
                     DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE);
7173
2
    if (extendee.IsNull()) {
7174
0
      AddNotDefinedError(field->full_name(), proto,
7175
0
                         DescriptorPool::ErrorCollector::EXTENDEE,
7176
0
                         proto.extendee());
7177
0
      return;
7178
2
    } else if (extendee.type() != Symbol::MESSAGE) {
7179
0
      AddError(field->full_name(), proto,
7180
0
               DescriptorPool::ErrorCollector::EXTENDEE, [&] {
7181
0
                 return absl::StrCat("\"", proto.extendee(),
7182
0
                                     "\" is not a message type.");
7183
0
               });
7184
0
      return;
7185
0
    }
7186
2
    field->containing_type_ = extendee.descriptor();
7187
7188
2
    const Descriptor::ExtensionRange* extension_range =
7189
2
        field->containing_type()->FindExtensionRangeContainingNumber(
7190
2
            field->number());
7191
7192
2
    if (extension_range == nullptr) {
7193
      // Set of valid extension numbers for MessageSet is different (< 2^32)
7194
      // from other extendees (< 2^29). If unknown deps are allowed, we may not
7195
      // have that information, and wrongly deem the extension as invalid.
7196
0
      auto skip_check = get_allow_unknown(pool_) &&
7197
0
                        proto.extendee() == "google.protobuf.bridge.MessageSet";
7198
0
      if (!skip_check) {
7199
0
        AddError(field->full_name(), proto,
7200
0
                 DescriptorPool::ErrorCollector::NUMBER, [&] {
7201
0
                   return absl::Substitute(
7202
0
                       "\"$0\" does not declare $1 as an "
7203
0
                       "extension number.",
7204
0
                       field->containing_type()->full_name(), field->number());
7205
0
                 });
7206
0
      }
7207
0
    }
7208
2
  }
7209
7210
396
  if (field->containing_oneof() != nullptr) {
7211
14
    if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
7212
      // Note that this error will never happen when parsing .proto files.
7213
      // It can only happen if you manually construct a FileDescriptorProto
7214
      // that is incorrect.
7215
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7216
0
               "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
7217
0
    }
7218
14
  }
7219
7220
396
  if (proto.has_type_name()) {
7221
    // Assume we are expecting a message type unless the proto contains some
7222
    // evidence that it expects an enum type.  This only makes a difference if
7223
    // we end up creating a placeholder.
7224
170
    bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
7225
170
                          proto.has_default_value();
7226
7227
    // In case of weak fields we force building the dependency. We need to know
7228
    // if the type exist or not. If it doesn't exist we substitute Empty which
7229
    // should only be done if the type can't be found in the generated pool.
7230
    // TODO Ideally we should query the database directly to check
7231
    // if weak fields exist or not so that we don't need to force building
7232
    // weak dependencies. However the name lookup rules for symbols are
7233
    // somewhat complicated, so I defer it too another CL.
7234
170
    bool is_weak = !pool_->enforce_weak_ && proto.options().weak();
7235
170
    bool is_lazy = pool_->lazily_build_dependencies_ && !is_weak;
7236
7237
170
    Symbol type =
7238
170
        LookupSymbol(proto.type_name(), field->full_name(),
7239
170
                     expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM
7240
170
                                    : DescriptorPool::PLACEHOLDER_MESSAGE,
7241
170
                     LOOKUP_TYPES, !is_lazy);
7242
7243
170
    if (type.IsNull()) {
7244
0
      if (is_lazy) {
7245
        // Save the symbol names for later for lookup, and allocate the once
7246
        // object needed for the accessors.
7247
0
        const std::string& name = proto.type_name();
7248
7249
0
        int name_sizes = static_cast<int>(name.size() + 1 +
7250
0
                                          proto.default_value().size() + 1);
7251
7252
0
        field->type_once_ = ::new (tables_->AllocateBytes(
7253
0
            static_cast<int>(sizeof(absl::once_flag)) + name_sizes))
7254
0
            absl::once_flag{};
7255
0
        char* names = reinterpret_cast<char*>(field->type_once_ + 1);
7256
7257
0
        memcpy(names, name.c_str(), name.size() + 1);
7258
0
        memcpy(names + name.size() + 1, proto.default_value().c_str(),
7259
0
               proto.default_value().size() + 1);
7260
7261
        // AddFieldByNumber and AddExtension are done later in this function,
7262
        // and can/must be done if the field type was not found. The related
7263
        // error checking is not necessary when in lazily_build_dependencies_
7264
        // mode, and can't be done without building the type's descriptor,
7265
        // which we don't want to do.
7266
0
        file_tables_->AddFieldByNumber(field);
7267
0
        if (field->is_extension()) {
7268
0
          tables_->AddExtension(field);
7269
0
        }
7270
0
        return;
7271
0
      } else {
7272
        // If the type is a weak type, we change the type to a google.protobuf.Empty
7273
        // field.
7274
0
        if (is_weak) {
7275
0
          type = FindSymbol(kNonLinkedWeakMessageReplacementName);
7276
0
        }
7277
0
        if (type.IsNull()) {
7278
0
          AddNotDefinedError(field->full_name(), proto,
7279
0
                             DescriptorPool::ErrorCollector::TYPE,
7280
0
                             proto.type_name());
7281
0
          return;
7282
0
        }
7283
0
      }
7284
0
    }
7285
7286
170
    if (!proto.has_type()) {
7287
      // Choose field type based on symbol.
7288
0
      if (type.type() == Symbol::MESSAGE) {
7289
0
        field->type_ = FieldDescriptor::TYPE_MESSAGE;
7290
0
      } else if (type.type() == Symbol::ENUM) {
7291
0
        field->type_ = FieldDescriptor::TYPE_ENUM;
7292
0
      } else {
7293
0
        AddError(field->full_name(), proto,
7294
0
                 DescriptorPool::ErrorCollector::TYPE, [&] {
7295
0
                   return absl::StrCat("\"", proto.type_name(),
7296
0
                                       "\" is not a type.");
7297
0
                 });
7298
0
        return;
7299
0
      }
7300
0
    }
7301
7302
170
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
7303
128
      field->type_descriptor_.message_type = type.descriptor();
7304
128
      if (field->type_descriptor_.message_type == nullptr) {
7305
0
        AddError(field->full_name(), proto,
7306
0
                 DescriptorPool::ErrorCollector::TYPE, [&] {
7307
0
                   return absl::StrCat("\"", proto.type_name(),
7308
0
                                       "\" is not a message type.");
7309
0
                 });
7310
0
        return;
7311
0
      }
7312
7313
128
      if (field->has_default_value()) {
7314
0
        AddError(field->full_name(), proto,
7315
0
                 DescriptorPool::ErrorCollector::DEFAULT_VALUE,
7316
0
                 "Messages can't have default values.");
7317
0
      }
7318
128
    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
7319
42
      field->type_descriptor_.enum_type = type.enum_descriptor();
7320
42
      if (field->type_descriptor_.enum_type == nullptr) {
7321
0
        AddError(field->full_name(), proto,
7322
0
                 DescriptorPool::ErrorCollector::TYPE, [&] {
7323
0
                   return absl::StrCat("\"", proto.type_name(),
7324
0
                                       "\" is not an enum type.");
7325
0
                 });
7326
0
        return;
7327
0
      }
7328
7329
42
      if (field->enum_type()->is_placeholder_) {
7330
        // We can't look up default values for placeholder types.  We'll have
7331
        // to just drop them.
7332
0
        field->has_default_value_ = false;
7333
0
      }
7334
7335
42
      if (field->has_default_value()) {
7336
        // Ensure that the default value is an identifier. Parser cannot always
7337
        // verify this because it does not have complete type information.
7338
        // N.B. that this check yields better error messages but is not
7339
        // necessary for correctness (an enum symbol must be a valid identifier
7340
        // anyway), only for better errors.
7341
10
        if (!io::Tokenizer::IsIdentifier(proto.default_value())) {
7342
0
          AddError(field->full_name(), proto,
7343
0
                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
7344
0
                   "Default value for an enum field must be an identifier.");
7345
10
        } else {
7346
          // We can't just use field->enum_type()->FindValueByName() here
7347
          // because that locks the pool's mutex, which we have already locked
7348
          // at this point.
7349
10
          const EnumValueDescriptor* default_value =
7350
10
              LookupSymbolNoPlaceholder(proto.default_value(),
7351
10
                                        field->enum_type()->full_name())
7352
10
                  .enum_value_descriptor();
7353
7354
10
          if (default_value != nullptr &&
7355
10
              default_value->type() == field->enum_type()) {
7356
10
            field->default_value_enum_ = default_value;
7357
10
          } else {
7358
0
            AddError(field->full_name(), proto,
7359
0
                     DescriptorPool::ErrorCollector::DEFAULT_VALUE, [&] {
7360
0
                       return absl::StrCat("Enum type \"",
7361
0
                                           field->enum_type()->full_name(),
7362
0
                                           "\" has no value named \"",
7363
0
                                           proto.default_value(), "\".");
7364
0
                     });
7365
0
          }
7366
10
        }
7367
32
      } else if (field->enum_type()->value_count() > 0) {
7368
        // All enums must have at least one value, or we would have reported
7369
        // an error elsewhere.  We use the first defined value as the default
7370
        // if a default is not explicitly defined.
7371
32
        field->default_value_enum_ = field->enum_type()->value(0);
7372
32
      }
7373
42
    } else {
7374
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7375
0
               "Field with primitive type has type_name.");
7376
0
    }
7377
226
  } else {
7378
226
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
7379
226
        field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
7380
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7381
0
               "Field with message or enum type missing type_name.");
7382
0
    }
7383
226
  }
7384
7385
  // Add the field to the fields-by-number table.
7386
  // Note:  We have to do this *after* cross-linking because extensions do not
7387
  // know their containing type until now. If we're in
7388
  // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no
7389
  // risk to calling containing_type() or other accessors that will build
7390
  // dependencies.
7391
396
  if (!file_tables_->AddFieldByNumber(field)) {
7392
0
    const FieldDescriptor* conflicting_field = file_tables_->FindFieldByNumber(
7393
0
        field->containing_type(), field->number());
7394
0
    std::string containing_type_name =
7395
0
        field->containing_type() == nullptr
7396
0
            ? "unknown"
7397
0
            : field->containing_type()->full_name();
7398
0
    if (field->is_extension()) {
7399
0
      AddError(field->full_name(), proto,
7400
0
               DescriptorPool::ErrorCollector::NUMBER, [&] {
7401
0
                 return absl::Substitute(
7402
0
                     "Extension number $0 has already been used "
7403
0
                     "in \"$1\" by extension \"$2\".",
7404
0
                     field->number(), containing_type_name,
7405
0
                     conflicting_field->full_name());
7406
0
               });
7407
0
    } else {
7408
0
      AddError(field->full_name(), proto,
7409
0
               DescriptorPool::ErrorCollector::NUMBER, [&] {
7410
0
                 return absl::Substitute(
7411
0
                     "Field number $0 has already been used in "
7412
0
                     "\"$1\" by field \"$2\".",
7413
0
                     field->number(), containing_type_name,
7414
0
                     conflicting_field->name());
7415
0
               });
7416
0
    }
7417
396
  } else {
7418
396
    if (field->is_extension()) {
7419
2
      if (!tables_->AddExtension(field)) {
7420
0
        auto make_error = [&] {
7421
0
          const FieldDescriptor* conflicting_field =
7422
0
              tables_->FindExtension(field->containing_type(), field->number());
7423
0
          std::string containing_type_name =
7424
0
              field->containing_type() == nullptr
7425
0
                  ? "unknown"
7426
0
                  : field->containing_type()->full_name();
7427
0
          return absl::Substitute(
7428
0
              "Extension number $0 has already been used in \"$1\" by "
7429
0
              "extension "
7430
0
              "\"$2\" defined in $3.",
7431
0
              field->number(), containing_type_name,
7432
0
              conflicting_field->full_name(),
7433
0
              conflicting_field->file()->name());
7434
0
        };
7435
        // Conflicting extension numbers should be an error. However, before
7436
        // turning this into an error we need to fix all existing broken
7437
        // protos first.
7438
        // TODO: Change this to an error.
7439
0
        AddWarning(field->full_name(), proto,
7440
0
                   DescriptorPool::ErrorCollector::NUMBER, make_error);
7441
0
      }
7442
2
    }
7443
396
  }
7444
396
}
7445
7446
void DescriptorBuilder::CrossLinkEnum(EnumDescriptor* enum_type,
7447
34
                                      const EnumDescriptorProto& proto) {
7448
34
  if (enum_type->options_ == nullptr) {
7449
34
    enum_type->options_ = &EnumOptions::default_instance();
7450
34
  }
7451
7452
192
  for (int i = 0; i < enum_type->value_count(); i++) {
7453
158
    CrossLinkEnumValue(&enum_type->values_[i], proto.value(i));
7454
158
  }
7455
34
}
7456
7457
void DescriptorBuilder::CrossLinkEnumValue(
7458
    EnumValueDescriptor* enum_value,
7459
158
    const EnumValueDescriptorProto& /* proto */) {
7460
158
  if (enum_value->options_ == nullptr) {
7461
158
    enum_value->options_ = &EnumValueOptions::default_instance();
7462
158
  }
7463
158
}
7464
7465
void DescriptorBuilder::CrossLinkService(ServiceDescriptor* service,
7466
0
                                         const ServiceDescriptorProto& proto) {
7467
0
  if (service->options_ == nullptr) {
7468
0
    service->options_ = &ServiceOptions::default_instance();
7469
0
  }
7470
7471
0
  for (int i = 0; i < service->method_count(); i++) {
7472
0
    CrossLinkMethod(&service->methods_[i], proto.method(i));
7473
0
  }
7474
0
}
7475
7476
void DescriptorBuilder::CrossLinkMethod(MethodDescriptor* method,
7477
0
                                        const MethodDescriptorProto& proto) {
7478
0
  if (method->options_ == nullptr) {
7479
0
    method->options_ = &MethodOptions::default_instance();
7480
0
  }
7481
7482
0
  Symbol input_type =
7483
0
      LookupSymbol(proto.input_type(), method->full_name(),
7484
0
                   DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL,
7485
0
                   !pool_->lazily_build_dependencies_);
7486
0
  if (input_type.IsNull()) {
7487
0
    if (!pool_->lazily_build_dependencies_) {
7488
0
      AddNotDefinedError(method->full_name(), proto,
7489
0
                         DescriptorPool::ErrorCollector::INPUT_TYPE,
7490
0
                         proto.input_type());
7491
0
    } else {
7492
0
      method->input_type_.SetLazy(proto.input_type(), file_);
7493
0
    }
7494
0
  } else if (input_type.type() != Symbol::MESSAGE) {
7495
0
    AddError(method->full_name(), proto,
7496
0
             DescriptorPool::ErrorCollector::INPUT_TYPE, [&] {
7497
0
               return absl::StrCat("\"", proto.input_type(),
7498
0
                                   "\" is not a message type.");
7499
0
             });
7500
0
  } else {
7501
0
    method->input_type_.Set(input_type.descriptor());
7502
0
  }
7503
7504
0
  Symbol output_type =
7505
0
      LookupSymbol(proto.output_type(), method->full_name(),
7506
0
                   DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL,
7507
0
                   !pool_->lazily_build_dependencies_);
7508
0
  if (output_type.IsNull()) {
7509
0
    if (!pool_->lazily_build_dependencies_) {
7510
0
      AddNotDefinedError(method->full_name(), proto,
7511
0
                         DescriptorPool::ErrorCollector::OUTPUT_TYPE,
7512
0
                         proto.output_type());
7513
0
    } else {
7514
0
      method->output_type_.SetLazy(proto.output_type(), file_);
7515
0
    }
7516
0
  } else if (output_type.type() != Symbol::MESSAGE) {
7517
0
    AddError(method->full_name(), proto,
7518
0
             DescriptorPool::ErrorCollector::OUTPUT_TYPE, [&] {
7519
0
               return absl::StrCat("\"", proto.output_type(),
7520
0
                                   "\" is not a message type.");
7521
0
             });
7522
0
  } else {
7523
0
    method->output_type_.Set(output_type.descriptor());
7524
0
  }
7525
0
}
7526
7527
void DescriptorBuilder::SuggestFieldNumbers(FileDescriptor* file,
7528
0
                                            const FileDescriptorProto& proto) {
7529
0
  for (int message_index = 0; message_index < file->message_type_count();
7530
0
       message_index++) {
7531
0
    const Descriptor* message = &file->message_types_[message_index];
7532
0
    auto hints_it = message_hints_.find(message);
7533
0
    if (hints_it == message_hints_.end()) continue;
7534
0
    auto* hints = &hints_it->second;
7535
0
    constexpr int kMaxSuggestions = 3;
7536
0
    int fields_to_suggest = std::min(kMaxSuggestions, hints->fields_to_suggest);
7537
0
    if (fields_to_suggest <= 0) continue;
7538
0
    struct Range {
7539
0
      int from;
7540
0
      int to;
7541
0
    };
7542
0
    std::vector<Range> used_ordinals;
7543
0
    auto add_ordinal = [&](int ordinal) {
7544
0
      if (ordinal <= 0 || ordinal > FieldDescriptor::kMaxNumber) return;
7545
0
      if (!used_ordinals.empty() && ordinal == used_ordinals.back().to) {
7546
0
        used_ordinals.back().to = ordinal + 1;
7547
0
      } else {
7548
0
        used_ordinals.push_back({ordinal, ordinal + 1});
7549
0
      }
7550
0
    };
7551
0
    auto add_range = [&](int from, int to) {
7552
0
      from = std::max(0, std::min(FieldDescriptor::kMaxNumber + 1, from));
7553
0
      to = std::max(0, std::min(FieldDescriptor::kMaxNumber + 1, to));
7554
0
      if (from >= to) return;
7555
0
      used_ordinals.push_back({from, to});
7556
0
    };
7557
0
    for (int i = 0; i < message->field_count(); i++) {
7558
0
      add_ordinal(message->field(i)->number());
7559
0
    }
7560
0
    for (int i = 0; i < message->extension_count(); i++) {
7561
0
      add_ordinal(message->extension(i)->number());
7562
0
    }
7563
0
    for (int i = 0; i < message->reserved_range_count(); i++) {
7564
0
      auto range = message->reserved_range(i);
7565
0
      add_range(range->start, range->end);
7566
0
    }
7567
0
    for (int i = 0; i < message->extension_range_count(); i++) {
7568
0
      auto range = message->extension_range(i);
7569
0
      add_range(range->start_number(), range->end_number());
7570
0
    }
7571
0
    used_ordinals.push_back(
7572
0
        {FieldDescriptor::kMaxNumber, FieldDescriptor::kMaxNumber + 1});
7573
0
    used_ordinals.push_back({FieldDescriptor::kFirstReservedNumber,
7574
0
                             FieldDescriptor::kLastReservedNumber});
7575
0
    std::sort(used_ordinals.begin(), used_ordinals.end(),
7576
0
              [](Range lhs, Range rhs) {
7577
0
                return std::tie(lhs.from, lhs.to) < std::tie(rhs.from, rhs.to);
7578
0
              });
7579
0
    int current_ordinal = 1;
7580
0
    if (hints->first_reason) {
7581
0
      auto make_error = [&] {
7582
0
        std::stringstream id_list;
7583
0
        id_list << "Suggested field numbers for " << message->full_name()
7584
0
                << ": ";
7585
0
        const char* separator = "";
7586
0
        for (auto& current_range : used_ordinals) {
7587
0
          while (current_ordinal < current_range.from &&
7588
0
                 fields_to_suggest > 0) {
7589
0
            id_list << separator << current_ordinal++;
7590
0
            separator = ", ";
7591
0
            fields_to_suggest--;
7592
0
          }
7593
0
          if (fields_to_suggest == 0) break;
7594
0
          current_ordinal = std::max(current_ordinal, current_range.to);
7595
0
        }
7596
0
        return id_list.str();
7597
0
      };
7598
0
      AddError(message->full_name(), *hints->first_reason,
7599
0
               hints->first_reason_location, make_error);
7600
0
    }
7601
0
  }
7602
0
}
7603
7604
// -------------------------------------------------------------------
7605
7606
// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to
7607
// avoid problems that exist at init time.
7608
0
static bool IsLite(const FileDescriptor* file) {
7609
  // TODO:  I don't even remember how many of these conditions are
7610
  //   actually possible.  I'm just being super-safe.
7611
0
  return file != nullptr &&
7612
0
         &file->options() != &FileOptions::default_instance() &&
7613
0
         file->options().optimize_for() == FileOptions::LITE_RUNTIME;
7614
0
}
7615
7616
void DescriptorBuilder::ValidateOptions(const FileDescriptor* file,
7617
0
                                        const FileDescriptorProto& proto) {
7618
0
  ValidateFileFeatures(file, proto);
7619
7620
  // Lite files can only be imported by other Lite files.
7621
0
  if (!IsLite(file)) {
7622
0
    for (int i = 0; i < file->dependency_count(); i++) {
7623
0
      if (IsLite(file->dependency(i))) {
7624
0
        AddError(file->dependency(i)->name(), proto,
7625
0
                 DescriptorPool::ErrorCollector::IMPORT, [&] {
7626
0
                   return absl::StrCat(
7627
0
                       "Files that do not use optimize_for = LITE_RUNTIME "
7628
0
                       "cannot import files which do use this option.  This "
7629
0
                       "file is not lite, but it imports \"",
7630
0
                       file->dependency(i)->name(), "\" which is.");
7631
0
                 });
7632
0
        break;
7633
0
      }
7634
0
    }
7635
0
  }
7636
0
  if (FileDescriptorLegacy(file).syntax() ==
7637
0
      FileDescriptorLegacy::Syntax::SYNTAX_PROTO3) {
7638
0
    ValidateProto3(file, proto);
7639
0
  }
7640
0
}
7641
7642
void DescriptorBuilder::ValidateProto3(const FileDescriptor* file,
7643
0
                                       const FileDescriptorProto& proto) {
7644
0
  for (int i = 0; i < file->extension_count(); ++i) {
7645
0
    ValidateProto3Field(file->extensions_ + i, proto.extension(i));
7646
0
  }
7647
0
  for (int i = 0; i < file->message_type_count(); ++i) {
7648
0
    ValidateProto3Message(file->message_types_ + i, proto.message_type(i));
7649
0
  }
7650
0
}
7651
7652
void DescriptorBuilder::ValidateProto3Message(const Descriptor* message,
7653
0
                                              const DescriptorProto& proto) {
7654
0
  for (int i = 0; i < message->nested_type_count(); ++i) {
7655
0
    ValidateProto3Message(message->nested_types_ + i, proto.nested_type(i));
7656
0
  }
7657
0
  for (int i = 0; i < message->field_count(); ++i) {
7658
0
    ValidateProto3Field(message->fields_ + i, proto.field(i));
7659
0
  }
7660
0
  for (int i = 0; i < message->extension_count(); ++i) {
7661
0
    ValidateProto3Field(message->extensions_ + i, proto.extension(i));
7662
0
  }
7663
0
  if (message->extension_range_count() > 0) {
7664
0
    AddError(message->full_name(), proto.extension_range(0),
7665
0
             DescriptorPool::ErrorCollector::NUMBER,
7666
0
             "Extension ranges are not allowed in proto3.");
7667
0
  }
7668
0
  if (message->options().message_set_wire_format()) {
7669
    // Using MessageSet doesn't make sense since we disallow extensions.
7670
0
    AddError(message->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7671
0
             "MessageSet is not supported in proto3.");
7672
0
  }
7673
0
}
7674
7675
void DescriptorBuilder::ValidateProto3Field(const FieldDescriptor* field,
7676
0
                                            const FieldDescriptorProto& proto) {
7677
0
  if (field->is_extension() &&
7678
0
      !AllowedExtendeeInProto3(field->containing_type()->full_name())) {
7679
0
    AddError(field->full_name(), proto,
7680
0
             DescriptorPool::ErrorCollector::EXTENDEE,
7681
0
             "Extensions in proto3 are only allowed for defining options.");
7682
0
  }
7683
0
  if (field->is_required()) {
7684
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7685
0
             "Required fields are not allowed in proto3.");
7686
0
  }
7687
0
  if (field->has_default_value()) {
7688
0
    AddError(field->full_name(), proto,
7689
0
             DescriptorPool::ErrorCollector::DEFAULT_VALUE,
7690
0
             "Explicit default values are not allowed in proto3.");
7691
0
  }
7692
0
  if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
7693
0
      field->enum_type() &&
7694
0
      FileDescriptorLegacy(field->enum_type()->file()).syntax() !=
7695
0
          FileDescriptorLegacy::Syntax::SYNTAX_PROTO3 &&
7696
0
      FileDescriptorLegacy(field->enum_type()->file()).syntax() !=
7697
0
          FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN) {
7698
    // Proto3 messages can only use Proto3 enum types; otherwise we can't
7699
    // guarantee that the default value is zero.
7700
0
    AddError(
7701
0
        field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE, [&] {
7702
0
          return absl::StrCat("Enum type \"", field->enum_type()->full_name(),
7703
0
                              "\" is not a proto3 enum, but is used in \"",
7704
0
                              field->containing_type()->full_name(),
7705
0
                              "\" which is a proto3 message type.");
7706
0
        });
7707
0
  }
7708
0
  if (field->type() == FieldDescriptor::TYPE_GROUP) {
7709
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7710
0
             "Groups are not supported in proto3 syntax.");
7711
0
  }
7712
0
}
7713
7714
void DescriptorBuilder::ValidateOptions(const Descriptor* message,
7715
0
                                        const DescriptorProto& proto) {
7716
0
  CheckFieldJsonNameUniqueness(proto, message);
7717
0
  ValidateExtensionRangeOptions(proto, *message);
7718
0
}
7719
7720
void DescriptorBuilder::ValidateOptions(const OneofDescriptor* /*oneof*/,
7721
0
                                        const OneofDescriptorProto& /*proto*/) {
7722
0
}
7723
7724
7725
void DescriptorBuilder::ValidateOptions(const FieldDescriptor* field,
7726
0
                                        const FieldDescriptorProto& proto) {
7727
0
  if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) {
7728
0
    return;
7729
0
  }
7730
7731
0
  ValidateFieldFeatures(field, proto);
7732
7733
  // Only message type fields may be lazy.
7734
0
  if (field->options().lazy() || field->options().unverified_lazy()) {
7735
0
    if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
7736
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7737
0
               "[lazy = true] can only be specified for submessage fields.");
7738
0
    }
7739
0
  }
7740
7741
  // Only repeated primitive fields may be packed.
7742
0
  if (field->options().packed() && !field->is_packable()) {
7743
0
    AddError(
7744
0
        field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7745
0
        "[packed = true] can only be specified for repeated primitive fields.");
7746
0
  }
7747
7748
  // Note:  Default instance may not yet be initialized here, so we have to
7749
  //   avoid reading from it.
7750
0
  if (field->containing_type_ != nullptr &&
7751
0
      &field->containing_type()->options() !=
7752
0
          &MessageOptions::default_instance() &&
7753
0
      field->containing_type()->options().message_set_wire_format()) {
7754
0
    if (field->is_extension()) {
7755
0
      if (!field->is_optional() ||
7756
0
          field->type() != FieldDescriptor::TYPE_MESSAGE) {
7757
0
        AddError(field->full_name(), proto,
7758
0
                 DescriptorPool::ErrorCollector::TYPE,
7759
0
                 "Extensions of MessageSets must be optional messages.");
7760
0
      }
7761
0
    } else {
7762
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7763
0
               "MessageSets cannot have fields, only extensions.");
7764
0
    }
7765
0
  }
7766
7767
  // Lite extensions can only be of Lite types.
7768
0
  if (IsLite(field->file()) && field->containing_type_ != nullptr &&
7769
0
      !IsLite(field->containing_type()->file())) {
7770
0
    AddError(field->full_name(), proto,
7771
0
             DescriptorPool::ErrorCollector::EXTENDEE,
7772
0
             "Extensions to non-lite types can only be declared in non-lite "
7773
0
             "files.  Note that you cannot extend a non-lite type to contain "
7774
0
             "a lite type, but the reverse is allowed.");
7775
0
  }
7776
7777
  // Validate map types.
7778
0
  if (field->is_map()) {
7779
0
    if (!ValidateMapEntry(field, proto)) {
7780
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
7781
0
               "map_entry should not be set explicitly. Use map<KeyType, "
7782
0
               "ValueType> instead.");
7783
0
    }
7784
0
  }
7785
7786
0
  ValidateJSType(field, proto);
7787
7788
  // json_name option is not allowed on extension fields. Note that the
7789
  // json_name field in FieldDescriptorProto is always populated by protoc
7790
  // when it sends descriptor data to plugins (calculated from field name if
7791
  // the option is not explicitly set) so we can't rely on its presence to
7792
  // determine whether the json_name option is set on the field. Here we
7793
  // compare it against the default calculated json_name value and consider
7794
  // the option set if they are different. This won't catch the case when
7795
  // a user explicitly sets json_name to the default value, but should be
7796
  // good enough to catch common misuses.
7797
0
  if (field->is_extension() &&
7798
0
      (field->has_json_name() &&
7799
0
       field->json_name() != ToJsonName(field->name()))) {
7800
0
    AddError(field->full_name(), proto,
7801
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
7802
0
             "option json_name is not allowed on extension fields.");
7803
0
  }
7804
7805
0
  if (absl::StrContains(field->json_name(), '\0')) {
7806
0
    AddError(field->full_name(), proto,
7807
0
             DescriptorPool::ErrorCollector::OPTION_NAME,
7808
0
             "json_name cannot have embedded null characters.");
7809
0
  }
7810
7811
7812
  // If this is a declared extension, validate that the actual name and type
7813
  // match the declaration.
7814
0
  if (field->is_extension()) {
7815
0
    if (pool_->IsExtendingDescriptor(*field)) return;
7816
0
    const Descriptor::ExtensionRange* extension_range =
7817
0
        field->containing_type()->FindExtensionRangeContainingNumber(
7818
0
            field->number());
7819
7820
0
    if (extension_range->options_ == nullptr) {
7821
0
      return;
7822
0
    }
7823
7824
0
    if (pool_->enforce_extension_declarations_) {
7825
0
      for (const auto& declaration : extension_range->options_->declaration()) {
7826
0
        if (declaration.number() != field->number()) continue;
7827
0
        if (declaration.reserved()) {
7828
0
          AddError(
7829
0
              field->full_name(), proto,
7830
0
              DescriptorPool::ErrorCollector::EXTENDEE, [&] {
7831
0
                return absl::Substitute(
7832
0
                    "Cannot use number $0 for extension field $1, as it is "
7833
0
                    "reserved in the extension declarations for message $2.",
7834
0
                    field->number(), field->full_name(),
7835
0
                    field->containing_type()->full_name());
7836
0
              });
7837
0
          return;
7838
0
        }
7839
0
        CheckExtensionDeclaration(*field, proto, declaration.full_name(),
7840
0
                                  declaration.type(), declaration.repeated());
7841
0
        return;
7842
0
      }
7843
7844
      // Either no declarations, or there are but no matches. If there are no
7845
      // declarations, we check its verification state. If there are other
7846
      // non-matching declarations, we enforce that this extension must also be
7847
      // declared.
7848
0
      if (!extension_range->options_->declaration().empty() ||
7849
0
          (extension_range->options_->verification() ==
7850
0
           ExtensionRangeOptions::DECLARATION)) {
7851
0
        AddError(
7852
0
            field->full_name(), proto, DescriptorPool::ErrorCollector::EXTENDEE,
7853
0
            [&] {
7854
0
              return absl::Substitute(
7855
0
                  "Missing extension declaration for field $0 with number $1 "
7856
0
                  "in extendee message $2. An extension range must declare for "
7857
0
                  "all extension fields if its verification state is "
7858
0
                  "DECLARATION or there's any declaration in the range "
7859
0
                  "already. Otherwise, consider splitting up the range.",
7860
0
                  field->full_name(), field->number(),
7861
0
                  field->containing_type()->full_name());
7862
0
            });
7863
0
        return;
7864
0
      }
7865
0
    }
7866
0
  }
7867
0
}
7868
7869
0
static bool IsStringMapType(const FieldDescriptor& field) {
7870
0
  if (!field.is_map()) return false;
7871
0
  for (int i = 0; i < field.message_type()->field_count(); ++i) {
7872
0
    if (field.message_type()->field(i)->type() ==
7873
0
        FieldDescriptor::TYPE_STRING) {
7874
0
      return true;
7875
0
    }
7876
0
  }
7877
0
  return false;
7878
0
}
7879
7880
void DescriptorBuilder::ValidateFileFeatures(const FileDescriptor* file,
7881
0
                                             const FileDescriptorProto& proto) {
7882
0
  if (file->features().field_presence() == FeatureSet::LEGACY_REQUIRED) {
7883
0
    AddError(file->name(), proto, DescriptorPool::ErrorCollector::EDITIONS,
7884
0
             "Required presence can't be specified by default.");
7885
0
  }
7886
0
}
7887
7888
void DescriptorBuilder::ValidateFieldFeatures(
7889
0
    const FieldDescriptor* field, const FieldDescriptorProto& proto) {
7890
  // Rely on our legacy validation for proto2/proto3 files.
7891
0
  if (FileDescriptorLegacy(field->file()).syntax() !=
7892
0
      FileDescriptorLegacy::SYNTAX_EDITIONS) {
7893
0
    return;
7894
0
  }
7895
7896
  // Double check proto descriptors in editions.  These would usually be caught
7897
  // by the parser, but may not be for dynamically built descriptors.
7898
0
  if (proto.label() == FieldDescriptorProto::LABEL_REQUIRED) {
7899
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7900
0
             "Required label is not allowed under editions.  Use the feature "
7901
0
             "field_presence = LEGACY_REQUIRED to control this behavior.");
7902
0
  }
7903
0
  if (proto.type() == FieldDescriptorProto::TYPE_GROUP) {
7904
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7905
0
             "Group types are not allowed under editions.  Use the feature "
7906
0
             "message_encoding = DELIMITED to control this behavior.");
7907
0
  }
7908
7909
  // Validate legacy options that have been migrated to features.
7910
0
  if (field->options().has_packed()) {
7911
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7912
0
             "Field option packed is not allowed under editions.  Use the "
7913
0
             "repeated_field_encoding feature to control this behavior.");
7914
0
  }
7915
7916
  // Validate fully resolved features.
7917
0
  if (field->has_default_value() &&
7918
0
      field->features().field_presence() == FeatureSet::IMPLICIT) {
7919
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7920
0
             "Implicit presence fields can't specify defaults.");
7921
0
  }
7922
0
  if (field->enum_type() != nullptr &&
7923
0
      field->enum_type()->features().enum_type() != FeatureSet::OPEN &&
7924
0
      field->features().field_presence() == FeatureSet::IMPLICIT) {
7925
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7926
0
             "Implicit presence enum fields must always be open.");
7927
0
  }
7928
0
  if (field->is_extension() &&
7929
0
      field->features().field_presence() == FeatureSet::LEGACY_REQUIRED) {
7930
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7931
0
             "Extensions can't be required.");
7932
0
  }
7933
7934
0
  if (field->containing_type() != nullptr &&
7935
0
      field->containing_type()->options().map_entry()) {
7936
    // Skip validation of explicit features on generated map fields.  These will
7937
    // be blindly propagated from the original map field, and may violate a lot
7938
    // of these conditions.  Note: we do still validate the user-specified map
7939
    // field.
7940
0
    return;
7941
0
  }
7942
7943
  // Validate explicitly specified features on the field proto.
7944
0
  if (field->proto_features_->has_field_presence()) {
7945
0
    if (field->containing_oneof() != nullptr) {
7946
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7947
0
               "Oneof fields can't specify field presence.");
7948
0
    } else if (field->is_repeated()) {
7949
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7950
0
               "Repeated fields can't specify field presence.");
7951
0
    } else if (field->is_extension() &&
7952
0
               field->proto_features_->field_presence() !=
7953
0
                   FeatureSet::LEGACY_REQUIRED) {
7954
      // Note: required extensions will fail elsewhere, so we skip reporting a
7955
      // second error here.
7956
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7957
0
               "Extensions can't specify field presence.");
7958
0
    } else if (field->message_type() != nullptr &&
7959
0
               field->proto_features_->field_presence() ==
7960
0
                   FeatureSet::IMPLICIT) {
7961
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7962
0
               "Message fields can't specify implicit presence.");
7963
0
    }
7964
0
  }
7965
0
  if (!field->is_repeated() &&
7966
0
      field->proto_features_->has_repeated_field_encoding()) {
7967
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7968
0
             "Only repeated fields can specify repeated field encoding.");
7969
0
  }
7970
0
  if (field->type() != FieldDescriptor::TYPE_STRING &&
7971
0
      !IsStringMapType(*field) &&
7972
0
      field->proto_features_->has_utf8_validation()) {
7973
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7974
0
             "Only string fields can specify utf8 validation.");
7975
0
  }
7976
0
  if (!field->is_packable() &&
7977
0
      field->proto_features_->repeated_field_encoding() == FeatureSet::PACKED) {
7978
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7979
0
             "Only repeated primitive fields can specify PACKED repeated field "
7980
0
             "encoding.");
7981
0
  }
7982
0
  if ((field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE ||
7983
0
       field->is_map_message_type()) &&
7984
0
      field->proto_features_->has_message_encoding()) {
7985
0
    AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
7986
0
             "Only message fields can specify message encoding.");
7987
0
  }
7988
0
}
7989
7990
void DescriptorBuilder::ValidateOptions(const EnumDescriptor* enm,
7991
0
                                        const EnumDescriptorProto& proto) {
7992
0
  CheckEnumValueUniqueness(proto, enm);
7993
7994
0
  if (!enm->is_closed() && enm->value_count() > 0 &&
7995
0
      enm->value(0)->number() != 0) {
7996
0
    AddError(enm->full_name(), proto.value(0),
7997
0
             DescriptorPool::ErrorCollector::NUMBER,
7998
0
             "The first enum value must be zero for open enums.");
7999
0
  }
8000
8001
0
  if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
8002
0
    absl::flat_hash_map<int, std::string> used_values;
8003
0
    for (int i = 0; i < enm->value_count(); ++i) {
8004
0
      const EnumValueDescriptor* enum_value = enm->value(i);
8005
0
      auto insert_result =
8006
0
          used_values.emplace(enum_value->number(), enum_value->full_name());
8007
0
      bool inserted = insert_result.second;
8008
0
      if (!inserted) {
8009
0
        if (!enm->options().allow_alias()) {
8010
          // Generate error if duplicated enum values are explicitly disallowed.
8011
0
          auto make_error = [&] {
8012
            // Find the next free number.
8013
0
            absl::flat_hash_set<int64_t> used;
8014
0
            for (int j = 0; j < enm->value_count(); ++j) {
8015
0
              used.insert(enm->value(j)->number());
8016
0
            }
8017
0
            int64_t next_value = static_cast<int64_t>(enum_value->number()) + 1;
8018
0
            while (used.contains(next_value)) ++next_value;
8019
8020
0
            std::string error = absl::StrCat(
8021
0
                "\"", enum_value->full_name(),
8022
0
                "\" uses the same enum value as \"",
8023
0
                insert_result.first->second,
8024
0
                "\". If this is intended, set "
8025
0
                "'option allow_alias = true;' to the enum definition.");
8026
0
            if (next_value < std::numeric_limits<int32_t>::max()) {
8027
0
              absl::StrAppend(&error, " The next available enum value is ",
8028
0
                              next_value, ".");
8029
0
            }
8030
0
            return error;
8031
0
          };
8032
0
          AddError(enm->full_name(), proto.value(i),
8033
0
                   DescriptorPool::ErrorCollector::NUMBER, make_error);
8034
0
        }
8035
0
      }
8036
0
    }
8037
0
  }
8038
0
}
8039
8040
void DescriptorBuilder::ValidateOptions(
8041
    const EnumValueDescriptor* /* enum_value */,
8042
0
    const EnumValueDescriptorProto& /* proto */) {
8043
  // Nothing to do so far.
8044
0
}
8045
8046
namespace {
8047
// Validates that a fully-qualified symbol for extension declaration must
8048
// have a leading dot and valid identifiers.
8049
absl::optional<std::string> ValidateSymbolForDeclaration(
8050
0
    absl::string_view symbol) {
8051
0
  if (!absl::StartsWith(symbol, ".")) {
8052
0
    return absl::StrCat("\"", symbol,
8053
0
                        "\" must have a leading dot to indicate the "
8054
0
                        "fully-qualified scope.");
8055
0
  }
8056
0
  if (!ValidateQualifiedName(symbol)) {
8057
0
    return absl::StrCat("\"", symbol, "\" contains invalid identifiers.");
8058
0
  }
8059
0
  return absl::nullopt;
8060
0
}
8061
}  // namespace
8062
8063
8064
void DescriptorBuilder::ValidateExtensionDeclaration(
8065
    const std::string& full_name,
8066
    const RepeatedPtrField<ExtensionRangeOptions_Declaration>& declarations,
8067
    const DescriptorProto_ExtensionRange& proto,
8068
0
    absl::flat_hash_set<absl::string_view>& full_name_set) {
8069
0
  absl::flat_hash_set<int> extension_number_set;
8070
0
  for (const auto& declaration : declarations) {
8071
0
    if (declaration.number() < proto.start() ||
8072
0
        declaration.number() >= proto.end()) {
8073
0
      AddError(full_name, proto, DescriptorPool::ErrorCollector::NUMBER, [&] {
8074
0
        return absl::Substitute(
8075
0
            "Extension declaration number $0 is not in the "
8076
0
            "extension range.",
8077
0
            declaration.number());
8078
0
      });
8079
0
    }
8080
8081
0
    if (!extension_number_set.insert(declaration.number()).second) {
8082
0
      AddError(full_name, proto, DescriptorPool::ErrorCollector::NUMBER, [&] {
8083
0
        return absl::Substitute(
8084
0
            "Extension declaration number $0 is declared multiple times.",
8085
0
            declaration.number());
8086
0
      });
8087
0
    }
8088
8089
    // Both full_name and type should be present. If none of them is set,
8090
    // add an error unless reserved is set to true. If only one of them is set,
8091
    // add an error whether or not reserved is set to true.
8092
0
    if (!declaration.has_full_name() || !declaration.has_type()) {
8093
0
      if (declaration.has_full_name() != declaration.has_type() ||
8094
0
          !declaration.reserved()) {
8095
0
        AddError(full_name, proto, DescriptorPool::ErrorCollector::EXTENDEE,
8096
0
                 [&] {
8097
0
                   return absl::StrCat(
8098
0
                       "Extension declaration #", declaration.number(),
8099
0
                       " should have both \"full_name\" and \"type\" set.");
8100
0
                 });
8101
0
      }
8102
0
    } else {
8103
0
      if (!full_name_set.insert(declaration.full_name()).second) {
8104
0
        AddError(
8105
0
            declaration.full_name(), proto,
8106
0
            DescriptorPool::ErrorCollector::NAME, [&] {
8107
0
              return absl::Substitute(
8108
0
                  "Extension field name \"$0\" is declared multiple times.",
8109
0
                  declaration.full_name());
8110
0
            });
8111
0
        return;
8112
0
      }
8113
0
      absl::optional<std::string> err =
8114
0
          ValidateSymbolForDeclaration(declaration.full_name());
8115
0
      if (err.has_value()) {
8116
0
        AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
8117
0
                 [err] { return *err; });
8118
0
      }
8119
0
      if (!IsNonMessageType(declaration.type())) {
8120
0
        err = ValidateSymbolForDeclaration(declaration.type());
8121
0
        if (err.has_value()) {
8122
0
          AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME,
8123
0
                   [err] { return *err; });
8124
0
        }
8125
0
      }
8126
0
    }
8127
0
  }
8128
0
}
8129
8130
void DescriptorBuilder::ValidateExtensionRangeOptions(
8131
0
    const DescriptorProto& proto, const Descriptor& message) {
8132
0
  const int64_t max_extension_range =
8133
0
      static_cast<int64_t>(message.options().message_set_wire_format()
8134
0
                               ? std::numeric_limits<int32_t>::max()
8135
0
                               : FieldDescriptor::kMaxNumber);
8136
8137
0
  size_t num_declarations = 0;
8138
0
  for (int i = 0; i < message.extension_range_count(); i++) {
8139
0
    if (message.extension_range(i)->options_ == nullptr) continue;
8140
0
    num_declarations +=
8141
0
        message.extension_range(i)->options_->declaration_size();
8142
0
  }
8143
8144
  // Contains the full names from both "declaration" and "metadata".
8145
0
  absl::flat_hash_set<absl::string_view> declaration_full_name_set;
8146
0
  declaration_full_name_set.reserve(num_declarations);
8147
8148
0
  for (int i = 0; i < message.extension_range_count(); i++) {
8149
0
    const auto& range = *message.extension_range(i);
8150
0
    if (range.end_number() > max_extension_range + 1) {
8151
0
      AddError(message.full_name(), proto,
8152
0
               DescriptorPool::ErrorCollector::NUMBER, [&] {
8153
0
                 return absl::Substitute(
8154
0
                     "Extension numbers cannot be greater than $0.",
8155
0
                     max_extension_range);
8156
0
               });
8157
0
    }
8158
0
    const auto& range_options = *range.options_;
8159
8160
8161
0
    if (!range_options.declaration().empty()) {
8162
      // TODO: remove the "has_verification" check once the default
8163
      // is flipped to DECLARATION.
8164
0
      if (range_options.has_verification() &&
8165
0
          range_options.verification() == ExtensionRangeOptions::UNVERIFIED) {
8166
0
        AddError(message.full_name(), proto.extension_range(i),
8167
0
                 DescriptorPool::ErrorCollector::EXTENDEE, [&] {
8168
0
                   return "Cannot mark the extension range as UNVERIFIED when "
8169
0
                          "it has extension(s) declared.";
8170
0
                 });
8171
0
        return;
8172
0
      }
8173
0
      ValidateExtensionDeclaration(
8174
0
          message.full_name(), range_options.declaration(),
8175
0
          proto.extension_range(i), declaration_full_name_set);
8176
0
    }
8177
0
  }
8178
0
}
8179
8180
void DescriptorBuilder::ValidateOptions(const ServiceDescriptor* service,
8181
0
                                        const ServiceDescriptorProto& proto) {
8182
0
  if (IsLite(service->file()) &&
8183
0
      (service->file()->options().cc_generic_services() ||
8184
0
       service->file()->options().java_generic_services())) {
8185
0
    AddError(service->full_name(), proto, DescriptorPool::ErrorCollector::NAME,
8186
0
             "Files with optimize_for = LITE_RUNTIME cannot define services "
8187
0
             "unless you set both options cc_generic_services and "
8188
0
             "java_generic_services to false.");
8189
0
  }
8190
0
}
8191
8192
void DescriptorBuilder::ValidateOptions(
8193
    const MethodDescriptor* /* method */,
8194
0
    const MethodDescriptorProto& /* proto */) {
8195
  // Nothing to do so far.
8196
0
}
8197
8198
bool DescriptorBuilder::ValidateMapEntry(const FieldDescriptor* field,
8199
0
                                         const FieldDescriptorProto& proto) {
8200
0
  const Descriptor* message = field->message_type();
8201
0
  if (  // Must not contain extensions, extension range or nested message or
8202
        // enums
8203
0
      message->extension_count() != 0 ||
8204
0
      field->label() != FieldDescriptor::LABEL_REPEATED ||
8205
0
      message->extension_range_count() != 0 ||
8206
0
      message->nested_type_count() != 0 || message->enum_type_count() != 0 ||
8207
      // Must contain exactly two fields
8208
0
      message->field_count() != 2 ||
8209
      // Field name and message name must match
8210
0
      message->name() !=
8211
0
          absl::StrCat(ToCamelCase(field->name(), false), "Entry") ||
8212
      // Entry message must be in the same containing type of the field.
8213
0
      field->containing_type() != message->containing_type()) {
8214
0
    return false;
8215
0
  }
8216
8217
0
  const FieldDescriptor* key = message->map_key();
8218
0
  const FieldDescriptor* value = message->map_value();
8219
0
  if (key->label() != FieldDescriptor::LABEL_OPTIONAL || key->number() != 1 ||
8220
0
      key->name() != "key") {
8221
0
    return false;
8222
0
  }
8223
0
  if (value->label() != FieldDescriptor::LABEL_OPTIONAL ||
8224
0
      value->number() != 2 || value->name() != "value") {
8225
0
    return false;
8226
0
  }
8227
8228
  // Check key types are legal.
8229
0
  switch (key->type()) {
8230
0
    case FieldDescriptor::TYPE_ENUM:
8231
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
8232
0
               "Key in map fields cannot be enum types.");
8233
0
      break;
8234
0
    case FieldDescriptor::TYPE_FLOAT:
8235
0
    case FieldDescriptor::TYPE_DOUBLE:
8236
0
    case FieldDescriptor::TYPE_MESSAGE:
8237
0
    case FieldDescriptor::TYPE_GROUP:
8238
0
    case FieldDescriptor::TYPE_BYTES:
8239
0
      AddError(
8240
0
          field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
8241
0
          "Key in map fields cannot be float/double, bytes or message types.");
8242
0
      break;
8243
0
    case FieldDescriptor::TYPE_BOOL:
8244
0
    case FieldDescriptor::TYPE_INT32:
8245
0
    case FieldDescriptor::TYPE_INT64:
8246
0
    case FieldDescriptor::TYPE_SINT32:
8247
0
    case FieldDescriptor::TYPE_SINT64:
8248
0
    case FieldDescriptor::TYPE_STRING:
8249
0
    case FieldDescriptor::TYPE_UINT32:
8250
0
    case FieldDescriptor::TYPE_UINT64:
8251
0
    case FieldDescriptor::TYPE_FIXED32:
8252
0
    case FieldDescriptor::TYPE_FIXED64:
8253
0
    case FieldDescriptor::TYPE_SFIXED32:
8254
0
    case FieldDescriptor::TYPE_SFIXED64:
8255
      // Legal cases
8256
0
      break;
8257
      // Do not add a default, so that the compiler will complain when new types
8258
      // are added.
8259
0
  }
8260
8261
0
  if (value->type() == FieldDescriptor::TYPE_ENUM) {
8262
0
    if (value->enum_type()->value(0)->number() != 0) {
8263
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
8264
0
               "Enum value in map must define 0 as the first value.");
8265
0
    }
8266
0
  }
8267
8268
0
  return true;
8269
0
}
8270
8271
void DescriptorBuilder::DetectMapConflicts(const Descriptor* message,
8272
0
                                           const DescriptorProto& proto) {
8273
0
  DescriptorsByNameSet<Descriptor> seen_types;
8274
0
  for (int i = 0; i < message->nested_type_count(); ++i) {
8275
0
    const Descriptor* nested = message->nested_type(i);
8276
0
    auto insert_result = seen_types.insert(nested);
8277
0
    bool inserted = insert_result.second;
8278
0
    if (!inserted) {
8279
0
      if ((*insert_result.first)->options().map_entry() ||
8280
0
          nested->options().map_entry()) {
8281
0
        AddError(message->full_name(), proto,
8282
0
                 DescriptorPool::ErrorCollector::NAME, [&] {
8283
0
                   return absl::StrCat(
8284
0
                       "Expanded map entry type ", nested->name(),
8285
0
                       " conflicts with an existing nested message type.");
8286
0
                 });
8287
0
        break;
8288
0
      }
8289
0
    }
8290
    // Recursively test on the nested types.
8291
0
    DetectMapConflicts(message->nested_type(i), proto.nested_type(i));
8292
0
  }
8293
  // Check for conflicted field names.
8294
0
  for (int i = 0; i < message->field_count(); ++i) {
8295
0
    const FieldDescriptor* field = message->field(i);
8296
0
    auto iter = seen_types.find(field->name());
8297
0
    if (iter != seen_types.end() && (*iter)->options().map_entry()) {
8298
0
      AddError(message->full_name(), proto,
8299
0
               DescriptorPool::ErrorCollector::NAME, [&] {
8300
0
                 return absl::StrCat("Expanded map entry type ",
8301
0
                                     (*iter)->name(),
8302
0
                                     " conflicts with an existing field.");
8303
0
               });
8304
0
    }
8305
0
  }
8306
  // Check for conflicted enum names.
8307
0
  for (int i = 0; i < message->enum_type_count(); ++i) {
8308
0
    const EnumDescriptor* enum_desc = message->enum_type(i);
8309
0
    auto iter = seen_types.find(enum_desc->name());
8310
0
    if (iter != seen_types.end() && (*iter)->options().map_entry()) {
8311
0
      AddError(message->full_name(), proto,
8312
0
               DescriptorPool::ErrorCollector::NAME, [&] {
8313
0
                 return absl::StrCat("Expanded map entry type ",
8314
0
                                     (*iter)->name(),
8315
0
                                     " conflicts with an existing enum type.");
8316
0
               });
8317
0
    }
8318
0
  }
8319
  // Check for conflicted oneof names.
8320
0
  for (int i = 0; i < message->oneof_decl_count(); ++i) {
8321
0
    const OneofDescriptor* oneof_desc = message->oneof_decl(i);
8322
0
    auto iter = seen_types.find(oneof_desc->name());
8323
0
    if (iter != seen_types.end() && (*iter)->options().map_entry()) {
8324
0
      AddError(message->full_name(), proto,
8325
0
               DescriptorPool::ErrorCollector::NAME, [&] {
8326
0
                 return absl::StrCat("Expanded map entry type ",
8327
0
                                     (*iter)->name(),
8328
0
                                     " conflicts with an existing oneof type.");
8329
0
               });
8330
0
    }
8331
0
  }
8332
0
}
8333
8334
void DescriptorBuilder::ValidateJSType(const FieldDescriptor* field,
8335
0
                                       const FieldDescriptorProto& proto) {
8336
0
  FieldOptions::JSType jstype = field->options().jstype();
8337
  // The default is always acceptable.
8338
0
  if (jstype == FieldOptions::JS_NORMAL) {
8339
0
    return;
8340
0
  }
8341
8342
0
  switch (field->type()) {
8343
    // Integral 64-bit types may be represented as JavaScript numbers or
8344
    // strings.
8345
0
    case FieldDescriptor::TYPE_UINT64:
8346
0
    case FieldDescriptor::TYPE_INT64:
8347
0
    case FieldDescriptor::TYPE_SINT64:
8348
0
    case FieldDescriptor::TYPE_FIXED64:
8349
0
    case FieldDescriptor::TYPE_SFIXED64:
8350
0
      if (jstype == FieldOptions::JS_STRING ||
8351
0
          jstype == FieldOptions::JS_NUMBER) {
8352
0
        return;
8353
0
      }
8354
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
8355
0
               [&] {
8356
0
                 return absl::StrCat(
8357
0
                     "Illegal jstype for int64, uint64, sint64, fixed64 "
8358
0
                     "or sfixed64 field: ",
8359
0
                     FieldOptions_JSType_descriptor()->value(jstype)->name());
8360
0
               });
8361
0
      break;
8362
8363
    // No other types permit a jstype option.
8364
0
    default:
8365
0
      AddError(field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
8366
0
               "jstype is only allowed on int64, uint64, sint64, fixed64 "
8367
0
               "or sfixed64 fields.");
8368
0
      break;
8369
0
  }
8370
0
}
8371
8372
// -------------------------------------------------------------------
8373
8374
DescriptorBuilder::OptionInterpreter::OptionInterpreter(
8375
    DescriptorBuilder* builder)
8376
8
    : builder_(builder) {
8377
8
  ABSL_CHECK(builder_);
8378
8
}
8379
8380
8
DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {}
8381
8382
bool DescriptorBuilder::OptionInterpreter::InterpretOptionExtensions(
8383
0
    OptionsToInterpret* options_to_interpret) {
8384
0
  return InterpretOptionsImpl(options_to_interpret, /*skip_extensions=*/false);
8385
0
}
8386
bool DescriptorBuilder::OptionInterpreter::InterpretNonExtensionOptions(
8387
0
    OptionsToInterpret* options_to_interpret) {
8388
0
  return InterpretOptionsImpl(options_to_interpret, /*skip_extensions=*/true);
8389
0
}
8390
bool DescriptorBuilder::OptionInterpreter::InterpretOptionsImpl(
8391
0
    OptionsToInterpret* options_to_interpret, bool skip_extensions) {
8392
  // Note that these may be in different pools, so we can't use the same
8393
  // descriptor and reflection objects on both.
8394
0
  Message* options = options_to_interpret->options;
8395
0
  const Message* original_options = options_to_interpret->original_options;
8396
8397
0
  bool failed = false;
8398
0
  options_to_interpret_ = options_to_interpret;
8399
8400
  // Find the uninterpreted_option field in the mutable copy of the options
8401
  // and clear them, since we're about to interpret them.
8402
0
  const FieldDescriptor* uninterpreted_options_field =
8403
0
      options->GetDescriptor()->FindFieldByName("uninterpreted_option");
8404
0
  ABSL_CHECK(uninterpreted_options_field != nullptr)
8405
0
      << "No field named \"uninterpreted_option\" in the Options proto.";
8406
0
  options->GetReflection()->ClearField(options, uninterpreted_options_field);
8407
8408
0
  std::vector<int> src_path = options_to_interpret->element_path;
8409
0
  src_path.push_back(uninterpreted_options_field->number());
8410
8411
  // Find the uninterpreted_option field in the original options.
8412
0
  const FieldDescriptor* original_uninterpreted_options_field =
8413
0
      original_options->GetDescriptor()->FindFieldByName(
8414
0
          "uninterpreted_option");
8415
0
  ABSL_CHECK(original_uninterpreted_options_field != nullptr)
8416
0
      << "No field named \"uninterpreted_option\" in the Options proto.";
8417
8418
0
  const int num_uninterpreted_options =
8419
0
      original_options->GetReflection()->FieldSize(
8420
0
          *original_options, original_uninterpreted_options_field);
8421
0
  for (int i = 0; i < num_uninterpreted_options; ++i) {
8422
0
    src_path.push_back(i);
8423
0
    uninterpreted_option_ = DownCast<const UninterpretedOption*>(
8424
0
        &original_options->GetReflection()->GetRepeatedMessage(
8425
0
            *original_options, original_uninterpreted_options_field, i));
8426
0
    if (!InterpretSingleOption(options, src_path,
8427
0
                               options_to_interpret->element_path,
8428
0
                               skip_extensions)) {
8429
      // Error already added by InterpretSingleOption().
8430
0
      failed = true;
8431
0
      break;
8432
0
    }
8433
0
    src_path.pop_back();
8434
0
  }
8435
  // Reset these, so we don't have any dangling pointers.
8436
0
  uninterpreted_option_ = nullptr;
8437
0
  options_to_interpret_ = nullptr;
8438
8439
0
  if (!failed) {
8440
    // InterpretSingleOption() added the interpreted options in the
8441
    // UnknownFieldSet, in case the option isn't yet known to us.  Now we
8442
    // serialize the options message and deserialize it back.  That way, any
8443
    // option fields that we do happen to know about will get moved from the
8444
    // UnknownFieldSet into the real fields, and thus be available right away.
8445
    // If they are not known, that's OK too. They will get reparsed into the
8446
    // UnknownFieldSet and wait there until the message is parsed by something
8447
    // that does know about the options.
8448
8449
    // Keep the unparsed options around in case the reparsing fails.
8450
0
    std::unique_ptr<Message> unparsed_options(options->New());
8451
0
    options->GetReflection()->Swap(unparsed_options.get(), options);
8452
8453
0
    std::string buf;
8454
0
    if (!unparsed_options->AppendToString(&buf) ||
8455
0
        !options->ParseFromString(buf)) {
8456
0
      builder_->AddError(
8457
0
          options_to_interpret->element_name, *original_options,
8458
0
          DescriptorPool::ErrorCollector::OTHER, [&] {
8459
0
            return absl::StrCat(
8460
0
                "Some options could not be correctly parsed using the proto "
8461
0
                "descriptors compiled into this binary.\n"
8462
0
                "Unparsed options: ",
8463
0
                unparsed_options->ShortDebugString(),
8464
0
                "\n"
8465
0
                "Parsing attempt:  ",
8466
0
                options->ShortDebugString());
8467
0
          });
8468
      // Restore the unparsed options.
8469
0
      options->GetReflection()->Swap(unparsed_options.get(), options);
8470
0
    }
8471
0
  }
8472
8473
0
  return !failed;
8474
0
}
8475
8476
bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
8477
    Message* options, const std::vector<int>& src_path,
8478
0
    const std::vector<int>& options_path, bool skip_extensions) {
8479
  // First do some basic validation.
8480
0
  if (uninterpreted_option_->name_size() == 0) {
8481
    // This should never happen unless the parser has gone seriously awry or
8482
    // someone has manually created the uninterpreted option badly.
8483
0
    if (skip_extensions) {
8484
      // Come back to it later.
8485
0
      return true;
8486
0
    }
8487
0
    return AddNameError(
8488
0
        []() -> std::string { return "Option must have a name."; });
8489
0
  }
8490
0
  if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") {
8491
0
    if (skip_extensions) {
8492
      // Come back to it later.
8493
0
      return true;
8494
0
    }
8495
0
    return AddNameError([]() -> std::string {
8496
0
      return "Option must not use reserved name \"uninterpreted_option\".";
8497
0
    });
8498
0
  }
8499
8500
0
  if (skip_extensions == uninterpreted_option_->name(0).is_extension()) {
8501
    // Allow feature and option interpretation to occur in two phases.  This is
8502
    // necessary because features *are* options and need to be interpreted
8503
    // before resolving them.  However, options can also *have* features
8504
    // attached to them.
8505
0
    return true;
8506
0
  }
8507
8508
0
  const Descriptor* options_descriptor = nullptr;
8509
  // Get the options message's descriptor from the builder's pool, so that we
8510
  // get the version that knows about any extension options declared in the file
8511
  // we're currently building. The descriptor should be there as long as the
8512
  // file we're building imported descriptor.proto.
8513
8514
  // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
8515
  // DescriptorPool::FindMessageTypeByName() because we're already holding the
8516
  // pool's mutex, and the latter method locks it again.  We don't use
8517
  // FindSymbol() because files that use custom options only need to depend on
8518
  // the file that defines the option, not descriptor.proto itself.
8519
0
  Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
8520
0
      options->GetDescriptor()->full_name());
8521
0
  options_descriptor = symbol.descriptor();
8522
0
  if (options_descriptor == nullptr) {
8523
    // The options message's descriptor was not in the builder's pool, so use
8524
    // the standard version from the generated pool. We're not holding the
8525
    // generated pool's mutex, so we can search it the straightforward way.
8526
0
    options_descriptor = options->GetDescriptor();
8527
0
  }
8528
0
  ABSL_CHECK(options_descriptor);
8529
8530
  // We iterate over the name parts to drill into the submessages until we find
8531
  // the leaf field for the option. As we drill down we remember the current
8532
  // submessage's descriptor in |descriptor| and the next field in that
8533
  // submessage in |field|. We also track the fields we're drilling down
8534
  // through in |intermediate_fields|. As we go, we reconstruct the full option
8535
  // name in |debug_msg_name|, for use in error messages.
8536
0
  const Descriptor* descriptor = options_descriptor;
8537
0
  const FieldDescriptor* field = nullptr;
8538
0
  std::vector<const FieldDescriptor*> intermediate_fields;
8539
0
  std::string debug_msg_name = "";
8540
8541
0
  std::vector<int> dest_path = options_path;
8542
8543
0
  for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
8544
0
    builder_->undefine_resolved_name_.clear();
8545
0
    const std::string& name_part = uninterpreted_option_->name(i).name_part();
8546
0
    if (!debug_msg_name.empty()) {
8547
0
      absl::StrAppend(&debug_msg_name, ".");
8548
0
    }
8549
0
    if (uninterpreted_option_->name(i).is_extension()) {
8550
0
      absl::StrAppend(&debug_msg_name, "(", name_part, ")");
8551
      // Search for the extension's descriptor as an extension in the builder's
8552
      // pool. Note that we use DescriptorBuilder::LookupSymbol(), not
8553
      // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
8554
      // relative lookups, and 2) because we're already holding the pool's
8555
      // mutex, and the latter method locks it again.
8556
0
      symbol =
8557
0
          builder_->LookupSymbol(name_part, options_to_interpret_->name_scope);
8558
0
      field = symbol.field_descriptor();
8559
      // If we don't find the field then the field's descriptor was not in the
8560
      // builder's pool, but there's no point in looking in the generated
8561
      // pool. We require that you import the file that defines any extensions
8562
      // you use, so they must be present in the builder's pool.
8563
0
    } else {
8564
0
      absl::StrAppend(&debug_msg_name, name_part);
8565
      // Search for the field's descriptor as a regular field.
8566
0
      field = descriptor->FindFieldByName(name_part);
8567
0
    }
8568
8569
0
    if (field == nullptr) {
8570
0
      if (get_allow_unknown(builder_->pool_)) {
8571
        // We can't find the option, but AllowUnknownDependencies() is enabled,
8572
        // so we will just leave it as uninterpreted.
8573
0
        AddWithoutInterpreting(*uninterpreted_option_, options);
8574
0
        return true;
8575
0
      } else if (!(builder_->undefine_resolved_name_).empty()) {
8576
        // Option is resolved to a name which is not defined.
8577
0
        return AddNameError([&] {
8578
0
          return absl::StrCat(
8579
0
              "Option \"", debug_msg_name, "\" is resolved to \"(",
8580
0
              builder_->undefine_resolved_name_,
8581
0
              ")\", which is not defined. The innermost scope is searched "
8582
0
              "first "
8583
0
              "in name resolution. Consider using a leading '.'(i.e., \"(.",
8584
0
              debug_msg_name.substr(1),
8585
0
              "\") to start from the outermost scope.");
8586
0
        });
8587
0
      } else {
8588
0
        return AddNameError([&] {
8589
0
          return absl::StrCat(
8590
0
              "Option \"", debug_msg_name, "\" unknown. Ensure that your proto",
8591
0
              " definition file imports the proto which defines the option.");
8592
0
        });
8593
0
      }
8594
0
    } else if (field->containing_type() != descriptor) {
8595
0
      if (get_is_placeholder(field->containing_type())) {
8596
        // The field is an extension of a placeholder type, so we can't
8597
        // reliably verify whether it is a valid extension to use here (e.g.
8598
        // we don't know if it is an extension of the correct *Options message,
8599
        // or if it has a valid field number, etc.).  Just leave it as
8600
        // uninterpreted instead.
8601
0
        AddWithoutInterpreting(*uninterpreted_option_, options);
8602
0
        return true;
8603
0
      } else {
8604
        // This can only happen if, due to some insane misconfiguration of the
8605
        // pools, we find the options message in one pool but the field in
8606
        // another. This would probably imply a hefty bug somewhere.
8607
0
        return AddNameError([&] {
8608
0
          return absl::StrCat("Option field \"", debug_msg_name,
8609
0
                              "\" is not a field or extension of message \"",
8610
0
                              descriptor->name(), "\".");
8611
0
        });
8612
0
      }
8613
0
    } else {
8614
      // accumulate field numbers to form path to interpreted option
8615
0
      dest_path.push_back(field->number());
8616
8617
0
      if (i < uninterpreted_option_->name_size() - 1) {
8618
0
        if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
8619
0
          return AddNameError([&] {
8620
0
            return absl::StrCat("Option \"", debug_msg_name,
8621
0
                                "\" is an atomic type, not a message.");
8622
0
          });
8623
0
        } else if (field->is_repeated()) {
8624
0
          return AddNameError([&] {
8625
0
            return absl::StrCat("Option field \"", debug_msg_name,
8626
0
                                "\" is a repeated message. Repeated message "
8627
0
                                "options must be initialized using an "
8628
0
                                "aggregate value.");
8629
0
          });
8630
0
        } else {
8631
          // Drill down into the submessage.
8632
0
          intermediate_fields.push_back(field);
8633
0
          descriptor = field->message_type();
8634
0
        }
8635
0
      }
8636
0
    }
8637
0
  }
8638
8639
  // We've found the leaf field. Now we use UnknownFieldSets to set its value
8640
  // on the options message. We do so because the message may not yet know
8641
  // about its extension fields, so we may not be able to set the fields
8642
  // directly. But the UnknownFieldSets will serialize to the same wire-format
8643
  // message, so reading that message back in once the extension fields are
8644
  // known will populate them correctly.
8645
8646
  // First see if the option is already set.
8647
0
  if (!field->is_repeated() &&
8648
0
      !ExamineIfOptionIsSet(
8649
0
          intermediate_fields.begin(), intermediate_fields.end(), field,
8650
0
          debug_msg_name,
8651
0
          options->GetReflection()->GetUnknownFields(*options))) {
8652
0
    return false;  // ExamineIfOptionIsSet() already added the error.
8653
0
  }
8654
8655
  // First set the value on the UnknownFieldSet corresponding to the
8656
  // innermost message.
8657
0
  std::unique_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet());
8658
0
  if (!SetOptionValue(field, unknown_fields.get())) {
8659
0
    return false;  // SetOptionValue() already added the error.
8660
0
  }
8661
8662
  // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all
8663
  // the intermediate messages.
8664
0
  for (std::vector<const FieldDescriptor*>::reverse_iterator iter =
8665
0
           intermediate_fields.rbegin();
8666
0
       iter != intermediate_fields.rend(); ++iter) {
8667
0
    std::unique_ptr<UnknownFieldSet> parent_unknown_fields(
8668
0
        new UnknownFieldSet());
8669
0
    switch ((*iter)->type()) {
8670
0
      case FieldDescriptor::TYPE_MESSAGE: {
8671
0
        std::string* outstr =
8672
0
            parent_unknown_fields->AddLengthDelimited((*iter)->number());
8673
0
        ABSL_CHECK(unknown_fields->SerializeToString(outstr))
8674
0
            << "Unexpected failure while serializing option submessage "
8675
0
            << debug_msg_name << "\".";
8676
0
        break;
8677
0
      }
8678
8679
0
      case FieldDescriptor::TYPE_GROUP: {
8680
0
        parent_unknown_fields->AddGroup((*iter)->number())
8681
0
            ->MergeFrom(*unknown_fields);
8682
0
        break;
8683
0
      }
8684
8685
0
      default:
8686
0
        ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
8687
0
                        << (*iter)->type();
8688
0
        return false;
8689
0
    }
8690
0
    unknown_fields.reset(parent_unknown_fields.release());
8691
0
  }
8692
8693
  // Now merge the UnknownFieldSet corresponding to the top-level message into
8694
  // the options message.
8695
0
  options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
8696
0
      *unknown_fields);
8697
8698
  // record the element path of the interpreted option
8699
0
  if (field->is_repeated()) {
8700
0
    int index = repeated_option_counts_[dest_path]++;
8701
0
    dest_path.push_back(index);
8702
0
  }
8703
0
  interpreted_paths_[src_path] = dest_path;
8704
8705
0
  return true;
8706
0
}
8707
8708
void DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo(
8709
0
    SourceCodeInfo* info) {
8710
0
  if (interpreted_paths_.empty()) {
8711
    // nothing to do!
8712
0
    return;
8713
0
  }
8714
8715
  // We find locations that match keys in interpreted_paths_ and
8716
  // 1) replace the path with the corresponding value in interpreted_paths_
8717
  // 2) remove any subsequent sub-locations (sub-location is one whose path
8718
  //    has the parent path as a prefix)
8719
  //
8720
  // To avoid quadratic behavior of removing interior rows as we go,
8721
  // we keep a copy. But we don't actually copy anything until we've
8722
  // found the first match (so if the source code info has no locations
8723
  // that need to be changed, there is zero copy overhead).
8724
8725
0
  RepeatedPtrField<SourceCodeInfo_Location>* locs = info->mutable_location();
8726
0
  RepeatedPtrField<SourceCodeInfo_Location> new_locs;
8727
0
  bool copying = false;
8728
8729
0
  std::vector<int> pathv;
8730
0
  bool matched = false;
8731
8732
0
  for (RepeatedPtrField<SourceCodeInfo_Location>::iterator loc = locs->begin();
8733
0
       loc != locs->end(); loc++) {
8734
0
    if (matched) {
8735
      // see if this location is in the range to remove
8736
0
      bool loc_matches = true;
8737
0
      if (loc->path_size() < static_cast<int64_t>(pathv.size())) {
8738
0
        loc_matches = false;
8739
0
      } else {
8740
0
        for (size_t j = 0; j < pathv.size(); j++) {
8741
0
          if (loc->path(j) != pathv[j]) {
8742
0
            loc_matches = false;
8743
0
            break;
8744
0
          }
8745
0
        }
8746
0
      }
8747
8748
0
      if (loc_matches) {
8749
        // don't copy this row since it is a sub-location that we're removing
8750
0
        continue;
8751
0
      }
8752
8753
0
      matched = false;
8754
0
    }
8755
8756
0
    pathv.clear();
8757
0
    for (int j = 0; j < loc->path_size(); j++) {
8758
0
      pathv.push_back(loc->path(j));
8759
0
    }
8760
8761
0
    auto entry = interpreted_paths_.find(pathv);
8762
8763
0
    if (entry == interpreted_paths_.end()) {
8764
      // not a match
8765
0
      if (copying) {
8766
0
        *new_locs.Add() = *loc;
8767
0
      }
8768
0
      continue;
8769
0
    }
8770
8771
0
    matched = true;
8772
8773
0
    if (!copying) {
8774
      // initialize the copy we are building
8775
0
      copying = true;
8776
0
      new_locs.Reserve(locs->size());
8777
0
      for (RepeatedPtrField<SourceCodeInfo_Location>::iterator it =
8778
0
               locs->begin();
8779
0
           it != loc; it++) {
8780
0
        *new_locs.Add() = *it;
8781
0
      }
8782
0
    }
8783
8784
    // add replacement and update its path
8785
0
    SourceCodeInfo_Location* replacement = new_locs.Add();
8786
0
    *replacement = *loc;
8787
0
    replacement->clear_path();
8788
0
    for (std::vector<int>::iterator rit = entry->second.begin();
8789
0
         rit != entry->second.end(); rit++) {
8790
0
      replacement->add_path(*rit);
8791
0
    }
8792
0
  }
8793
8794
  // if we made a changed copy, put it in place
8795
0
  if (copying) {
8796
0
    *locs = new_locs;
8797
0
  }
8798
0
}
8799
8800
void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting(
8801
0
    const UninterpretedOption& uninterpreted_option, Message* options) {
8802
0
  const FieldDescriptor* field =
8803
0
      options->GetDescriptor()->FindFieldByName("uninterpreted_option");
8804
0
  ABSL_CHECK(field != nullptr);
8805
8806
0
  options->GetReflection()
8807
0
      ->AddMessage(options, field)
8808
0
      ->CopyFrom(uninterpreted_option);
8809
0
}
8810
8811
bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet(
8812
    std::vector<const FieldDescriptor*>::const_iterator
8813
        intermediate_fields_iter,
8814
    std::vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
8815
    const FieldDescriptor* innermost_field, const std::string& debug_msg_name,
8816
0
    const UnknownFieldSet& unknown_fields) {
8817
  // We do linear searches of the UnknownFieldSet and its sub-groups.  This
8818
  // should be fine since it's unlikely that any one options structure will
8819
  // contain more than a handful of options.
8820
8821
0
  if (intermediate_fields_iter == intermediate_fields_end) {
8822
    // We're at the innermost submessage.
8823
0
    for (int i = 0; i < unknown_fields.field_count(); i++) {
8824
0
      if (unknown_fields.field(i).number() == innermost_field->number()) {
8825
0
        return AddNameError([&] {
8826
0
          return absl::StrCat("Option \"", debug_msg_name,
8827
0
                              "\" was already set.");
8828
0
        });
8829
0
      }
8830
0
    }
8831
0
    return true;
8832
0
  }
8833
8834
0
  for (int i = 0; i < unknown_fields.field_count(); i++) {
8835
0
    if (unknown_fields.field(i).number() ==
8836
0
        (*intermediate_fields_iter)->number()) {
8837
0
      const UnknownField* unknown_field = &unknown_fields.field(i);
8838
0
      FieldDescriptor::Type type = (*intermediate_fields_iter)->type();
8839
      // Recurse into the next submessage.
8840
0
      switch (type) {
8841
0
        case FieldDescriptor::TYPE_MESSAGE:
8842
0
          if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) {
8843
0
            UnknownFieldSet intermediate_unknown_fields;
8844
0
            if (intermediate_unknown_fields.ParseFromString(
8845
0
                    unknown_field->length_delimited()) &&
8846
0
                !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
8847
0
                                      intermediate_fields_end, innermost_field,
8848
0
                                      debug_msg_name,
8849
0
                                      intermediate_unknown_fields)) {
8850
0
              return false;  // Error already added.
8851
0
            }
8852
0
          }
8853
0
          break;
8854
8855
0
        case FieldDescriptor::TYPE_GROUP:
8856
0
          if (unknown_field->type() == UnknownField::TYPE_GROUP) {
8857
0
            if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
8858
0
                                      intermediate_fields_end, innermost_field,
8859
0
                                      debug_msg_name, unknown_field->group())) {
8860
0
              return false;  // Error already added.
8861
0
            }
8862
0
          }
8863
0
          break;
8864
8865
0
        default:
8866
0
          ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type;
8867
0
          return false;
8868
0
      }
8869
0
    }
8870
0
  }
8871
0
  return true;
8872
0
}
8873
8874
namespace {
8875
// Helpers for method below
8876
8877
template <typename T>
8878
std::string ValueOutOfRange(absl::string_view type_name,
8879
0
                            absl::string_view option_name) {
8880
0
  return absl::StrFormat("Value out of range, %d to %d, for %s option \"%s\".",
8881
0
                         std::numeric_limits<T>::min(),
8882
0
                         std::numeric_limits<T>::max(), type_name, option_name);
8883
0
}
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueOutOfRange<int>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueOutOfRange<long>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueOutOfRange<unsigned int>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
8884
8885
template <typename T>
8886
std::string ValueMustBeInt(absl::string_view type_name,
8887
0
                           absl::string_view option_name) {
8888
0
  return absl::StrFormat(
8889
0
      "Value must be integer, from %d to %d, for %s option \"%s\".",
8890
0
      std::numeric_limits<T>::min(), std::numeric_limits<T>::max(), type_name,
8891
0
      option_name);
8892
0
}
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueMustBeInt<int>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueMustBeInt<long>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueMustBeInt<unsigned int>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
Unexecuted instantiation: descriptor.cc:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > google::protobuf::(anonymous namespace)::ValueMustBeInt<unsigned long>(absl::lts_20230802::string_view, absl::lts_20230802::string_view)
8893
8894
}  // namespace
8895
8896
bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
8897
0
    const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
8898
  // We switch on the CppType to validate.
8899
0
  switch (option_field->cpp_type()) {
8900
0
    case FieldDescriptor::CPPTYPE_INT32:
8901
0
      if (uninterpreted_option_->has_positive_int_value()) {
8902
0
        if (uninterpreted_option_->positive_int_value() >
8903
0
            static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) {
8904
0
          return AddValueError([&] {
8905
0
            return ValueOutOfRange<int32_t>("int32", option_field->full_name());
8906
0
          });
8907
0
        } else {
8908
0
          SetInt32(option_field->number(),
8909
0
                   uninterpreted_option_->positive_int_value(),
8910
0
                   option_field->type(), unknown_fields);
8911
0
        }
8912
0
      } else if (uninterpreted_option_->has_negative_int_value()) {
8913
0
        if (uninterpreted_option_->negative_int_value() <
8914
0
            static_cast<int64_t>(std::numeric_limits<int32_t>::min())) {
8915
0
          return AddValueError([&] {
8916
0
            return ValueOutOfRange<int32_t>("int32", option_field->full_name());
8917
0
          });
8918
0
        } else {
8919
0
          SetInt32(option_field->number(),
8920
0
                   uninterpreted_option_->negative_int_value(),
8921
0
                   option_field->type(), unknown_fields);
8922
0
        }
8923
0
      } else {
8924
0
        return AddValueError([&] {
8925
0
          return ValueMustBeInt<int32_t>("int32", option_field->full_name());
8926
0
        });
8927
0
      }
8928
0
      break;
8929
8930
0
    case FieldDescriptor::CPPTYPE_INT64:
8931
0
      if (uninterpreted_option_->has_positive_int_value()) {
8932
0
        if (uninterpreted_option_->positive_int_value() >
8933
0
            static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
8934
0
          return AddValueError([&] {
8935
0
            return ValueOutOfRange<int64_t>("int64", option_field->full_name());
8936
0
          });
8937
0
        } else {
8938
0
          SetInt64(option_field->number(),
8939
0
                   uninterpreted_option_->positive_int_value(),
8940
0
                   option_field->type(), unknown_fields);
8941
0
        }
8942
0
      } else if (uninterpreted_option_->has_negative_int_value()) {
8943
0
        SetInt64(option_field->number(),
8944
0
                 uninterpreted_option_->negative_int_value(),
8945
0
                 option_field->type(), unknown_fields);
8946
0
      } else {
8947
0
        return AddValueError([&] {
8948
0
          return ValueMustBeInt<int64_t>("int64", option_field->full_name());
8949
0
        });
8950
0
      }
8951
0
      break;
8952
8953
0
    case FieldDescriptor::CPPTYPE_UINT32:
8954
0
      if (uninterpreted_option_->has_positive_int_value()) {
8955
0
        if (uninterpreted_option_->positive_int_value() >
8956
0
            std::numeric_limits<uint32_t>::max()) {
8957
0
          return AddValueError([&] {
8958
0
            return ValueOutOfRange<uint32_t>("uint32",
8959
0
                                             option_field->full_name());
8960
0
          });
8961
0
        } else {
8962
0
          SetUInt32(option_field->number(),
8963
0
                    uninterpreted_option_->positive_int_value(),
8964
0
                    option_field->type(), unknown_fields);
8965
0
        }
8966
0
      } else {
8967
0
        return AddValueError([&] {
8968
0
          return ValueMustBeInt<uint32_t>("uint32", option_field->full_name());
8969
0
        });
8970
0
      }
8971
0
      break;
8972
8973
0
    case FieldDescriptor::CPPTYPE_UINT64:
8974
0
      if (uninterpreted_option_->has_positive_int_value()) {
8975
0
        SetUInt64(option_field->number(),
8976
0
                  uninterpreted_option_->positive_int_value(),
8977
0
                  option_field->type(), unknown_fields);
8978
0
      } else {
8979
0
        return AddValueError([&] {
8980
0
          return ValueMustBeInt<uint64_t>("uint64", option_field->full_name());
8981
0
        });
8982
0
      }
8983
0
      break;
8984
8985
0
    case FieldDescriptor::CPPTYPE_FLOAT: {
8986
0
      float value;
8987
0
      if (uninterpreted_option_->has_double_value()) {
8988
0
        value = uninterpreted_option_->double_value();
8989
0
      } else if (uninterpreted_option_->has_positive_int_value()) {
8990
0
        value = uninterpreted_option_->positive_int_value();
8991
0
      } else if (uninterpreted_option_->has_negative_int_value()) {
8992
0
        value = uninterpreted_option_->negative_int_value();
8993
0
      } else {
8994
0
        return AddValueError([&] {
8995
0
          return absl::StrCat("Value must be number for float option \"",
8996
0
                              option_field->full_name(), "\".");
8997
0
        });
8998
0
      }
8999
0
      unknown_fields->AddFixed32(option_field->number(),
9000
0
                                 internal::WireFormatLite::EncodeFloat(value));
9001
0
      break;
9002
0
    }
9003
9004
0
    case FieldDescriptor::CPPTYPE_DOUBLE: {
9005
0
      double value;
9006
0
      if (uninterpreted_option_->has_double_value()) {
9007
0
        value = uninterpreted_option_->double_value();
9008
0
      } else if (uninterpreted_option_->has_positive_int_value()) {
9009
0
        value = uninterpreted_option_->positive_int_value();
9010
0
      } else if (uninterpreted_option_->has_negative_int_value()) {
9011
0
        value = uninterpreted_option_->negative_int_value();
9012
0
      } else {
9013
0
        return AddValueError([&] {
9014
0
          return absl::StrCat("Value must be number for double option \"",
9015
0
                              option_field->full_name(), "\".");
9016
0
        });
9017
0
      }
9018
0
      unknown_fields->AddFixed64(option_field->number(),
9019
0
                                 internal::WireFormatLite::EncodeDouble(value));
9020
0
      break;
9021
0
    }
9022
9023
0
    case FieldDescriptor::CPPTYPE_BOOL:
9024
0
      uint64_t value;
9025
0
      if (!uninterpreted_option_->has_identifier_value()) {
9026
0
        return AddValueError([&] {
9027
0
          return absl::StrCat("Value must be identifier for boolean option \"",
9028
0
                              option_field->full_name(), "\".");
9029
0
        });
9030
0
      }
9031
0
      if (uninterpreted_option_->identifier_value() == "true") {
9032
0
        value = 1;
9033
0
      } else if (uninterpreted_option_->identifier_value() == "false") {
9034
0
        value = 0;
9035
0
      } else {
9036
0
        return AddValueError([&] {
9037
0
          return absl::StrCat(
9038
0
              "Value must be \"true\" or \"false\" for boolean option \"",
9039
0
              option_field->full_name(), "\".");
9040
0
        });
9041
0
      }
9042
0
      unknown_fields->AddVarint(option_field->number(), value);
9043
0
      break;
9044
9045
0
    case FieldDescriptor::CPPTYPE_ENUM: {
9046
0
      if (!uninterpreted_option_->has_identifier_value()) {
9047
0
        return AddValueError([&] {
9048
0
          return absl::StrCat(
9049
0
              "Value must be identifier for enum-valued option \"",
9050
0
              option_field->full_name(), "\".");
9051
0
        });
9052
0
      }
9053
0
      const EnumDescriptor* enum_type = option_field->enum_type();
9054
0
      const std::string& value_name = uninterpreted_option_->identifier_value();
9055
0
      const EnumValueDescriptor* enum_value = nullptr;
9056
9057
0
      if (enum_type->file()->pool() != DescriptorPool::generated_pool()) {
9058
        // Note that the enum value's fully-qualified name is a sibling of the
9059
        // enum's name, not a child of it.
9060
0
        std::string fully_qualified_name = enum_type->full_name();
9061
0
        fully_qualified_name.resize(fully_qualified_name.size() -
9062
0
                                    enum_type->name().size());
9063
0
        fully_qualified_name += value_name;
9064
9065
        // Search for the enum value's descriptor in the builder's pool. Note
9066
        // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
9067
        // DescriptorPool::FindEnumValueByName() because we're already holding
9068
        // the pool's mutex, and the latter method locks it again.
9069
0
        Symbol symbol =
9070
0
            builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
9071
0
        if (auto* candicate_descriptor = symbol.enum_value_descriptor()) {
9072
0
          if (candicate_descriptor->type() != enum_type) {
9073
0
            return AddValueError([&] {
9074
0
              return absl::StrCat(
9075
0
                  "Enum type \"", enum_type->full_name(),
9076
0
                  "\" has no value named \"", value_name, "\" for option \"",
9077
0
                  option_field->full_name(),
9078
0
                  "\". This appears to be a value from a sibling type.");
9079
0
            });
9080
0
          } else {
9081
0
            enum_value = candicate_descriptor;
9082
0
          }
9083
0
        }
9084
0
      } else {
9085
        // The enum type is in the generated pool, so we can search for the
9086
        // value there.
9087
0
        enum_value = enum_type->FindValueByName(value_name);
9088
0
      }
9089
9090
0
      if (enum_value == nullptr) {
9091
0
        return AddValueError([&] {
9092
0
          return absl::StrCat(
9093
0
              "Enum type \"", option_field->enum_type()->full_name(),
9094
0
              "\" has no value named \"", value_name, "\" for option \"",
9095
0
              option_field->full_name(), "\".");
9096
0
        });
9097
0
      } else {
9098
        // Sign-extension is not a problem, since we cast directly from int32_t
9099
        // to uint64_t, without first going through uint32_t.
9100
0
        unknown_fields->AddVarint(
9101
0
            option_field->number(),
9102
0
            static_cast<uint64_t>(static_cast<int64_t>(enum_value->number())));
9103
0
      }
9104
0
      break;
9105
0
    }
9106
9107
0
    case FieldDescriptor::CPPTYPE_STRING:
9108
0
      if (!uninterpreted_option_->has_string_value()) {
9109
0
        return AddValueError([&] {
9110
0
          return absl::StrCat(
9111
0
              "Value must be quoted string for string option \"",
9112
0
              option_field->full_name(), "\".");
9113
0
        });
9114
0
      }
9115
      // The string has already been unquoted and unescaped by the parser.
9116
0
      unknown_fields->AddLengthDelimited(option_field->number(),
9117
0
                                         uninterpreted_option_->string_value());
9118
0
      break;
9119
9120
0
    case FieldDescriptor::CPPTYPE_MESSAGE:
9121
0
      if (!SetAggregateOption(option_field, unknown_fields)) {
9122
0
        return false;
9123
0
      }
9124
0
      break;
9125
0
  }
9126
9127
0
  return true;
9128
0
}
9129
9130
class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
9131
    : public TextFormat::Finder {
9132
 public:
9133
  DescriptorBuilder* builder_;
9134
9135
  const Descriptor* FindAnyType(const Message& /*message*/,
9136
                                const std::string& prefix,
9137
0
                                const std::string& name) const override {
9138
0
    if (prefix != internal::kTypeGoogleApisComPrefix &&
9139
0
        prefix != internal::kTypeGoogleProdComPrefix) {
9140
0
      return nullptr;
9141
0
    }
9142
0
    assert_mutex_held(builder_->pool_);
9143
0
    return builder_->FindSymbol(name).descriptor();
9144
0
  }
9145
9146
  const FieldDescriptor* FindExtension(Message* message,
9147
0
                                       const std::string& name) const override {
9148
0
    assert_mutex_held(builder_->pool_);
9149
0
    const Descriptor* descriptor = message->GetDescriptor();
9150
0
    Symbol result =
9151
0
        builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name());
9152
0
    if (auto* field = result.field_descriptor()) {
9153
0
      return field;
9154
0
    } else if (result.type() == Symbol::MESSAGE &&
9155
0
               descriptor->options().message_set_wire_format()) {
9156
0
      const Descriptor* foreign_type = result.descriptor();
9157
      // The text format allows MessageSet items to be specified using
9158
      // the type name, rather than the extension identifier. If the symbol
9159
      // lookup returned a Message, and the enclosing Message has
9160
      // message_set_wire_format = true, then return the message set
9161
      // extension, if one exists.
9162
0
      for (int i = 0; i < foreign_type->extension_count(); i++) {
9163
0
        const FieldDescriptor* extension = foreign_type->extension(i);
9164
0
        if (extension->containing_type() == descriptor &&
9165
0
            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
9166
0
            extension->is_optional() &&
9167
0
            extension->message_type() == foreign_type) {
9168
          // Found it.
9169
0
          return extension;
9170
0
        }
9171
0
      }
9172
0
    }
9173
0
    return nullptr;
9174
0
  }
9175
};
9176
9177
// A custom error collector to record any text-format parsing errors
9178
namespace {
9179
class AggregateErrorCollector : public io::ErrorCollector {
9180
 public:
9181
  std::string error_;
9182
9183
  void RecordError(int /* line */, int /* column */,
9184
0
                   const absl::string_view message) override {
9185
0
    if (!error_.empty()) {
9186
0
      absl::StrAppend(&error_, "; ");
9187
0
    }
9188
0
    absl::StrAppend(&error_, message);
9189
0
  }
9190
9191
  void RecordWarning(int /* line */, int /* column */,
9192
0
                     const absl::string_view /* message */) override {
9193
    // Ignore warnings
9194
0
  }
9195
};
9196
}  // namespace
9197
9198
// We construct a dynamic message of the type corresponding to
9199
// option_field, parse the supplied text-format string into this
9200
// message, and serialize the resulting message to produce the value.
9201
bool DescriptorBuilder::OptionInterpreter::SetAggregateOption(
9202
0
    const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields) {
9203
0
  if (!uninterpreted_option_->has_aggregate_value()) {
9204
0
    return AddValueError([&] {
9205
0
      return absl::StrCat("Option \"", option_field->full_name(),
9206
0
                          "\" is a message. "
9207
0
                          "To set the entire message, use syntax like \"",
9208
0
                          option_field->name(),
9209
0
                          " = { <proto text format> }\". "
9210
0
                          "To set fields within it, use syntax like \"",
9211
0
                          option_field->name(), ".foo = value\".");
9212
0
    });
9213
0
  }
9214
9215
0
  const Descriptor* type = option_field->message_type();
9216
0
  std::unique_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
9217
0
  ABSL_CHECK(dynamic.get() != nullptr)
9218
0
      << "Could not create an instance of " << option_field->DebugString();
9219
9220
0
  AggregateErrorCollector collector;
9221
0
  AggregateOptionFinder finder;
9222
0
  finder.builder_ = builder_;
9223
0
  TextFormat::Parser parser;
9224
0
  parser.RecordErrorsTo(&collector);
9225
0
  parser.SetFinder(&finder);
9226
0
  if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
9227
0
                              dynamic.get())) {
9228
0
    AddValueError([&] {
9229
0
      return absl::StrCat("Error while parsing option value for \"",
9230
0
                          option_field->name(), "\": ", collector.error_);
9231
0
    });
9232
0
    return false;
9233
0
  } else {
9234
0
    std::string serial;
9235
0
    dynamic->SerializeToString(&serial);  // Never fails
9236
0
    if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) {
9237
0
      unknown_fields->AddLengthDelimited(option_field->number(), serial);
9238
0
    } else {
9239
0
      ABSL_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP);
9240
0
      UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number());
9241
0
      group->ParseFromString(serial);
9242
0
    }
9243
0
    return true;
9244
0
  }
9245
0
}
9246
9247
void DescriptorBuilder::OptionInterpreter::SetInt32(
9248
    int number, int32_t value, FieldDescriptor::Type type,
9249
0
    UnknownFieldSet* unknown_fields) {
9250
0
  switch (type) {
9251
0
    case FieldDescriptor::TYPE_INT32:
9252
0
      unknown_fields->AddVarint(
9253
0
          number, static_cast<uint64_t>(static_cast<int64_t>(value)));
9254
0
      break;
9255
9256
0
    case FieldDescriptor::TYPE_SFIXED32:
9257
0
      unknown_fields->AddFixed32(number, static_cast<uint32_t>(value));
9258
0
      break;
9259
9260
0
    case FieldDescriptor::TYPE_SINT32:
9261
0
      unknown_fields->AddVarint(
9262
0
          number, internal::WireFormatLite::ZigZagEncode32(value));
9263
0
      break;
9264
9265
0
    default:
9266
0
      ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type;
9267
0
      break;
9268
0
  }
9269
0
}
9270
9271
void DescriptorBuilder::OptionInterpreter::SetInt64(
9272
    int number, int64_t value, FieldDescriptor::Type type,
9273
0
    UnknownFieldSet* unknown_fields) {
9274
0
  switch (type) {
9275
0
    case FieldDescriptor::TYPE_INT64:
9276
0
      unknown_fields->AddVarint(number, static_cast<uint64_t>(value));
9277
0
      break;
9278
9279
0
    case FieldDescriptor::TYPE_SFIXED64:
9280
0
      unknown_fields->AddFixed64(number, static_cast<uint64_t>(value));
9281
0
      break;
9282
9283
0
    case FieldDescriptor::TYPE_SINT64:
9284
0
      unknown_fields->AddVarint(
9285
0
          number, internal::WireFormatLite::ZigZagEncode64(value));
9286
0
      break;
9287
9288
0
    default:
9289
0
      ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type;
9290
0
      break;
9291
0
  }
9292
0
}
9293
9294
void DescriptorBuilder::OptionInterpreter::SetUInt32(
9295
    int number, uint32_t value, FieldDescriptor::Type type,
9296
0
    UnknownFieldSet* unknown_fields) {
9297
0
  switch (type) {
9298
0
    case FieldDescriptor::TYPE_UINT32:
9299
0
      unknown_fields->AddVarint(number, static_cast<uint64_t>(value));
9300
0
      break;
9301
9302
0
    case FieldDescriptor::TYPE_FIXED32:
9303
0
      unknown_fields->AddFixed32(number, static_cast<uint32_t>(value));
9304
0
      break;
9305
9306
0
    default:
9307
0
      ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
9308
0
      break;
9309
0
  }
9310
0
}
9311
9312
void DescriptorBuilder::OptionInterpreter::SetUInt64(
9313
    int number, uint64_t value, FieldDescriptor::Type type,
9314
0
    UnknownFieldSet* unknown_fields) {
9315
0
  switch (type) {
9316
0
    case FieldDescriptor::TYPE_UINT64:
9317
0
      unknown_fields->AddVarint(number, value);
9318
0
      break;
9319
9320
0
    case FieldDescriptor::TYPE_FIXED64:
9321
0
      unknown_fields->AddFixed64(number, value);
9322
0
      break;
9323
9324
0
    default:
9325
0
      ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type;
9326
0
      break;
9327
0
  }
9328
0
}
9329
9330
void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto,
9331
0
                                            const FileDescriptor* result) {
9332
0
  (void)result;  // Parameter is used by Google-internal code.
9333
9334
0
  if (!unused_dependency_.empty()) {
9335
0
    auto itr = pool_->unused_import_track_files_.find(proto.name());
9336
0
    bool is_error =
9337
0
        itr != pool_->unused_import_track_files_.end() && itr->second;
9338
0
    for (const auto* unused : unused_dependency_) {
9339
0
      auto make_error = [&] {
9340
0
        return absl::StrCat("Import ", unused->name(), " is unused.");
9341
0
      };
9342
0
      if (is_error) {
9343
0
        AddError(unused->name(), proto, DescriptorPool::ErrorCollector::IMPORT,
9344
0
                 make_error);
9345
0
      } else {
9346
0
        AddWarning(unused->name(), proto,
9347
0
                   DescriptorPool::ErrorCollector::IMPORT, make_error);
9348
0
      }
9349
0
    }
9350
0
  }
9351
0
}
9352
9353
Symbol DescriptorPool::CrossLinkOnDemandHelper(absl::string_view name,
9354
0
                                               bool expecting_enum) const {
9355
0
  (void)expecting_enum;  // Parameter is used by Google-internal code.
9356
0
  auto lookup_name = std::string(name);
9357
0
  if (!lookup_name.empty() && lookup_name[0] == '.') {
9358
0
    lookup_name = lookup_name.substr(1);
9359
0
  }
9360
0
  Symbol result = tables_->FindByNameHelper(this, lookup_name);
9361
0
  return result;
9362
0
}
9363
9364
// Handle the lazy import building for a message field whose type wasn't built
9365
// at cross link time. If that was the case, we saved the name of the type to
9366
// be looked up when the accessor for the type was called. Set type_,
9367
// enum_type_, message_type_, and default_value_enum_ appropriately.
9368
0
void FieldDescriptor::InternalTypeOnceInit() const {
9369
0
  ABSL_CHECK(file()->finished_building_ == true);
9370
0
  const EnumDescriptor* enum_type = nullptr;
9371
0
  const char* lazy_type_name = reinterpret_cast<const char*>(type_once_ + 1);
9372
0
  const char* lazy_default_value_enum_name =
9373
0
      lazy_type_name + strlen(lazy_type_name) + 1;
9374
0
  Symbol result = file()->pool()->CrossLinkOnDemandHelper(
9375
0
      lazy_type_name, type_ == FieldDescriptor::TYPE_ENUM);
9376
0
  if (result.type() == Symbol::MESSAGE) {
9377
0
    type_ = FieldDescriptor::TYPE_MESSAGE;
9378
0
    type_descriptor_.message_type = result.descriptor();
9379
0
  } else if (result.type() == Symbol::ENUM) {
9380
0
    type_ = FieldDescriptor::TYPE_ENUM;
9381
0
    enum_type = type_descriptor_.enum_type = result.enum_descriptor();
9382
0
  }
9383
9384
0
  if (enum_type) {
9385
0
    if (lazy_default_value_enum_name[0] != '\0') {
9386
      // Have to build the full name now instead of at CrossLink time,
9387
      // because enum_type may not be known at the time.
9388
0
      std::string name = enum_type->full_name();
9389
      // Enum values reside in the same scope as the enum type.
9390
0
      std::string::size_type last_dot = name.find_last_of('.');
9391
0
      if (last_dot != std::string::npos) {
9392
0
        name = absl::StrCat(name.substr(0, last_dot), ".",
9393
0
                            lazy_default_value_enum_name);
9394
0
      } else {
9395
0
        name = lazy_default_value_enum_name;
9396
0
      }
9397
0
      Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true);
9398
0
      default_value_enum_ = result.enum_value_descriptor();
9399
0
    } else {
9400
0
      default_value_enum_ = nullptr;
9401
0
    }
9402
0
    if (!default_value_enum_) {
9403
      // We use the first defined value as the default
9404
      // if a default is not explicitly defined.
9405
0
      ABSL_CHECK(enum_type->value_count());
9406
0
      default_value_enum_ = enum_type->value(0);
9407
0
    }
9408
0
  }
9409
0
}
9410
9411
0
void FieldDescriptor::TypeOnceInit(const FieldDescriptor* to_init) {
9412
0
  to_init->InternalTypeOnceInit();
9413
0
}
9414
9415
// message_type(), enum_type(), default_value_enum(), and type()
9416
// all share the same absl::call_once init path to do lazy
9417
// import building and cross linking of a field of a message.
9418
9.99k
const Descriptor* FieldDescriptor::message_type() const {
9419
9.99k
  if (type_once_) {
9420
0
    absl::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this);
9421
0
  }
9422
9.99k
  return type_ == TYPE_MESSAGE || type_ == TYPE_GROUP
9423
9.99k
             ? type_descriptor_.message_type
9424
9.99k
             : nullptr;
9425
9.99k
}
9426
9427
126
const EnumDescriptor* FieldDescriptor::enum_type() const {
9428
126
  if (type_once_) {
9429
0
    absl::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this);
9430
0
  }
9431
126
  return type_ == TYPE_ENUM ? type_descriptor_.enum_type : nullptr;
9432
126
}
9433
9434
0
const EnumValueDescriptor* FieldDescriptor::default_value_enum() const {
9435
0
  if (type_once_) {
9436
0
    absl::call_once(*type_once_, FieldDescriptor::TypeOnceInit, this);
9437
0
  }
9438
0
  return default_value_enum_;
9439
0
}
9440
9441
0
const std::string& FieldDescriptor::PrintableNameForExtension() const {
9442
0
  const bool is_message_set_extension =
9443
0
      is_extension() &&
9444
0
      containing_type()->options().message_set_wire_format() &&
9445
0
      type() == FieldDescriptor::TYPE_MESSAGE && is_optional() &&
9446
0
      extension_scope() == message_type();
9447
0
  return is_message_set_extension ? message_type()->full_name() : full_name();
9448
0
}
9449
9450
0
void FileDescriptor::InternalDependenciesOnceInit() const {
9451
0
  ABSL_CHECK(finished_building_ == true);
9452
0
  const char* names_ptr = reinterpret_cast<const char*>(dependencies_once_ + 1);
9453
0
  for (int i = 0; i < dependency_count(); i++) {
9454
0
    const char* name = names_ptr;
9455
0
    names_ptr += strlen(name) + 1;
9456
0
    if (name[0] != '\0') {
9457
0
      dependencies_[i] = pool_->FindFileByName(name);
9458
0
    }
9459
0
  }
9460
0
}
9461
9462
0
void FileDescriptor::DependenciesOnceInit(const FileDescriptor* to_init) {
9463
0
  to_init->InternalDependenciesOnceInit();
9464
0
}
9465
9466
0
const FileDescriptor* FileDescriptor::dependency(int index) const {
9467
0
  if (dependencies_once_) {
9468
    // Do once init for all indices, as it's unlikely only a single index would
9469
    // be called, and saves on absl::call_once allocations.
9470
0
    absl::call_once(*dependencies_once_, FileDescriptor::DependenciesOnceInit,
9471
0
                    this);
9472
0
  }
9473
0
  return dependencies_[index];
9474
0
}
9475
9476
0
const Descriptor* MethodDescriptor::input_type() const {
9477
0
  return input_type_.Get(service());
9478
0
}
9479
9480
0
const Descriptor* MethodDescriptor::output_type() const {
9481
0
  return output_type_.Get(service());
9482
0
}
9483
9484
namespace internal {
9485
0
void LazyDescriptor::Set(const Descriptor* descriptor) {
9486
0
  ABSL_CHECK(!once_);
9487
0
  descriptor_ = descriptor;
9488
0
}
9489
9490
void LazyDescriptor::SetLazy(absl::string_view name,
9491
0
                             const FileDescriptor* file) {
9492
  // verify Init() has been called and Set hasn't been called yet.
9493
0
  ABSL_CHECK(!descriptor_);
9494
0
  ABSL_CHECK(!once_);
9495
0
  ABSL_CHECK(file && file->pool_);
9496
0
  ABSL_CHECK(file->pool_->lazily_build_dependencies_);
9497
0
  ABSL_CHECK(!file->finished_building_);
9498
0
  once_ = ::new (file->pool_->tables_->AllocateBytes(static_cast<int>(
9499
0
      sizeof(absl::once_flag) + name.size() + 1))) absl::once_flag{};
9500
0
  char* lazy_name = reinterpret_cast<char*>(once_ + 1);
9501
0
  memcpy(lazy_name, name.data(), name.size());
9502
0
  lazy_name[name.size()] = 0;
9503
0
}
9504
9505
0
void LazyDescriptor::Once(const ServiceDescriptor* service) {
9506
0
  if (once_) {
9507
0
    absl::call_once(*once_, [&] {
9508
0
      auto* file = service->file();
9509
0
      ABSL_CHECK(file->finished_building_);
9510
0
      const char* lazy_name = reinterpret_cast<const char*>(once_ + 1);
9511
0
      descriptor_ =
9512
0
          file->pool_->CrossLinkOnDemandHelper(lazy_name, false).descriptor();
9513
0
    });
9514
0
  }
9515
0
}
9516
9517
42
bool ParseNoReflection(absl::string_view from, google::protobuf::MessageLite& to) {
9518
42
  to.Clear();
9519
42
  const char* ptr;
9520
42
  internal::ParseContext ctx(io::CodedInputStream::GetDefaultRecursionLimit(),
9521
42
                             false, &ptr, from);
9522
42
  ptr = to._InternalParse(ptr, &ctx);
9523
42
  if (ptr == nullptr || !ctx.EndedAtLimit()) return false;
9524
42
  return to.IsInitializedWithErrors();
9525
42
}
9526
9527
namespace cpp {
9528
0
bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) {
9529
0
  if (field->legacy_enum_field_treated_as_closed()) {
9530
0
    return false;
9531
0
  }
9532
9533
0
  return field->enum_type() != nullptr && !field->enum_type()->is_closed();
9534
0
}
9535
9536
0
bool HasHasbit(const FieldDescriptor* field) {
9537
0
  return field->has_presence() && !field->real_containing_oneof() &&
9538
0
         !field->options().weak();
9539
0
}
9540
9541
0
static bool IsVerifyUtf8(const FieldDescriptor* field, bool is_lite) {
9542
0
  if (is_lite) return false;
9543
0
  return true;
9544
0
}
9545
9546
// Which level of UTF-8 enforcemant is placed on this file.
9547
0
Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field, bool is_lite) {
9548
0
  if (IsStrictUtf8(field)) {
9549
0
    return Utf8CheckMode::kStrict;
9550
0
  } else if (IsVerifyUtf8(field, is_lite)) {
9551
0
    return Utf8CheckMode::kVerify;
9552
0
  } else {
9553
0
    return Utf8CheckMode::kNone;
9554
0
  }
9555
0
}
9556
9557
10
bool IsLazilyInitializedFile(absl::string_view filename) {
9558
10
  if (filename == "third_party/protobuf/cpp_features.proto" ||
9559
10
      filename == "google/protobuf/cpp_features.proto") {
9560
2
    return true;
9561
2
  }
9562
8
  return filename == "net/proto2/proto/descriptor.proto" ||
9563
8
         filename == "google/protobuf/descriptor.proto";
9564
10
}
9565
9566
}  // namespace cpp
9567
}  // namespace internal
9568
9569
0
Edition FileDescriptor::edition() const { return edition_; }
9570
9571
namespace internal {
9572
0
absl::string_view ShortEditionName(Edition edition) {
9573
0
  return absl::StripPrefix(Edition_Name(edition), "EDITION_");
9574
0
}
9575
}  // namespace internal
9576
9577
}  // namespace protobuf
9578
}  // namespace google
9579
9580
#include "google/protobuf/port_undef.inc"