diff --git a/acl/grpc/types_frostfs.pb.go b/acl/grpc/types_frostfs.pb.go index e5a6f32..bc90cb7 100644 Binary files a/acl/grpc/types_frostfs.pb.go and b/acl/grpc/types_frostfs.pb.go differ diff --git a/ape/grpc/types_frostfs.pb.go b/ape/grpc/types_frostfs.pb.go index cf9499f..1f2a1a5 100644 Binary files a/ape/grpc/types_frostfs.pb.go and b/ape/grpc/types_frostfs.pb.go differ diff --git a/apemanager/grpc/service_frostfs.pb.go b/apemanager/grpc/service_frostfs.pb.go index 7f3ed10..b2633e1 100644 Binary files a/apemanager/grpc/service_frostfs.pb.go and b/apemanager/grpc/service_frostfs.pb.go differ diff --git a/container/grpc/types_frostfs.pb.go b/container/grpc/types_frostfs.pb.go index 4ca23fa..a4f0882 100644 Binary files a/container/grpc/types_frostfs.pb.go and b/container/grpc/types_frostfs.pb.go differ diff --git a/netmap/grpc/types_frostfs.pb.go b/netmap/grpc/types_frostfs.pb.go index 0328531..24003c6 100644 Binary files a/netmap/grpc/types_frostfs.pb.go and b/netmap/grpc/types_frostfs.pb.go differ diff --git a/object/grpc/service_frostfs.pb.go b/object/grpc/service_frostfs.pb.go index 9ee5a3d..a55a41b 100644 Binary files a/object/grpc/service_frostfs.pb.go and b/object/grpc/service_frostfs.pb.go differ diff --git a/object/grpc/types_frostfs.pb.go b/object/grpc/types_frostfs.pb.go index e4a916f..a6d4f01 100644 Binary files a/object/grpc/types_frostfs.pb.go and b/object/grpc/types_frostfs.pb.go differ diff --git a/refs/grpc/types_frostfs.pb.go b/refs/grpc/types_frostfs.pb.go index 5a16f8e..f2a2663 100644 Binary files a/refs/grpc/types_frostfs.pb.go and b/refs/grpc/types_frostfs.pb.go differ diff --git a/session/grpc/service_frostfs.pb.go b/session/grpc/service_frostfs.pb.go index 6d3ea9f..26213b9 100644 Binary files a/session/grpc/service_frostfs.pb.go and b/session/grpc/service_frostfs.pb.go differ diff --git a/session/grpc/types_frostfs.pb.go b/session/grpc/types_frostfs.pb.go index e9f3b42..542a02b 100644 Binary files a/session/grpc/types_frostfs.pb.go and b/session/grpc/types_frostfs.pb.go differ diff --git a/status/grpc/types_frostfs.pb.go b/status/grpc/types_frostfs.pb.go index 1d8b477..6c62a0f 100644 Binary files a/status/grpc/types_frostfs.pb.go and b/status/grpc/types_frostfs.pb.go differ diff --git a/tombstone/grpc/types_frostfs.pb.go b/tombstone/grpc/types_frostfs.pb.go index acb1836..e56832a 100644 Binary files a/tombstone/grpc/types_frostfs.pb.go and b/tombstone/grpc/types_frostfs.pb.go differ diff --git a/util/proto/marshal_test.go b/util/proto/marshal_test.go index 5498cf9..29af711 100644 --- a/util/proto/marshal_test.go +++ b/util/proto/marshal_test.go @@ -50,9 +50,6 @@ func TestStableMarshalSingle(t *testing.T) { var actualFrostfs generated.Primitives require.NoError(t, actualFrostfs.UnmarshalJSON(r)) - if len(actualFrostfs.FieldA) == 0 { - actualFrostfs.FieldA = nil - } require.Equal(t, input, &actualFrostfs) primitivesEqual(t, input, &actual) @@ -110,9 +107,6 @@ func TestStableMarshalSingle(t *testing.T) { var actualFrostfs generated.Primitives require.NoError(t, actualFrostfs.UnmarshalJSON(r)) - if len(actualFrostfs.FieldA) == 0 { - actualFrostfs.FieldA = nil - } require.Equal(t, tc.input, &actualFrostfs) primitivesEqual(t, tc.input, &actual) @@ -124,9 +118,7 @@ func TestStableMarshalSingle(t *testing.T) { func primitivesEqual(t *testing.T, a *generated.Primitives, b *test.Primitives) { // Compare each field directly, because proto-generated code has private fields. require.Equal(t, len(a.FieldA), len(b.FieldA)) - if len(a.FieldA) != 0 { - require.Equal(t, a.FieldA, b.FieldA) - } + require.Equal(t, a.FieldA, b.FieldA) require.Equal(t, a.FieldB, b.FieldB) require.Equal(t, a.FieldC, b.FieldC) require.Equal(t, a.FieldD, b.FieldD) diff --git a/util/proto/test/custom/test_frostfs.pb.go b/util/proto/test/custom/test_frostfs.pb.go index f979038..5ef95a6 100644 Binary files a/util/proto/test/custom/test_frostfs.pb.go and b/util/proto/test/custom/test_frostfs.pb.go differ diff --git a/util/protogen/internalgengo/json.go b/util/protogen/internalgengo/json.go index 15facfd..55c9cd3 100644 --- a/util/protogen/internalgengo/json.go +++ b/util/protogen/internalgengo/json.go @@ -129,7 +129,17 @@ func emitJSONFieldRead(g *protogen.GeneratedFile, f *protogen.Field, name string case protoreflect.StringKind: template = "%s = in.String()" case protoreflect.BytesKind: - template = "%s = in.Bytes()" + // Since some time ago proto3 support optional keyword, thus the presence is not tracked by default: + // https://github.com/protocolbuffers/protobuf-go/blob/fb995f184a1719ec42b247a3771d1036d92adf67/internal/impl/message_reflect_field.go#L327 + // We do not explicitly support `optional` keyword, protoc will fail on such fileds. + // Thus, treat empty string as `[]byte(nil)`. + template = `{ + tmp := in.Bytes() + if len(tmp) == 0 { + tmp = nil + } + %s = tmp + }` case protoreflect.MessageKind: if f.Desc.IsList() { g.P("f = ", fieldType(g, f)[2:], "{}")