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 // This file contains miscellaneous helper code used by generated code --
13 // including lite types -- but which should not be used directly by users.
14
15 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
16 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
17
18 #include <assert.h>
19
20 #include <algorithm>
21 #include <atomic>
22 #include <climits>
23 #include <cstddef>
24 #include <initializer_list>
25 #include <memory>
26 #include <string>
27 #include <type_traits>
28 #include <utility>
29 #include <vector>
30
31 #include "google/protobuf/stubs/common.h"
32 #include "absl/base/call_once.h"
33 #include "absl/base/casts.h"
34 #include "absl/strings/string_view.h"
35 #include "absl/types/optional.h"
36 #include "google/protobuf/any.h"
37 #include "google/protobuf/has_bits.h"
38 #include "google/protobuf/implicit_weak_message.h"
39 #include "google/protobuf/message_lite.h"
40 #include "google/protobuf/port.h"
41 #include "google/protobuf/repeated_field.h"
42 #include "google/protobuf/repeated_ptr_field.h"
43 #include "google/protobuf/wire_format_lite.h"
44
45
46 // Must be included last.
47 #include "google/protobuf/port_def.inc"
48
49 #ifdef SWIG
50 #error "You cannot SWIG proto headers"
51 #endif
52
53 namespace google {
54 namespace protobuf {
55
56 class Arena;
57 class Message;
58
59 namespace io {
60 class CodedInputStream;
61 }
62
63 namespace internal {
64
65
66 // This fastpath inlines a single branch instead of having to make the
67 // InitProtobufDefaults function call.
68 // It also generates less inlined code than a function-scope static initializer.
69 PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state;
70 PROTOBUF_EXPORT void InitProtobufDefaultsSlow();
InitProtobufDefaults()71 PROTOBUF_EXPORT inline void InitProtobufDefaults() {
72 if (PROTOBUF_PREDICT_FALSE(
73 !init_protobuf_defaults_state.load(std::memory_order_acquire))) {
74 InitProtobufDefaultsSlow();
75 }
76 }
77
78 // This used by proto1
GetEmptyString()79 PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
80 InitProtobufDefaults();
81 return GetEmptyStringAlreadyInited();
82 }
83
84 // Default empty Cord object. Don't use directly. Instead, call
85 // GetEmptyCordAlreadyInited() to get the reference.
86 union EmptyCord {
EmptyCord()87 constexpr EmptyCord() : value() {}
~EmptyCord()88 ~EmptyCord() {}
89 ::absl::Cord value;
90 };
91 PROTOBUF_EXPORT extern const EmptyCord empty_cord_;
92
GetEmptyCordAlreadyInited()93 constexpr const ::absl::Cord& GetEmptyCordAlreadyInited() {
94 return empty_cord_.value;
95 }
96
97 // True if IsInitialized() is true for all elements of t. Type is expected
98 // to be a RepeatedPtrField<some message type>. It's useful to have this
99 // helper here to keep the protobuf compiler from ever having to emit loops in
100 // IsInitialized() methods. We want the C++ compiler to inline this or not
101 // as it sees fit.
102 template <typename Msg>
AllAreInitialized(const RepeatedPtrField<Msg> & t)103 bool AllAreInitialized(const RepeatedPtrField<Msg>& t) {
104 for (int i = t.size(); --i >= 0;) {
105 if (!t.Get(i).IsInitialized()) return false;
106 }
107 return true;
108 }
109
110 // "Weak" variant of AllAreInitialized, used to implement implicit weak fields.
111 // This version operates on MessageLite to avoid introducing a dependency on the
112 // concrete message type.
113 template <class T>
AllAreInitializedWeak(const RepeatedPtrField<T> & t)114 bool AllAreInitializedWeak(const RepeatedPtrField<T>& t) {
115 for (int i = t.size(); --i >= 0;) {
116 if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t)
117 .Get<ImplicitWeakTypeHandler<T> >(i)
118 .IsInitialized()) {
119 return false;
120 }
121 }
122 return true;
123 }
124
IsPresent(const void * base,uint32_t hasbit)125 inline bool IsPresent(const void* base, uint32_t hasbit) {
126 const uint32_t* has_bits_array = static_cast<const uint32_t*>(base);
127 return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0;
128 }
129
IsOneofPresent(const void * base,uint32_t offset,uint32_t tag)130 inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) {
131 const uint32_t* oneof = reinterpret_cast<const uint32_t*>(
132 static_cast<const uint8_t*>(base) + offset);
133 return *oneof == tag >> 3;
134 }
135
136 typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset,
137 uint32_t tag, uint32_t has_offset,
138 io::CodedOutputStream* output);
139
140 PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee,
141 const uint8_t* ptr, uint32_t offset,
142 uint32_t tag, uint32_t has_offset,
143 io::CodedOutputStream* output);
144 PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base,
145 uint32_t offset, uint32_t tag,
146 uint32_t has_offset,
147 io::CodedOutputStream* output);
148
149 PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message);
150 PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena,
151 MessageLite* submessage,
152 Arena* submessage_arena);
153 PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2);
154 // We specialize GenericSwap for non-lite messages to benefit from reflection.
155 PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2);
156
157 template <typename T>
DuplicateIfNonNull(T * message)158 T* DuplicateIfNonNull(T* message) {
159 // The casts must be reinterpret_cast<> because T might be a forward-declared
160 // type that the compiler doesn't know is related to MessageLite.
161 return reinterpret_cast<T*>(
162 DuplicateIfNonNullInternal(reinterpret_cast<MessageLite*>(message)));
163 }
164
165 template <typename T>
GetOwnedMessage(Arena * message_arena,T * submessage,Arena * submessage_arena)166 T* GetOwnedMessage(Arena* message_arena, T* submessage,
167 Arena* submessage_arena) {
168 // The casts must be reinterpret_cast<> because T might be a forward-declared
169 // type that the compiler doesn't know is related to MessageLite.
170 return reinterpret_cast<T*>(GetOwnedMessageInternal(
171 message_arena, reinterpret_cast<MessageLite*>(submessage),
172 submessage_arena));
173 }
174
175 PROTOBUF_EXPORT void DestroyMessage(const void* message);
176 PROTOBUF_EXPORT void DestroyString(const void* s);
177 // Destroy (not delete) the message
OnShutdownDestroyMessage(const void * ptr)178 inline void OnShutdownDestroyMessage(const void* ptr) {
179 OnShutdownRun(DestroyMessage, ptr);
180 }
181 // Destroy the string (call std::string destructor)
OnShutdownDestroyString(const std::string * ptr)182 inline void OnShutdownDestroyString(const std::string* ptr) {
183 OnShutdownRun(DestroyString, ptr);
184 }
185
186 // Helpers for deterministic serialization =============================
187
188 // Iterator base for MapSorterFlat and MapSorterPtr.
189 template <typename storage_type>
190 struct MapSorterIt {
191 storage_type* ptr;
MapSorterItMapSorterIt192 MapSorterIt(storage_type* ptr) : ptr(ptr) {}
193 bool operator==(const MapSorterIt& other) const { return ptr == other.ptr; }
194 bool operator!=(const MapSorterIt& other) const { return !(*this == other); }
195 MapSorterIt& operator++() {
196 ++ptr;
197 return *this;
198 }
199 MapSorterIt operator++(int) {
200 auto other = *this;
201 ++ptr;
202 return other;
203 }
204 MapSorterIt operator+(int v) { return MapSorterIt{ptr + v}; }
205 };
206
207 // Defined outside of MapSorterFlat to only be templatized on the key.
208 template <typename KeyT>
209 struct MapSorterLessThan {
210 using storage_type = std::pair<KeyT, const void*>;
operatorMapSorterLessThan211 bool operator()(const storage_type& a, const storage_type& b) const {
212 return a.first < b.first;
213 }
214 };
215
216 // MapSorterFlat stores keys inline with pointers to map entries, so that
217 // keys can be compared without indirection. This type is used for maps with
218 // keys that are not strings.
219 template <typename MapT>
220 class MapSorterFlat {
221 public:
222 using value_type = typename MapT::value_type;
223 // To avoid code bloat we don't put `value_type` in `storage_type`. It is not
224 // necessary for the call to sort, and avoiding it prevents unnecessary
225 // separate instantiations of sort.
226 using storage_type = std::pair<typename MapT::key_type, const void*>;
227
228 // This const_iterator dereferenes to the map entry stored in the sorting
229 // array pairs. This is the same interface as the Map::const_iterator type,
230 // and allows generated code to use the same loop body with either form:
231 // for (const auto& entry : map) { ... }
232 // for (const auto& entry : MapSorterFlat(map)) { ... }
233 struct const_iterator : public MapSorterIt<storage_type> {
234 using pointer = const typename MapT::value_type*;
235 using reference = const typename MapT::value_type&;
236 using MapSorterIt<storage_type>::MapSorterIt;
237
238 pointer operator->() const {
239 return static_cast<const value_type*>(this->ptr->second);
240 }
241 reference operator*() const { return *this->operator->(); }
242 };
243
MapSorterFlat(const MapT & m)244 explicit MapSorterFlat(const MapT& m)
245 : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
246 if (!size_) return;
247 storage_type* it = &items_[0];
248 for (const auto& entry : m) {
249 *it++ = {entry.first, &entry};
250 }
251 std::sort(&items_[0], &items_[size_],
252 MapSorterLessThan<typename MapT::key_type>{});
253 }
size()254 size_t size() const { return size_; }
begin()255 const_iterator begin() const { return {items_.get()}; }
end()256 const_iterator end() const { return {items_.get() + size_}; }
257
258 private:
259 size_t size_;
260 std::unique_ptr<storage_type[]> items_;
261 };
262
263 // Defined outside of MapSorterPtr to only be templatized on the key.
264 template <typename KeyT>
265 struct MapSorterPtrLessThan {
operatorMapSorterPtrLessThan266 bool operator()(const void* a, const void* b) const {
267 // The pointers point to the `std::pair<const Key, Value>` object.
268 // We cast directly to the key to read it.
269 return *reinterpret_cast<const KeyT*>(a) <
270 *reinterpret_cast<const KeyT*>(b);
271 }
272 };
273
274 // MapSorterPtr stores and sorts pointers to map entries. This type is used for
275 // maps with keys that are strings.
276 template <typename MapT>
277 class MapSorterPtr {
278 public:
279 using value_type = typename MapT::value_type;
280 // To avoid code bloat we don't put `value_type` in `storage_type`. It is not
281 // necessary for the call to sort, and avoiding it prevents unnecessary
282 // separate instantiations of sort.
283 using storage_type = const void*;
284
285 // This const_iterator dereferenes the map entry pointer stored in the sorting
286 // array. This is the same interface as the Map::const_iterator type, and
287 // allows generated code to use the same loop body with either form:
288 // for (const auto& entry : map) { ... }
289 // for (const auto& entry : MapSorterPtr(map)) { ... }
290 struct const_iterator : public MapSorterIt<storage_type> {
291 using pointer = const typename MapT::value_type*;
292 using reference = const typename MapT::value_type&;
293 using MapSorterIt<storage_type>::MapSorterIt;
294
295 pointer operator->() const {
296 return static_cast<const value_type*>(*this->ptr);
297 }
298 reference operator*() const { return *this->operator->(); }
299 };
300
MapSorterPtr(const MapT & m)301 explicit MapSorterPtr(const MapT& m)
302 : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
303 if (!size_) return;
304 storage_type* it = &items_[0];
305 for (const auto& entry : m) {
306 *it++ = &entry;
307 }
308 static_assert(PROTOBUF_FIELD_OFFSET(typename MapT::value_type, first) == 0,
309 "Must hold for MapSorterPtrLessThan to work.");
310 std::sort(&items_[0], &items_[size_],
311 MapSorterPtrLessThan<typename MapT::key_type>{});
312 }
size()313 size_t size() const { return size_; }
begin()314 const_iterator begin() const { return {items_.get()}; }
end()315 const_iterator end() const { return {items_.get() + size_}; }
316
317 private:
318 size_t size_;
319 std::unique_ptr<storage_type[]> items_;
320 };
321
322 struct WeakDescriptorDefaultTail {
323 const Message** target;
324 size_t size;
325 };
326
327 // Tag to distinguish overloads below:
328 // - if last argument is `BytesTag tag = BytesTag{}` then the overload is
329 // available to both string and byte fields.
330 // - if last argument is `BytesTag tag` then the overload is only available to
331 // byte fields.
332 // - if there is no BytesTag argument, then the overload is only available to
333 // string fields.
334 struct BytesTag {
335 explicit BytesTag() = default;
336 };
337
338 // Assigns to `dest` the content of `value`, optionally bounded by `size`.
339 // This overload set is used to implement `set_xxx()` methods for repeated
340 // string fields in generated code.
341 inline void AssignToString(std::string& dest, const std::string& value,
342 BytesTag tag = BytesTag{}) {
343 dest.assign(value);
344 }
345 inline void AssignToString(std::string& dest, std::string&& value,
346 BytesTag tag = BytesTag{}) {
347 dest.assign(std::move(value));
348 }
349 inline void AssignToString(std::string& dest, const char* value,
350 BytesTag tag = BytesTag{}) {
351 dest.assign(value);
352 }
AssignToString(std::string & dest,const char * value,std::size_t size)353 inline void AssignToString(std::string& dest, const char* value,
354 std::size_t size) {
355 dest.assign(value, size);
356 }
AssignToString(std::string & dest,const void * value,std::size_t size,BytesTag tag)357 inline void AssignToString(std::string& dest, const void* value,
358 std::size_t size, BytesTag tag) {
359 dest.assign(reinterpret_cast<const char*>(value), size);
360 }
361 inline void AssignToString(std::string& dest, absl::string_view value,
362 BytesTag tag = BytesTag{}) {
363 dest.assign(value.data(), value.size());
364 }
365
366 // Adds `value`, optionally bounded by `size`, as the last element of `dest`.
367 // This overload set is used to implement `add_xxx()` methods for repeated
368 // string fields in generated code.
369 template <typename Arg, typename... Args>
AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string> & dest,Arg && value,Args...args)370 void AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string>& dest,
371 Arg&& value, Args... args) {
372 AssignToString(*dest.Add(), std::forward<Arg>(value), args...);
373 }
374 inline void AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string>& dest,
375 std::string&& value,
376 BytesTag tag = BytesTag{}) {
377 dest.Add(std::move(value));
378 }
379
EncodePlacementArenaOffsets(std::initializer_list<size_t> offsets)380 constexpr absl::optional<uintptr_t> EncodePlacementArenaOffsets(
381 std::initializer_list<size_t> offsets) {
382 uintptr_t arena_bits = 0;
383 for (size_t offset : offsets) {
384 offset /= sizeof(Arena*);
385 if (offset >= sizeof(arena_bits) * 8) {
386 return absl::nullopt;
387 }
388 arena_bits |= uintptr_t{1} << offset;
389 }
390 return arena_bits;
391 }
392
393 } // namespace internal
394 } // namespace protobuf
395 } // namespace google
396
397 #include "google/protobuf/port_undef.inc"
398
399 #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
400