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