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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years 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>
43 #include <google/protobuf/unknown_field_set.h> 45 #include <google/protobuf/unknown_field_set.h>
44 46
45 namespace google { 47 namespace google {
46 namespace protobuf { 48 namespace protobuf {
47 namespace internal { 49 namespace internal {
48 50
49 // This is the representation for messages that support arena allocation. It 51 // This is the representation for messages that support arena allocation. It
50 // uses a tagged pointer to either store the Arena pointer, if there are no 52 // uses a tagged pointer to either store the Arena pointer, if there are no
51 // unknown fields, or a pointer to a block of memory with both the Arena pointer 53 // unknown fields, or a pointer to a block of memory with both the Arena pointer
52 // and the UnknownFieldSet, if there are unknown fields. This optimization 54 // and the UnknownFieldSet, if there are unknown fields. This optimization
53 // allows for "zero-overhead" storage of the Arena pointer, relative to the 55 // allows for "zero-overhead" storage of the Arena pointer, relative to the
54 // above baseline implementation. 56 // above baseline implementation.
55 // 57 //
56 // The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to 58 // The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to
57 // indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container 59 // indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container
58 // pointer. 60 // pointer.
59 class LIBPROTOBUF_EXPORT InternalMetadataWithArena { 61 template <class T, class Derived>
62 class InternalMetadataWithArenaBase {
60 public: 63 public:
61 InternalMetadataWithArena() : ptr_(NULL) {} 64 InternalMetadataWithArenaBase() : ptr_(NULL) {}
62 explicit InternalMetadataWithArena(Arena* arena) 65 explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {}
63 : ptr_ (arena) {}
64 66
65 ~InternalMetadataWithArena() { 67 ~InternalMetadataWithArenaBase() {
66 if (have_unknown_fields() && arena() == NULL) { 68 if (have_unknown_fields() && arena() == NULL) {
67 delete PtrValue<Container>(); 69 delete PtrValue<Container>();
68 } 70 }
69 ptr_ = NULL; 71 ptr_ = NULL;
70 } 72 }
71 73
72 GOOGLE_ATTRIBUTE_ALWAYS_INLINE const UnknownFieldSet& unknown_fields() const { 74 GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const {
73 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { 75 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
74 return PtrValue<Container>()->unknown_fields_; 76 return PtrValue<Container>()->unknown_fields;
75 } else { 77 } else {
76 return *UnknownFieldSet::default_instance(); 78 return Derived::default_instance();
77 } 79 }
78 } 80 }
79 81
80 GOOGLE_ATTRIBUTE_ALWAYS_INLINE UnknownFieldSet* mutable_unknown_fields() { 82 GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() {
81 if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) { 83 if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) {
82 return &PtrValue<Container>()->unknown_fields_; 84 return &PtrValue<Container>()->unknown_fields;
83 } else { 85 } else {
84 return mutable_unknown_fields_slow(); 86 return mutable_unknown_fields_slow();
85 } 87 }
86 } 88 }
87 89
88 GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const { 90 GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const {
89 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { 91 if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
90 return PtrValue<Container>()->arena_; 92 return PtrValue<Container>()->arena;
91 } else { 93 } else {
92 return PtrValue<Arena>(); 94 return PtrValue<Arena>();
93 } 95 }
94 } 96 }
95 97
96 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const { 98 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const {
97 return PtrTag() == kTagContainer; 99 return PtrTag() == kTagContainer;
98 } 100 }
99 101
100 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(InternalMetadataWithArena* other) { 102 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* other) {
101 // Semantics here are that we swap only the unknown fields, not the arena 103 // Semantics here are that we swap only the unknown fields, not the arena
102 // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to 104 // pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
103 // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in 105 // maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
104 // different states (direct arena pointer vs. container with UFS) so we 106 // different states (direct arena pointer vs. container with UFS) so we
105 // cannot simply swap ptr_ and then restore the arena pointers. We reuse 107 // cannot simply swap ptr_ and then restore the arena pointers. We reuse
106 // UFS's swap implementation instead. 108 // UFS's swap implementation instead.
107 if (have_unknown_fields() || other->have_unknown_fields()) { 109 if (have_unknown_fields() || other->have_unknown_fields()) {
108 mutable_unknown_fields()->Swap(other->mutable_unknown_fields()); 110 static_cast<Derived*>(this)->DoSwap(other->mutable_unknown_fields());
109 } 111 }
110 } 112 }
111 113
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
112 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const { 126 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const {
113 return ptr_; 127 return ptr_;
114 } 128 }
115 129
116 private: 130 private:
117 void* ptr_; 131 void* ptr_;
118 132
119 // Tagged pointer implementation. 133 // Tagged pointer implementation.
120 enum { 134 enum {
121 // ptr_ is an Arena*. 135 // ptr_ is an Arena*.
122 kTagArena = 0, 136 kTagArena = 0,
123 // ptr_ is a Container*. 137 // ptr_ is a Container*.
124 kTagContainer = 1, 138 kTagContainer = 1,
125 }; 139 };
126 static const intptr_t kPtrTagMask = 1; 140 static const intptr_t kPtrTagMask = 1;
127 static const intptr_t kPtrValueMask = ~kPtrTagMask; 141 static const intptr_t kPtrValueMask = ~kPtrTagMask;
128 142
129 // Accessors for pointer tag and pointer value. 143 // Accessors for pointer tag and pointer value.
130 GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const { 144 GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const {
131 return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask; 145 return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
132 } 146 }
133 147
134 template<typename T> T* PtrValue() const { 148 template<typename U> U* PtrValue() const {
135 return reinterpret_cast<T*>( 149 return reinterpret_cast<U*>(
136 reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask); 150 reinterpret_cast<intptr_t>(ptr_) & kPtrValueMask);
137 } 151 }
138 152
139 // If ptr_'s tag is kTagContainer, it points to an instance of this struct. 153 // If ptr_'s tag is kTagContainer, it points to an instance of this struct.
140 struct Container { 154 struct Container {
141 UnknownFieldSet unknown_fields_; 155 T unknown_fields;
142 Arena* arena_; 156 Arena* arena;
143 }; 157 };
144 158
145 GOOGLE_ATTRIBUTE_NOINLINE UnknownFieldSet* mutable_unknown_fields_slow() { 159 GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() {
146 Arena* my_arena = arena(); 160 Arena* my_arena = arena();
147 Container* container = Arena::Create<Container>(my_arena); 161 Container* container = Arena::Create<Container>(my_arena);
148 ptr_ = reinterpret_cast<void*>( 162 ptr_ = reinterpret_cast<void*>(
149 reinterpret_cast<intptr_t>(container) | kTagContainer); 163 reinterpret_cast<intptr_t>(container) | kTagContainer);
150 container->arena_ = my_arena; 164 container->arena = my_arena;
151 return &(container->unknown_fields_); 165 return &(container->unknown_fields);
152 } 166 }
153 }; 167 };
154 168
155 // Temporary compatibility typedef. Remove once this is released in components 169 class InternalMetadataWithArena
156 // and upb CL is submitted. 170 : public InternalMetadataWithArenaBase<UnknownFieldSet,
157 typedef InternalMetadataWithArena InternalMetadata; 171 InternalMetadataWithArena> {
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 };
158 222
159 } // namespace internal 223 } // namespace internal
160 } // namespace protobuf 224 } // namespace protobuf
161 225
162 } // namespace google 226 } // namespace google
163 #endif // GOOGLE_PROTOBUF_METADATA_H__ 227 #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