yalantinglibs/src/struct_pb/protoc-plugin/StringFieldGenerator.cpp

185 lines
5.9 KiB
C++

#include "StringFieldGenerator.h"
namespace struct_pb {
namespace compiler {
StringFieldGenerator::StringFieldGenerator(const FieldDescriptor *field,
const Options &options)
: FieldGenerator(field, options) {}
void StringFieldGenerator::generate_calculate_size_only(
google::protobuf::io::Printer *p, const std::string &value) const {
Formatter format(p);
format("$1$.size()", value);
}
void StringFieldGenerator::generate_calculate_size(
google::protobuf::io::Printer *p, const std::string &value,
bool can_ignore_default_value) const {
Formatter format(p);
auto tag_sz = calculate_tag_size(d_);
if (is_optional()) {
format("if ($1$.has_value()) {\n", value);
format.indent();
format("total += $1$ + calculate_varint_size($2$->size()) + $2$->size();\n",
tag_sz, value);
format.outdent();
format("}\n");
}
else {
if (can_ignore_default_value) {
format("if (!$1$.empty()) {\n", value);
format.indent();
format("total += $1$ + calculate_varint_size($2$.size()) + $2$.size();\n",
tag_sz, value);
format.outdent();
format("}\n");
}
else {
format("total += $1$ + calculate_varint_size($2$.size()) + $2$.size();\n",
tag_sz, value);
}
}
}
void StringFieldGenerator::generate_serialization(
google::protobuf::io::Printer *p, const std::string &value,
bool can_ignore_default_value) const {
Formatter format(p);
if (is_optional()) {
format("if ($1$.has_value()) {\n", value);
format.indent();
generate_serialization_only(p, value + ".value()");
format.outdent();
format("}\n");
}
else {
if (can_ignore_default_value) {
format("if (!$1$.empty()) {\n", value);
format.indent();
generate_serialization_only(p, value);
format.outdent();
format("}\n");
}
else {
generate_serialization_only(p, value);
}
}
}
void StringFieldGenerator::generate_serialization_only(
google::protobuf::io::Printer *p, const std::string &value) const {
Formatter format(p);
format("serialize_varint(data, pos, size, $1$);\n", calculate_tag_str(d_));
format("serialize_varint(data, pos, size, $1$.size());\n", value);
format("std::memcpy(data + pos, $1$.data(), $1$.size());\n", value);
format("pos += $1$.size();\n", value);
}
std::string StringFieldGenerator::cpp_type_name() const {
if (d_->has_presence()) {
return "std::optional<std::string>";
}
return "std::string";
}
void StringFieldGenerator::generate_deserialization_only(
google::protobuf::io::Printer *p, const std::string &output,
const std::string &sz, const std::string &max_size) const {
p->Print({{"output", output}, {"sz", sz}, {"max_size", max_size}},
R"(uint64_t $sz$ = 0;
ok = deserialize_varint(data, pos, $max_size$, $sz$);
if (!ok) {
return false;
}
$output$.resize($sz$);
if (pos + $sz$ > $max_size$) {
return false;
}
std::memcpy($output$.data(), data+pos, $sz$);
pos += $sz$;
)");
}
void StringFieldGenerator::generate_deserialization(
google::protobuf::io::Printer *p, const std::string &value) const {
Formatter format(p);
format("case $1$: {\n", calculate_tag_str(d_));
format.indent();
if (is_optional()) {
format("if (!$1$.has_value()) {\n", value);
format.indent();
format("$1$ = std::string();\n", value);
format.outdent();
format("}\n");
generate_deserialization_only(p, value + ".value()");
}
else {
generate_deserialization_only(p, value);
}
format("break;\n");
format.outdent();
format("}\n");
}
RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
const FieldDescriptor *field, const Options &options)
: FieldGenerator(field, options) {}
std::string RepeatedStringFieldGenerator::cpp_type_name() const {
return "std::vector<std::string>";
}
void RepeatedStringFieldGenerator::generate_calculate_size(
google::protobuf::io::Printer *p, const std::string &value,
bool can_ignore_default_value) const {
Formatter format(p);
format("for (const auto& s: $1$) {\n", value);
format.indent();
format("total += $1$ + calculate_varint_size(s.size()) + s.size();\n",
calculate_tag_size(d_));
format.outdent();
format("}\n");
}
void RepeatedStringFieldGenerator::generate_calculate_only(
google::protobuf::io::Printer *p, const std::string &value,
const std::string &output) const {
p->Print({{"value", value},
{"tag_sz", calculate_tag_size(d_)},
{"output", output}},
R"(
std::size_t $output$ = 0;
for (const auto& s: $value$) {
$output$ += $tag_sz$ + calculate_varint_size(s.size()) + s.size();
}
)");
}
void RepeatedStringFieldGenerator::generate_serialization(
google::protobuf::io::Printer *p, const std::string &value,
bool can_ignore_default_value) const {
Formatter format(p);
if (can_ignore_default_value) {
format("if (!$1$.empty()) {\n", value);
format.indent();
generate_serialization_only(p, value);
format.outdent();
format("}\n");
}
else {
generate_serialization_only(p, value);
}
}
void RepeatedStringFieldGenerator::generate_serialization_only(
google::protobuf::io::Printer *p, const std::string &value) const {
Formatter format(p);
format("for(const auto& s: $1$) {\n", value);
format.indent();
StringFieldGenerator g(d_, options_);
g.generate_serialization_only(p, "s");
format.outdent();
format("}\n");
}
void RepeatedStringFieldGenerator::generate_deserialization(
google::protobuf::io::Printer *p, const std::string &value) const {
StringFieldGenerator g(d_, options_);
Formatter format(p);
format("case $1$: {\n", calculate_tag_str(d_));
format.indent();
format("std::string tmp_str;\n");
g.generate_deserialization_only(p, "tmp_str");
format("$1$.push_back(std::move(tmp_str));\n", value);
format("break;\n");
format.outdent();
format("}\n");
}
} // namespace compiler
} // namespace struct_pb