blob: d7c28da5a7582d112760893e587cbbb33b2469dc [file] [log] [blame]
David K. Bainbridgebd6b2882021-08-26 13:31:02 +00001// 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 proto
6
7import (
8 protoV2 "google.golang.org/protobuf/proto"
9 "google.golang.org/protobuf/runtime/protoiface"
10)
11
12// Size returns the size in bytes of the wire-format encoding of m.
13func Size(m Message) int {
14 if m == nil {
15 return 0
16 }
17 mi := MessageV2(m)
18 return protoV2.Size(mi)
19}
20
21// Marshal returns the wire-format encoding of m.
22func Marshal(m Message) ([]byte, error) {
23 b, err := marshalAppend(nil, m, false)
24 if b == nil {
25 b = zeroBytes
26 }
27 return b, err
28}
29
30var zeroBytes = make([]byte, 0, 0)
31
32func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) {
33 if m == nil {
34 return nil, ErrNil
35 }
36 mi := MessageV2(m)
37 nbuf, err := protoV2.MarshalOptions{
38 Deterministic: deterministic,
39 AllowPartial: true,
40 }.MarshalAppend(buf, mi)
41 if err != nil {
42 return buf, err
43 }
44 if len(buf) == len(nbuf) {
45 if !mi.ProtoReflect().IsValid() {
46 return buf, ErrNil
47 }
48 }
49 return nbuf, checkRequiredNotSet(mi)
50}
51
52// Unmarshal parses a wire-format message in b and places the decoded results in m.
53//
54// Unmarshal resets m before starting to unmarshal, so any existing data in m is always
55// removed. Use UnmarshalMerge to preserve and append to existing data.
56func Unmarshal(b []byte, m Message) error {
57 m.Reset()
58 return UnmarshalMerge(b, m)
59}
60
61// UnmarshalMerge parses a wire-format message in b and places the decoded results in m.
62func UnmarshalMerge(b []byte, m Message) error {
63 mi := MessageV2(m)
64 out, err := protoV2.UnmarshalOptions{
65 AllowPartial: true,
66 Merge: true,
67 }.UnmarshalState(protoiface.UnmarshalInput{
68 Buf: b,
69 Message: mi.ProtoReflect(),
70 })
71 if err != nil {
72 return err
73 }
74 if out.Flags&protoiface.UnmarshalInitialized > 0 {
75 return nil
76 }
77 return checkRequiredNotSet(mi)
78}