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 #ifndef GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ 9 #define GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ 10 11 #include <cstddef> 12 #include <string> 13 14 #include "google/protobuf/arena.h" 15 #include "google/protobuf/generated_message_tctable_decl.h" 16 #include "google/protobuf/io/coded_stream.h" 17 #include "google/protobuf/message_lite.h" 18 #include "google/protobuf/repeated_field.h" 19 20 #ifdef SWIG 21 #error "You cannot SWIG proto headers" 22 #endif 23 24 // Must be included last. 25 #include "google/protobuf/port_def.inc" 26 27 // This file is logically internal-only and should only be used by protobuf 28 // generated code. 29 30 namespace google { 31 namespace protobuf { 32 namespace internal { 33 34 // An implementation of MessageLite that treats all data as unknown. This type 35 // acts as a placeholder for an implicit weak field in the case where the true 36 // message type does not get linked into the binary. 37 class PROTOBUF_EXPORT ImplicitWeakMessage final : public MessageLite { 38 public: ImplicitWeakMessage()39 ImplicitWeakMessage() : ImplicitWeakMessage(nullptr) {} 40 explicit constexpr ImplicitWeakMessage(ConstantInitialized); 41 ImplicitWeakMessage(const ImplicitWeakMessage&) = delete; 42 ImplicitWeakMessage& operator=(const ImplicitWeakMessage&) = delete; 43 44 // Arena enabled constructors: for internal use only. ImplicitWeakMessage(internal::InternalVisibility,Arena * arena)45 ImplicitWeakMessage(internal::InternalVisibility, Arena* arena) 46 : ImplicitWeakMessage(arena) {} 47 48 // TODO: make this constructor private ImplicitWeakMessage(Arena * arena)49 explicit ImplicitWeakMessage(Arena* arena) 50 : MessageLite(arena, class_data_.base()), data_(new std::string) {} 51 ~ImplicitWeakMessage()52 ~ImplicitWeakMessage() PROTOBUF_FINAL { 53 // data_ will be null in the default instance, but we can safely call delete 54 // here because the default instance will never be destroyed. 55 delete data_; 56 } 57 58 static const ImplicitWeakMessage& default_instance(); 59 60 const ClassData* GetClassData() const PROTOBUF_FINAL; 61 Clear()62 void Clear() PROTOBUF_FINAL { data_->clear(); } 63 ByteSizeLong()64 size_t ByteSizeLong() const PROTOBUF_FINAL { 65 size_t size = data_ == nullptr ? 0 : data_->size(); 66 cached_size_.Set(internal::ToCachedSize(size)); 67 return size; 68 } 69 _InternalSerialize(uint8_t * target,io::EpsCopyOutputStream * stream)70 uint8_t* _InternalSerialize( 71 uint8_t* target, io::EpsCopyOutputStream* stream) const PROTOBUF_FINAL { 72 if (data_ == nullptr) { 73 return target; 74 } 75 return stream->WriteRaw(data_->data(), static_cast<int>(data_->size()), 76 target); 77 } 78 79 typedef void InternalArenaConstructable_; 80 81 static PROTOBUF_CC const char* ParseImpl(ImplicitWeakMessage* msg, 82 const char* ptr, ParseContext* ctx); 83 84 private: 85 static const TcParseTable<0> table_; 86 static const ClassDataLite<1> class_data_; 87 88 static void MergeImpl(MessageLite&, const MessageLite&); 89 DestroyImpl(MessageLite & msg)90 static void DestroyImpl(MessageLite& msg) { 91 static_cast<ImplicitWeakMessage&>(msg).~ImplicitWeakMessage(); 92 } ByteSizeLongImpl(const MessageLite & msg)93 static size_t ByteSizeLongImpl(const MessageLite& msg) { 94 return static_cast<const ImplicitWeakMessage&>(msg).ByteSizeLong(); 95 } 96 _InternalSerializeImpl(const MessageLite & msg,uint8_t * target,io::EpsCopyOutputStream * stream)97 static uint8_t* _InternalSerializeImpl(const MessageLite& msg, 98 uint8_t* target, 99 io::EpsCopyOutputStream* stream) { 100 return static_cast<const ImplicitWeakMessage&>(msg)._InternalSerialize( 101 target, stream); 102 } 103 104 // This std::string is allocated on the heap, but we use a raw pointer so that 105 // the default instance can be constant-initialized. In the const methods, we 106 // have to handle the possibility of data_ being null. 107 std::string* data_; 108 google::protobuf::internal::CachedSize cached_size_{}; 109 }; 110 111 struct ImplicitWeakMessageDefaultType; 112 extern ImplicitWeakMessageDefaultType implicit_weak_message_default_instance; 113 114 // A type handler for use with implicit weak repeated message fields. 115 template <typename ImplicitWeakType> 116 class ImplicitWeakTypeHandler { 117 public: 118 typedef MessageLite Type; 119 static constexpr bool Moveable = false; 120 121 static inline MessageLite* NewFromPrototype(const MessageLite* prototype, 122 Arena* arena = nullptr) { 123 return prototype->New(arena); 124 } 125 Delete(MessageLite * value,Arena * arena)126 static inline void Delete(MessageLite* value, Arena* arena) { 127 if (arena == nullptr) { 128 delete value; 129 } 130 } GetArena(MessageLite * value)131 static inline Arena* GetArena(MessageLite* value) { 132 return value->GetArena(); 133 } Clear(MessageLite * value)134 static inline void Clear(MessageLite* value) { value->Clear(); } Merge(const MessageLite & from,MessageLite * to)135 static void Merge(const MessageLite& from, MessageLite* to) { 136 to->CheckTypeAndMergeFrom(from); 137 } 138 }; 139 140 } // namespace internal 141 142 template <typename T> 143 struct WeakRepeatedPtrField { 144 using InternalArenaConstructable_ = void; 145 using DestructorSkippable_ = void; 146 147 using TypeHandler = internal::ImplicitWeakTypeHandler<T>; 148 WeakRepeatedPtrFieldWeakRepeatedPtrField149 constexpr WeakRepeatedPtrField() : weak() {} WeakRepeatedPtrFieldWeakRepeatedPtrField150 WeakRepeatedPtrField(const WeakRepeatedPtrField& rhs) 151 : WeakRepeatedPtrField(nullptr, rhs) {} 152 153 // Arena enabled constructors: for internal use only. WeakRepeatedPtrFieldWeakRepeatedPtrField154 WeakRepeatedPtrField(internal::InternalVisibility, Arena* arena) 155 : WeakRepeatedPtrField(arena) {} WeakRepeatedPtrFieldWeakRepeatedPtrField156 WeakRepeatedPtrField(internal::InternalVisibility, Arena* arena, 157 const WeakRepeatedPtrField& rhs) 158 : WeakRepeatedPtrField(arena, rhs) {} 159 160 // TODO: make this constructor private WeakRepeatedPtrFieldWeakRepeatedPtrField161 explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} 162 ~WeakRepeatedPtrFieldWeakRepeatedPtrField163 ~WeakRepeatedPtrField() { 164 if (weak.NeedsDestroy()) { 165 weak.DestroyProtos(); 166 } 167 } 168 169 typedef internal::RepeatedPtrIterator<MessageLite> iterator; 170 typedef internal::RepeatedPtrIterator<const MessageLite> const_iterator; 171 typedef internal::RepeatedPtrOverPtrsIterator<MessageLite*, void*> 172 pointer_iterator; 173 typedef internal::RepeatedPtrOverPtrsIterator<const MessageLite* const, 174 const void* const> 175 const_pointer_iterator; 176 emptyWeakRepeatedPtrField177 bool empty() const { return base().empty(); } beginWeakRepeatedPtrField178 iterator begin() { return iterator(base().raw_data()); } beginWeakRepeatedPtrField179 const_iterator begin() const { return iterator(base().raw_data()); } cbeginWeakRepeatedPtrField180 const_iterator cbegin() const { return begin(); } endWeakRepeatedPtrField181 iterator end() { return begin() + base().size(); } endWeakRepeatedPtrField182 const_iterator end() const { return begin() + base().size(); } cendWeakRepeatedPtrField183 const_iterator cend() const { return end(); } pointer_beginWeakRepeatedPtrField184 pointer_iterator pointer_begin() { 185 return pointer_iterator(base().raw_mutable_data()); 186 } pointer_beginWeakRepeatedPtrField187 const_pointer_iterator pointer_begin() const { 188 return const_pointer_iterator(base().raw_data()); 189 } pointer_endWeakRepeatedPtrField190 pointer_iterator pointer_end() { 191 return pointer_iterator(base().raw_mutable_data() + base().size()); 192 } pointer_endWeakRepeatedPtrField193 const_pointer_iterator pointer_end() const { 194 return const_pointer_iterator(base().raw_data() + base().size()); 195 } 196 AddWeakRepeatedPtrField197 T* Add() { return weak.Add(); } ClearWeakRepeatedPtrField198 void Clear() { base().template Clear<TypeHandler>(); } MergeFromWeakRepeatedPtrField199 void MergeFrom(const WeakRepeatedPtrField& other) { 200 if (other.empty()) return; 201 base().template MergeFrom<MessageLite>(other.base()); 202 } InternalSwapWeakRepeatedPtrField203 void InternalSwap(WeakRepeatedPtrField* PROTOBUF_RESTRICT other) { 204 base().InternalSwap(&other->base()); 205 } 206 baseWeakRepeatedPtrField207 const internal::RepeatedPtrFieldBase& base() const { return weak; } baseWeakRepeatedPtrField208 internal::RepeatedPtrFieldBase& base() { return weak; } 209 // Union disables running the destructor. Which would create a strong link. 210 // Instead we explicitly destroy the underlying base through the virtual 211 // destructor. 212 union { 213 RepeatedPtrField<T> weak; 214 }; 215 InternalGetArenaOffsetWeakRepeatedPtrField216 static constexpr size_t InternalGetArenaOffset( 217 internal::InternalVisibility visibility) { 218 return decltype(weak)::InternalGetArenaOffset(visibility); 219 } 220 221 private: WeakRepeatedPtrFieldWeakRepeatedPtrField222 WeakRepeatedPtrField(Arena* arena, const WeakRepeatedPtrField& rhs) 223 : WeakRepeatedPtrField(arena) { 224 MergeFrom(rhs); 225 } 226 }; 227 228 } // namespace protobuf 229 } // namespace google 230 231 #include "google/protobuf/port_undef.inc" 232 233 #endif // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ 234