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// Must be included last.
46#include <google/protobuf/port_def.inc>
47
48// This file is logically internal-only and should only be used by protobuf
49// generated code.
50
51namespace google {
52namespace protobuf {
53namespace internal {
54
55// An implementation of MessageLite that treats all data as unknown. This type
56// acts as a placeholder for an implicit weak field in the case where the true
57// message type does not get linked into the binary.
58class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite {
59 public:
60 ImplicitWeakMessage() : data_(new std::string) {}
61 explicit constexpr ImplicitWeakMessage(ConstantInitialized)
62 : data_(nullptr) {}
63 explicit ImplicitWeakMessage(Arena* arena)
64 : MessageLite(arena), data_(new std::string) {}
65
66 ~ImplicitWeakMessage() override {
67 // data_ will be null in the default instance, but we can safely call delete
68 // here because the default instance will never be destroyed.
69 delete data_;
70 }
71
72 static const ImplicitWeakMessage* default_instance();
73
74 std::string GetTypeName() const override { return ""; }
75
76 MessageLite* New(Arena* arena) const override {
77 return Arena::CreateMessage<ImplicitWeakMessage>(arena);
78 }
79
80 void Clear() override { data_->clear(); }
81
82 bool IsInitialized() const override { return true; }
83
84 void CheckTypeAndMergeFrom(const MessageLite& other) override {
85 const std::string* other_data =
86 static_cast<const ImplicitWeakMessage&>(other).data_;
87 if (other_data != nullptr) {
88 data_->append(str: *other_data);
89 }
90 }
91
92 const char* _InternalParse(const char* ptr, ParseContext* ctx) final;
93
94 size_t ByteSizeLong() const override {
95 return data_ == nullptr ? 0 : data_->size();
96 }
97
98 uint8_t* _InternalSerialize(uint8_t* target,
99 io::EpsCopyOutputStream* stream) const final {
100 if (data_ == nullptr) {
101 return target;
102 }
103 return stream->WriteRaw(data: data_->data(), size: static_cast<int>(data_->size()),
104 ptr: target);
105 }
106
107 int GetCachedSize() const override {
108 return data_ == nullptr ? 0 : static_cast<int>(data_->size());
109 }
110
111 typedef void InternalArenaConstructable_;
112
113 private:
114 // This std::string is allocated on the heap, but we use a raw pointer so that
115 // the default instance can be constant-initialized. In the const methods, we
116 // have to handle the possibility of data_ being null.
117 std::string* data_;
118 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImplicitWeakMessage);
119};
120
121struct ImplicitWeakMessageDefaultType;
122extern ImplicitWeakMessageDefaultType implicit_weak_message_default_instance;
123
124// A type handler for use with implicit weak repeated message fields.
125template <typename ImplicitWeakType>
126class ImplicitWeakTypeHandler {
127 public:
128 typedef MessageLite Type;
129 static constexpr bool Moveable = false;
130
131 static inline MessageLite* NewFromPrototype(const MessageLite* prototype,
132 Arena* arena = nullptr) {
133 return prototype->New(arena);
134 }
135
136 static inline void Delete(MessageLite* value, Arena* arena) {
137 if (arena == nullptr) {
138 delete value;
139 }
140 }
141 static inline Arena* GetArena(MessageLite* value) {
142 return value->GetArena();
143 }
144 static inline void Clear(MessageLite* value) { value->Clear(); }
145 static void Merge(const MessageLite& from, MessageLite* to) {
146 to->CheckTypeAndMergeFrom(other: from);
147 }
148};
149
150} // namespace internal
151
152template <typename T>
153struct WeakRepeatedPtrField {
154 using TypeHandler = internal::ImplicitWeakTypeHandler<T>;
155 constexpr WeakRepeatedPtrField() : weak() {}
156 explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {}
157 ~WeakRepeatedPtrField() { weak.template Destroy<TypeHandler>(); }
158
159 typedef internal::RepeatedPtrIterator<MessageLite> iterator;
160 typedef internal::RepeatedPtrIterator<const MessageLite> const_iterator;
161 typedef internal::RepeatedPtrOverPtrsIterator<MessageLite*, void*>
162 pointer_iterator;
163 typedef internal::RepeatedPtrOverPtrsIterator<const MessageLite* const,
164 const void* const>
165 const_pointer_iterator;
166
167 iterator begin() { return iterator(base().raw_data()); }
168 const_iterator begin() const { return iterator(base().raw_data()); }
169 const_iterator cbegin() const { return begin(); }
170 iterator end() { return begin() + base().size(); }
171 const_iterator end() const { return begin() + base().size(); }
172 const_iterator cend() const { return end(); }
173 pointer_iterator pointer_begin() {
174 return pointer_iterator(base().raw_mutable_data());
175 }
176 const_pointer_iterator pointer_begin() const {
177 return const_pointer_iterator(base().raw_mutable_data());
178 }
179 pointer_iterator pointer_end() {
180 return pointer_iterator(base().raw_mutable_data() + base().size());
181 }
182 const_pointer_iterator pointer_end() const {
183 return const_pointer_iterator(base().raw_mutable_data() + base().size());
184 }
185
186 MessageLite* AddWeak(const MessageLite* prototype) {
187 return base().AddWeak(prototype);
188 }
189 T* Add() { return weak.Add(); }
190 void Clear() { base().template Clear<TypeHandler>(); }
191 void MergeFrom(const WeakRepeatedPtrField& other) {
192 base().template MergeFrom<TypeHandler>(other.base());
193 }
194 void InternalSwap(WeakRepeatedPtrField* other) {
195 base().InternalSwap(&other->base());
196 }
197
198 const internal::RepeatedPtrFieldBase& base() const { return weak; }
199 internal::RepeatedPtrFieldBase& base() { return weak; }
200 // Union disables running the destructor. Which would create a strong link.
201 // Instead we explicitly destroy the underlying base through the virtual
202 // destructor.
203 union {
204 RepeatedPtrField<T> weak;
205 };
206};
207
208} // namespace protobuf
209} // namespace google
210
211#include <google/protobuf/port_undef.inc>
212
213#endif // GOOGLE_PROTOBUF_IMPLICIT_WEAK_MESSAGE_H__
214