gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

codec_messageset.go (3228B)


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