|
|
|
#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_
|