proto: fix merge semantics for oneof message
The proper semantics for a message field within a oneof
when unmarshaling is to merge into an existing message,
rather than replacing it.
Change-Id: I7c08f6e4fa958c6ee6241e9083f7311515a97e15
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185957
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/impl/codec_field.go b/internal/impl/codec_field.go
index f5e9755..8d0e339 100644
--- a/internal/impl/codec_field.go
+++ b/internal/impl/codec_field.go
@@ -52,12 +52,18 @@
return funcs.marshal(b, v, wiretag, opts)
},
unmarshal: func(b []byte, p pointer, wtyp wire.Type, opts unmarshalOptions) (int, error) {
- v := reflect.New(ot)
- n, err := funcs.unmarshal(b, pointerOfValue(v).Apply(zeroOffset), wtyp, opts)
+ var vw reflect.Value // pointer to wrapper type
+ vi := p.AsValueOf(ft).Elem() // oneof field value of interface kind
+ if !vi.IsNil() && !vi.Elem().IsNil() && vi.Elem().Elem().Type() == ot {
+ vw = vi.Elem()
+ } else {
+ vw = reflect.New(ot)
+ }
+ n, err := funcs.unmarshal(b, pointerOfValue(vw).Apply(zeroOffset), wtyp, opts)
if err != nil {
return 0, err
}
- p.AsValueOf(ft).Elem().Set(v)
+ vi.Set(vw)
return n, nil
},
}