1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // https://developers.google.com/protocol-buffers/ 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions are 7 // met: 8 // 9 // * Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // * Redistributions in binary form must reproduce the above 12 // copyright notice, this list of conditions and the following disclaimer 13 // in the documentation and/or other materials provided with the 14 // distribution. 15 // * Neither the name of Google Inc. nor the names of its 16 // contributors may be used to endorse or promote products derived from 17 // this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 #ifndef GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ 32 #define GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ 33 34 #include <string> 35 36 #include <google/protobuf/io/coded_stream.h> 37 #include <google/protobuf/arena.h> 38 #include <google/protobuf/message_lite.h> 39 #include <google/protobuf/repeated_field.h> 40 41 #ifdef SWIG 42 #error "You cannot SWIG proto headers" 43 #endif 44 45 #include <google/protobuf/port_def.inc> 46 47 // This file is logically internal-only and should only be used by protobuf 48 // generated code. 49 50 namespace google { 51 namespace protobuf { 52 namespace internal { 53 54 // An implementation of MessageLite that treats all data as unknown. This type 55 // acts as a placeholder for an implicit weak field in the case where the true 56 // message type does not get linked into the binary. 57 class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite { 58 public: ImplicitWeakMessage()59 ImplicitWeakMessage() {} ImplicitWeakMessage(Arena * arena)60 explicit ImplicitWeakMessage(Arena* arena) : MessageLite(arena) {} 61 62 static const ImplicitWeakMessage* default_instance(); 63 GetTypeName()64 std::string GetTypeName() const override { return ""; } 65 New()66 MessageLite* New() const override { return new ImplicitWeakMessage; } New(Arena * arena)67 MessageLite* New(Arena* arena) const override { 68 return Arena::CreateMessage<ImplicitWeakMessage>(arena); 69 } 70 Clear()71 void Clear() override { data_.clear(); } 72 IsInitialized()73 bool IsInitialized() const override { return true; } 74 CheckTypeAndMergeFrom(const MessageLite & other)75 void CheckTypeAndMergeFrom(const MessageLite& other) override { 76 data_.append(static_cast<const ImplicitWeakMessage&>(other).data_); 77 } 78 79 const char* _InternalParse(const char* ptr, ParseContext* ctx) final; 80 ByteSizeLong()81 size_t ByteSizeLong() const override { return data_.size(); } 82 _InternalSerialize(uint8 * target,io::EpsCopyOutputStream * stream)83 uint8* _InternalSerialize(uint8* target, 84 io::EpsCopyOutputStream* stream) const final { 85 return stream->WriteRaw(data_.data(), static_cast<int>(data_.size()), 86 target); 87 } 88 GetCachedSize()89 int GetCachedSize() const override { return static_cast<int>(data_.size()); } 90 91 typedef void InternalArenaConstructable_; 92 93 private: 94 std::string data_; 95 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage); 96 }; 97 98 // A type handler for use with implicit weak repeated message fields. 99 template <typename ImplicitWeakType> 100 class ImplicitWeakTypeHandler { 101 public: 102 typedef MessageLite Type; 103 static constexpr bool Moveable = false; 104 105 static inline MessageLite* NewFromPrototype(const MessageLite* prototype, 106 Arena* arena = NULL) { 107 return prototype->New(arena); 108 } 109 Delete(MessageLite * value,Arena * arena)110 static inline void Delete(MessageLite* value, Arena* arena) { 111 if (arena == NULL) { 112 delete value; 113 } 114 } GetArena(MessageLite * value)115 static inline Arena* GetArena(MessageLite* value) { 116 return value->GetArena(); 117 } GetMaybeArenaPointer(MessageLite * value)118 static inline void* GetMaybeArenaPointer(MessageLite* value) { 119 return value->GetArena(); 120 } Clear(MessageLite * value)121 static inline void Clear(MessageLite* value) { value->Clear(); } Merge(const MessageLite & from,MessageLite * to)122 static void Merge(const MessageLite& from, MessageLite* to) { 123 to->CheckTypeAndMergeFrom(from); 124 } 125 }; 126 127 } // namespace internal 128 129 template <typename T> 130 struct WeakRepeatedPtrField { 131 using TypeHandler = internal::ImplicitWeakTypeHandler<T>; WeakRepeatedPtrFieldWeakRepeatedPtrField132 WeakRepeatedPtrField() : weak() {} WeakRepeatedPtrFieldWeakRepeatedPtrField133 explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {} ~WeakRepeatedPtrFieldWeakRepeatedPtrField134 ~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); } 135 136 typedef internal::RepeatedPtrIterator<MessageLite> iterator; 137 typedef internal::RepeatedPtrIterator<const MessageLite> const_iterator; 138 typedef internal::RepeatedPtrOverPtrsIterator<MessageLite*, void*> 139 pointer_iterator; 140 typedef internal::RepeatedPtrOverPtrsIterator<const MessageLite* const, 141 const void* const> 142 const_pointer_iterator; 143 beginWeakRepeatedPtrField144 iterator begin() { return iterator(base().raw_data()); } beginWeakRepeatedPtrField145 const_iterator begin() const { return iterator(base().raw_data()); } cbeginWeakRepeatedPtrField146 const_iterator cbegin() const { return begin(); } endWeakRepeatedPtrField147 iterator end() { return begin() + base().size(); } endWeakRepeatedPtrField148 const_iterator end() const { return begin() + base().size(); } cendWeakRepeatedPtrField149 const_iterator cend() const { return end(); } pointer_beginWeakRepeatedPtrField150 pointer_iterator pointer_begin() { 151 return pointer_iterator(base().raw_mutable_data()); 152 } pointer_beginWeakRepeatedPtrField153 const_pointer_iterator pointer_begin() const { 154 return const_pointer_iterator(base().raw_mutable_data()); 155 } pointer_endWeakRepeatedPtrField156 pointer_iterator pointer_end() { 157 return pointer_iterator(base().raw_mutable_data() + base().size()); 158 } pointer_endWeakRepeatedPtrField159 const_pointer_iterator pointer_end() const { 160 return const_pointer_iterator(base().raw_mutable_data() + base().size()); 161 } 162 AddWeakWeakRepeatedPtrField163 MessageLite* AddWeak(const MessageLite* prototype) { 164 return base().AddWeak(prototype); 165 } AddWeakRepeatedPtrField166 T* Add() { return weak.Add(); } ClearWeakRepeatedPtrField167 void Clear() { base().template Clear<TypeHandler>(); } MergeFromWeakRepeatedPtrField168 void MergeFrom(const WeakRepeatedPtrField& other) { 169 base().template MergeFrom<TypeHandler>(other.base()); 170 } InternalSwapWeakRepeatedPtrField171 void InternalSwap(WeakRepeatedPtrField* other) { 172 base().InternalSwap(&other->base()); 173 } 174 baseWeakRepeatedPtrField175 const internal::RepeatedPtrFieldBase& base() const { return weak; } baseWeakRepeatedPtrField176 internal::RepeatedPtrFieldBase& base() { return weak; } 177 // Union disables running the destructor. Which would create a strong link. 178 // Instead we explicitly destroy the underlying base through the virtual 179 // destructor. 180 union { 181 RepeatedPtrField<T> weak; 182 }; 183 }; 184 185 } // namespace protobuf 186 } // namespace google 187 188 #include <google/protobuf/port_undef.inc> 189 190 #endif // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__ 191