proto, internal/impl: store unknown MessageSet items in non-mset format
In the v1 implementation, unknown MessageSet items are stored in a
message's unknown fields section in non-MessageSet format. For example,
consider a MessageSet containing an item with type_id T and value V.
If the type_id is not resolvable, the item will be placed in the unknown
fields as a bytes-valued field with number T and contents V. This
conversion is then reversed when marshaling a MessageSet containing
unknown fields.
Preserve this behavior in v2.
One consequence of this change is that actual unknown fields in a
MessageSet (any field other than 1) are now discarded. This matches
the previous behavior.
Change-Id: I3d913613f84e0ae82481078dbc91cb25628651cc
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/205697
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/impl/encode.go b/internal/impl/encode.go
index d7dc892..cd57998 100644
--- a/internal/impl/encode.go
+++ b/internal/impl/encode.go
@@ -8,6 +8,7 @@
"sort"
"sync/atomic"
+ "google.golang.org/protobuf/internal/flags"
proto "google.golang.org/protobuf/proto"
pref "google.golang.org/protobuf/reflect/protoreflect"
piface "google.golang.org/protobuf/runtime/protoiface"
@@ -69,6 +70,13 @@
}
func (mi *MessageInfo) sizePointerSlow(p pointer, opts marshalOptions) (size int) {
+ if flags.ProtoLegacy && mi.isMessageSet {
+ size = sizeMessageSet(mi, p, opts)
+ if mi.sizecacheOffset.IsValid() {
+ atomic.StoreInt32(p.Apply(mi.sizecacheOffset).Int32(), int32(size))
+ }
+ return size
+ }
if mi.extensionOffset.IsValid() {
e := p.Apply(mi.extensionOffset).Extensions()
size += mi.sizeExtensions(e, opts)
@@ -109,6 +117,9 @@
if p.IsNil() {
return b, nil
}
+ if flags.ProtoLegacy && mi.isMessageSet {
+ return marshalMessageSet(mi, b, p, opts)
+ }
var err error
// The old marshaler encodes extensions at beginning.
if mi.extensionOffset.IsValid() {
@@ -132,7 +143,7 @@
return b, err
}
}
- if mi.unknownOffset.IsValid() {
+ if mi.unknownOffset.IsValid() && !mi.isMessageSet {
u := *p.Apply(mi.unknownOffset).Bytes()
b = append(b, u...)
}