wire.go raw

   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 proto
   6  
   7  import (
   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.
  13  func 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.
  22  func 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  
  30  var zeroBytes = make([]byte, 0, 0)
  31  
  32  func 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.
  56  func 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.
  62  func 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  }
  79