planetscale / planetscale/vtprotobuf
Unmarshaling empty messages is incompatible with proto.Unmarshal
Open
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 1.1k
- Forks
- 112
- PR merge metrics
- No merged PRs in 30d
Description
When unmarshaling an empty message embedded in another message, vtprotobuf is allocating the message, but proto.Unmarshal is using a typed nil.
Steps to reproduce:
syntax = "proto3";
package repro;
message TopLevel {
message Empty {}
Empty embedded = 1;
}
func TestEmbeddedEmpty(t *testing.T) {
m := &pb.TopLevel{Embedded: &pb.TopLevel_Empty{}}
// Marshal it with protobuf.
protobuf, err := proto.Marshal(m)
if err != nil {
t.Fatal(err)
}
// Unmarshal it with protobuf.
pbm := &pb.TopLevel{}
if err := proto.Unmarshal(protobuf, m); err != nil {
t.Fatal(err)
}
// Unmarshal it with vtprotobuf.
vtm := &pb.TopLevel{}
if err := vtm.UnmarshalVT(protobuf); err != nil {
t.Fatal(err)
}
fmt.Printf("%#v\n\n", pbm)
fmt.Printf("%#v\n", vtm)
require.True(t, pbm.EqualVT(vtm), "EqualVT")
require.True(t, proto.Equal(pbm, vtm), "proto.Equal")
}
Output:
&proto.TopLevel{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(nil)}, sizeCache:0, unknownFields:[]uint8(nil), Embedded:(*proto.TopLevel_Empty)(nil)}
&proto.TopLevel{state:impl.MessageState{NoUnkeyedLiterals:pragma.NoUnkeyedLiterals{}, DoNotCompare:pragma.DoNotCompare{}, DoNotCopy:pragma.DoNotCopy{}, atomicMessageInfo:(*impl.MessageInfo)(nil)}, sizeCache:0, unknownFields:[]uint8(nil), Embedded:(*proto.TopLevel_Empty)(0xc00011fbc0)}
--- FAIL: TestEmbeddedEmpty (0.00s)
main_test.go:37:
Error Trace: main_test.go:37
Error: Should be true
Test: TestEmbeddedEmpty
Messages: EqualVT
FAIL
exit status 1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the TestEmbeddedEmpty reproduction and compare proto.Unmarshal with the generated UnmarshalVT entry point for the embedded TopLevel_Empty message. Trace how each path handles an empty embedded message; done means both paths produce equivalent results and the EqualVT and proto.Equal checks pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100