...

Source file src/google.golang.org/protobuf/internal/impl/codec_messageset.go

Documentation: google.golang.org/protobuf/internal/impl

     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  }
   124  

View as plain text