blob: 2c09c790e3faf45f4c63f3b6e9e467da0ef771e7 [file] [log] [blame]
Damien Neil302cb322019-06-19 15:22:13 -07001// 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
5package impl
6
7import (
8 "sort"
9
10 "google.golang.org/protobuf/internal/encoding/messageset"
11 "google.golang.org/protobuf/internal/encoding/wire"
12 "google.golang.org/protobuf/internal/errors"
13 "google.golang.org/protobuf/internal/flags"
14)
15
Damien Neilce3384c2019-11-06 13:18:28 -080016func sizeMessageSet(mi *MessageInfo, p pointer, opts marshalOptions) (size int) {
17 if !flags.ProtoLegacy {
Damien Neil302cb322019-06-19 15:22:13 -070018 return 0
19 }
Damien Neilce3384c2019-11-06 13:18:28 -080020
21 ext := *p.Apply(mi.extensionOffset).Extensions()
Damien Neil302cb322019-06-19 15:22:13 -070022 for _, x := range ext {
Damien Neil79571e92019-12-09 10:24:36 -080023 xi := getExtensionFieldInfo(x.Type())
Damien Neil302cb322019-06-19 15:22:13 -070024 if xi.funcs.size == nil {
25 continue
26 }
27 num, _ := wire.DecodeTag(xi.wiretag)
Damien Neilce3384c2019-11-06 13:18:28 -080028 size += messageset.SizeField(num)
29 size += xi.funcs.size(x.Value(), wire.SizeTag(messageset.FieldMessage), opts)
Damien Neil302cb322019-06-19 15:22:13 -070030 }
Damien Neilce3384c2019-11-06 13:18:28 -080031
32 unknown := *p.Apply(mi.unknownOffset).Bytes()
33 size += messageset.SizeUnknown(unknown)
34
35 return size
Damien Neil302cb322019-06-19 15:22:13 -070036}
37
Damien Neilce3384c2019-11-06 13:18:28 -080038func marshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts marshalOptions) ([]byte, error) {
Joe Tsai1799d112019-08-08 13:31:59 -070039 if !flags.ProtoLegacy {
Damien Neil302cb322019-06-19 15:22:13 -070040 return b, errors.New("no support for message_set_wire_format")
41 }
Damien Neilce3384c2019-11-06 13:18:28 -080042
43 ext := *p.Apply(mi.extensionOffset).Extensions()
Damien Neil302cb322019-06-19 15:22:13 -070044 switch len(ext) {
45 case 0:
Damien Neil302cb322019-06-19 15:22:13 -070046 case 1:
47 // Fast-path for one extension: Don't bother sorting the keys.
48 for _, x := range ext {
49 var err error
50 b, err = marshalMessageSetField(mi, b, x, opts)
51 if err != nil {
52 return b, err
53 }
54 }
Damien Neil302cb322019-06-19 15:22:13 -070055 default:
56 // Sort the keys to provide a deterministic encoding.
57 // Not sure this is required, but the old code does it.
58 keys := make([]int, 0, len(ext))
59 for k := range ext {
60 keys = append(keys, int(k))
61 }
62 sort.Ints(keys)
63 for _, k := range keys {
64 var err error
65 b, err = marshalMessageSetField(mi, b, ext[int32(k)], opts)
66 if err != nil {
67 return b, err
68 }
69 }
Damien Neil302cb322019-06-19 15:22:13 -070070 }
Damien Neilce3384c2019-11-06 13:18:28 -080071
72 unknown := *p.Apply(mi.unknownOffset).Bytes()
73 b, err := messageset.AppendUnknown(b, unknown)
74 if err != nil {
75 return b, err
76 }
77
78 return b, nil
Damien Neil302cb322019-06-19 15:22:13 -070079}
80
81func marshalMessageSetField(mi *MessageInfo, b []byte, x ExtensionField, opts marshalOptions) ([]byte, error) {
Damien Neil79571e92019-12-09 10:24:36 -080082 xi := getExtensionFieldInfo(x.Type())
Damien Neil302cb322019-06-19 15:22:13 -070083 num, _ := wire.DecodeTag(xi.wiretag)
84 b = messageset.AppendFieldStart(b, num)
Damien Neil68b81c32019-08-22 11:41:32 -070085 b, err := xi.funcs.marshal(b, x.Value(), wire.EncodeTag(messageset.FieldMessage, wire.BytesType), opts)
Damien Neil302cb322019-06-19 15:22:13 -070086 if err != nil {
87 return b, err
88 }
89 b = messageset.AppendFieldEnd(b)
90 return b, nil
91}
92
Damien Neilf0831e82020-01-21 14:25:12 -080093func unmarshalMessageSet(mi *MessageInfo, b []byte, p pointer, opts unmarshalOptions) (out unmarshalOutput, err error) {
Joe Tsai1799d112019-08-08 13:31:59 -070094 if !flags.ProtoLegacy {
Damien Neilf0831e82020-01-21 14:25:12 -080095 return out, errors.New("no support for message_set_wire_format")
Damien Neil302cb322019-06-19 15:22:13 -070096 }
Damien Neilce3384c2019-11-06 13:18:28 -080097
98 ep := p.Apply(mi.extensionOffset).Extensions()
Damien Neil302cb322019-06-19 15:22:13 -070099 if *ep == nil {
100 *ep = make(map[int32]ExtensionField)
101 }
102 ext := *ep
Damien Neilce3384c2019-11-06 13:18:28 -0800103 unknown := p.Apply(mi.unknownOffset).Bytes()
Damien Neil0bf97b72020-01-24 09:00:33 -0800104 initialized := true
Damien Neilf0831e82020-01-21 14:25:12 -0800105 err = messageset.Unmarshal(b, true, func(num wire.Number, v []byte) error {
Damien Neil0bf97b72020-01-24 09:00:33 -0800106 o, err := mi.unmarshalExtension(v, num, wire.BytesType, ext, opts)
Damien Neilce3384c2019-11-06 13:18:28 -0800107 if err == errUnknown {
108 *unknown = wire.AppendTag(*unknown, num, wire.BytesType)
109 *unknown = append(*unknown, v...)
110 return nil
111 }
Damien Neil0bf97b72020-01-24 09:00:33 -0800112 if !o.initialized {
113 initialized = false
114 }
Damien Neilce3384c2019-11-06 13:18:28 -0800115 return err
116 })
Damien Neilf0831e82020-01-21 14:25:12 -0800117 out.n = len(b)
Damien Neil0bf97b72020-01-24 09:00:33 -0800118 out.initialized = initialized
Damien Neilf0831e82020-01-21 14:25:12 -0800119 return out, err
Damien Neil302cb322019-06-19 15:22:13 -0700120}