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