Skip to content

Commit 40b8800

Browse files
committed
refactor proto-struct: better io
commit_hash:68558bf9d88bf5924af42c69b3b21811aa2dd3a5
1 parent 59cf92f commit 40b8800

File tree

23 files changed

+468
-361
lines changed

23 files changed

+468
-361
lines changed

.mapping.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,6 +2589,7 @@
25892589
"libraries/grpc-reflection/src/grpc-reflection/reflection_service_component.cpp":"taxi/uservices/userver/libraries/grpc-reflection/src/grpc-reflection/reflection_service_component.cpp",
25902590
"libraries/proto-structs/codegen-tests/proto/enums/names.proto":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/enums/names.proto",
25912591
"libraries/proto-structs/codegen-tests/proto/maps/basic.proto":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/maps/basic.proto",
2592+
"libraries/proto-structs/codegen-tests/proto/not_recommended_field_names/basic.proto":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/not_recommended_field_names/basic.proto",
25922593
"libraries/proto-structs/codegen-tests/proto/oneof/basic.proto":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/oneof/basic.proto",
25932594
"libraries/proto-structs/codegen-tests/proto/oneof/proto2.proto":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/oneof/proto2.proto",
25942595
"libraries/proto-structs/codegen-tests/proto/simple/cycles.proto":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/simple/cycles.proto",
@@ -2598,6 +2599,7 @@
25982599
"libraries/proto-structs/codegen-tests/src/cycles_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/cycles_test.cpp",
25992600
"libraries/proto-structs/codegen-tests/src/enums/names_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/enums/names_test.cpp",
26002601
"libraries/proto-structs/codegen-tests/src/maps/basic_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/maps/basic_test.cpp",
2602+
"libraries/proto-structs/codegen-tests/src/not_recommended_field_names/basic_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/not_recommended_field_names/basic_test.cpp",
26012603
"libraries/proto-structs/codegen-tests/src/oneof/basic_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/oneof/basic_test.cpp",
26022604
"libraries/proto-structs/codegen-tests/src/oneof/proto2_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/oneof/proto2_test.cpp",
26032605
"libraries/proto-structs/codegen-tests/src/simple_test.cpp":"taxi/uservices/userver/libraries/proto-structs/codegen-tests/src/simple_test.cpp",
@@ -4276,6 +4278,7 @@
42764278
"scripts/proto_structs/models/vanilla.py":"taxi/uservices/userver/scripts/proto_structs/models/vanilla.py",
42774279
"scripts/proto_structs/templates/forward_declarations.inc.jinja":"taxi/uservices/userver/scripts/proto_structs/templates/forward_declarations.inc.jinja",
42784280
"scripts/proto_structs/templates/io.inc.jinja":"taxi/uservices/userver/scripts/proto_structs/templates/io.inc.jinja",
4281+
"scripts/proto_structs/templates/io_forward_declarations.inc.jinja":"taxi/uservices/userver/scripts/proto_structs/templates/io_forward_declarations.inc.jinja",
42794282
"scripts/proto_structs/templates/structs.usrv.cpp.jinja":"taxi/uservices/userver/scripts/proto_structs/templates/structs.usrv.cpp.jinja",
42804283
"scripts/proto_structs/templates/structs.usrv.hpp.jinja":"taxi/uservices/userver/scripts/proto_structs/templates/structs.usrv.hpp.jinja",
42814284
"scripts/proto_structs/templates/types.inc.jinja":"taxi/uservices/userver/scripts/proto_structs/templates/types.inc.jinja",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
syntax = "proto3";
2+
3+
package not_recommended_field_names;
4+
5+
option go_package = "a.yandex-team.ru/taxi/uservices/userver/libraries/proto-structs/codegen-tests/proto/not_recommended_field_names;not_recommended_field_names";
6+
7+
message Basic {
8+
int32 protected = 1;
9+
int32 final = 2;
10+
int32 void__ = 3;
11+
int32 float = 4;
12+
int32 typeid = 5;
13+
int32 new = 6;
14+
int32 double = 7;
15+
// Not generated by a plugin.
16+
int32 major = 8;
17+
int32 minor = 9;
18+
}
19+
20+
message Upper {
21+
int32 XYandexUid = 1;
22+
int32 Float = 2;
23+
int32 New = 3;
24+
}

libraries/proto-structs/codegen-tests/proto/oneof/proto2.proto

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,5 @@ message Proto2 {
4949

5050
optional Group.MessageInGroup message_from_group = 10;
5151
repeated Group.EnumInGroup enum_from_group = 11;
52-
repeated float Float = 12;
53-
optional bool New = 13;
52+
optional bool opt_bool = 12;
5453
}

libraries/proto-structs/codegen-tests/proto/simple/file1.proto

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,6 @@ message SimpleStruct {
4343
string digit1u = 8;
4444
}
4545

46-
message NotRecommendedFieldNames {
47-
string protected = 1;
48-
string final = 2;
49-
string void__ = 3;
50-
string XYandexUid = 4;
51-
int32 float = 5;
52-
int32 typeid = 6;
53-
int32 new = 7;
54-
int32 double = 8;
55-
string major = 9;
56-
string minor = 10;
57-
}
58-
5946
message SecondStruct {
6047
string str = 1;
6148

libraries/proto-structs/codegen-tests/src/maps/basic_test.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
#include <gtest/gtest.h>
44

5+
#include <maps/basic.pb.h>
56
#include <maps/basic.structs.usrv.pb.hpp>
67

8+
#include <userver/proto-structs/convert.hpp>
9+
710
USERVER_NAMESPACE_BEGIN
811

912
TEST(MapsBasic, FundamentalTypes) {
@@ -12,6 +15,39 @@ TEST(MapsBasic, FundamentalTypes) {
1215
static_assert(std::is_same_v<decltype(Struct::string_string), proto_structs::HashMap<std::string, std::string>>);
1316
static_assert(std::is_same_v<decltype(Struct::int_int), proto_structs::HashMap<std::int64_t, std::int64_t>>);
1417
static_assert(std::is_same_v<decltype(Struct::int_string), proto_structs::HashMap<std::int64_t, std::string>>);
18+
19+
Struct s{};
20+
s.int_int = {{1, 2}, {3, 4}};
21+
s.int_string = {{1, "2"}, {3, "4"}};
22+
s.string_int = {{"1", 2}, {"3", 4}};
23+
s.string_string = {{"1", "2"}, {"3", "4"}};
24+
25+
Struct::ProtobufMessage vanilla{};
26+
proto_structs::StructToMessage(std::move(s), vanilla);
27+
{
28+
auto map = vanilla.int_int();
29+
ASSERT_EQ(map.size(), 2u);
30+
ASSERT_EQ(map.at(1), 2);
31+
ASSERT_EQ(map.at(3), 4);
32+
}
33+
{
34+
auto map = vanilla.int_string();
35+
ASSERT_EQ(map.size(), 2u);
36+
ASSERT_EQ(map.at(1), "2");
37+
ASSERT_EQ(map.at(3), "4");
38+
}
39+
{
40+
auto map = vanilla.string_int();
41+
ASSERT_EQ(map.size(), 2u);
42+
ASSERT_EQ(map.at("1"), 2);
43+
ASSERT_EQ(map.at("3"), 4);
44+
}
45+
{
46+
auto map = vanilla.string_string();
47+
ASSERT_EQ(map.size(), 2u);
48+
ASSERT_EQ(map.at("1"), "2");
49+
ASSERT_EQ(map.at("3"), "4");
50+
}
1551
}
1652

1753
USERVER_NAMESPACE_END
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <gtest/gtest.h>
2+
3+
#include <not_recommended_field_names/basic.pb.h>
4+
#include <not_recommended_field_names/basic.structs.usrv.pb.hpp>
5+
6+
#include <userver/proto-structs/convert.hpp>
7+
8+
USERVER_NAMESPACE_BEGIN
9+
10+
TEST(NotRecommendedFieldNameBasic, Basic) {
11+
using Struct = not_recommended_field_names::structs::Basic;
12+
Struct s{};
13+
14+
s.protected_ = 0;
15+
s.final_ = 1;
16+
s.void__ = 2;
17+
s.float_ = 3;
18+
s.typeid_ = 4;
19+
s.new_ = 5;
20+
s.double_ = 6;
21+
22+
Struct::ProtobufMessage vanilla{};
23+
proto_structs::StructToMessage(std::move(s), vanilla);
24+
25+
ASSERT_EQ(vanilla.protected_(), 0);
26+
ASSERT_EQ(vanilla.final(), 1);
27+
ASSERT_EQ(vanilla.void__(), 2);
28+
ASSERT_EQ(vanilla.float_(), 3);
29+
ASSERT_EQ(vanilla.typeid_(), 4);
30+
ASSERT_EQ(vanilla.new_(), 5);
31+
ASSERT_EQ(vanilla.double_(), 6);
32+
// Not generated by a plagin.
33+
ASSERT_EQ(vanilla.minor(), 0);
34+
ASSERT_EQ(vanilla.major(), 0);
35+
}
36+
37+
TEST(NotRecommendedFieldNameBasic, Upper) {
38+
using Struct = not_recommended_field_names::structs::Upper;
39+
Struct s{};
40+
s.XYandexUid = 1;
41+
s.Float = 2;
42+
s.New = 3;
43+
44+
Struct::ProtobufMessage vanilla{};
45+
proto_structs::StructToMessage(std::move(s), vanilla);
46+
ASSERT_EQ(vanilla.xyandexuid(), 1);
47+
ASSERT_EQ(vanilla.float_(), 2);
48+
ASSERT_EQ(vanilla.new_(), 3);
49+
}
50+
51+
USERVER_NAMESPACE_END

libraries/proto-structs/codegen-tests/src/simple_test.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
#include <gtest/gtest.h>
44

5+
#include <userver/proto-structs/convert.hpp>
6+
57
#include <simple/file1.pb.h>
68
#include <simple/file1.structs.usrv.pb.hpp>
7-
#include <userver/proto-structs/convert.hpp>
89

910
namespace ss = simple::structs;
1011

@@ -17,19 +18,31 @@ TEST(SingleFile, SimpleStruct) {
1718
message.some_text = std::optional<std::string>("foo");
1819
message.is_condition = true;
1920
message.some_bytes = {"foo", "bar"};
21+
message.something.set_bar("bar_val");
22+
message.inner_enum = ss::SimpleStruct::InnerEnum2::FOO_VAL;
2023

21-
ss::SimpleStruct::ProtobufMessage s;
24+
ss::SimpleStruct::ProtobufMessage vanilla;
2225

23-
::proto_structs::StructToMessage(std::move(message), s);
26+
::proto_structs::StructToMessage(std::move(message), vanilla);
2427

25-
[[maybe_unused]] ss::SimpleStruct to;
26-
::proto_structs::MessageToStruct(s, to);
28+
EXPECT_EQ(vanilla.some_integer(), 5);
29+
EXPECT_EQ(vanilla.some_text(), "foo");
30+
EXPECT_EQ(vanilla.is_condition(), true);
31+
EXPECT_EQ(vanilla.some_bytes().Get(0), "foo");
32+
EXPECT_EQ(vanilla.some_bytes().Get(1), "bar");
33+
EXPECT_EQ(vanilla.bar(), "bar_val");
34+
EXPECT_EQ(vanilla.inner_enum(), ss::SimpleStruct::ProtobufMessage::FOO_VAL);
35+
36+
ss::SimpleStruct to;
37+
::proto_structs::MessageToStruct(vanilla, to);
2738

28-
ASSERT_EQ(to.some_text, std::optional<std::string>("foo"));
2939
ASSERT_EQ(to.some_integer, 5);
40+
ASSERT_EQ(to.some_text, std::optional<std::string>("foo"));
3041
ASSERT_TRUE(to.is_condition);
3142
std::vector<std::string> exp = {"foo", "bar"};
3243
ASSERT_EQ(to.some_bytes, exp);
44+
ASSERT_EQ(to.something.bar(), "bar_val");
45+
ASSERT_THROW([[maybe_unused]] auto foo = to.something.foo(), proto_structs::OneofAccessError);
3346
}
3447

3548
TEST(SingleFile, NestedStruct) {

libraries/proto-structs/include/userver/proto-structs/impl/bundles/structs_cpp.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,11 @@
99
#include <userver/proto-structs/io/std/string_conv.hpp>
1010
#include <userver/proto-structs/io/std/vector_conv.hpp>
1111

12-
// RM
13-
#include <userver/proto-structs/io/supported_types_conv.hpp>
12+
#include <userver/proto-structs/io/std/int32_t_conv.hpp>
13+
#include <userver/proto-structs/io/std/int64_t_conv.hpp>
14+
#include <userver/proto-structs/io/std/size_t_conv.hpp>
15+
#include <userver/proto-structs/io/std/uint32_t_conv.hpp>
16+
#include <userver/proto-structs/io/std/uint64_t_conv.hpp>
17+
18+
// For keyword types.
19+
#include <userver/proto-structs/io/std/scalar_conv.hpp>

libraries/proto-structs/include/userver/proto-structs/impl/bundles/structs_hpp.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
#include <utility>
99
#include <vector>
1010

11+
#include <userver/proto-structs/impl/oneof_codegen.hpp>
1112
#include <userver/proto-structs/io/fwd.hpp>

scripts/proto_structs/descriptors/node_parsers.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from proto_structs.descriptors import option_parsers
2020
from proto_structs.descriptors import type_mapping
2121
from proto_structs.models import gen_node
22+
from proto_structs.models import io
2223
from proto_structs.models import names
2324
from proto_structs.models import options
2425
from proto_structs.models import sort_dependencies
@@ -142,6 +143,42 @@ def parse_message(
142143
_SYNTHETIC_ONEOF_NAME_REGEX = re.compile(r'X*_\w*')
143144

144145

146+
def _io_kind_read(field: descriptor.FieldDescriptor) -> io.ReadVanillaFieldKind:
147+
if typing.cast(int, field.label) == descriptor.FieldDescriptor.LABEL_OPTIONAL:
148+
if typing.cast(bool, field.has_presence):
149+
return io.ReadVanillaFieldKind.OPTIONAL
150+
151+
return io.ReadVanillaFieldKind.OTHER
152+
153+
154+
def _io_kind_write(field: descriptor.FieldDescriptor) -> io.WriteVanillaFieldKind:
155+
type_kind: int = field.type
156+
label = typing.cast(int, field.label)
157+
158+
# Check repeated firstly. Also handle a repeated map entry.
159+
if label == descriptor.FieldDescriptor.LABEL_REPEATED:
160+
return io.WriteVanillaFieldKind.VECTOR_MAP_MESSAGE
161+
162+
if type_kind == descriptor.FieldDescriptor.TYPE_STRING or type_kind == descriptor.FieldDescriptor.TYPE_BYTES:
163+
return io.WriteVanillaFieldKind.STRING
164+
165+
if type_mapping.BUILTIN_TYPES.get(type_kind) is not None or type_kind == descriptor.FieldDescriptor.TYPE_ENUM:
166+
return io.WriteVanillaFieldKind.OTHER
167+
168+
if type_kind == descriptor.FieldDescriptor.TYPE_MESSAGE or type_kind == descriptor.FieldDescriptor.TYPE_GROUP:
169+
return io.WriteVanillaFieldKind.VECTOR_MAP_MESSAGE
170+
171+
raise Exception('unreachable')
172+
173+
174+
def _io_kind_by_field(field: descriptor.FieldDescriptor) -> io.IoKind:
175+
return io.IoKind(read=_io_kind_read(field), write=_io_kind_write(field))
176+
177+
178+
def _io_kind_oneof() -> io.IoKind:
179+
return io.IoKind(read=io.ReadVanillaFieldKind.ONEOF, write=io.WriteVanillaFieldKind.ONEOF)
180+
181+
145182
def _apply_options_to_field(
146183
field: descriptor.FieldDescriptor, struct_field: gen_node.StructField, *, plugin_options: options.PluginOptions
147184
) -> gen_node.StructField:
@@ -223,6 +260,7 @@ def parse_field(
223260
field_type=parsed_type,
224261
number=typing.cast(int, field.number),
225262
oneof_fields=None,
263+
io_kinds=_io_kind_by_field(field),
226264
)
227265
return _apply_options_to_field(field, result_field, plugin_options=plugin_options)
228266

@@ -279,6 +317,7 @@ def parse_oneof(
279317
field_type=type_reference,
280318
number=None,
281319
oneof_fields=fields,
320+
io_kinds=_io_kind_oneof(),
282321
)
283322

284323

0 commit comments

Comments
 (0)