messageset.go (3045B)
1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package proto 6 7 import ( 8 "google.golang.org/protobuf/encoding/protowire" 9 "google.golang.org/protobuf/internal/encoding/messageset" 10 "google.golang.org/protobuf/internal/errors" 11 "google.golang.org/protobuf/internal/flags" 12 "google.golang.org/protobuf/internal/order" 13 "google.golang.org/protobuf/reflect/protoreflect" 14 "google.golang.org/protobuf/reflect/protoregistry" 15 ) 16 17 func (o MarshalOptions) sizeMessageSet(m protoreflect.Message) (size int) { 18 m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { 19 size += messageset.SizeField(fd.Number()) 20 size += protowire.SizeTag(messageset.FieldMessage) 21 size += protowire.SizeBytes(o.size(v.Message())) 22 return true 23 }) 24 size += messageset.SizeUnknown(m.GetUnknown()) 25 return size 26 } 27 28 func (o MarshalOptions) marshalMessageSet(b []byte, m protoreflect.Message) ([]byte, error) { 29 if !flags.ProtoLegacy { 30 return b, errors.New("no support for message_set_wire_format") 31 } 32 fieldOrder := order.AnyFieldOrder 33 if o.Deterministic { 34 fieldOrder = order.NumberFieldOrder 35 } 36 var err error 37 order.RangeFields(m, fieldOrder, func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { 38 b, err = o.marshalMessageSetField(b, fd, v) 39 return err == nil 40 }) 41 if err != nil { 42 return b, err 43 } 44 return messageset.AppendUnknown(b, m.GetUnknown()) 45 } 46 47 func (o MarshalOptions) marshalMessageSetField(b []byte, fd protoreflect.FieldDescriptor, value protoreflect.Value) ([]byte, error) { 48 b = messageset.AppendFieldStart(b, fd.Number()) 49 b = protowire.AppendTag(b, messageset.FieldMessage, protowire.BytesType) 50 b = protowire.AppendVarint(b, uint64(o.Size(value.Message().Interface()))) 51 b, err := o.marshalMessage(b, value.Message()) 52 if err != nil { 53 return b, err 54 } 55 b = messageset.AppendFieldEnd(b) 56 return b, nil 57 } 58 59 func (o UnmarshalOptions) unmarshalMessageSet(b []byte, m protoreflect.Message) error { 60 if !flags.ProtoLegacy { 61 return errors.New("no support for message_set_wire_format") 62 } 63 return messageset.Unmarshal(b, false, func(num protowire.Number, v []byte) error { 64 err := o.unmarshalMessageSetField(m, num, v) 65 if err == errUnknown { 66 unknown := m.GetUnknown() 67 unknown = protowire.AppendTag(unknown, num, protowire.BytesType) 68 unknown = protowire.AppendBytes(unknown, v) 69 m.SetUnknown(unknown) 70 return nil 71 } 72 return err 73 }) 74 } 75 76 func (o UnmarshalOptions) unmarshalMessageSetField(m protoreflect.Message, num protowire.Number, v []byte) error { 77 md := m.Descriptor() 78 if !md.ExtensionRanges().Has(num) { 79 return errUnknown 80 } 81 xt, err := o.Resolver.FindExtensionByNumber(md.FullName(), num) 82 if err == protoregistry.NotFound { 83 return errUnknown 84 } 85 if err != nil { 86 return errors.New("%v: unable to resolve extension %v: %v", md.FullName(), num, err) 87 } 88 xd := xt.TypeDescriptor() 89 if err := o.unmarshalMessage(v, m.Mutable(xd).Message()); err != nil { 90 return err 91 } 92 return nil 93 }