| // Protocol Buffers - Google's data interchange format | |
| // Copyright 2008 Google Inc. All rights reserved. | |
| // | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file or at | |
| // https://developers.google.com/open-source/licenses/bsd | |
| // Author: kenton@google.com (Kenton Varda) | |
| // Based on original Protocol Buffers design by | |
| // Sanjay Ghemawat, Jeff Dean, and others. | |
| // | |
| // This file contains miscellaneous helper code used by generated code -- | |
| // including lite types -- but which should not be used directly by users. | |
| #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ | |
| #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ | |
| #include <assert.h> | |
| #include <algorithm> | |
| #include <atomic> | |
| #include <climits> | |
| #include <cstddef> | |
| #include <cstdint> | |
| #include <initializer_list> | |
| #include <memory> | |
| #include <string> | |
| #include <type_traits> | |
| #include <utility> | |
| #include <vector> | |
| #include "google/protobuf/stubs/common.h" | |
| #include "absl/base/call_once.h" | |
| #include "absl/base/casts.h" | |
| #include "absl/base/optimization.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/types/optional.h" | |
| #include "google/protobuf/any.h" | |
| #include "google/protobuf/class_data.h" | |
| #include "google/protobuf/has_bits.h" | |
| #include "google/protobuf/implicit_weak_message.h" | |
| #include "google/protobuf/internal_visibility.h" | |
| #include "google/protobuf/message_lite.h" | |
| #include "google/protobuf/port.h" | |
| #include "google/protobuf/repeated_field.h" | |
| #include "google/protobuf/repeated_ptr_field.h" | |
| #include "google/protobuf/wire_format_lite.h" | |
| // Must be included last. | |
| #include "google/protobuf/port_def.inc" | |
| #ifdef SWIG | |
| #error "You cannot SWIG proto headers" | |
| #endif | |
| namespace google { | |
| namespace protobuf { | |
| class Arena; | |
| class Message; | |
| namespace io { | |
| class CodedInputStream; | |
| } | |
| namespace internal { | |
| class ExtensionSet; | |
| // This fastpath inlines a single branch instead of having to make the | |
| // InitProtobufDefaults function call. | |
| // It also generates less inlined code than a function-scope static initializer. | |
| PROTOBUF_EXPORT extern std::atomic<bool> init_protobuf_defaults_state; | |
| PROTOBUF_EXPORT void InitProtobufDefaultsSlow(); | |
| PROTOBUF_EXPORT inline void InitProtobufDefaults() { | |
| if (ABSL_PREDICT_FALSE( | |
| !init_protobuf_defaults_state.load(std::memory_order_acquire))) { | |
| InitProtobufDefaultsSlow(); | |
| } | |
| } | |
| // This used by proto1 | |
| PROTOBUF_FUTURE_ADD_EARLY_NODISCARD | |
| PROTOBUF_EXPORT inline const std::string& GetEmptyString() { | |
| InitProtobufDefaults(); | |
| return GetEmptyStringAlreadyInited(); | |
| } | |
| // Default empty Cord object. Don't use directly. Instead, call | |
| // GetEmptyCordAlreadyInited() to get the reference. | |
| union EmptyCord { | |
| constexpr EmptyCord() : value() {} | |
| ~EmptyCord() {} | |
| ::absl::Cord value; | |
| }; | |
| PROTOBUF_EXPORT extern const EmptyCord empty_cord_; | |
| PROTOBUF_FUTURE_ADD_EARLY_NODISCARD | |
| constexpr const ::absl::Cord& GetEmptyCordAlreadyInited() { | |
| return empty_cord_.value; | |
| } | |
| // True if IsInitialized() is true for all elements of t. Type is expected | |
| // to be a RepeatedPtrField<some message type>. It's useful to have this | |
| // helper here to keep the protobuf compiler from ever having to emit loops in | |
| // IsInitialized() methods. We want the C++ compiler to inline this or not | |
| // as it sees fit. | |
| template <typename Msg> | |
| PROTOBUF_FUTURE_ADD_EARLY_NODISCARD bool AllAreInitialized( | |
| const RepeatedPtrField<Msg>& t) { | |
| for (int i = t.size(); --i >= 0;) { | |
| if (!t.Get(i).IsInitialized()) return false; | |
| } | |
| return true; | |
| } | |
| // "Weak" variant of AllAreInitialized, used to implement implicit weak fields. | |
| // This version operates on MessageLite to avoid introducing a dependency on the | |
| // concrete message type. | |
| template <class T> | |
| PROTOBUF_FUTURE_ADD_EARLY_NODISCARD bool AllAreInitializedWeak( | |
| const RepeatedPtrField<T>& t) { | |
| for (int i = t.size(); --i >= 0;) { | |
| if (!reinterpret_cast<const RepeatedPtrFieldBase&>(t) | |
| .Get<ImplicitWeakTypeHandler<T> >(i) | |
| .IsInitialized()) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| PROTOBUF_FUTURE_ADD_EARLY_NODISCARD | |
| inline bool IsPresent(const void* base, uint32_t hasbit) { | |
| const uint32_t* has_bits_array = static_cast<const uint32_t*>(base); | |
| return (has_bits_array[hasbit / 32] & (1u << (hasbit & 31))) != 0; | |
| } | |
| PROTOBUF_FUTURE_ADD_EARLY_NODISCARD | |
| inline bool IsOneofPresent(const void* base, uint32_t offset, uint32_t tag) { | |
| const uint32_t* oneof = reinterpret_cast<const uint32_t*>( | |
| static_cast<const uint8_t*>(base) + offset); | |
| return *oneof == tag >> 3; | |
| } | |
| typedef void (*SpecialSerializer)(const uint8_t* base, uint32_t offset, | |
| uint32_t tag, uint32_t has_offset, | |
| io::CodedOutputStream* output); | |
| PROTOBUF_EXPORT void ExtensionSerializer(const MessageLite* extendee, | |
| const uint8_t* ptr, uint32_t offset, | |
| uint32_t tag, uint32_t has_offset, | |
| io::CodedOutputStream* output); | |
| PROTOBUF_EXPORT void UnknownFieldSerializerLite(const uint8_t* base, | |
| uint32_t offset, uint32_t tag, | |
| uint32_t has_offset, | |
| io::CodedOutputStream* output); | |
| PROTOBUF_EXPORT MessageLite* DuplicateIfNonNullInternal(MessageLite* message); | |
| PROTOBUF_EXPORT MessageLite* GetOwnedMessageInternal(Arena* message_arena, | |
| MessageLite* submessage, | |
| Arena* submessage_arena); | |
| PROTOBUF_EXPORT void GenericSwap(MessageLite* lhs, MessageLite* rhs); | |
| // We specialize GenericSwap for non-lite messages to benefit from reflection. | |
| PROTOBUF_EXPORT void GenericSwap(Message* lhs, Message* rhs); | |
| template <typename T> | |
| T* DuplicateIfNonNull(T* message) { | |
| // The casts must be reinterpret_cast<> because T might be a forward-declared | |
| // type that the compiler doesn't know is related to MessageLite. | |
| return reinterpret_cast<T*>( | |
| DuplicateIfNonNullInternal(reinterpret_cast<MessageLite*>(message))); | |
| } | |
| template <typename T> | |
| T* GetOwnedMessage(Arena* message_arena, T* submessage, | |
| Arena* submessage_arena) { | |
| // The casts must be reinterpret_cast<> because T might be a forward-declared | |
| // type that the compiler doesn't know is related to MessageLite. | |
| return reinterpret_cast<T*>(GetOwnedMessageInternal( | |
| message_arena, reinterpret_cast<MessageLite*>(submessage), | |
| submessage_arena)); | |
| } | |
| PROTOBUF_EXPORT void DestroyMessage(const void* message); | |
| PROTOBUF_EXPORT void DestroyString(const void* s); | |
| // Destroy (not delete) the message | |
| inline void OnShutdownDestroyMessage(const void* ptr) { | |
| OnShutdownRun(DestroyMessage, ptr); | |
| } | |
| // Destroy the string (call std::string destructor) | |
| inline void OnShutdownDestroyString(const std::string* ptr) { | |
| OnShutdownRun(DestroyString, ptr); | |
| } | |
| // Helpers for deterministic serialization ============================= | |
| // Iterator base for MapSorterFlat and MapSorterPtr. | |
| template <typename storage_type> | |
| struct MapSorterIt { | |
| storage_type* ptr; | |
| MapSorterIt(storage_type* ptr) : ptr(ptr) {} | |
| bool operator==(const MapSorterIt& other) const { return ptr == other.ptr; } | |
| bool operator!=(const MapSorterIt& other) const { return !(*this == other); } | |
| MapSorterIt& operator++() { | |
| ++ptr; | |
| return *this; | |
| } | |
| MapSorterIt operator++(int) { | |
| auto other = *this; | |
| ++ptr; | |
| return other; | |
| } | |
| MapSorterIt operator+(int v) { return MapSorterIt{ptr + v}; } | |
| }; | |
| // Defined outside of MapSorterFlat to only be templatized on the key. | |
| template <typename KeyT> | |
| struct MapSorterLessThan { | |
| using storage_type = std::pair<KeyT, const void*>; | |
| bool operator()(const storage_type& a, const storage_type& b) const { | |
| return a.first < b.first; | |
| } | |
| }; | |
| // MapSorterFlat stores keys inline with pointers to map entries, so that | |
| // keys can be compared without indirection. This type is used for maps with | |
| // keys that are not strings. | |
| template <typename MapT> | |
| class MapSorterFlat { | |
| public: | |
| using value_type = typename MapT::value_type; | |
| // To avoid code bloat we don't put `value_type` in `storage_type`. It is not | |
| // necessary for the call to sort, and avoiding it prevents unnecessary | |
| // separate instantiations of sort. | |
| using storage_type = std::pair<typename MapT::key_type, const void*>; | |
| // This const_iterator dereferenes to the map entry stored in the sorting | |
| // array pairs. This is the same interface as the Map::const_iterator type, | |
| // and allows generated code to use the same loop body with either form: | |
| // for (const auto& entry : map) { ... } | |
| // for (const auto& entry : MapSorterFlat(map)) { ... } | |
| struct const_iterator : public MapSorterIt<storage_type> { | |
| using pointer = const typename MapT::value_type*; | |
| using reference = const typename MapT::value_type&; | |
| using MapSorterIt<storage_type>::MapSorterIt; | |
| pointer operator->() const { | |
| return static_cast<const value_type*>(this->ptr->second); | |
| } | |
| reference operator*() const { return *this->operator->(); } | |
| }; | |
| explicit MapSorterFlat(const MapT& m) | |
| : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) { | |
| if (!size_) return; | |
| storage_type* it = &items_[0]; | |
| for (const auto& entry : m) { | |
| *it++ = {entry.first, &entry}; | |
| } | |
| std::sort(&items_[0], &items_[size_], | |
| MapSorterLessThan<typename MapT::key_type>{}); | |
| } | |
| size_t size() const { return size_; } | |
| const_iterator begin() const { return {items_.get()}; } | |
| const_iterator end() const { return {items_.get() + size_}; } | |
| private: | |
| size_t size_; | |
| std::unique_ptr<storage_type[]> items_; | |
| }; | |
| // Defined outside of MapSorterPtr to only be templatized on the key. | |
| template <typename KeyT> | |
| struct MapSorterPtrLessThan { | |
| bool operator()(const void* a, const void* b) const { | |
| // The pointers point to the `std::pair<const Key, Value>` object. | |
| // We cast directly to the key to read it. | |
| return *reinterpret_cast<const KeyT*>(a) < | |
| *reinterpret_cast<const KeyT*>(b); | |
| } | |
| }; | |
| // MapSorterPtr stores and sorts pointers to map entries. This type is used for | |
| // maps with keys that are strings. | |
| template <typename MapT> | |
| class MapSorterPtr { | |
| public: | |
| using value_type = typename MapT::value_type; | |
| // To avoid code bloat we don't put `value_type` in `storage_type`. It is not | |
| // necessary for the call to sort, and avoiding it prevents unnecessary | |
| // separate instantiations of sort. | |
| using storage_type = const void*; | |
| // This const_iterator dereferenes the map entry pointer stored in the sorting | |
| // array. This is the same interface as the Map::const_iterator type, and | |
| // allows generated code to use the same loop body with either form: | |
| // for (const auto& entry : map) { ... } | |
| // for (const auto& entry : MapSorterPtr(map)) { ... } | |
| struct const_iterator : public MapSorterIt<storage_type> { | |
| using pointer = const typename MapT::value_type*; | |
| using reference = const typename MapT::value_type&; | |
| using MapSorterIt<storage_type>::MapSorterIt; | |
| pointer operator->() const { | |
| return static_cast<const value_type*>(*this->ptr); | |
| } | |
| reference operator*() const { return *this->operator->(); } | |
| }; | |
| explicit MapSorterPtr(const MapT& m) | |
| : size_(m.size()), items_(size_ ? new storage_type[size_] : nullptr) { | |
| if (!size_) return; | |
| storage_type* it = &items_[0]; | |
| for (const auto& entry : m) { | |
| *it++ = &entry; | |
| } | |
| static_assert(PROTOBUF_FIELD_OFFSET(typename MapT::value_type, first) == 0, | |
| "Must hold for MapSorterPtrLessThan to work."); | |
| std::sort(&items_[0], &items_[size_], | |
| MapSorterPtrLessThan<typename MapT::key_type>{}); | |
| } | |
| size_t size() const { return size_; } | |
| const_iterator begin() const { return {items_.get()}; } | |
| const_iterator end() const { return {items_.get() + size_}; } | |
| private: | |
| size_t size_; | |
| std::unique_ptr<storage_type[]> items_; | |
| }; | |
| struct WeakDescriptorDefaultTail { | |
| const MessageGlobalsBase** target; | |
| size_t size; | |
| }; | |
| // Tag to distinguish overloads below: | |
| // - if last argument is `BytesTag tag = BytesTag{}` then the overload is | |
| // available to both string and byte fields. | |
| // - if last argument is `BytesTag tag` then the overload is only available to | |
| // byte fields. | |
| // - if there is no BytesTag argument, then the overload is only available to | |
| // string fields. | |
| struct BytesTag { | |
| explicit BytesTag() = default; | |
| }; | |
| // Assigns to `dest` the content of `value`, optionally bounded by `size`. | |
| // This overload set is used to implement `set_xxx()` methods for repeated | |
| // string fields in generated code. | |
| inline void AssignToString(std::string& dest, const std::string& value, | |
| BytesTag /*tag*/ = BytesTag{}) { | |
| dest.assign(value); | |
| } | |
| inline void AssignToString(std::string& dest, std::string&& value, | |
| BytesTag /*tag*/ = BytesTag{}) { | |
| dest.assign(std::move(value)); | |
| } | |
| inline void AssignToString(std::string& dest, const char* value, | |
| BytesTag /*tag*/ = BytesTag{}) { | |
| dest.assign(value); | |
| } | |
| inline void AssignToString(std::string& dest, const char* value, | |
| std::size_t size) { | |
| dest.assign(value, size); | |
| } | |
| inline void AssignToString(std::string& dest, const void* value, | |
| std::size_t size, BytesTag /*tag*/) { | |
| dest.assign(reinterpret_cast<const char*>(value), size); | |
| } | |
| inline void AssignToString(std::string& dest, absl::string_view value, | |
| BytesTag /*tag*/ = BytesTag{}) { | |
| dest.assign(value.data(), value.size()); | |
| } | |
| inline void AssignToString(std::string& dest, const absl::Cord& value, | |
| BytesTag tag = BytesTag{}) { | |
| absl::CopyCordToString(value, &dest); | |
| } | |
| // Adds `value`, optionally bounded by `size`, as the last element of `dest`. | |
| // This overload set is used to implement `add_xxx()` methods for repeated | |
| // string fields in generated code. | |
| template <typename Arg, typename... Args> | |
| void AddToRepeatedPtrField(InternalVisibility visibility, google::protobuf::Arena* arena, | |
| google::protobuf::RepeatedPtrField<std::string>& dest, | |
| Arg&& value, Args... args) { | |
| AssignToString(*dest.InternalAddWithArena(visibility, arena), | |
| std::forward<Arg>(value), args...); | |
| } | |
| inline void AddToRepeatedPtrField(InternalVisibility visibility, | |
| google::protobuf::Arena* arena, | |
| google::protobuf::RepeatedPtrField<std::string>& dest, | |
| std::string&& value, | |
| BytesTag /*tag*/ = BytesTag{}) { | |
| dest.InternalAddWithArena(visibility, arena, std::move(value)); | |
| } | |
| } // namespace internal | |
| } // namespace protobuf | |
| } // namespace google | |
| #include "google/protobuf/port_undef.inc" | |
| #endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ |