File indexing completed on 2026-09-09 09:11:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
0016 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
0017
0018 #include <assert.h>
0019
0020 #include <algorithm>
0021 #include <atomic>
0022 #include <climits>
0023 #include <cstddef>
0024 #include <cstdint>
0025 #include <initializer_list>
0026 #include <memory>
0027 #include <optional>
0028 #include <string>
0029 #include <type_traits>
0030 #include <utility>
0031 #include <vector>
0032
0033 #include "google/protobuf/stubs/common.h"
0034 #include "absl/base/call_once.h"
0035 #include "absl/base/casts.h"
0036 #include "absl/base/optimization.h"
0037 #include "absl/strings/string_view.h"
0038 #include "google/protobuf/any.h"
0039 #include "google/protobuf/has_bits.h"
0040 #include "google/protobuf/implicit_weak_message.h"
0041 #include "google/protobuf/message_lite.h"
0042 #include "google/protobuf/port.h"
0043 #include "google/protobuf/repeated_field.h"
0044 #include "google/protobuf/repeated_ptr_field.h"
0045 #include "google/protobuf/wire_format_lite.h"
0046
0047
0048
0049 #include "google/protobuf/port_def.inc"
0050
0051 #ifdef SWIG
0052 #error "You cannot SWIG proto headers"
0053 #endif
0054
0055 namespace google {
0056 namespace protobuf {
0057
0058 class Arena;
0059 class Message;
0060
0061 namespace io {
0062 class CodedInputStream;
0063 }
0064
0065 namespace internal {
0066
0067
0068
0069
0070
0071 PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state;
0072 PROTOBUF_EXPORT void InitProtobufDefaultsSlow();
0073 PROTOBUF_EXPORT inline void InitProtobufDefaults() {
0074 if (ABSL_PREDICT_FALSE(
0075 !init_protobuf_defaults_state.load(std::memory_order_acquire))) {
0076 InitProtobufDefaultsSlow();
0077 }
0078 }
0079
0080
0081 PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
0082 InitProtobufDefaults();
0083 return GetEmptyStringAlreadyInited();
0084 }
0085
0086
0087
0088 union EmptyCord {
0089 constexpr EmptyCord() : value() {}
0090 ~EmptyCord() {}
0091 ::absl::Cord value;
0092 };
0093 PROTOBUF_EXPORT extern const EmptyCord empty_cord_;
0094
0095 constexpr const ::absl::Cord& GetEmptyCordAlreadyInited() {
0096 return empty_cord_.value;
0097 }
0098
0099
0100
0101
0102
0103
0104 template <typename Msg>
0105 bool AllAreInitialized(const RepeatedPtrField<Msg>& t) {
0106 for (int i = t.size(); --i >= 0;) {
0107 if (!t.Get(i).IsInitialized()) return false;
0108 }
0109 return true;
0110 }
0111
0112
0113
0114
0115 template <class T>
0116 bool AllAreInitializedWeak(const RepeatedPtrField<T>& t) {
0117 for (int i = t.size(); --i >= 0;) {
0118 if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t)
0119 .Get<ImplicitWeakTypeHandler<T> >(i)
0120 .IsInitialized()) {
0121 return false;
0122 }
0123 }
0124 return true;
0125 }
0126
0127 inline bool IsPresent(const void* base, uint32_t hasbit) {
0128 const uint32_t* has_bits_array = static_cast<const uint32_t*>(base);
0129 return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0;
0130 }
0131
0132 inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) {
0133 const uint32_t* oneof = reinterpret_cast<const uint32_t*>(
0134 static_cast<const uint8_t*>(base) + offset);
0135 return *oneof == tag >> 3;
0136 }
0137
0138 typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset,
0139 uint32_t tag, uint32_t has_offset,
0140 io::CodedOutputStream* output);
0141
0142 PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee,
0143 const uint8_t* ptr, uint32_t offset,
0144 uint32_t tag, uint32_t has_offset,
0145 io::CodedOutputStream* output);
0146 PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base,
0147 uint32_t offset, uint32_t tag,
0148 uint32_t has_offset,
0149 io::CodedOutputStream* output);
0150
0151 PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message);
0152 PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena,
0153 MessageLite* submessage,
0154 Arena* submessage_arena);
0155 PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2);
0156
0157 PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2);
0158
0159 template <typename T>
0160 T* DuplicateIfNonNull(T* message) {
0161
0162
0163 return reinterpret_cast<T*>(
0164 DuplicateIfNonNullInternal(reinterpret_cast<MessageLite*>(message)));
0165 }
0166
0167 template <typename T>
0168 T* GetOwnedMessage(Arena* message_arena, T* submessage,
0169 Arena* submessage_arena) {
0170
0171
0172 return reinterpret_cast<T*>(GetOwnedMessageInternal(
0173 message_arena, reinterpret_cast<MessageLite*>(submessage),
0174 submessage_arena));
0175 }
0176
0177 PROTOBUF_EXPORT void DestroyMessage(const void* message);
0178 PROTOBUF_EXPORT void DestroyString(const void* s);
0179
0180 inline void OnShutdownDestroyMessage(const void* ptr) {
0181 OnShutdownRun(DestroyMessage, ptr);
0182 }
0183
0184 inline void OnShutdownDestroyString(const std::string* ptr) {
0185 OnShutdownRun(DestroyString, ptr);
0186 }
0187
0188
0189
0190
0191 template <typename storage_type>
0192 struct MapSorterIt {
0193 storage_type* ptr;
0194 MapSorterIt(storage_type* ptr) : ptr(ptr) {}
0195 bool operator==(const MapSorterIt& other) const { return ptr == other.ptr; }
0196 bool operator!=(const MapSorterIt& other) const { return !(*this == other); }
0197 MapSorterIt& operator++() {
0198 ++ptr;
0199 return *this;
0200 }
0201 MapSorterIt operator++(int) {
0202 auto other = *this;
0203 ++ptr;
0204 return other;
0205 }
0206 MapSorterIt operator+(int v) { return MapSorterIt{ptr + v}; }
0207 };
0208
0209
0210 template <typename KeyT>
0211 struct MapSorterLessThan {
0212 using storage_type = std::pair<KeyT, const void*>;
0213 bool operator()(const storage_type& a, const storage_type& b) const {
0214 return a.first < b.first;
0215 }
0216 };
0217
0218
0219
0220
0221 template <typename MapT>
0222 class MapSorterFlat {
0223 public:
0224 using value_type = typename MapT::value_type;
0225
0226
0227
0228 using storage_type = std::pair<typename MapT::key_type, const void*>;
0229
0230
0231
0232
0233
0234
0235 struct const_iterator : public MapSorterIt<storage_type> {
0236 using pointer = const typename MapT::value_type*;
0237 using reference = const typename MapT::value_type&;
0238 using MapSorterIt<storage_type>::MapSorterIt;
0239
0240 pointer operator->() const {
0241 return static_cast<const value_type*>(this->ptr->second);
0242 }
0243 reference operator*() const { return *this->operator->(); }
0244 };
0245
0246 explicit MapSorterFlat(const MapT& m)
0247 : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
0248 if (!size_) return;
0249 storage_type* it = &items_[0];
0250 for (const auto& entry : m) {
0251 *it++ = {entry.first, &entry};
0252 }
0253 std::sort(&items_[0], &items_[size_],
0254 MapSorterLessThan<typename MapT::key_type>{});
0255 }
0256 size_t size() const { return size_; }
0257 const_iterator begin() const { return {items_.get()}; }
0258 const_iterator end() const { return {items_.get() + size_}; }
0259
0260 private:
0261 size_t size_;
0262 std::unique_ptr<storage_type[]> items_;
0263 };
0264
0265
0266 template <typename KeyT>
0267 struct MapSorterPtrLessThan {
0268 bool operator()(const void* a, const void* b) const {
0269
0270
0271 return *reinterpret_cast<const KeyT*>(a) <
0272 *reinterpret_cast<const KeyT*>(b);
0273 }
0274 };
0275
0276
0277
0278 template <typename MapT>
0279 class MapSorterPtr {
0280 public:
0281 using value_type = typename MapT::value_type;
0282
0283
0284
0285 using storage_type = const void*;
0286
0287
0288
0289
0290
0291
0292 struct const_iterator : public MapSorterIt<storage_type> {
0293 using pointer = const typename MapT::value_type*;
0294 using reference = const typename MapT::value_type&;
0295 using MapSorterIt<storage_type>::MapSorterIt;
0296
0297 pointer operator->() const {
0298 return static_cast<const value_type*>(*this->ptr);
0299 }
0300 reference operator*() const { return *this->operator->(); }
0301 };
0302
0303 explicit MapSorterPtr(const MapT& m)
0304 : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
0305 if (!size_) return;
0306 storage_type* it = &items_[0];
0307 for (const auto& entry : m) {
0308 *it++ = &entry;
0309 }
0310 static_assert(PROTOBUF_FIELD_OFFSET(typename MapT::value_type, first) == 0,
0311 "Must hold for MapSorterPtrLessThan to work.");
0312 std::sort(&items_[0], &items_[size_],
0313 MapSorterPtrLessThan<typename MapT::key_type>{});
0314 }
0315 size_t size() const { return size_; }
0316 const_iterator begin() const { return {items_.get()}; }
0317 const_iterator end() const { return {items_.get() + size_}; }
0318
0319 private:
0320 size_t size_;
0321 std::unique_ptr<storage_type[]> items_;
0322 };
0323
0324 struct WeakDescriptorDefaultTail {
0325 const Message** target;
0326 size_t size;
0327 };
0328
0329
0330
0331
0332
0333
0334
0335
0336 struct BytesTag {
0337 explicit BytesTag() = default;
0338 };
0339
0340
0341
0342
0343 inline void AssignToString(std::string& dest, const std::string& value,
0344 BytesTag = BytesTag{}) {
0345 dest.assign(value);
0346 }
0347 inline void AssignToString(std::string& dest, std::string&& value,
0348 BytesTag = BytesTag{}) {
0349 dest.assign(std::move(value));
0350 }
0351 inline void AssignToString(std::string& dest, const char* value,
0352 BytesTag = BytesTag{}) {
0353 dest.assign(value);
0354 }
0355 inline void AssignToString(std::string& dest, const char* value,
0356 std::size_t size) {
0357 dest.assign(value, size);
0358 }
0359 inline void AssignToString(std::string& dest, const void* value,
0360 std::size_t size, BytesTag ) {
0361 dest.assign(reinterpret_cast<const char*>(value), size);
0362 }
0363 inline void AssignToString(std::string& dest, absl::string_view value,
0364 BytesTag = BytesTag{}) {
0365 dest.assign(value.data(), value.size());
0366 }
0367
0368
0369
0370
0371 template <typename Arg, typename... Args>
0372 void AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string>& dest,
0373 Arg&& value, Args... args) {
0374 AssignToString(*dest.Add(), std::forward<Arg>(value), args...);
0375 }
0376 inline void AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string>& dest,
0377 std::string&& value,
0378 BytesTag = BytesTag{}) {
0379 dest.Add(std::move(value));
0380 }
0381
0382 constexpr std::optional<uintptr_t> EncodePlacementArenaOffsets(
0383 std::initializer_list<size_t> offsets) {
0384 uintptr_t arena_bits = 0;
0385 for (size_t offset : offsets) {
0386 offset /= sizeof(Arena*);
0387 if (offset >= sizeof(arena_bits) * 8) {
0388 return std::nullopt;
0389 }
0390 arena_bits |= uintptr_t{1} << offset;
0391 }
0392 return arena_bits;
0393 }
0394
0395 }
0396 }
0397 }
0398
0399 #include "google/protobuf/port_undef.inc"
0400
0401 #endif