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
50namespace google {
51namespace protobuf {
52namespace 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.
57class PROTOBUF_EXPORT ImplicitWeakMessage : public MessageLite {
58 public:
59 ImplicitWeakMessage() {}
60 explicit ImplicitWeakMessage(Arena* arena) : MessageLite(arena) {}
61
62 static const ImplicitWeakMessage* default_instance();
63
64 std::string GetTypeName() const override { return ""; }
65
66 MessageLite* New() const override { return new ImplicitWeakMessage; }
67 MessageLite* New(Arena* arena) const override {
68 return Arena::CreateMessage<ImplicitWeakMessage>(arena);
69 }
70
71 void Clear() override { data_.clear(); }
72
73 bool IsInitialized() const override { return true; }
74
75 void CheckTypeAndMergeFrom(const MessageLite& other) override {
76 data_.append(str: static_cast<const ImplicitWeakMessage&>(other).data_);
77 }
78
79 const char* _InternalParse(const char* ptr, ParseContext* ctx) final;
80
81 size_t ByteSizeLong() const override { return data_.size(); }
82
83 uint8* _InternalSerialize(uint8* target,
84 io::EpsCopyOutputStream* stream) const final {
85 return stream->WriteRaw(data: data_.data(), size: static_cast<int>(data_.size()),
86 ptr: target);
87 }
88
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.
99template <typename ImplicitWeakType>
100class 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
110 static inline void Delete(MessageLite* value, Arena* arena) {
111 if (arena == NULL) {
112 delete value;
113 }
114 }
115 static inline Arena* GetArena(MessageLite* value) {
116 return value->GetArena();
117 }
118 static inline void* GetMaybeArenaPointer(MessageLite* value) {
119 return value->GetArena();
120 }
121 static inline void Clear(MessageLite* value) { value->Clear(); }
122 static void Merge(const MessageLite& from, MessageLite* to) {
123 to->CheckTypeAndMergeFrom(other: from);
124 }
125};
126
127} // namespace internal
128
129template <typename T>
130struct WeakRepeatedPtrField {
131 using TypeHandler = internal::ImplicitWeakTypeHandler<T>;
132 WeakRepeatedPtrField() : weak() {}
133 explicit WeakRepeatedPtrField(Arena* arena) : weak(arena) {}
134 ~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
144 iterator begin() { return iterator(base().raw_data()); }
145 const_iterator begin() const { return iterator(base().raw_data()); }
146 const_iterator cbegin() const { return begin(); }
147 iterator end() { return begin() + base().size(); }
148 const_iterator end() const { return begin() + base().size(); }
149 const_iterator cend() const { return end(); }
150 pointer_iterator pointer_begin() {
151 return pointer_iterator(base().raw_mutable_data());
152 }
153 const_pointer_iterator pointer_begin() const {
154 return const_pointer_iterator(base().raw_mutable_data());
155 }
156 pointer_iterator pointer_end() {
157 return pointer_iterator(base().raw_mutable_data() + base().size());
158 }
159 const_pointer_iterator pointer_end() const {
160 return const_pointer_iterator(base().raw_mutable_data() + base().size());
161 }
162
163 MessageLite* AddWeak(const MessageLite* prototype) {
164 return base().AddWeak(prototype);
165 }
166 T* Add() { return weak.Add(); }
167 void Clear() { base().template Clear<TypeHandler>(); }
168 void MergeFrom(const WeakRepeatedPtrField& other) {
169 base().template MergeFrom<TypeHandler>(other.base());
170 }
171 void InternalSwap(WeakRepeatedPtrField* other) {
172 base().InternalSwap(&other->base());
173 }
174
175 const internal::RepeatedPtrFieldBase& base() const { return weak; }
176 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

source code of include/google/protobuf/implicit_weak_message.h