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 7using google::protobuf::FieldDescriptor; 8using google::protobuf::Message; 9using google::protobuf::Reflection; 10 11namespace google { 12namespace protobuf { 13namespace util { 14 15class DataStripper { 16 public: 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 45class GogoDataStripper : public DataStripper { 46 private: 47 virtual bool ShouldBeClear(const FieldDescriptor *field) { 48 return field->type() == FieldDescriptor::TYPE_GROUP; 49 } 50}; 51 52class Proto3DataStripper : public DataStripper { 53 private: 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