1 #ifndef PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_ 2 #define PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_ 3 4 #include "google/protobuf/message.h" 5 #include "google/protobuf/descriptor.h" 6 7 using google::protobuf::FieldDescriptor; 8 using google::protobuf::Message; 9 using google::protobuf::Reflection; 10 11 namespace google { 12 namespace protobuf { 13 namespace util { 14 15 class DataStripper { 16 public: StripMessage(Message * message)17 void StripMessage(Message *message) { 18 std::vector<const FieldDescriptor*> set_fields; 19 const Reflection* reflection = message->GetReflection(); 20 reflection->ListFields(*message, &set_fields); 21 22 for (size_t i = 0; i < set_fields.size(); i++) { 23 const FieldDescriptor* field = set_fields[i]; 24 if (ShouldBeClear(field)) { 25 reflection->ClearField(message, field); 26 continue; 27 } 28 if (field->type() == FieldDescriptor::TYPE_MESSAGE) { 29 if (field->is_repeated()) { 30 for (int j = 0; j < reflection->FieldSize(*message, field); j++) { 31 StripMessage(reflection->MutableRepeatedMessage(message, field, j)); 32 } 33 } else { 34 StripMessage(reflection->MutableMessage(message, field)); 35 } 36 } 37 } 38 39 reflection->MutableUnknownFields(message)->Clear(); 40 } 41 private: 42 virtual bool ShouldBeClear(const FieldDescriptor *field) = 0; 43 }; 44 45 class GogoDataStripper : public DataStripper { 46 private: ShouldBeClear(const FieldDescriptor * field)47 virtual bool ShouldBeClear(const FieldDescriptor *field) { 48 return field->type() == FieldDescriptor::TYPE_GROUP; 49 } 50 }; 51 52 class Proto3DataStripper : public DataStripper { 53 private: ShouldBeClear(const FieldDescriptor * field)54 virtual bool ShouldBeClear(const FieldDescriptor *field) { 55 return field->type() == FieldDescriptor::TYPE_GROUP || 56 field->is_extension(); 57 } 58 }; 59 60 } // namespace util 61 } // namespace protobuf 62 } // namespace google 63 64 #endif // PROTOBUF_BENCHMARKS_UTIL_DATA_PROTO2_TO_PROTO3_UTIL_H_ 65