metadata_lite.h
Go to the documentation of this file.
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_METADATA_LITE_H__
32 #define GOOGLE_PROTOBUF_METADATA_LITE_H__
33 
34 #include <string>
36 #include <google/protobuf/arena.h>
39 #include <google/protobuf/port.h>
40 
41 #include <google/protobuf/port_def.inc>
42 
43 #ifdef SWIG
44 #error "You cannot SWIG proto headers"
45 #endif
46 
47 namespace google {
48 namespace protobuf {
49 namespace internal {
50 
51 // This is the representation for messages that support arena allocation. It
52 // uses a tagged pointer to either store the Arena pointer, if there are no
53 // unknown fields, or a pointer to a block of memory with both the Arena pointer
54 // and the UnknownFieldSet, if there are unknown fields. This optimization
55 // allows for "zero-overhead" storage of the Arena pointer, relative to the
56 // above baseline implementation.
57 //
58 // The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
59 // indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
60 // pointer.
61 template <class T, class Derived>
63  public:
66 
68  if (have_unknown_fields() && arena() == NULL) {
69  delete PtrValue<Container>();
70  }
71  ptr_ = NULL;
72  }
73 
74  PROTOBUF_ALWAYS_INLINE const T& unknown_fields() const {
75  if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) {
76  return PtrValue<Container>()->unknown_fields;
77  } else {
78  return Derived::default_instance();
79  }
80  }
81 
82  PROTOBUF_ALWAYS_INLINE T* mutable_unknown_fields() {
83  if (PROTOBUF_PREDICT_TRUE(have_unknown_fields())) {
84  return &PtrValue<Container>()->unknown_fields;
85  } else {
87  }
88  }
89 
90  PROTOBUF_ALWAYS_INLINE Arena* arena() const {
91  if (PROTOBUF_PREDICT_FALSE(have_unknown_fields())) {
92  return PtrValue<Container>()->arena;
93  } else {
94  return PtrValue<Arena>();
95  }
96  }
97 
98  PROTOBUF_ALWAYS_INLINE bool have_unknown_fields() const {
99  return PtrTag() == kTagContainer;
100  }
101 
102  PROTOBUF_ALWAYS_INLINE void Swap(Derived* other) {
103  // Semantics here are that we swap only the unknown fields, not the arena
104  // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
105  // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
106  // different states (direct arena pointer vs. container with UFS) so we
107  // cannot simply swap ptr_ and then restore the arena pointers. We reuse
108  // UFS's swap implementation instead.
109  if (have_unknown_fields() || other->have_unknown_fields()) {
110  static_cast<Derived*>(this)->DoSwap(other->mutable_unknown_fields());
111  }
112  }
113 
114  PROTOBUF_ALWAYS_INLINE void MergeFrom(const Derived& other) {
115  if (other.have_unknown_fields()) {
116  static_cast<Derived*>(this)->DoMergeFrom(other.unknown_fields());
117  }
118  }
119 
120  PROTOBUF_ALWAYS_INLINE void Clear() {
121  if (have_unknown_fields()) {
122  static_cast<Derived*>(this)->DoClear();
123  }
124  }
125 
126  PROTOBUF_ALWAYS_INLINE void* raw_arena_ptr() const { return ptr_; }
127 
128  private:
129  void* ptr_;
130 
131  // Tagged pointer implementation.
132  enum {
133  // ptr_ is an Arena*.
135  // ptr_ is a Container*.
137  };
138  static const intptr_t kPtrTagMask = 1;
139  static const intptr_t kPtrValueMask = ~kPtrTagMask;
140 
141  // Accessors for pointer tag and pointer value.
142  PROTOBUF_ALWAYS_INLINE int PtrTag() const {
143  return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
144  }
145 
146  template <typename U>
147  U* PtrValue() const {
148  return reinterpret_cast<U*>(reinterpret_cast<intptr_t>(ptr_) &
149  kPtrValueMask);
150  }
151 
152  // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
153  struct Container {
155  Arena* arena;
156  };
157 
158  PROTOBUF_NOINLINE T* mutable_unknown_fields_slow() {
159  Arena* my_arena = arena();
160  Container* container = Arena::Create<Container>(my_arena);
161  // Two-step assignment works around a bug in clang's static analyzer:
162  // https://bugs.llvm.org/show_bug.cgi?id=34198.
163  ptr_ = container;
164  ptr_ = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(ptr_) |
165  kTagContainer);
166  container->arena = my_arena;
167  return &(container->unknown_fields);
168  }
169 };
170 
171 // We store unknown fields as a std::string right now, because there is
172 // currently no good interface for reading unknown fields into an ArenaString.
173 // We may want to revisit this to allow unknown fields to be parsed onto the
174 // Arena.
176  : public InternalMetadataWithArenaBase<std::string,
177  InternalMetadataWithArenaLite> {
178  public:
180 
184 
185  void DoSwap(std::string* other) { mutable_unknown_fields()->swap(*other); }
186 
187  void DoMergeFrom(const std::string& other) {
188  mutable_unknown_fields()->append(other);
189  }
190 
191  void DoClear() { mutable_unknown_fields()->clear(); }
192 
193  static const std::string& default_instance() {
194  // Can't use GetEmptyStringAlreadyInited() here because empty string
195  // may not have been initalized yet. This happens when protocol compiler
196  // statically determines the user can't access defaults and omits init code
197  // from proto constructors. However unknown fields are always part of a
198  // proto so it needs to be lazily initailzed. See b/112613846.
199  return GetEmptyString();
200  }
201 };
202 
203 // This helper RAII class is needed to efficiently parse unknown fields. We
204 // should only call mutable_unknown_fields if there are actual unknown fields.
205 // The obvious thing to just use a stack string and swap it at the end of
206 // the parse won't work, because the destructor of StringOutputStream needs to
207 // be called before we can modify the string (it check-fails). Using
208 // LiteUnknownFieldSetter setter(&_internal_metadata_);
209 // StringOutputStream stream(setter.buffer());
210 // guarantees that the string is only swapped after stream is destroyed.
211 class PROTOBUF_EXPORT LiteUnknownFieldSetter {
212  public:
214  : metadata_(metadata) {
215  if (metadata->have_unknown_fields()) {
216  buffer_.swap(*metadata->mutable_unknown_fields());
217  }
218  }
220  if (!buffer_.empty()) metadata_->mutable_unknown_fields()->swap(buffer_);
221  }
222  std::string* buffer() { return &buffer_; }
223 
224  private:
227 };
228 
229 } // namespace internal
230 } // namespace protobuf
231 } // namespace google
232 
233 #include <google/protobuf/port_undef.inc>
234 
235 #endif // GOOGLE_PROTOBUF_METADATA_LITE_H__
google::protobuf.internal::LiteUnknownFieldSetter::buffer_
std::string buffer_
Definition: metadata_lite.h:226
google::protobuf.internal::InternalMetadataWithArenaBase::PtrTag
PROTOBUF_ALWAYS_INLINE int PtrTag() const
Definition: metadata_lite.h:142
google::protobuf.internal::InternalMetadataWithArenaBase::unknown_fields
const PROTOBUF_ALWAYS_INLINE T & unknown_fields() const
Definition: metadata_lite.h:74
google::protobuf.internal::InternalMetadataWithArenaBase::Swap
PROTOBUF_ALWAYS_INLINE void Swap(Derived *other)
Definition: metadata_lite.h:102
google::protobuf.internal::InternalMetadataWithArenaLite
Definition: metadata_lite.h:175
google::protobuf.internal::InternalMetadataWithArenaLite::InternalMetadataWithArenaLite
InternalMetadataWithArenaLite()
Definition: metadata_lite.h:179
google::protobuf.internal::InternalMetadataWithArenaBase::kPtrTagMask
static const intptr_t kPtrTagMask
Definition: metadata_lite.h:138
google::protobuf.internal::LiteUnknownFieldSetter
Definition: metadata_lite.h:211
google::protobuf.internal::InternalMetadataWithArenaBase::Container
Definition: metadata_lite.h:153
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf.internal::InternalMetadataWithArenaBase::InternalMetadataWithArenaBase
InternalMetadataWithArenaBase()
Definition: metadata_lite.h:64
benchmarks.util.result_uploader.metadata
def metadata
Definition: result_uploader.py:97
google::protobuf.internal::InternalMetadataWithArenaBase::Container::arena
Arena * arena
Definition: metadata_lite.h:155
google::protobuf.internal::InternalMetadataWithArenaBase::Container::unknown_fields
T unknown_fields
Definition: metadata_lite.h:154
google::protobuf.internal::InternalMetadataWithArenaLite::default_instance
static const std::string & default_instance()
Definition: metadata_lite.h:193
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf.internal::InternalMetadataWithArenaBase::~InternalMetadataWithArenaBase
~InternalMetadataWithArenaBase()
Definition: metadata_lite.h:67
port.h
T
#define T(upbtypeconst, upbtype, ctype, default_value)
google::protobuf.internal::InternalMetadataWithArenaLite::DoSwap
void DoSwap(std::string *other)
Definition: metadata_lite.h:185
google::protobuf.internal::LiteUnknownFieldSetter::LiteUnknownFieldSetter
LiteUnknownFieldSetter(InternalMetadataWithArenaLite *metadata)
Definition: metadata_lite.h:213
google::protobuf.internal::InternalMetadataWithArenaBase
Definition: metadata_lite.h:62
google::protobuf.internal::InternalMetadataWithArenaBase::kPtrValueMask
static const intptr_t kPtrValueMask
Definition: metadata_lite.h:139
google::protobuf.internal::InternalMetadataWithArenaBase::mutable_unknown_fields
PROTOBUF_ALWAYS_INLINE T * mutable_unknown_fields()
Definition: metadata_lite.h:82
google::protobuf.internal::InternalMetadataWithArenaBase::kTagContainer
@ kTagContainer
Definition: metadata_lite.h:136
google::protobuf.internal::InternalMetadataWithArenaBase::ptr_
void * ptr_
Definition: metadata_lite.h:129
google::protobuf.internal::InternalMetadataWithArenaBase::kTagArena
@ kTagArena
Definition: metadata_lite.h:134
google::protobuf.internal::InternalMetadataWithArenaBase::raw_arena_ptr
PROTOBUF_ALWAYS_INLINE void * raw_arena_ptr() const
Definition: metadata_lite.h:126
google::protobuf.internal::GetEmptyString
const PROTOBUF_EXPORT std::string & GetEmptyString()
Definition: generated_message_util.h:87
google::protobuf.internal::LiteUnknownFieldSetter::buffer
std::string * buffer()
Definition: metadata_lite.h:222
google::protobuf.internal::InternalMetadataWithArenaBase::Clear
PROTOBUF_ALWAYS_INLINE void Clear()
Definition: metadata_lite.h:120
google::protobuf.internal::LiteUnknownFieldSetter::~LiteUnknownFieldSetter
~LiteUnknownFieldSetter()
Definition: metadata_lite.h:219
common.h
google::protobuf.internal::InternalMetadataWithArenaLite::DoMergeFrom
void DoMergeFrom(const std::string &other)
Definition: metadata_lite.h:187
std
arena.h
google::protobuf.internal::InternalMetadataWithArenaBase::MergeFrom
PROTOBUF_ALWAYS_INLINE void MergeFrom(const Derived &other)
Definition: metadata_lite.h:114
message_lite.h
google::protobuf.internal::InternalMetadataWithArenaBase::mutable_unknown_fields_slow
PROTOBUF_NOINLINE T * mutable_unknown_fields_slow()
Definition: metadata_lite.h:158
google::protobuf.internal::InternalMetadataWithArenaBase::arena
PROTOBUF_ALWAYS_INLINE Arena * arena() const
Definition: metadata_lite.h:90
google::protobuf.internal::InternalMetadataWithArenaLite::InternalMetadataWithArenaLite
InternalMetadataWithArenaLite(Arena *arena)
Definition: metadata_lite.h:181
generated_message_util.h
internal
Definition: any.pb.h:40
buffer_
static uint8 buffer_[kBufferSize]
Definition: coded_stream_unittest.cc:136
google::protobuf.internal::InternalMetadataWithArenaBase::have_unknown_fields
PROTOBUF_ALWAYS_INLINE bool have_unknown_fields() const
Definition: metadata_lite.h:98
google::protobuf.internal::LiteUnknownFieldSetter::metadata_
InternalMetadataWithArenaLite * metadata_
Definition: metadata_lite.h:225
google::protobuf.internal::InternalMetadataWithArenaBase::PtrValue
U * PtrValue() const
Definition: metadata_lite.h:147
google::protobuf.internal::InternalMetadataWithArenaLite::DoClear
void DoClear()
Definition: metadata_lite.h:191
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf.internal::InternalMetadataWithArenaBase::InternalMetadataWithArenaBase
InternalMetadataWithArenaBase(Arena *arena)
Definition: metadata_lite.h:65


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:57