wire.go 1.9 KB

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