forked from TrueCloudLab/frostfs-api-go
[#123] protogen: Treat bytes field as non-nullable
In protobuf 3.12 they have added an support for `optional` keyword, which has made it into the main branch in 3.15. https://github.com/protocolbuffers/protobuf/blob/main/docs/implementing_proto3_presence.md https://github.com/protocolbuffers/protobuf/blob/v3.12.0/docs/field_presence.md#presence-in-proto3-apis This means that without an explicit `optional` keyword field presence for scalars is not tracked, thus empty string in JSON should be unmarshaled to a nil byte slice. Relevant decoding code and tests from protojson:fb995f184a/internal/impl/message_reflect_field.go (L327)
fb995f184a/encoding/protojson/decode_test.go (L134)
fb995f184a/encoding/protojson/decode_test.go (L156)
We do not support `optional` keyword and the generator will fail if it sees on. So only implement the default behaviour. Refs #122 Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
29c522d5d8
commit
29f2157563
15 changed files with 12 additions and 10 deletions
BIN
acl/grpc/types_frostfs.pb.go
generated
BIN
acl/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
ape/grpc/types_frostfs.pb.go
generated
BIN
ape/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
apemanager/grpc/service_frostfs.pb.go
generated
BIN
apemanager/grpc/service_frostfs.pb.go
generated
Binary file not shown.
BIN
container/grpc/types_frostfs.pb.go
generated
BIN
container/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
netmap/grpc/types_frostfs.pb.go
generated
BIN
netmap/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
object/grpc/service_frostfs.pb.go
generated
BIN
object/grpc/service_frostfs.pb.go
generated
Binary file not shown.
BIN
object/grpc/types_frostfs.pb.go
generated
BIN
object/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
refs/grpc/types_frostfs.pb.go
generated
BIN
refs/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
session/grpc/service_frostfs.pb.go
generated
BIN
session/grpc/service_frostfs.pb.go
generated
Binary file not shown.
BIN
session/grpc/types_frostfs.pb.go
generated
BIN
session/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
status/grpc/types_frostfs.pb.go
generated
BIN
status/grpc/types_frostfs.pb.go
generated
Binary file not shown.
BIN
tombstone/grpc/types_frostfs.pb.go
generated
BIN
tombstone/grpc/types_frostfs.pb.go
generated
Binary file not shown.
|
@ -50,9 +50,6 @@ func TestStableMarshalSingle(t *testing.T) {
|
||||||
|
|
||||||
var actualFrostfs generated.Primitives
|
var actualFrostfs generated.Primitives
|
||||||
require.NoError(t, actualFrostfs.UnmarshalJSON(r))
|
require.NoError(t, actualFrostfs.UnmarshalJSON(r))
|
||||||
if len(actualFrostfs.FieldA) == 0 {
|
|
||||||
actualFrostfs.FieldA = nil
|
|
||||||
}
|
|
||||||
require.Equal(t, input, &actualFrostfs)
|
require.Equal(t, input, &actualFrostfs)
|
||||||
|
|
||||||
primitivesEqual(t, input, &actual)
|
primitivesEqual(t, input, &actual)
|
||||||
|
@ -110,9 +107,6 @@ func TestStableMarshalSingle(t *testing.T) {
|
||||||
|
|
||||||
var actualFrostfs generated.Primitives
|
var actualFrostfs generated.Primitives
|
||||||
require.NoError(t, actualFrostfs.UnmarshalJSON(r))
|
require.NoError(t, actualFrostfs.UnmarshalJSON(r))
|
||||||
if len(actualFrostfs.FieldA) == 0 {
|
|
||||||
actualFrostfs.FieldA = nil
|
|
||||||
}
|
|
||||||
require.Equal(t, tc.input, &actualFrostfs)
|
require.Equal(t, tc.input, &actualFrostfs)
|
||||||
|
|
||||||
primitivesEqual(t, tc.input, &actual)
|
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) {
|
func primitivesEqual(t *testing.T, a *generated.Primitives, b *test.Primitives) {
|
||||||
// Compare each field directly, because proto-generated code has private fields.
|
// Compare each field directly, because proto-generated code has private fields.
|
||||||
require.Equal(t, len(a.FieldA), len(b.FieldA))
|
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.FieldB, b.FieldB)
|
||||||
require.Equal(t, a.FieldC, b.FieldC)
|
require.Equal(t, a.FieldC, b.FieldC)
|
||||||
require.Equal(t, a.FieldD, b.FieldD)
|
require.Equal(t, a.FieldD, b.FieldD)
|
||||||
|
|
BIN
util/proto/test/custom/test_frostfs.pb.go
generated
BIN
util/proto/test/custom/test_frostfs.pb.go
generated
Binary file not shown.
|
@ -129,7 +129,17 @@ func emitJSONFieldRead(g *protogen.GeneratedFile, f *protogen.Field, name string
|
||||||
case protoreflect.StringKind:
|
case protoreflect.StringKind:
|
||||||
template = "%s = in.String()"
|
template = "%s = in.String()"
|
||||||
case protoreflect.BytesKind:
|
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:
|
case protoreflect.MessageKind:
|
||||||
if f.Desc.IsList() {
|
if f.Desc.IsList() {
|
||||||
g.P("f = ", fieldType(g, f)[2:], "{}")
|
g.P("f = ", fieldType(g, f)[2:], "{}")
|
||||||
|
|
Loading…
Reference in a new issue