1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__ 9 #define GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__ 10 11 #include "absl/strings/cord.h" 12 #include "google/protobuf/map_field.h" 13 #include "google/protobuf/reflection.h" 14 #include "google/protobuf/repeated_field.h" 15 16 namespace google { 17 namespace protobuf { 18 namespace internal { 19 // A base class for RepeatedFieldAccessor implementations that can support 20 // random-access efficiently. All iterator methods delegates the work to 21 // corresponding random-access methods. 22 class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor { 23 public: BeginIterator(const Field *)24 Iterator* BeginIterator(const Field* /*data*/) const override { 25 return PositionToIterator(0); 26 } EndIterator(const Field * data)27 Iterator* EndIterator(const Field* data) const override { 28 return PositionToIterator(this->Size(data)); 29 } CopyIterator(const Field *,const Iterator * iterator)30 Iterator* CopyIterator(const Field* /*data*/, 31 const Iterator* iterator) const override { 32 return const_cast<Iterator*>(iterator); 33 } AdvanceIterator(const Field *,Iterator * iterator)34 Iterator* AdvanceIterator(const Field* /*data*/, 35 Iterator* iterator) const override { 36 return PositionToIterator(IteratorToPosition(iterator) + 1); 37 } EqualsIterator(const Field *,const Iterator * a,const Iterator * b)38 bool EqualsIterator(const Field* /*data*/, const Iterator* a, 39 const Iterator* b) const override { 40 return a == b; 41 } DeleteIterator(const Field *,Iterator *)42 void DeleteIterator(const Field* /*data*/, 43 Iterator* /*iterator*/) const override {} GetIteratorValue(const Field * data,const Iterator * iterator,Value * scratch_space)44 const Value* GetIteratorValue(const Field* data, const Iterator* iterator, 45 Value* scratch_space) const override { 46 return Get(data, static_cast<int>(IteratorToPosition(iterator)), 47 scratch_space); 48 } 49 50 protected: 51 ~RandomAccessRepeatedFieldAccessor() = default; 52 53 private: IteratorToPosition(const Iterator * iterator)54 static intptr_t IteratorToPosition(const Iterator* iterator) { 55 return reinterpret_cast<intptr_t>(iterator); 56 } PositionToIterator(intptr_t position)57 static Iterator* PositionToIterator(intptr_t position) { 58 return reinterpret_cast<Iterator*>(position); 59 } 60 }; 61 62 // Base class for RepeatedFieldAccessor implementations that manipulates 63 // RepeatedField<T>. 64 template <typename T> 65 class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor { 66 public: RepeatedFieldWrapper()67 RepeatedFieldWrapper() {} IsEmpty(const Field * data)68 bool IsEmpty(const Field* data) const override { 69 return GetRepeatedField(data)->empty(); 70 } Size(const Field * data)71 int Size(const Field* data) const override { 72 return GetRepeatedField(data)->size(); 73 } Get(const Field * data,int index,Value * scratch_space)74 const Value* Get(const Field* data, int index, 75 Value* scratch_space) const override { 76 return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space); 77 } Clear(Field * data)78 void Clear(Field* data) const override { 79 MutableRepeatedField(data)->Clear(); 80 } Set(Field * data,int index,const Value * value)81 void Set(Field* data, int index, const Value* value) const override { 82 MutableRepeatedField(data)->Set(index, ConvertToT(value)); 83 } Add(Field * data,const Value * value)84 void Add(Field* data, const Value* value) const override { 85 MutableRepeatedField(data)->Add(ConvertToT(value)); 86 } RemoveLast(Field * data)87 void RemoveLast(Field* data) const override { 88 MutableRepeatedField(data)->RemoveLast(); 89 } Reserve(Field * data,int size)90 void Reserve(Field* data, int size) const override { 91 MutableRepeatedField(data)->Reserve(size); 92 } SwapElements(Field * data,int index1,int index2)93 void SwapElements(Field* data, int index1, int index2) const override { 94 MutableRepeatedField(data)->SwapElements(index1, index2); 95 } 96 97 protected: 98 ~RepeatedFieldWrapper() = default; 99 typedef RepeatedField<T> RepeatedFieldType; GetRepeatedField(const Field * data)100 static const RepeatedFieldType* GetRepeatedField(const Field* data) { 101 return reinterpret_cast<const RepeatedFieldType*>(data); 102 } MutableRepeatedField(Field * data)103 static RepeatedFieldType* MutableRepeatedField(Field* data) { 104 return reinterpret_cast<RepeatedFieldType*>(data); 105 } 106 107 // Convert an object received by this accessor to an object to be stored in 108 // the underlying RepeatedField. 109 virtual T ConvertToT(const Value* value) const = 0; 110 111 // Convert an object stored in RepeatedPtrField to an object that will be 112 // returned by this accessor. If the two objects have the same type (true for 113 // string fields with ctype=STRING), a pointer to the source object can be 114 // returned directly. Otherwise, data should be copied from value to 115 // scratch_space and scratch_space should be returned. 116 virtual const Value* ConvertFromT(const T& value, 117 Value* scratch_space) const = 0; 118 }; 119 120 // Base class for RepeatedFieldAccessor implementations that manipulates 121 // RepeatedPtrField<T>. 122 template <typename T> 123 class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor { 124 public: IsEmpty(const Field * data)125 bool IsEmpty(const Field* data) const override { 126 return GetRepeatedField(data)->empty(); 127 } Size(const Field * data)128 int Size(const Field* data) const override { 129 return GetRepeatedField(data)->size(); 130 } Get(const Field * data,int index,Value * scratch_space)131 const Value* Get(const Field* data, int index, 132 Value* scratch_space) const override { 133 return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space); 134 } Clear(Field * data)135 void Clear(Field* data) const override { 136 MutableRepeatedField(data)->Clear(); 137 } Set(Field * data,int index,const Value * value)138 void Set(Field* data, int index, const Value* value) const override { 139 ConvertToT(value, MutableRepeatedField(data)->Mutable(index)); 140 } Add(Field * data,const Value * value)141 void Add(Field* data, const Value* value) const override { 142 T* allocated = New(value); 143 ConvertToT(value, allocated); 144 MutableRepeatedField(data)->AddAllocated(allocated); 145 } RemoveLast(Field * data)146 void RemoveLast(Field* data) const override { 147 MutableRepeatedField(data)->RemoveLast(); 148 } Reserve(Field * data,int size)149 void Reserve(Field* data, int size) const override { 150 MutableRepeatedField(data)->Reserve(size); 151 } SwapElements(Field * data,int index1,int index2)152 void SwapElements(Field* data, int index1, int index2) const override { 153 MutableRepeatedField(data)->SwapElements(index1, index2); 154 } 155 156 protected: 157 ~RepeatedPtrFieldWrapper() = default; 158 typedef RepeatedPtrField<T> RepeatedFieldType; GetRepeatedField(const Field * data)159 static const RepeatedFieldType* GetRepeatedField(const Field* data) { 160 return reinterpret_cast<const RepeatedFieldType*>(data); 161 } MutableRepeatedField(Field * data)162 static RepeatedFieldType* MutableRepeatedField(Field* data) { 163 return reinterpret_cast<RepeatedFieldType*>(data); 164 } 165 166 // Create a new T instance. For repeated message fields, T can be specified 167 // as google::protobuf::Message so we can't use "new T()" directly. In that case, value 168 // should be a message of the same type (it's ensured by the caller) and a 169 // new message object will be created using it. 170 virtual T* New(const Value* value) const = 0; 171 172 // Convert an object received by this accessor to an object that will be 173 // stored in the underlying RepeatedPtrField. 174 virtual void ConvertToT(const Value* value, T* result) const = 0; 175 176 // Convert an object stored in RepeatedPtrField to an object that will be 177 // returned by this accessor. If the two objects have the same type (true for 178 // string fields with ctype=STRING), a pointer to the source object can be 179 // returned directly. Otherwise, data should be copied from value to 180 // scratch_space and scratch_space should be returned. 181 virtual const Value* ConvertFromT(const T& value, 182 Value* scratch_space) const = 0; 183 }; 184 185 // An implementation of RandomAccessRepeatedFieldAccessor that manipulates 186 // MapFieldBase. 187 class MapFieldAccessor final : public RandomAccessRepeatedFieldAccessor { 188 public: MapFieldAccessor()189 MapFieldAccessor() {} ~MapFieldAccessor()190 virtual ~MapFieldAccessor() {} IsEmpty(const Field * data)191 bool IsEmpty(const Field* data) const override { 192 return GetRepeatedField(data)->empty(); 193 } Size(const Field * data)194 int Size(const Field* data) const override { 195 return GetRepeatedField(data)->size(); 196 } Get(const Field * data,int index,Value * scratch_space)197 const Value* Get(const Field* data, int index, 198 Value* scratch_space) const override { 199 return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space); 200 } Clear(Field * data)201 void Clear(Field* data) const override { 202 MutableRepeatedField(data)->Clear(); 203 } Set(Field * data,int index,const Value * value)204 void Set(Field* data, int index, const Value* value) const override { 205 ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index)); 206 } Add(Field * data,const Value * value)207 void Add(Field* data, const Value* value) const override { 208 Message* allocated = New(value); 209 ConvertToEntry(value, allocated); 210 MutableRepeatedField(data)->AddAllocated(allocated); 211 } RemoveLast(Field * data)212 void RemoveLast(Field* data) const override { 213 MutableRepeatedField(data)->RemoveLast(); 214 } Reserve(Field * data,int size)215 void Reserve(Field* data, int size) const override { 216 MutableRepeatedField(data)->Reserve(size); 217 } SwapElements(Field * data,int index1,int index2)218 void SwapElements(Field* data, int index1, int index2) const override { 219 MutableRepeatedField(data)->SwapElements(index1, index2); 220 } Swap(Field * data,const internal::RepeatedFieldAccessor * other_mutator,Field * other_data)221 void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, 222 Field* other_data) const override { 223 ABSL_CHECK(this == other_mutator); 224 MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); 225 } 226 227 protected: 228 typedef RepeatedPtrField<Message> RepeatedFieldType; GetRepeatedField(const Field * data)229 static const RepeatedFieldType* GetRepeatedField(const Field* data) { 230 return reinterpret_cast<const RepeatedFieldType*>( 231 (&reinterpret_cast<const MapFieldBase*>(data)->GetRepeatedField())); 232 } MutableRepeatedField(Field * data)233 static RepeatedFieldType* MutableRepeatedField(Field* data) { 234 return reinterpret_cast<RepeatedFieldType*>( 235 reinterpret_cast<MapFieldBase*>(data)->MutableRepeatedField()); 236 } New(const Value * value)237 virtual Message* New(const Value* value) const { 238 return static_cast<const Message*>(value)->New(); 239 } 240 // Convert an object received by this accessor to an MapEntry message to be 241 // stored in the underlying MapFieldBase. ConvertToEntry(const Value * value,Message * result)242 virtual void ConvertToEntry(const Value* value, Message* result) const { 243 result->CopyFrom(*static_cast<const Message*>(value)); 244 } 245 // Convert a MapEntry message stored in the underlying MapFieldBase to an 246 // object that will be returned by this accessor. ConvertFromEntry(const Message & value,Value *)247 virtual const Value* ConvertFromEntry(const Message& value, 248 Value* /*scratch_space*/) const { 249 return static_cast<const Value*>(&value); 250 } 251 }; 252 253 // Default implementations of RepeatedFieldAccessor for primitive types. 254 template <typename T> 255 class RepeatedFieldPrimitiveAccessor final : public RepeatedFieldWrapper<T> { 256 typedef void Field; 257 typedef void Value; 258 using RepeatedFieldWrapper<T>::MutableRepeatedField; 259 260 public: RepeatedFieldPrimitiveAccessor()261 RepeatedFieldPrimitiveAccessor() {} Swap(Field * data,const internal::RepeatedFieldAccessor * other_mutator,Field * other_data)262 void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, 263 Field* other_data) const override { 264 // Currently RepeatedFieldPrimitiveAccessor is the only implementation of 265 // RepeatedFieldAccessor for primitive types. As we are using singletons 266 // for these accessors, here "other_mutator" must be "this". 267 ABSL_CHECK(this == other_mutator); 268 MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); 269 } 270 271 protected: ConvertToT(const Value * value)272 T ConvertToT(const Value* value) const override { 273 return *static_cast<const T*>(value); 274 } ConvertFromT(const T & value,Value *)275 const Value* ConvertFromT(const T& value, 276 Value* /*scratch_space*/) const override { 277 return static_cast<const Value*>(&value); 278 } 279 }; 280 281 // Default implementation of RepeatedFieldAccessor for string fields with 282 // ctype=STRING. 283 class RepeatedPtrFieldStringAccessor final 284 : public RepeatedPtrFieldWrapper<std::string> { 285 typedef void Field; 286 typedef void Value; 287 using RepeatedFieldAccessor::Add; 288 289 public: RepeatedPtrFieldStringAccessor()290 RepeatedPtrFieldStringAccessor() {} Swap(Field * data,const internal::RepeatedFieldAccessor * other_mutator,Field * other_data)291 void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, 292 Field* other_data) const override { 293 if (this == other_mutator) { 294 MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); 295 } else { 296 RepeatedPtrField<std::string> tmp; 297 tmp.Swap(MutableRepeatedField(data)); 298 int other_size = other_mutator->Size(other_data); 299 for (int i = 0; i < other_size; ++i) { 300 Add<std::string>(data, other_mutator->Get<std::string>(other_data, i)); 301 } 302 int size = Size(data); 303 other_mutator->Clear(other_data); 304 for (int i = 0; i < size; ++i) { 305 other_mutator->Add<std::string>(other_data, tmp.Get(i)); 306 } 307 } 308 } 309 310 protected: New(const Value *)311 std::string* New(const Value*) const override { return new std::string(); } ConvertToT(const Value * value,std::string * result)312 void ConvertToT(const Value* value, std::string* result) const override { 313 *result = *static_cast<const std::string*>(value); 314 } ConvertFromT(const std::string & value,Value *)315 const Value* ConvertFromT(const std::string& value, 316 Value* /*scratch_space*/) const override { 317 return static_cast<const Value*>(&value); 318 } 319 }; 320 321 322 class RepeatedPtrFieldMessageAccessor final 323 : public RepeatedPtrFieldWrapper<Message> { 324 typedef void Field; 325 typedef void Value; 326 327 public: RepeatedPtrFieldMessageAccessor()328 RepeatedPtrFieldMessageAccessor() {} Swap(Field * data,const internal::RepeatedFieldAccessor * other_mutator,Field * other_data)329 void Swap(Field* data, const internal::RepeatedFieldAccessor* other_mutator, 330 Field* other_data) const override { 331 ABSL_CHECK(this == other_mutator); 332 MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); 333 } 334 335 protected: New(const Value * value)336 Message* New(const Value* value) const override { 337 return static_cast<const Message*>(value)->New(); 338 } ConvertToT(const Value * value,Message * result)339 void ConvertToT(const Value* value, Message* result) const override { 340 result->CopyFrom(*static_cast<const Message*>(value)); 341 } ConvertFromT(const Message & value,Value *)342 const Value* ConvertFromT(const Message& value, 343 Value* /*scratch_space*/) const override { 344 return static_cast<const Value*>(&value); 345 } 346 }; 347 } // namespace internal 348 } // namespace protobuf 349 } // namespace google 350 351 #endif // GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__ 352