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