1*fd525a9cSAndroid Build Coastguard Worker // Copyright 2016 Google Inc. All rights reserved. 2*fd525a9cSAndroid Build Coastguard Worker // 3*fd525a9cSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*fd525a9cSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*fd525a9cSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*fd525a9cSAndroid Build Coastguard Worker // 7*fd525a9cSAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*fd525a9cSAndroid Build Coastguard Worker // 9*fd525a9cSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*fd525a9cSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*fd525a9cSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*fd525a9cSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*fd525a9cSAndroid Build Coastguard Worker // limitations under the License. 14*fd525a9cSAndroid Build Coastguard Worker 15*fd525a9cSAndroid Build Coastguard Worker #ifndef SRC_FIELD_INSTANCE_H_ 16*fd525a9cSAndroid Build Coastguard Worker #define SRC_FIELD_INSTANCE_H_ 17*fd525a9cSAndroid Build Coastguard Worker 18*fd525a9cSAndroid Build Coastguard Worker #include <memory> 19*fd525a9cSAndroid Build Coastguard Worker #include <string> 20*fd525a9cSAndroid Build Coastguard Worker 21*fd525a9cSAndroid Build Coastguard Worker #include "port/protobuf.h" 22*fd525a9cSAndroid Build Coastguard Worker 23*fd525a9cSAndroid Build Coastguard Worker namespace protobuf_mutator { 24*fd525a9cSAndroid Build Coastguard Worker 25*fd525a9cSAndroid Build Coastguard Worker // Helper class for common protobuf fields operations. 26*fd525a9cSAndroid Build Coastguard Worker class ConstFieldInstance { 27*fd525a9cSAndroid Build Coastguard Worker public: 28*fd525a9cSAndroid Build Coastguard Worker static const size_t kInvalidIndex = -1; 29*fd525a9cSAndroid Build Coastguard Worker 30*fd525a9cSAndroid Build Coastguard Worker struct Enum { 31*fd525a9cSAndroid Build Coastguard Worker size_t index; 32*fd525a9cSAndroid Build Coastguard Worker size_t count; 33*fd525a9cSAndroid Build Coastguard Worker }; 34*fd525a9cSAndroid Build Coastguard Worker ConstFieldInstance()35*fd525a9cSAndroid Build Coastguard Worker ConstFieldInstance() 36*fd525a9cSAndroid Build Coastguard Worker : message_(nullptr), descriptor_(nullptr), index_(kInvalidIndex) {} 37*fd525a9cSAndroid Build Coastguard Worker ConstFieldInstance(const protobuf::Message * message,const protobuf::FieldDescriptor * field,size_t index)38*fd525a9cSAndroid Build Coastguard Worker ConstFieldInstance(const protobuf::Message* message, 39*fd525a9cSAndroid Build Coastguard Worker const protobuf::FieldDescriptor* field, size_t index) 40*fd525a9cSAndroid Build Coastguard Worker : message_(message), descriptor_(field), index_(index) { 41*fd525a9cSAndroid Build Coastguard Worker assert(message_); 42*fd525a9cSAndroid Build Coastguard Worker assert(descriptor_); 43*fd525a9cSAndroid Build Coastguard Worker assert(index_ != kInvalidIndex); 44*fd525a9cSAndroid Build Coastguard Worker assert(descriptor_->is_repeated()); 45*fd525a9cSAndroid Build Coastguard Worker } 46*fd525a9cSAndroid Build Coastguard Worker ConstFieldInstance(const protobuf::Message * message,const protobuf::FieldDescriptor * field)47*fd525a9cSAndroid Build Coastguard Worker ConstFieldInstance(const protobuf::Message* message, 48*fd525a9cSAndroid Build Coastguard Worker const protobuf::FieldDescriptor* field) 49*fd525a9cSAndroid Build Coastguard Worker : message_(message), descriptor_(field), index_(kInvalidIndex) { 50*fd525a9cSAndroid Build Coastguard Worker assert(message_); 51*fd525a9cSAndroid Build Coastguard Worker assert(descriptor_); 52*fd525a9cSAndroid Build Coastguard Worker assert(!descriptor_->is_repeated()); 53*fd525a9cSAndroid Build Coastguard Worker } 54*fd525a9cSAndroid Build Coastguard Worker GetDefault(int32_t * out)55*fd525a9cSAndroid Build Coastguard Worker void GetDefault(int32_t* out) const { 56*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_int32(); 57*fd525a9cSAndroid Build Coastguard Worker } 58*fd525a9cSAndroid Build Coastguard Worker GetDefault(int64_t * out)59*fd525a9cSAndroid Build Coastguard Worker void GetDefault(int64_t* out) const { 60*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_int64(); 61*fd525a9cSAndroid Build Coastguard Worker } 62*fd525a9cSAndroid Build Coastguard Worker GetDefault(uint32_t * out)63*fd525a9cSAndroid Build Coastguard Worker void GetDefault(uint32_t* out) const { 64*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_uint32(); 65*fd525a9cSAndroid Build Coastguard Worker } 66*fd525a9cSAndroid Build Coastguard Worker GetDefault(uint64_t * out)67*fd525a9cSAndroid Build Coastguard Worker void GetDefault(uint64_t* out) const { 68*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_uint64(); 69*fd525a9cSAndroid Build Coastguard Worker } 70*fd525a9cSAndroid Build Coastguard Worker GetDefault(double * out)71*fd525a9cSAndroid Build Coastguard Worker void GetDefault(double* out) const { 72*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_double(); 73*fd525a9cSAndroid Build Coastguard Worker } 74*fd525a9cSAndroid Build Coastguard Worker GetDefault(float * out)75*fd525a9cSAndroid Build Coastguard Worker void GetDefault(float* out) const { 76*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_float(); 77*fd525a9cSAndroid Build Coastguard Worker } 78*fd525a9cSAndroid Build Coastguard Worker GetDefault(bool * out)79*fd525a9cSAndroid Build Coastguard Worker void GetDefault(bool* out) const { *out = descriptor_->default_value_bool(); } 80*fd525a9cSAndroid Build Coastguard Worker GetDefault(Enum * out)81*fd525a9cSAndroid Build Coastguard Worker void GetDefault(Enum* out) const { 82*fd525a9cSAndroid Build Coastguard Worker const protobuf::EnumValueDescriptor* value = 83*fd525a9cSAndroid Build Coastguard Worker descriptor_->default_value_enum(); 84*fd525a9cSAndroid Build Coastguard Worker const protobuf::EnumDescriptor* type = value->type(); 85*fd525a9cSAndroid Build Coastguard Worker *out = {static_cast<size_t>(value->index()), 86*fd525a9cSAndroid Build Coastguard Worker static_cast<size_t>(type->value_count())}; 87*fd525a9cSAndroid Build Coastguard Worker } 88*fd525a9cSAndroid Build Coastguard Worker GetDefault(std::string * out)89*fd525a9cSAndroid Build Coastguard Worker void GetDefault(std::string* out) const { 90*fd525a9cSAndroid Build Coastguard Worker *out = descriptor_->default_value_string(); 91*fd525a9cSAndroid Build Coastguard Worker } 92*fd525a9cSAndroid Build Coastguard Worker GetDefault(std::unique_ptr<protobuf::Message> * out)93*fd525a9cSAndroid Build Coastguard Worker void GetDefault(std::unique_ptr<protobuf::Message>* out) const { 94*fd525a9cSAndroid Build Coastguard Worker out->reset(reflection() 95*fd525a9cSAndroid Build Coastguard Worker .GetMessageFactory() 96*fd525a9cSAndroid Build Coastguard Worker ->GetPrototype(descriptor_->message_type()) 97*fd525a9cSAndroid Build Coastguard Worker ->New()); 98*fd525a9cSAndroid Build Coastguard Worker } 99*fd525a9cSAndroid Build Coastguard Worker Load(int32_t * value)100*fd525a9cSAndroid Build Coastguard Worker void Load(int32_t* value) const { 101*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() 102*fd525a9cSAndroid Build Coastguard Worker ? reflection().GetRepeatedInt32(*message_, descriptor_, index_) 103*fd525a9cSAndroid Build Coastguard Worker : reflection().GetInt32(*message_, descriptor_); 104*fd525a9cSAndroid Build Coastguard Worker } 105*fd525a9cSAndroid Build Coastguard Worker Load(int64_t * value)106*fd525a9cSAndroid Build Coastguard Worker void Load(int64_t* value) const { 107*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() 108*fd525a9cSAndroid Build Coastguard Worker ? reflection().GetRepeatedInt64(*message_, descriptor_, index_) 109*fd525a9cSAndroid Build Coastguard Worker : reflection().GetInt64(*message_, descriptor_); 110*fd525a9cSAndroid Build Coastguard Worker } 111*fd525a9cSAndroid Build Coastguard Worker Load(uint32_t * value)112*fd525a9cSAndroid Build Coastguard Worker void Load(uint32_t* value) const { 113*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() ? reflection().GetRepeatedUInt32(*message_, 114*fd525a9cSAndroid Build Coastguard Worker descriptor_, index_) 115*fd525a9cSAndroid Build Coastguard Worker : reflection().GetUInt32(*message_, descriptor_); 116*fd525a9cSAndroid Build Coastguard Worker } 117*fd525a9cSAndroid Build Coastguard Worker Load(uint64_t * value)118*fd525a9cSAndroid Build Coastguard Worker void Load(uint64_t* value) const { 119*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() ? reflection().GetRepeatedUInt64(*message_, 120*fd525a9cSAndroid Build Coastguard Worker descriptor_, index_) 121*fd525a9cSAndroid Build Coastguard Worker : reflection().GetUInt64(*message_, descriptor_); 122*fd525a9cSAndroid Build Coastguard Worker } 123*fd525a9cSAndroid Build Coastguard Worker Load(double * value)124*fd525a9cSAndroid Build Coastguard Worker void Load(double* value) const { 125*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() ? reflection().GetRepeatedDouble(*message_, 126*fd525a9cSAndroid Build Coastguard Worker descriptor_, index_) 127*fd525a9cSAndroid Build Coastguard Worker : reflection().GetDouble(*message_, descriptor_); 128*fd525a9cSAndroid Build Coastguard Worker } 129*fd525a9cSAndroid Build Coastguard Worker Load(float * value)130*fd525a9cSAndroid Build Coastguard Worker void Load(float* value) const { 131*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() 132*fd525a9cSAndroid Build Coastguard Worker ? reflection().GetRepeatedFloat(*message_, descriptor_, index_) 133*fd525a9cSAndroid Build Coastguard Worker : reflection().GetFloat(*message_, descriptor_); 134*fd525a9cSAndroid Build Coastguard Worker } 135*fd525a9cSAndroid Build Coastguard Worker Load(bool * value)136*fd525a9cSAndroid Build Coastguard Worker void Load(bool* value) const { 137*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() 138*fd525a9cSAndroid Build Coastguard Worker ? reflection().GetRepeatedBool(*message_, descriptor_, index_) 139*fd525a9cSAndroid Build Coastguard Worker : reflection().GetBool(*message_, descriptor_); 140*fd525a9cSAndroid Build Coastguard Worker } 141*fd525a9cSAndroid Build Coastguard Worker Load(Enum * value)142*fd525a9cSAndroid Build Coastguard Worker void Load(Enum* value) const { 143*fd525a9cSAndroid Build Coastguard Worker const protobuf::EnumValueDescriptor* value_descriptor = 144*fd525a9cSAndroid Build Coastguard Worker is_repeated() 145*fd525a9cSAndroid Build Coastguard Worker ? reflection().GetRepeatedEnum(*message_, descriptor_, index_) 146*fd525a9cSAndroid Build Coastguard Worker : reflection().GetEnum(*message_, descriptor_); 147*fd525a9cSAndroid Build Coastguard Worker *value = {static_cast<size_t>(value_descriptor->index()), 148*fd525a9cSAndroid Build Coastguard Worker static_cast<size_t>(value_descriptor->type()->value_count())}; 149*fd525a9cSAndroid Build Coastguard Worker if (value->index >= value->count) GetDefault(value); 150*fd525a9cSAndroid Build Coastguard Worker } 151*fd525a9cSAndroid Build Coastguard Worker Load(std::string * value)152*fd525a9cSAndroid Build Coastguard Worker void Load(std::string* value) const { 153*fd525a9cSAndroid Build Coastguard Worker *value = is_repeated() ? reflection().GetRepeatedString(*message_, 154*fd525a9cSAndroid Build Coastguard Worker descriptor_, index_) 155*fd525a9cSAndroid Build Coastguard Worker : reflection().GetString(*message_, descriptor_); 156*fd525a9cSAndroid Build Coastguard Worker } 157*fd525a9cSAndroid Build Coastguard Worker Load(std::unique_ptr<protobuf::Message> * value)158*fd525a9cSAndroid Build Coastguard Worker void Load(std::unique_ptr<protobuf::Message>* value) const { 159*fd525a9cSAndroid Build Coastguard Worker const protobuf::Message& source = 160*fd525a9cSAndroid Build Coastguard Worker is_repeated() 161*fd525a9cSAndroid Build Coastguard Worker ? reflection().GetRepeatedMessage(*message_, descriptor_, index_) 162*fd525a9cSAndroid Build Coastguard Worker : reflection().GetMessage(*message_, descriptor_); 163*fd525a9cSAndroid Build Coastguard Worker value->reset(source.New()); 164*fd525a9cSAndroid Build Coastguard Worker (*value)->CopyFrom(source); 165*fd525a9cSAndroid Build Coastguard Worker } 166*fd525a9cSAndroid Build Coastguard Worker 167*fd525a9cSAndroid Build Coastguard Worker template <class T> CanStore(const T & value)168*fd525a9cSAndroid Build Coastguard Worker bool CanStore(const T& value) const { 169*fd525a9cSAndroid Build Coastguard Worker return true; 170*fd525a9cSAndroid Build Coastguard Worker } 171*fd525a9cSAndroid Build Coastguard Worker CanStore(const std::string & value)172*fd525a9cSAndroid Build Coastguard Worker bool CanStore(const std::string& value) const { 173*fd525a9cSAndroid Build Coastguard Worker if (!EnforceUtf8()) return true; 174*fd525a9cSAndroid Build Coastguard Worker using protobuf::internal::WireFormatLite; 175*fd525a9cSAndroid Build Coastguard Worker return WireFormatLite::VerifyUtf8String(value.data(), value.length(), 176*fd525a9cSAndroid Build Coastguard Worker WireFormatLite::PARSE, ""); 177*fd525a9cSAndroid Build Coastguard Worker } 178*fd525a9cSAndroid Build Coastguard Worker name()179*fd525a9cSAndroid Build Coastguard Worker std::string name() const { return descriptor_->name(); } 180*fd525a9cSAndroid Build Coastguard Worker cpp_type()181*fd525a9cSAndroid Build Coastguard Worker protobuf::FieldDescriptor::CppType cpp_type() const { 182*fd525a9cSAndroid Build Coastguard Worker return descriptor_->cpp_type(); 183*fd525a9cSAndroid Build Coastguard Worker } 184*fd525a9cSAndroid Build Coastguard Worker enum_type()185*fd525a9cSAndroid Build Coastguard Worker const protobuf::EnumDescriptor* enum_type() const { 186*fd525a9cSAndroid Build Coastguard Worker return descriptor_->enum_type(); 187*fd525a9cSAndroid Build Coastguard Worker } 188*fd525a9cSAndroid Build Coastguard Worker message_type()189*fd525a9cSAndroid Build Coastguard Worker const protobuf::Descriptor* message_type() const { 190*fd525a9cSAndroid Build Coastguard Worker return descriptor_->message_type(); 191*fd525a9cSAndroid Build Coastguard Worker } 192*fd525a9cSAndroid Build Coastguard Worker EnforceUtf8()193*fd525a9cSAndroid Build Coastguard Worker bool EnforceUtf8() const { 194*fd525a9cSAndroid Build Coastguard Worker return descriptor_->type() == protobuf::FieldDescriptor::TYPE_STRING && 195*fd525a9cSAndroid Build Coastguard Worker descriptor()->file()->syntax() == 196*fd525a9cSAndroid Build Coastguard Worker protobuf::FileDescriptor::SYNTAX_PROTO3; 197*fd525a9cSAndroid Build Coastguard Worker } 198*fd525a9cSAndroid Build Coastguard Worker descriptor()199*fd525a9cSAndroid Build Coastguard Worker const protobuf::FieldDescriptor* descriptor() const { return descriptor_; } 200*fd525a9cSAndroid Build Coastguard Worker DebugString()201*fd525a9cSAndroid Build Coastguard Worker std::string DebugString() const { 202*fd525a9cSAndroid Build Coastguard Worker std::string s = descriptor_->DebugString(); 203*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) s += "[" + std::to_string(index_) + "]"; 204*fd525a9cSAndroid Build Coastguard Worker return s + " of\n" + message_->DebugString(); 205*fd525a9cSAndroid Build Coastguard Worker } 206*fd525a9cSAndroid Build Coastguard Worker 207*fd525a9cSAndroid Build Coastguard Worker protected: is_repeated()208*fd525a9cSAndroid Build Coastguard Worker bool is_repeated() const { return descriptor_->is_repeated(); } 209*fd525a9cSAndroid Build Coastguard Worker reflection()210*fd525a9cSAndroid Build Coastguard Worker const protobuf::Reflection& reflection() const { 211*fd525a9cSAndroid Build Coastguard Worker return *message_->GetReflection(); 212*fd525a9cSAndroid Build Coastguard Worker } 213*fd525a9cSAndroid Build Coastguard Worker index()214*fd525a9cSAndroid Build Coastguard Worker size_t index() const { return index_; } 215*fd525a9cSAndroid Build Coastguard Worker 216*fd525a9cSAndroid Build Coastguard Worker private: 217*fd525a9cSAndroid Build Coastguard Worker template <class Fn, class T> 218*fd525a9cSAndroid Build Coastguard Worker friend struct FieldFunction; 219*fd525a9cSAndroid Build Coastguard Worker 220*fd525a9cSAndroid Build Coastguard Worker const protobuf::Message* message_; 221*fd525a9cSAndroid Build Coastguard Worker const protobuf::FieldDescriptor* descriptor_; 222*fd525a9cSAndroid Build Coastguard Worker size_t index_; 223*fd525a9cSAndroid Build Coastguard Worker }; 224*fd525a9cSAndroid Build Coastguard Worker 225*fd525a9cSAndroid Build Coastguard Worker class FieldInstance : public ConstFieldInstance { 226*fd525a9cSAndroid Build Coastguard Worker public: 227*fd525a9cSAndroid Build Coastguard Worker static const size_t kInvalidIndex = -1; 228*fd525a9cSAndroid Build Coastguard Worker FieldInstance()229*fd525a9cSAndroid Build Coastguard Worker FieldInstance() : ConstFieldInstance(), message_(nullptr) {} 230*fd525a9cSAndroid Build Coastguard Worker FieldInstance(protobuf::Message * message,const protobuf::FieldDescriptor * field,size_t index)231*fd525a9cSAndroid Build Coastguard Worker FieldInstance(protobuf::Message* message, 232*fd525a9cSAndroid Build Coastguard Worker const protobuf::FieldDescriptor* field, size_t index) 233*fd525a9cSAndroid Build Coastguard Worker : ConstFieldInstance(message, field, index), message_(message) {} 234*fd525a9cSAndroid Build Coastguard Worker FieldInstance(protobuf::Message * message,const protobuf::FieldDescriptor * field)235*fd525a9cSAndroid Build Coastguard Worker FieldInstance(protobuf::Message* message, 236*fd525a9cSAndroid Build Coastguard Worker const protobuf::FieldDescriptor* field) 237*fd525a9cSAndroid Build Coastguard Worker : ConstFieldInstance(message, field), message_(message) {} 238*fd525a9cSAndroid Build Coastguard Worker Delete()239*fd525a9cSAndroid Build Coastguard Worker void Delete() const { 240*fd525a9cSAndroid Build Coastguard Worker if (!is_repeated()) return reflection().ClearField(message_, descriptor()); 241*fd525a9cSAndroid Build Coastguard Worker int field_size = reflection().FieldSize(*message_, descriptor()); 242*fd525a9cSAndroid Build Coastguard Worker // API has only method to delete the last message, so we move method from 243*fd525a9cSAndroid Build Coastguard Worker // the 244*fd525a9cSAndroid Build Coastguard Worker // middle to the end. 245*fd525a9cSAndroid Build Coastguard Worker for (int i = index() + 1; i < field_size; ++i) 246*fd525a9cSAndroid Build Coastguard Worker reflection().SwapElements(message_, descriptor(), i, i - 1); 247*fd525a9cSAndroid Build Coastguard Worker reflection().RemoveLast(message_, descriptor()); 248*fd525a9cSAndroid Build Coastguard Worker } 249*fd525a9cSAndroid Build Coastguard Worker 250*fd525a9cSAndroid Build Coastguard Worker template <class T> Create(const T & value)251*fd525a9cSAndroid Build Coastguard Worker void Create(const T& value) const { 252*fd525a9cSAndroid Build Coastguard Worker if (!is_repeated()) return Store(value); 253*fd525a9cSAndroid Build Coastguard Worker InsertRepeated(value); 254*fd525a9cSAndroid Build Coastguard Worker } 255*fd525a9cSAndroid Build Coastguard Worker Store(int32_t value)256*fd525a9cSAndroid Build Coastguard Worker void Store(int32_t value) const { 257*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 258*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedInt32(message_, descriptor(), index(), value); 259*fd525a9cSAndroid Build Coastguard Worker else 260*fd525a9cSAndroid Build Coastguard Worker reflection().SetInt32(message_, descriptor(), value); 261*fd525a9cSAndroid Build Coastguard Worker } 262*fd525a9cSAndroid Build Coastguard Worker Store(int64_t value)263*fd525a9cSAndroid Build Coastguard Worker void Store(int64_t value) const { 264*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 265*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedInt64(message_, descriptor(), index(), value); 266*fd525a9cSAndroid Build Coastguard Worker else 267*fd525a9cSAndroid Build Coastguard Worker reflection().SetInt64(message_, descriptor(), value); 268*fd525a9cSAndroid Build Coastguard Worker } 269*fd525a9cSAndroid Build Coastguard Worker Store(uint32_t value)270*fd525a9cSAndroid Build Coastguard Worker void Store(uint32_t value) const { 271*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 272*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedUInt32(message_, descriptor(), index(), value); 273*fd525a9cSAndroid Build Coastguard Worker else 274*fd525a9cSAndroid Build Coastguard Worker reflection().SetUInt32(message_, descriptor(), value); 275*fd525a9cSAndroid Build Coastguard Worker } 276*fd525a9cSAndroid Build Coastguard Worker Store(uint64_t value)277*fd525a9cSAndroid Build Coastguard Worker void Store(uint64_t value) const { 278*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 279*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedUInt64(message_, descriptor(), index(), value); 280*fd525a9cSAndroid Build Coastguard Worker else 281*fd525a9cSAndroid Build Coastguard Worker reflection().SetUInt64(message_, descriptor(), value); 282*fd525a9cSAndroid Build Coastguard Worker } 283*fd525a9cSAndroid Build Coastguard Worker Store(double value)284*fd525a9cSAndroid Build Coastguard Worker void Store(double value) const { 285*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 286*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedDouble(message_, descriptor(), index(), value); 287*fd525a9cSAndroid Build Coastguard Worker else 288*fd525a9cSAndroid Build Coastguard Worker reflection().SetDouble(message_, descriptor(), value); 289*fd525a9cSAndroid Build Coastguard Worker } 290*fd525a9cSAndroid Build Coastguard Worker Store(float value)291*fd525a9cSAndroid Build Coastguard Worker void Store(float value) const { 292*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 293*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedFloat(message_, descriptor(), index(), value); 294*fd525a9cSAndroid Build Coastguard Worker else 295*fd525a9cSAndroid Build Coastguard Worker reflection().SetFloat(message_, descriptor(), value); 296*fd525a9cSAndroid Build Coastguard Worker } 297*fd525a9cSAndroid Build Coastguard Worker Store(bool value)298*fd525a9cSAndroid Build Coastguard Worker void Store(bool value) const { 299*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 300*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedBool(message_, descriptor(), index(), value); 301*fd525a9cSAndroid Build Coastguard Worker else 302*fd525a9cSAndroid Build Coastguard Worker reflection().SetBool(message_, descriptor(), value); 303*fd525a9cSAndroid Build Coastguard Worker } 304*fd525a9cSAndroid Build Coastguard Worker Store(const Enum & value)305*fd525a9cSAndroid Build Coastguard Worker void Store(const Enum& value) const { 306*fd525a9cSAndroid Build Coastguard Worker assert(value.index < value.count); 307*fd525a9cSAndroid Build Coastguard Worker const protobuf::EnumValueDescriptor* enum_value = 308*fd525a9cSAndroid Build Coastguard Worker descriptor()->enum_type()->value(value.index); 309*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 310*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedEnum(message_, descriptor(), index(), enum_value); 311*fd525a9cSAndroid Build Coastguard Worker else 312*fd525a9cSAndroid Build Coastguard Worker reflection().SetEnum(message_, descriptor(), enum_value); 313*fd525a9cSAndroid Build Coastguard Worker } 314*fd525a9cSAndroid Build Coastguard Worker Store(const std::string & value)315*fd525a9cSAndroid Build Coastguard Worker void Store(const std::string& value) const { 316*fd525a9cSAndroid Build Coastguard Worker if (is_repeated()) 317*fd525a9cSAndroid Build Coastguard Worker reflection().SetRepeatedString(message_, descriptor(), index(), value); 318*fd525a9cSAndroid Build Coastguard Worker else 319*fd525a9cSAndroid Build Coastguard Worker reflection().SetString(message_, descriptor(), value); 320*fd525a9cSAndroid Build Coastguard Worker } 321*fd525a9cSAndroid Build Coastguard Worker Store(const std::unique_ptr<protobuf::Message> & value)322*fd525a9cSAndroid Build Coastguard Worker void Store(const std::unique_ptr<protobuf::Message>& value) const { 323*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* mutable_message = 324*fd525a9cSAndroid Build Coastguard Worker is_repeated() ? reflection().MutableRepeatedMessage( 325*fd525a9cSAndroid Build Coastguard Worker message_, descriptor(), index()) 326*fd525a9cSAndroid Build Coastguard Worker : reflection().MutableMessage(message_, descriptor()); 327*fd525a9cSAndroid Build Coastguard Worker mutable_message->Clear(); 328*fd525a9cSAndroid Build Coastguard Worker if (value) mutable_message->CopyFrom(*value); 329*fd525a9cSAndroid Build Coastguard Worker } 330*fd525a9cSAndroid Build Coastguard Worker 331*fd525a9cSAndroid Build Coastguard Worker private: 332*fd525a9cSAndroid Build Coastguard Worker template <class T> InsertRepeated(const T & value)333*fd525a9cSAndroid Build Coastguard Worker void InsertRepeated(const T& value) const { 334*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(value); 335*fd525a9cSAndroid Build Coastguard Worker size_t field_size = reflection().FieldSize(*message_, descriptor()); 336*fd525a9cSAndroid Build Coastguard Worker if (field_size == 1) return; 337*fd525a9cSAndroid Build Coastguard Worker // API has only method to add field to the end of the list. So we add 338*fd525a9cSAndroid Build Coastguard Worker // descriptor() 339*fd525a9cSAndroid Build Coastguard Worker // and move it into the middle. 340*fd525a9cSAndroid Build Coastguard Worker for (size_t i = field_size - 1; i > index(); --i) 341*fd525a9cSAndroid Build Coastguard Worker reflection().SwapElements(message_, descriptor(), i, i - 1); 342*fd525a9cSAndroid Build Coastguard Worker } 343*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(int32_t value)344*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(int32_t value) const { 345*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 346*fd525a9cSAndroid Build Coastguard Worker reflection().AddInt32(message_, descriptor(), value); 347*fd525a9cSAndroid Build Coastguard Worker } 348*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(int64_t value)349*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(int64_t value) const { 350*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 351*fd525a9cSAndroid Build Coastguard Worker reflection().AddInt64(message_, descriptor(), value); 352*fd525a9cSAndroid Build Coastguard Worker } 353*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(uint32_t value)354*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(uint32_t value) const { 355*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 356*fd525a9cSAndroid Build Coastguard Worker reflection().AddUInt32(message_, descriptor(), value); 357*fd525a9cSAndroid Build Coastguard Worker } 358*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(uint64_t value)359*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(uint64_t value) const { 360*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 361*fd525a9cSAndroid Build Coastguard Worker reflection().AddUInt64(message_, descriptor(), value); 362*fd525a9cSAndroid Build Coastguard Worker } 363*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(double value)364*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(double value) const { 365*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 366*fd525a9cSAndroid Build Coastguard Worker reflection().AddDouble(message_, descriptor(), value); 367*fd525a9cSAndroid Build Coastguard Worker } 368*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(float value)369*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(float value) const { 370*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 371*fd525a9cSAndroid Build Coastguard Worker reflection().AddFloat(message_, descriptor(), value); 372*fd525a9cSAndroid Build Coastguard Worker } 373*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(bool value)374*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(bool value) const { 375*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 376*fd525a9cSAndroid Build Coastguard Worker reflection().AddBool(message_, descriptor(), value); 377*fd525a9cSAndroid Build Coastguard Worker } 378*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(const Enum & value)379*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(const Enum& value) const { 380*fd525a9cSAndroid Build Coastguard Worker assert(value.index < value.count); 381*fd525a9cSAndroid Build Coastguard Worker const protobuf::EnumValueDescriptor* enum_value = 382*fd525a9cSAndroid Build Coastguard Worker descriptor()->enum_type()->value(value.index); 383*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 384*fd525a9cSAndroid Build Coastguard Worker reflection().AddEnum(message_, descriptor(), enum_value); 385*fd525a9cSAndroid Build Coastguard Worker } 386*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(const std::string & value)387*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(const std::string& value) const { 388*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 389*fd525a9cSAndroid Build Coastguard Worker reflection().AddString(message_, descriptor(), value); 390*fd525a9cSAndroid Build Coastguard Worker } 391*fd525a9cSAndroid Build Coastguard Worker PushBackRepeated(const std::unique_ptr<protobuf::Message> & value)392*fd525a9cSAndroid Build Coastguard Worker void PushBackRepeated(const std::unique_ptr<protobuf::Message>& value) const { 393*fd525a9cSAndroid Build Coastguard Worker assert(is_repeated()); 394*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* mutable_message = 395*fd525a9cSAndroid Build Coastguard Worker reflection().AddMessage(message_, descriptor()); 396*fd525a9cSAndroid Build Coastguard Worker mutable_message->Clear(); 397*fd525a9cSAndroid Build Coastguard Worker if (value) mutable_message->CopyFrom(*value); 398*fd525a9cSAndroid Build Coastguard Worker } 399*fd525a9cSAndroid Build Coastguard Worker 400*fd525a9cSAndroid Build Coastguard Worker protobuf::Message* message_; 401*fd525a9cSAndroid Build Coastguard Worker }; 402*fd525a9cSAndroid Build Coastguard Worker 403*fd525a9cSAndroid Build Coastguard Worker template <class Fn, class R = void> 404*fd525a9cSAndroid Build Coastguard Worker struct FieldFunction { 405*fd525a9cSAndroid Build Coastguard Worker template <class Field, class... Args> operatorFieldFunction406*fd525a9cSAndroid Build Coastguard Worker R operator()(const Field& field, const Args&... args) const { 407*fd525a9cSAndroid Build Coastguard Worker assert(field.descriptor()); 408*fd525a9cSAndroid Build Coastguard Worker using protobuf::FieldDescriptor; 409*fd525a9cSAndroid Build Coastguard Worker switch (field.cpp_type()) { 410*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_INT32: 411*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<int32_t>(field, 412*fd525a9cSAndroid Build Coastguard Worker args...); 413*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_INT64: 414*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<int64_t>(field, 415*fd525a9cSAndroid Build Coastguard Worker args...); 416*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_UINT32: 417*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<uint32_t>( 418*fd525a9cSAndroid Build Coastguard Worker field, args...); 419*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_UINT64: 420*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<uint64_t>( 421*fd525a9cSAndroid Build Coastguard Worker field, args...); 422*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_DOUBLE: 423*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<double>(field, 424*fd525a9cSAndroid Build Coastguard Worker args...); 425*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_FLOAT: 426*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<float>(field, 427*fd525a9cSAndroid Build Coastguard Worker args...); 428*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_BOOL: 429*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<bool>(field, 430*fd525a9cSAndroid Build Coastguard Worker args...); 431*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_ENUM: 432*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this) 433*fd525a9cSAndroid Build Coastguard Worker ->template ForType<ConstFieldInstance::Enum>(field, args...); 434*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_STRING: 435*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this)->template ForType<std::string>( 436*fd525a9cSAndroid Build Coastguard Worker field, args...); 437*fd525a9cSAndroid Build Coastguard Worker case FieldDescriptor::CPPTYPE_MESSAGE: 438*fd525a9cSAndroid Build Coastguard Worker return static_cast<const Fn*>(this) 439*fd525a9cSAndroid Build Coastguard Worker ->template ForType<std::unique_ptr<protobuf::Message>>(field, 440*fd525a9cSAndroid Build Coastguard Worker args...); 441*fd525a9cSAndroid Build Coastguard Worker } 442*fd525a9cSAndroid Build Coastguard Worker assert(false && "Unknown type"); 443*fd525a9cSAndroid Build Coastguard Worker abort(); 444*fd525a9cSAndroid Build Coastguard Worker } 445*fd525a9cSAndroid Build Coastguard Worker }; 446*fd525a9cSAndroid Build Coastguard Worker 447*fd525a9cSAndroid Build Coastguard Worker } // namespace protobuf_mutator 448*fd525a9cSAndroid Build Coastguard Worker 449*fd525a9cSAndroid Build Coastguard Worker #endif // SRC_FIELD_INSTANCE_H_ 450