Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
6.4 KiB
194 lines
6.4 KiB
#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_
|
|
|