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