Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 09:11:26

0001 // Protocol Buffers - Google's data interchange format
0002 // Copyright 2008 Google Inc.  All rights reserved.
0003 //
0004 // Use of this source code is governed by a BSD-style
0005 // license that can be found in the LICENSE file or at
0006 // https://developers.google.com/open-source/licenses/bsd
0007 
0008 // Author: kenton@google.com (Kenton Varda)
0009 //  Based on original Protocol Buffers design by
0010 //  Sanjay Ghemawat, Jeff Dean, and others.
0011 //
0012 // This file contains miscellaneous helper code used by generated code --
0013 // including lite types -- but which should not be used directly by users.
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 // Must be included last.
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 // This fastpath inlines a single branch instead of having to make the
0069 // InitProtobufDefaults function call.
0070 // It also generates less inlined code than a function-scope static initializer.
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 // This used by proto1
0081 PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
0082   InitProtobufDefaults();
0083   return GetEmptyStringAlreadyInited();
0084 }
0085 
0086 // Default empty Cord object. Don't use directly. Instead, call
0087 // GetEmptyCordAlreadyInited() to get the reference.
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 // True if IsInitialized() is true for all elements of t.  Type is expected
0100 // to be a RepeatedPtrField<some message type>.  It's useful to have this
0101 // helper here to keep the protobuf compiler from ever having to emit loops in
0102 // IsInitialized() methods.  We want the C++ compiler to inline this or not
0103 // as it sees fit.
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 // "Weak" variant of AllAreInitialized, used to implement implicit weak fields.
0113 // This version operates on MessageLite to avoid introducing a dependency on the
0114 // concrete message type.
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 // We specialize GenericSwap for non-lite messages to benefit from reflection.
0157 PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2);
0158 
0159 template <typename T>
0160 T* DuplicateIfNonNull(T* message) {
0161   // The casts must be reinterpret_cast<> because T might be a forward-declared
0162   // type that the compiler doesn't know is related to MessageLite.
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   // The casts must be reinterpret_cast<> because T might be a forward-declared
0171   // type that the compiler doesn't know is related to MessageLite.
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 // Destroy (not delete) the message
0180 inline void OnShutdownDestroyMessage(const void* ptr) {
0181   OnShutdownRun(DestroyMessage, ptr);
0182 }
0183 // Destroy the string (call std::string destructor)
0184 inline void OnShutdownDestroyString(const std::string* ptr) {
0185   OnShutdownRun(DestroyString, ptr);
0186 }
0187 
0188 // Helpers for deterministic serialization =============================
0189 
0190 // Iterator base for MapSorterFlat and MapSorterPtr.
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 // Defined outside of MapSorterFlat to only be templatized on the key.
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 // MapSorterFlat stores keys inline with pointers to map entries, so that
0219 // keys can be compared without indirection. This type is used for maps with
0220 // keys that are not strings.
0221 template <typename MapT>
0222 class MapSorterFlat {
0223  public:
0224   using value_type = typename MapT::value_type;
0225   // To avoid code bloat we don't put `value_type` in `storage_type`. It is not
0226   // necessary for the call to sort, and avoiding it prevents unnecessary
0227   // separate instantiations of sort.
0228   using storage_type = std::pair<typename MapT::key_type, const void*>;
0229 
0230   // This const_iterator dereferenes to the map entry stored in the sorting
0231   // array pairs. This is the same interface as the Map::const_iterator type,
0232   // and allows generated code to use the same loop body with either form:
0233   //   for (const auto& entry : map) { ... }
0234   //   for (const auto& entry : MapSorterFlat(map)) { ... }
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 // Defined outside of MapSorterPtr to only be templatized on the key.
0266 template <typename KeyT>
0267 struct MapSorterPtrLessThan {
0268   bool operator()(const void* a, const void* b) const {
0269     // The pointers point to the `std::pair<const Key, Value>` object.
0270     // We cast directly to the key to read it.
0271     return *reinterpret_cast<const KeyT*>(a) <
0272            *reinterpret_cast<const KeyT*>(b);
0273   }
0274 };
0275 
0276 // MapSorterPtr stores and sorts pointers to map entries. This type is used for
0277 // maps with keys that are strings.
0278 template <typename MapT>
0279 class MapSorterPtr {
0280  public:
0281   using value_type = typename MapT::value_type;
0282   // To avoid code bloat we don't put `value_type` in `storage_type`. It is not
0283   // necessary for the call to sort, and avoiding it prevents unnecessary
0284   // separate instantiations of sort.
0285   using storage_type = const void*;
0286 
0287   // This const_iterator dereferenes the map entry pointer stored in the sorting
0288   // array. This is the same interface as the Map::const_iterator type, and
0289   // allows generated code to use the same loop body with either form:
0290   //   for (const auto& entry : map) { ... }
0291   //   for (const auto& entry : MapSorterPtr(map)) { ... }
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 // Tag to distinguish overloads below:
0330 //  - if last argument is `BytesTag tag = BytesTag{}` then the overload is
0331 //    available to both string and byte fields.
0332 //  - if last argument is `BytesTag tag` then the overload is only available to
0333 //    byte fields.
0334 //  - if there is no BytesTag argument, then the overload is only available to
0335 //    string fields.
0336 struct BytesTag {
0337   explicit BytesTag() = default;
0338 };
0339 
0340 // Assigns to `dest` the content of `value`, optionally bounded by `size`.
0341 // This overload set is used to implement `set_xxx()` methods for repeated
0342 // string fields in generated code.
0343 inline void AssignToString(std::string& dest, const std::string& value,
0344                            BytesTag /*tag*/ = BytesTag{}) {
0345   dest.assign(value);
0346 }
0347 inline void AssignToString(std::string& dest, std::string&& value,
0348                            BytesTag /*tag*/ = BytesTag{}) {
0349   dest.assign(std::move(value));
0350 }
0351 inline void AssignToString(std::string& dest, const char* value,
0352                            BytesTag /*tag*/ = 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 /*tag*/) {
0361   dest.assign(reinterpret_cast<const char*>(value), size);
0362 }
0363 inline void AssignToString(std::string& dest, absl::string_view value,
0364                            BytesTag /*tag*/ = BytesTag{}) {
0365   dest.assign(value.data(), value.size());
0366 }
0367 
0368 // Adds `value`, optionally bounded by `size`, as the last element of `dest`.
0369 // This overload set is used to implement `add_xxx()` methods for repeated
0370 // string fields in generated code.
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 /*tag*/ = 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 }  // namespace internal
0396 }  // namespace protobuf
0397 }  // namespace google
0398 
0399 #include "google/protobuf/port_undef.inc"
0400 
0401 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__