| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 | #ifndef PROTOBUF_BENCHMARKS_UTIL_SCHEMA_PROTO2_TO_PROTO3_UTIL_H_#define PROTOBUF_BENCHMARKS_UTIL_SCHEMA_PROTO2_TO_PROTO3_UTIL_H_#include "google/protobuf/message.h"#include "google/protobuf/descriptor.h"#include "google/protobuf/descriptor.pb.h"#include <sstream>#include <algorithm>using google::protobuf::Descriptor;using google::protobuf::DescriptorProto;using google::protobuf::FileDescriptorProto;using google::protobuf::FieldDescriptorProto;using google::protobuf::Message;using google::protobuf::EnumValueDescriptorProto;namespace google {namespace protobuf {namespace util {class SchemaGroupStripper { public:  static void StripFile(const FileDescriptor* old_file,                        FileDescriptorProto *file) {    for (int i = file->mutable_message_type()->size() - 1; i >= 0; i--) {      if (IsMessageSet(old_file->message_type(i))) {        file->mutable_message_type()->DeleteSubrange(i, 1);        continue;      }      StripMessage(old_file->message_type(i), file->mutable_message_type(i));    }    for (int i = file->mutable_extension()->size() - 1; i >= 0; i--) {      auto field = old_file->extension(i);      if (field->type() == FieldDescriptor::TYPE_GROUP ||          IsMessageSet(field->message_type()) ||          IsMessageSet(field->containing_type())) {        file->mutable_extension()->DeleteSubrange(i, 1);      }    }  } private:  static bool IsMessageSet(const Descriptor *descriptor) {    if (descriptor != nullptr        && descriptor->options().message_set_wire_format()) {      return true;    }    return false;  }  static void StripMessage(const Descriptor *old_message,                           DescriptorProto *new_message) {    for (int i = new_message->mutable_field()->size() - 1; i >= 0; i--) {      if (old_message->field(i)->type() == FieldDescriptor::TYPE_GROUP ||          IsMessageSet(old_message->field(i)->message_type())) {        new_message->mutable_field()->DeleteSubrange(i, 1);      }    }    for (int i = new_message->mutable_extension()->size() - 1; i >= 0; i--) {      auto field_type_name = new_message->mutable_extension(i)->type_name();      if (old_message->extension(i)->type() == FieldDescriptor::TYPE_GROUP ||          IsMessageSet(old_message->extension(i)->containing_type()) ||          IsMessageSet(old_message->extension(i)->message_type())) {        new_message->mutable_extension()->DeleteSubrange(i, 1);      }    }    for (int i = 0; i < new_message->mutable_nested_type()->size(); i++) {      StripMessage(old_message->nested_type(i),                   new_message->mutable_nested_type(i));    }  }};class EnumScrubber { public:  EnumScrubber()      : total_added_(0) {  }  void ScrubFile(FileDescriptorProto *file) {    for (int i = 0; i < file->enum_type_size(); i++) {      ScrubEnum(file->mutable_enum_type(i));    }    for (int i = 0; i < file->mutable_message_type()->size(); i++) {      ScrubMessage(file->mutable_message_type(i));    }  } private:  void ScrubEnum(EnumDescriptorProto *enum_type) {    if (enum_type->value(0).number() != 0) {      bool has_zero = false;      for (int j = 0; j < enum_type->value().size(); j++) {        if (enum_type->value(j).number() == 0) {          EnumValueDescriptorProto temp_enum_value;          temp_enum_value.CopyFrom(enum_type->value(j));          enum_type->mutable_value(j)->CopyFrom(enum_type->value(0));          enum_type->mutable_value(0)->CopyFrom(temp_enum_value);          has_zero = true;          break;        }      }      if (!has_zero) {        enum_type->mutable_value()->Add();        for (int i = enum_type->mutable_value()->size() - 1; i > 0; i--) {          enum_type->mutable_value(i)->CopyFrom(              *enum_type->mutable_value(i - 1));        }        enum_type->mutable_value(0)->set_number(0);        enum_type->mutable_value(0)->set_name("ADDED_ZERO_VALUE_" +                                              std::to_string(total_added_++));      }    }  }  void ScrubMessage(DescriptorProto *message_type) {    for (int i = 0; i < message_type->mutable_enum_type()->size(); i++) {      ScrubEnum(message_type->mutable_enum_type(i));    }    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {      ScrubMessage(message_type->mutable_nested_type(i));    }  }  int total_added_;};class ExtensionStripper { public:  static void StripFile(FileDescriptorProto *file) {    for (int i = 0; i < file->mutable_message_type()->size(); i++) {      StripMessage(file->mutable_message_type(i));    }    file->mutable_extension()->Clear();  } private:  static void StripMessage(DescriptorProto *message_type) {    message_type->mutable_extension()->Clear();    message_type->clear_extension_range();    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {      StripMessage(message_type->mutable_nested_type(i));    }  }};class FieldScrubber { public:  static void ScrubFile(FileDescriptorProto *file) {    for (int i = 0; i < file->mutable_message_type()->size(); i++) {      ScrubMessage(file->mutable_message_type(i));    }    for (int i = 0; i < file->mutable_extension()->size(); i++) {      file->mutable_extension(i)->clear_default_value();      if (ShouldClearLabel(file->mutable_extension(i))) {        file->mutable_extension(i)->clear_label();      }    }  } private:  static bool ShouldClearLabel(const FieldDescriptorProto *field) {    return field->label() == FieldDescriptorProto::LABEL_REQUIRED;  }  static void ScrubMessage(DescriptorProto *message_type) {    message_type->mutable_extension()->Clear();    for (int i = 0; i < message_type->mutable_extension()->size(); i++) {      message_type->mutable_extension(i)->clear_default_value();      if (ShouldClearLabel(message_type->mutable_extension(i))) {        message_type->mutable_extension(i)->clear_label();      }    }    for (int i = 0; i < message_type->mutable_field()->size(); i++) {      message_type->mutable_field(i)->clear_default_value();      if (ShouldClearLabel(message_type->mutable_field(i))) {        message_type->mutable_field(i)->clear_label();      }    }    for (int i = 0; i < message_type->mutable_nested_type()->size(); i++) {      ScrubMessage(message_type->mutable_nested_type(i));    }  }};}  // namespace util}  // namespace protobuf}  // namespace google#endif  // PROTOBUF_BENCHMARKS_UTIL_SCHEMA_PROTO2_TO_PROTO3_UTIL_H_
 |