Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(353)

Side by Side Diff: third_party/protobuf/src/google/protobuf/metadata.h

Issue 2600753002: Reverts third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/ 3 // https://developers.google.com/protocol-buffers/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 22 matching lines...) Expand all
33 // representation to be made more space-efficient via various optimizations. 33 // representation to be made more space-efficient via various optimizations.
34 // 34 //
35 // Note that this is distinct from google::protobuf::Metadata, which encapsulate s 35 // Note that this is distinct from google::protobuf::Metadata, which encapsulate s
36 // Descriptor and Reflection pointers. 36 // Descriptor and Reflection pointers.
37 37
38 #ifndef GOOGLE_PROTOBUF_METADATA_H__ 38 #ifndef GOOGLE_PROTOBUF_METADATA_H__
39 #define GOOGLE_PROTOBUF_METADATA_H__ 39 #define GOOGLE_PROTOBUF_METADATA_H__
40 40
41 #include <google/protobuf/stubs/common.h> 41 #include <google/protobuf/stubs/common.h>
42 #include <google/protobuf/arena.h> 42 #include <google/protobuf/arena.h>
43 #include <google/protobuf/arenastring.h>
44 #include <google/protobuf/generated_message_util.h>
45 #include <google/protobuf/unknown_field_set.h> 43 #include <google/protobuf/unknown_field_set.h>
46 44
47 namespace google { 45 namespace google {
48 namespace protobuf { 46 namespace protobuf {
49 namespace internal { 47 namespace internal {
50 48
51 // This is the representation for messages that support arena allocation. It 49 // 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 50 // 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 51 // 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 52 // and the UnknownFieldSet, if there are unknown fields. This optimization
55 // allows for "zero-overhead" storage of the Arena pointer, relative to the 53 // allows for "zero-overhead" storage of the Arena pointer, relative to the
56 // above baseline implementation. 54 // above baseline implementation.
57 // 55 //
58 // The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to 56 // 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 57 // indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
60 // pointer. 58 // pointer.
61 template <class T, class Derived> 59 class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
62 class InternalMetadataWithArenaBase {
63 public: 60 public:
64 InternalMetadataWithArenaBase() : ptr_(NULL) {} 61 InternalMetadataWithArena() : ptr_(NULL) {}
65 explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {} 62 explicit InternalMetadataWithArena(Arena* arena)
63 : ptr_ (arena) {}
66 64
67 ~InternalMetadataWithArenaBase() { 65 ~InternalMetadataWithArena() {
68 if (have_unknown_fields() && arena() == NULL) { 66 if (have_unknown_fields() && arena() == NULL) {
69 delete PtrValue<Container>(); 67 delete PtrValue<Container>();
70 } 68 }
71 ptr_ = NULL; 69 ptr_ = NULL;
72 } 70 }
73 71
74 GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const { 72 GOOGLE_ATTRIBUTE_ALWAYS_INLINE const UnknownFieldSet& unknown_fields() const {
75 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { 73 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
76 return PtrValue<Container>()->unknown_fields; 74 return PtrValue<Container>()->unknown_fields_;
77 } else { 75 } else {
78 return Derived::default_instance(); 76 return *UnknownFieldSet::default_instance();
79 } 77 }
80 } 78 }
81 79
82 GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() { 80 GOOGLE_ATTRIBUTE_ALWAYS_INLINE UnknownFieldSet* mutable_unknown_fields() {
83 if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) { 81 if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) {
84 return &PtrValue<Container>()->unknown_fields; 82 return &PtrValue<Container>()->unknown_fields_;
85 } else { 83 } else {
86 return mutable_unknown_fields_slow(); 84 return mutable_unknown_fields_slow();
87 } 85 }
88 } 86 }
89 87
90 GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const { 88 GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const {
91 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { 89 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
92 return PtrValue<Container>()->arena; 90 return PtrValue<Container>()->arena_;
93 } else { 91 } else {
94 return PtrValue<Arena>(); 92 return PtrValue<Arena>();
95 } 93 }
96 } 94 }
97 95
98 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const { 96 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const {
99 return PtrTag() == kTagContainer; 97 return PtrTag() == kTagContainer;
100 } 98 }
101 99
102 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* other) { 100 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(InternalMetadataWithArena* other) {
103 // Semantics here are that we swap only the unknown fields, not the arena 101 // 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 102 // 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 103 // 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 104 // different states (direct arena pointer vs. container with UFS) so we
107 // cannot simply swap ptr_ and then restore the arena pointers. We reuse 105 // cannot simply swap ptr_ and then restore the arena pointers. We reuse
108 // UFS's swap implementation instead. 106 // UFS's swap implementation instead.
109 if (have_unknown_fields() || other->have_unknown_fields()) { 107 if (have_unknown_fields() || other->have_unknown_fields()) {
110 static_cast<Derived*>(this)->DoSwap(other->mutable_unknown_fields()); 108 mutable_unknown_fields()->Swap(other->mutable_unknown_fields());
111 } 109 }
112 } 110 }
113 111
114 GOOGLE_ATTRIBUTE_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 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() {
121 if (have_unknown_fields()) {
122 static_cast<Derived*>(this)->DoClear();
123 }
124 }
125
126 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const { 112 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const {
127 return ptr_; 113 return ptr_;
128 } 114 }
129 115
130 private: 116 private:
131 void* ptr_; 117 void* ptr_;
132 118
133 // Tagged pointer implementation. 119 // Tagged pointer implementation.
134 enum { 120 enum {
135 // ptr_ is an Arena*. 121 // ptr_ is an Arena*.
136 kTagArena = 0, 122 kTagArena = 0,
137 // ptr_ is a Container*. 123 // ptr_ is a Container*.
138 kTagContainer = 1, 124 kTagContainer = 1,
139 }; 125 };
140 static const intptr_t kPtrTagMask = 1; 126 static const intptr_t kPtrTagMask = 1;
141 static const intptr_t kPtrValueMask = ~kPtrTagMask; 127 static const intptr_t kPtrValueMask = ~kPtrTagMask;
142 128
143 // Accessors for pointer tag and pointer value. 129 // Accessors for pointer tag and pointer value.
144 GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const { 130 GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const {
145 return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask; 131 return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
146 } 132 }
147 133
148 template<typename U> U* PtrValue() const { 134 template<typename T> T* PtrValue() const {
149 return reinterpret_cast<U*>( 135 return reinterpret_cast<T*>(
150 reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask); 136 reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask);
151 } 137 }
152 138
153 // If ptr_'s tag is kTagContainer, it points to an instance of this struct. 139 // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
154 struct Container { 140 struct Container {
155 T unknown_fields; 141 UnknownFieldSet unknown_fields_;
156 Arena* arena; 142 Arena* arena_;
157 }; 143 };
158 144
159 GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() { 145 GOOGLE_ATTRIBUTE_NOINLINE UnknownFieldSet* mutable_unknown_fields_slow() {
160 Arena* my_arena = arena(); 146 Arena* my_arena = arena();
161 Container* container = Arena::Create<Container>(my_arena); 147 Container* container = Arena::Create<Container>(my_arena);
162 ptr_ = reinterpret_cast<void*>( 148 ptr_ = reinterpret_cast<void*>(
163 reinterpret_cast<intptr_t>(container) | kTagContainer); 149 reinterpret_cast<intptr_t>(container) | kTagContainer);
164 container->arena = my_arena; 150 container->arena_ = my_arena;
165 return &(container->unknown_fields); 151 return &(container->unknown_fields_);
166 } 152 }
167 }; 153 };
168 154
169 class InternalMetadataWithArena 155 // Temporary compatibility typedef. Remove once this is released in components
170 : public InternalMetadataWithArenaBase<UnknownFieldSet, 156 // and upb CL is submitted.
171 InternalMetadataWithArena> { 157 typedef InternalMetadataWithArena InternalMetadata;
172 public:
173 InternalMetadataWithArena() {}
174 explicit InternalMetadataWithArena(Arena* arena)
175 : InternalMetadataWithArenaBase(arena) {}
176
177 void DoSwap(UnknownFieldSet* other) {
178 mutable_unknown_fields()->Swap(other);
179 }
180
181 void DoMergeFrom(const UnknownFieldSet& other) {
182 mutable_unknown_fields()->MergeFrom(other);
183 }
184
185 void DoClear() {
186 mutable_unknown_fields()->Clear();
187 }
188
189 static const UnknownFieldSet& default_instance() {
190 return *UnknownFieldSet::default_instance();
191 }
192 };
193
194 // We store unknown fields as a string right now, because there is currently no
195 // good interface for reading unknown fields into an ArenaString. We may want
196 // to revisit this to allow unknown fields to be parsed onto the Arena.
197 class InternalMetadataWithArenaLite
198 : public InternalMetadataWithArenaBase<string,
199 InternalMetadataWithArenaLite> {
200 public:
201 InternalMetadataWithArenaLite() {}
202
203 explicit InternalMetadataWithArenaLite(Arena* arena)
204 : InternalMetadataWithArenaBase(arena) {}
205
206 void DoSwap(string* other) {
207 mutable_unknown_fields()->swap(*other);
208 }
209
210 void DoMergeFrom(const string& other) {
211 mutable_unknown_fields()->append(other);
212 }
213
214 void DoClear() {
215 mutable_unknown_fields()->clear();
216 }
217
218 static const string& default_instance() {
219 return GetEmptyStringAlreadyInited();
220 }
221 };
222 158
223 } // namespace internal 159 } // namespace internal
224 } // namespace protobuf 160 } // namespace protobuf
225 161
226 } // namespace google 162 } // namespace google
227 #endif // GOOGLE_PROTOBUF_METADATA_H__ 163 #endif // GOOGLE_PROTOBUF_METADATA_H__
OLDNEW
« no previous file with comments | « third_party/protobuf/src/google/protobuf/message_unittest.cc ('k') | third_party/protobuf/src/google/protobuf/reflection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698