• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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