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 impl 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "sort" 9*1c12ee1eSDan Willemsen 10*1c12ee1eSDan Willemsen "google.golang.org/protobuf/encoding/protowire" 11*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/encoding/messageset" 12*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/errors" 13*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/flags" 14*1c12ee1eSDan Willemsen) 15*1c12ee1eSDan Willemsen 16*1c12ee1eSDan Willemsenfunc sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int) { 17*1c12ee1eSDan Willemsen if !flags.ProtoLegacy { 18*1c12ee1eSDan Willemsen return 0 19*1c12ee1eSDan Willemsen } 20*1c12ee1eSDan Willemsen 21*1c12ee1eSDan Willemsen ext := *p.Apply(mi.extensionOffset).Extensions() 22*1c12ee1eSDan Willemsen for _, x := range ext { 23*1c12ee1eSDan Willemsen xi := getExtensionFieldInfo(x.Type()) 24*1c12ee1eSDan Willemsen if xi.funcs.size == nil { 25*1c12ee1eSDan Willemsen continue 26*1c12ee1eSDan Willemsen } 27*1c12ee1eSDan Willemsen num, _ := protowire.DecodeTag(xi.wiretag) 28*1c12ee1eSDan Willemsen size += messageset.SizeField(num) 29*1c12ee1eSDan Willemsen size += xi.funcs.size(x.Value(), protowire.SizeTag(messageset.FieldMessage), opts) 30*1c12ee1eSDan Willemsen } 31*1c12ee1eSDan Willemsen 32*1c12ee1eSDan Willemsen if u := mi.getUnknownBytes(p); u != nil { 33*1c12ee1eSDan Willemsen size += messageset.SizeUnknown(*u) 34*1c12ee1eSDan Willemsen } 35*1c12ee1eSDan Willemsen 36*1c12ee1eSDan Willemsen return size 37*1c12ee1eSDan Willemsen} 38*1c12ee1eSDan Willemsen 39*1c12ee1eSDan Willemsenfunc marshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts marshalOptions) ([]byte, error) { 40*1c12ee1eSDan Willemsen if !flags.ProtoLegacy { 41*1c12ee1eSDan Willemsen return b, errors.New("no support for message_set_wire_format") 42*1c12ee1eSDan Willemsen } 43*1c12ee1eSDan Willemsen 44*1c12ee1eSDan Willemsen ext := *p.Apply(mi.extensionOffset).Extensions() 45*1c12ee1eSDan Willemsen switch len(ext) { 46*1c12ee1eSDan Willemsen case 0: 47*1c12ee1eSDan Willemsen case 1: 48*1c12ee1eSDan Willemsen // Fast-path for one extension: Don't bother sorting the keys. 49*1c12ee1eSDan Willemsen for _, x := range ext { 50*1c12ee1eSDan Willemsen var err error 51*1c12ee1eSDan Willemsen b, err = marshalMessageSetField(mi, b, x, opts) 52*1c12ee1eSDan Willemsen if err != nil { 53*1c12ee1eSDan Willemsen return b, err 54*1c12ee1eSDan Willemsen } 55*1c12ee1eSDan Willemsen } 56*1c12ee1eSDan Willemsen default: 57*1c12ee1eSDan Willemsen // Sort the keys to provide a deterministic encoding. 58*1c12ee1eSDan Willemsen // Not sure this is required, but the old code does it. 59*1c12ee1eSDan Willemsen keys := make([]int, 0, len(ext)) 60*1c12ee1eSDan Willemsen for k := range ext { 61*1c12ee1eSDan Willemsen keys = append(keys, int(k)) 62*1c12ee1eSDan Willemsen } 63*1c12ee1eSDan Willemsen sort.Ints(keys) 64*1c12ee1eSDan Willemsen for _, k := range keys { 65*1c12ee1eSDan Willemsen var err error 66*1c12ee1eSDan Willemsen b, err = marshalMessageSetField(mi, b, ext[int32(k)], opts) 67*1c12ee1eSDan Willemsen if err != nil { 68*1c12ee1eSDan Willemsen return b, err 69*1c12ee1eSDan Willemsen } 70*1c12ee1eSDan Willemsen } 71*1c12ee1eSDan Willemsen } 72*1c12ee1eSDan Willemsen 73*1c12ee1eSDan Willemsen if u := mi.getUnknownBytes(p); u != nil { 74*1c12ee1eSDan Willemsen var err error 75*1c12ee1eSDan Willemsen b, err = messageset.AppendUnknown(b, *u) 76*1c12ee1eSDan Willemsen if err != nil { 77*1c12ee1eSDan Willemsen return b, err 78*1c12ee1eSDan Willemsen } 79*1c12ee1eSDan Willemsen } 80*1c12ee1eSDan Willemsen 81*1c12ee1eSDan Willemsen return b, nil 82*1c12ee1eSDan Willemsen} 83*1c12ee1eSDan Willemsen 84*1c12ee1eSDan Willemsenfunc marshalMessageSetField(mi *MessageInfo, b []byte, x ExtensionField, opts marshalOptions) ([]byte, error) { 85*1c12ee1eSDan Willemsen xi := getExtensionFieldInfo(x.Type()) 86*1c12ee1eSDan Willemsen num, _ := protowire.DecodeTag(xi.wiretag) 87*1c12ee1eSDan Willemsen b = messageset.AppendFieldStart(b, num) 88*1c12ee1eSDan Willemsen b, err := xi.funcs.marshal(b, x.Value(), protowire.EncodeTag(messageset.FieldMessage, protowire.BytesType), opts) 89*1c12ee1eSDan Willemsen if err != nil { 90*1c12ee1eSDan Willemsen return b, err 91*1c12ee1eSDan Willemsen } 92*1c12ee1eSDan Willemsen b = messageset.AppendFieldEnd(b) 93*1c12ee1eSDan Willemsen return b, nil 94*1c12ee1eSDan Willemsen} 95*1c12ee1eSDan Willemsen 96*1c12ee1eSDan Willemsenfunc unmarshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts unmarshalOptions) (out unmarshalOutput, err error) { 97*1c12ee1eSDan Willemsen if !flags.ProtoLegacy { 98*1c12ee1eSDan Willemsen return out, errors.New("no support for message_set_wire_format") 99*1c12ee1eSDan Willemsen } 100*1c12ee1eSDan Willemsen 101*1c12ee1eSDan Willemsen ep := p.Apply(mi.extensionOffset).Extensions() 102*1c12ee1eSDan Willemsen if *ep == nil { 103*1c12ee1eSDan Willemsen *ep = make(map[int32]ExtensionField) 104*1c12ee1eSDan Willemsen } 105*1c12ee1eSDan Willemsen ext := *ep 106*1c12ee1eSDan Willemsen initialized := true 107*1c12ee1eSDan Willemsen err = messageset.Unmarshal(b, true, func(num protowire.Number, v []byte) error { 108*1c12ee1eSDan Willemsen o, err := mi.unmarshalExtension(v, num, protowire.BytesType, ext, opts) 109*1c12ee1eSDan Willemsen if err == errUnknown { 110*1c12ee1eSDan Willemsen u := mi.mutableUnknownBytes(p) 111*1c12ee1eSDan Willemsen *u = protowire.AppendTag(*u, num, protowire.BytesType) 112*1c12ee1eSDan Willemsen *u = append(*u, v...) 113*1c12ee1eSDan Willemsen return nil 114*1c12ee1eSDan Willemsen } 115*1c12ee1eSDan Willemsen if !o.initialized { 116*1c12ee1eSDan Willemsen initialized = false 117*1c12ee1eSDan Willemsen } 118*1c12ee1eSDan Willemsen return err 119*1c12ee1eSDan Willemsen }) 120*1c12ee1eSDan Willemsen out.n = len(b) 121*1c12ee1eSDan Willemsen out.initialized = initialized 122*1c12ee1eSDan Willemsen return out, err 123*1c12ee1eSDan Willemsen} 124