Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:21

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 <memory>
0025 #include <string>
0026 #include <type_traits>
0027 #include <utility>
0028 #include <vector>
0029 
0030 #include "google/protobuf/stubs/common.h"
0031 #include "absl/base/call_once.h"
0032 #include "absl/base/casts.h"
0033 #include "absl/strings/string_view.h"
0034 #include "google/protobuf/any.h"
0035 #include "google/protobuf/has_bits.h"
0036 #include "google/protobuf/implicit_weak_message.h"
0037 #include "google/protobuf/message_lite.h"
0038 #include "google/protobuf/port.h"
0039 #include "google/protobuf/repeated_field.h"
0040 #include "google/protobuf/repeated_ptr_field.h"
0041 #include "google/protobuf/wire_format_lite.h"
0042 
0043 
0044 // Must be included last.
0045 #include "google/protobuf/port_def.inc"
0046 
0047 #ifdef SWIG
0048 #error "You cannot SWIG proto headers"
0049 #endif
0050 
0051 namespace google {
0052 namespace protobuf {
0053 
0054 class Arena;
0055 class Message;
0056 
0057 namespace io {
0058 class CodedInputStream;
0059 }
0060 
0061 namespace internal {
0062 
0063 
0064 // This fastpath inlines a single branch instead of having to make the
0065 // InitProtobufDefaults function call.
0066 // It also generates less inlined code than a function-scope static initializer.
0067 PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state;
0068 PROTOBUF_EXPORT void InitProtobufDefaultsSlow();
0069 PROTOBUF_EXPORT inline void InitProtobufDefaults() {
0070   if (PROTOBUF_PREDICT_FALSE(
0071           !init_protobuf_defaults_state.load(std::memory_order_acquire))) {
0072     InitProtobufDefaultsSlow();
0073   }
0074 }
0075 
0076 // This used by proto1
0077 PROTOBUF_EXPORT inline const std::string& GetEmptyString() {
0078   InitProtobufDefaults();
0079   return GetEmptyStringAlreadyInited();
0080 }
0081 
0082 // Default empty Cord object. Don't use directly. Instead, call
0083 // GetEmptyCordAlreadyInited() to get the reference.
0084 union EmptyCord {
0085   constexpr EmptyCord() : value() {}
0086   ~EmptyCord() {}
0087   ::absl::Cord value;
0088 };
0089 PROTOBUF_EXPORT extern const EmptyCord empty_cord_;
0090 
0091 constexpr const ::absl::Cord& GetEmptyCordAlreadyInited() {
0092   return empty_cord_.value;
0093 }
0094 
0095 // True if IsInitialized() is true for all elements of t.  Type is expected
0096 // to be a RepeatedPtrField<some message type>.  It's useful to have this
0097 // helper here to keep the protobuf compiler from ever having to emit loops in
0098 // IsInitialized() methods.  We want the C++ compiler to inline this or not
0099 // as it sees fit.
0100 template <typename Msg>
0101 bool AllAreInitialized(const RepeatedPtrField<Msg>& t) {
0102   for (int i = t.size(); --i >= 0;) {
0103     if (!t.Get(i).IsInitialized()) return false;
0104   }
0105   return true;
0106 }
0107 
0108 // "Weak" variant of AllAreInitialized, used to implement implicit weak fields.
0109 // This version operates on MessageLite to avoid introducing a dependency on the
0110 // concrete message type.
0111 template <class T>
0112 bool AllAreInitializedWeak(const RepeatedPtrField<T>& t) {
0113   for (int i = t.size(); --i >= 0;) {
0114     if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t)
0115              .Get<ImplicitWeakTypeHandler<T> >(i)
0116              .IsInitialized()) {
0117       return false;
0118     }
0119   }
0120   return true;
0121 }
0122 
0123 inline bool IsPresent(const void* base, uint32_t hasbit) {
0124   const uint32_t* has_bits_array = static_cast<const uint32_t*>(base);
0125   return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0;
0126 }
0127 
0128 inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) {
0129   const uint32_t* oneof = reinterpret_cast<const uint32_t*>(
0130       static_cast<const uint8_t*>(base) + offset);
0131   return *oneof == tag >> 3;
0132 }
0133 
0134 typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset,
0135                                   uint32_t tag, uint32_t has_offset,
0136                                   io::CodedOutputStream* output);
0137 
0138 PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee,
0139                                          const uint8_t* ptr, uint32_t offset,
0140                                          uint32_t tag, uint32_t has_offset,
0141                                          io::CodedOutputStream* output);
0142 PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base,
0143                                                 uint32_t offset, uint32_t tag,
0144                                                 uint32_t has_offset,
0145                                                 io::CodedOutputStream* output);
0146 
0147 PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message);
0148 PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena,
0149                                                      MessageLite* submessage,
0150                                                      Arena* submessage_arena);
0151 PROTOBUF_EXPORT void GenericSwap(MessageLite* m1, MessageLite* m2);
0152 // We specialize GenericSwap for non-lite messages to benefit from reflection.
0153 PROTOBUF_EXPORT void GenericSwap(Message* m1, Message* m2);
0154 
0155 template <typename T>
0156 T* DuplicateIfNonNull(T* message) {
0157   // The casts must be reinterpret_cast<> because T might be a forward-declared
0158   // type that the compiler doesn't know is related to MessageLite.
0159   return reinterpret_cast<T*>(
0160       DuplicateIfNonNullInternal(reinterpret_cast<MessageLite*>(message)));
0161 }
0162 
0163 template <typename T>
0164 T* GetOwnedMessage(Arena* message_arena, T* submessage,
0165                    Arena* submessage_arena) {
0166   // The casts must be reinterpret_cast<> because T might be a forward-declared
0167   // type that the compiler doesn't know is related to MessageLite.
0168   return reinterpret_cast<T*>(GetOwnedMessageInternal(
0169       message_arena, reinterpret_cast<MessageLite*>(submessage),
0170       submessage_arena));
0171 }
0172 
0173 PROTOBUF_EXPORT void DestroyMessage(const void* message);
0174 PROTOBUF_EXPORT void DestroyString(const void* s);
0175 // Destroy (not delete) the message
0176 inline void OnShutdownDestroyMessage(const void* ptr) {
0177   OnShutdownRun(DestroyMessage, ptr);
0178 }
0179 // Destroy the string (call std::string destructor)
0180 inline void OnShutdownDestroyString(const std::string* ptr) {
0181   OnShutdownRun(DestroyString, ptr);
0182 }
0183 
0184 // Helpers for deterministic serialization =============================
0185 
0186 // Iterator base for MapSorterFlat and MapSorterPtr.
0187 template <typename storage_type>
0188 struct MapSorterIt {
0189   storage_type* ptr;
0190   MapSorterIt(storage_type* ptr) : ptr(ptr) {}
0191   bool operator==(const MapSorterIt& other) const { return ptr == other.ptr; }
0192   bool operator!=(const MapSorterIt& other) const { return !(*this == other); }
0193   MapSorterIt& operator++() {
0194     ++ptr;
0195     return *this;
0196   }
0197   MapSorterIt operator++(int) {
0198     auto other = *this;
0199     ++ptr;
0200     return other;
0201   }
0202   MapSorterIt operator+(int v) { return MapSorterIt{ptr + v}; }
0203 };
0204 
0205 // Defined outside of MapSorterFlat to only be templatized on the key.
0206 template <typename KeyT>
0207 struct MapSorterLessThan {
0208   using storage_type = std::pair<KeyT, const void*>;
0209   bool operator()(const storage_type& a, const storage_type& b) const {
0210     return a.first < b.first;
0211   }
0212 };
0213 
0214 // MapSorterFlat stores keys inline with pointers to map entries, so that
0215 // keys can be compared without indirection. This type is used for maps with
0216 // keys that are not strings.
0217 template <typename MapT>
0218 class MapSorterFlat {
0219  public:
0220   using value_type = typename MapT::value_type;
0221   // To avoid code bloat we don't put `value_type` in `storage_type`. It is not
0222   // necessary for the call to sort, and avoiding it prevents unnecessary
0223   // separate instantiations of sort.
0224   using storage_type = std::pair<typename MapT::key_type, const void*>;
0225 
0226   // This const_iterator dereferenes to the map entry stored in the sorting
0227   // array pairs. This is the same interface as the Map::const_iterator type,
0228   // and allows generated code to use the same loop body with either form:
0229   //   for (const auto& entry : map) { ... }
0230   //   for (const auto& entry : MapSorterFlat(map)) { ... }
0231   struct const_iterator : public MapSorterIt<storage_type> {
0232     using pointer = const typename MapT::value_type*;
0233     using reference = const typename MapT::value_type&;
0234     using MapSorterIt<storage_type>::MapSorterIt;
0235 
0236     pointer operator->() const {
0237       return static_cast<const value_type*>(this->ptr->second);
0238     }
0239     reference operator*() const { return *this->operator->(); }
0240   };
0241 
0242   explicit MapSorterFlat(const MapT& m)
0243       : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
0244     if (!size_) return;
0245     storage_type* it = &items_[0];
0246     for (const auto& entry : m) {
0247       *it++ = {entry.first, &entry};
0248     }
0249     std::sort(&items_[0], &items_[size_],
0250               MapSorterLessThan<typename MapT::key_type>{});
0251   }
0252   size_t size() const { return size_; }
0253   const_iterator begin() const { return {items_.get()}; }
0254   const_iterator end() const { return {items_.get() + size_}; }
0255 
0256  private:
0257   size_t size_;
0258   std::unique_ptr<storage_type[]> items_;
0259 };
0260 
0261 // Defined outside of MapSorterPtr to only be templatized on the key.
0262 template <typename KeyT>
0263 struct MapSorterPtrLessThan {
0264   bool operator()(const void* a, const void* b) const {
0265     // The pointers point to the `std::pair<const Key, Value>` object.
0266     // We cast directly to the key to read it.
0267     return *reinterpret_cast<const KeyT*>(a) <
0268            *reinterpret_cast<const KeyT*>(b);
0269   }
0270 };
0271 
0272 // MapSorterPtr stores and sorts pointers to map entries. This type is used for
0273 // maps with keys that are strings.
0274 template <typename MapT>
0275 class MapSorterPtr {
0276  public:
0277   using value_type = typename MapT::value_type;
0278   // To avoid code bloat we don't put `value_type` in `storage_type`. It is not
0279   // necessary for the call to sort, and avoiding it prevents unnecessary
0280   // separate instantiations of sort.
0281   using storage_type = const void*;
0282 
0283   // This const_iterator dereferenes the map entry pointer stored in the sorting
0284   // array. This is the same interface as the Map::const_iterator type, and
0285   // allows generated code to use the same loop body with either form:
0286   //   for (const auto& entry : map) { ... }
0287   //   for (const auto& entry : MapSorterPtr(map)) { ... }
0288   struct const_iterator : public MapSorterIt<storage_type> {
0289     using pointer = const typename MapT::value_type*;
0290     using reference = const typename MapT::value_type&;
0291     using MapSorterIt<storage_type>::MapSorterIt;
0292 
0293     pointer operator->() const {
0294       return static_cast<const value_type*>(*this->ptr);
0295     }
0296     reference operator*() const { return *this->operator->(); }
0297   };
0298 
0299   explicit MapSorterPtr(const MapT& m)
0300       : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) {
0301     if (!size_) return;
0302     storage_type* it = &items_[0];
0303     for (const auto& entry : m) {
0304       *it++ = &entry;
0305     }
0306     static_assert(PROTOBUF_FIELD_OFFSET(typename MapT::value_type, first) == 0,
0307                   "Must hold for MapSorterPtrLessThan to work.");
0308     std::sort(&items_[0], &items_[size_],
0309               MapSorterPtrLessThan<typename MapT::key_type>{});
0310   }
0311   size_t size() const { return size_; }
0312   const_iterator begin() const { return {items_.get()}; }
0313   const_iterator end() const { return {items_.get() + size_}; }
0314 
0315  private:
0316   size_t size_;
0317   std::unique_ptr<storage_type[]> items_;
0318 };
0319 
0320 struct WeakDescriptorDefaultTail {
0321   const Message** target;
0322   size_t size;
0323 };
0324 
0325 // Tag to distinguish overloads below:
0326 //  - if last argument is `BytesTag tag = BytesTag{}` then the overload is
0327 //    available to both string and byte fields.
0328 //  - if last argument is `BytesTag tag` then the overload is only available to
0329 //    byte fields.
0330 //  - if there is no BytesTag argument, then the overload is only available to
0331 //    string fields.
0332 struct BytesTag {
0333   explicit BytesTag() = default;
0334 };
0335 
0336 // Assigns to `dest` the content of `value`, optionally bounded by `size`.
0337 // This overload set is used to implement `set_xxx()` methods for repeated
0338 // string fields in generated code.
0339 inline void AssignToString(std::string& dest, const std::string& value,
0340                            BytesTag tag = BytesTag{}) {
0341   dest.assign(value);
0342 }
0343 inline void AssignToString(std::string& dest, std::string&& value,
0344                            BytesTag tag = BytesTag{}) {
0345   dest.assign(std::move(value));
0346 }
0347 inline void AssignToString(std::string& dest, const char* value,
0348                            BytesTag tag = BytesTag{}) {
0349   dest.assign(value);
0350 }
0351 inline void AssignToString(std::string& dest, const char* value,
0352                            std::size_t size) {
0353   dest.assign(value, size);
0354 }
0355 inline void AssignToString(std::string& dest, const void* value,
0356                            std::size_t size, BytesTag tag) {
0357   dest.assign(reinterpret_cast<const char*>(value), size);
0358 }
0359 inline void AssignToString(std::string& dest, absl::string_view value,
0360                            BytesTag tag = BytesTag{}) {
0361   dest.assign(value.data(), value.size());
0362 }
0363 
0364 // Adds `value`, optionally bounded by `size`, as the last element of `dest`.
0365 // This overload set is used to implement `add_xxx()` methods for repeated
0366 // string fields in generated code.
0367 template <typename Arg, typename... Args>
0368 void AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string>& dest,
0369                            Arg&& value, Args... args) {
0370   AssignToString(*dest.Add(), std::forward<Arg>(value), args...);
0371 }
0372 inline void AddToRepeatedPtrField(google::protobuf::RepeatedPtrField<std::string>& dest,
0373                                   std::string&& value,
0374                                   BytesTag tag = BytesTag{}) {
0375   dest.Add(std::move(value));
0376 }
0377 
0378 }  // namespace internal
0379 }  // namespace protobuf
0380 }  // namespace google
0381 
0382 #include "google/protobuf/port_undef.inc"
0383 
0384 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__