vendor/google.golang.org/protobuf/proto/decode.go
author Mikael Berthe <mikael@lilotux.net>
Tue, 23 Aug 2022 22:39:43 +0200
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
permissions -rw-r--r--
Update vendor directory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     1
// Copyright 2018 The Go Authors. All rights reserved.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     2
// Use of this source code is governed by a BSD-style
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     3
// license that can be found in the LICENSE file.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     4
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     5
package proto
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     6
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     7
import (
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     8
	"google.golang.org/protobuf/encoding/protowire"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
     9
	"google.golang.org/protobuf/internal/encoding/messageset"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    10
	"google.golang.org/protobuf/internal/errors"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    11
	"google.golang.org/protobuf/internal/flags"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    12
	"google.golang.org/protobuf/internal/genid"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    13
	"google.golang.org/protobuf/internal/pragma"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    14
	"google.golang.org/protobuf/reflect/protoreflect"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
	"google.golang.org/protobuf/reflect/protoregistry"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
	"google.golang.org/protobuf/runtime/protoiface"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
// UnmarshalOptions configures the unmarshaler.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
//
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
// Example usage:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    22
//
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    23
//	err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
type UnmarshalOptions struct {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
	pragma.NoUnkeyedLiterals
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
	// Merge merges the input into the destination message.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
	// The default behavior is to always reset the message before unmarshaling,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
	// unless Merge is specified.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	Merge bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
	// AllowPartial accepts input for messages that will result in missing
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
	// required fields. If AllowPartial is false (the default), Unmarshal will
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
	// return an error if there are any missing required fields.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
	AllowPartial bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
	// If DiscardUnknown is set, unknown fields are ignored.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
	DiscardUnknown bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
	// Resolver is used for looking up types when unmarshaling extension fields.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
	// If nil, this defaults to using protoregistry.GlobalTypes.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
	Resolver interface {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
		FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
		FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
	}
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    46
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    47
	// RecursionLimit limits how deeply messages may be nested.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    48
	// If zero, a default limit is applied.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    49
	RecursionLimit int
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
// Unmarshal parses the wire-format message in b and places the result in m.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
// The provided message must be mutable (e.g., a non-nil pointer to a message).
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
func Unmarshal(b []byte, m Message) error {
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    55
	_, err := UnmarshalOptions{RecursionLimit: protowire.DefaultRecursionLimit}.unmarshal(b, m.ProtoReflect())
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
	return err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
// Unmarshal parses the wire-format message in b and places the result in m.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
// The provided message must be mutable (e.g., a non-nil pointer to a message).
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
func (o UnmarshalOptions) Unmarshal(b []byte, m Message) error {
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    62
	if o.RecursionLimit == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    63
		o.RecursionLimit = protowire.DefaultRecursionLimit
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    64
	}
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
	_, err := o.unmarshal(b, m.ProtoReflect())
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
	return err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
// UnmarshalState parses a wire-format message and places the result in m.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
//
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
// This method permits fine-grained control over the unmarshaler.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
// Most users should use Unmarshal instead.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
func (o UnmarshalOptions) UnmarshalState(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    74
	if o.RecursionLimit == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    75
		o.RecursionLimit = protowire.DefaultRecursionLimit
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
    76
	}
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
	return o.unmarshal(in.Buf, in.Message)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
// unmarshal is a centralized function that all unmarshal operations go through.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
// For profiling purposes, avoid changing the name of this function or
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
// introducing other code paths for unmarshal that do not go through this.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
func (o UnmarshalOptions) unmarshal(b []byte, m protoreflect.Message) (out protoiface.UnmarshalOutput, err error) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	if o.Resolver == nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
		o.Resolver = protoregistry.GlobalTypes
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
	if !o.Merge {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
		Reset(m.Interface())
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
	allowPartial := o.AllowPartial
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
	o.Merge = true
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
	o.AllowPartial = true
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
	methods := protoMethods(m)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	if methods != nil && methods.Unmarshal != nil &&
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
		!(o.DiscardUnknown && methods.Flags&protoiface.SupportUnmarshalDiscardUnknown == 0) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
		in := protoiface.UnmarshalInput{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
			Message:  m,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
			Buf:      b,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
			Resolver: o.Resolver,
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   100
			Depth:    o.RecursionLimit,
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
		if o.DiscardUnknown {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
			in.Flags |= protoiface.UnmarshalDiscardUnknown
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
		out, err = methods.Unmarshal(in)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	} else {
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   107
		o.RecursionLimit--
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   108
		if o.RecursionLimit < 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   109
			return out, errors.New("exceeded max recursion depth")
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   110
		}
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
		err = o.unmarshalMessageSlow(b, m)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
	if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
		return out, err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
	if allowPartial || (out.Flags&protoiface.UnmarshalInitialized != 0) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
		return out, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
	return out, checkInitialized(m)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
func (o UnmarshalOptions) unmarshalMessage(b []byte, m protoreflect.Message) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
	_, err := o.unmarshal(b, m)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   124
	return err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   125
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   126
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   127
func (o UnmarshalOptions) unmarshalMessageSlow(b []byte, m protoreflect.Message) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
	md := m.Descriptor()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
	if messageset.IsMessageSet(md) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
		return o.unmarshalMessageSet(b, m)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
	fields := md.Fields()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
	for len(b) > 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
		// Parse the tag (field number and wire type).
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
		num, wtyp, tagLen := protowire.ConsumeTag(b)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
		if tagLen < 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
			return errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
		if num > protowire.MaxValidNumber {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
			return errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
		// Find the field descriptor for this field number.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
		fd := fields.ByNumber(num)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
		if fd == nil && md.ExtensionRanges().Has(num) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
			extType, err := o.Resolver.FindExtensionByNumber(md.FullName(), num)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
			if err != nil && err != protoregistry.NotFound {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
				return errors.New("%v: unable to resolve extension %v: %v", md.FullName(), num, err)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
			if extType != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
				fd = extType.TypeDescriptor()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
		var err error
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
		if fd == nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
			err = errUnknown
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
		} else if flags.ProtoLegacy {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
			if fd.IsWeak() && fd.Message().IsPlaceholder() {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
				err = errUnknown // weak referent is not linked in
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
		// Parse the field value.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
		var valLen int
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
		switch {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
		case err != nil:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
		case fd.IsList():
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
			valLen, err = o.unmarshalList(b[tagLen:], wtyp, m.Mutable(fd).List(), fd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
		case fd.IsMap():
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
			valLen, err = o.unmarshalMap(b[tagLen:], wtyp, m.Mutable(fd).Map(), fd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
		default:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
			valLen, err = o.unmarshalSingular(b[tagLen:], wtyp, m, fd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
		if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
			if err != errUnknown {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
				return err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
			valLen = protowire.ConsumeFieldValue(num, wtyp, b[tagLen:])
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
			if valLen < 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
				return errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
			if !o.DiscardUnknown {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
				m.SetUnknown(append(m.GetUnknown(), b[:tagLen+valLen]...))
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
		b = b[tagLen+valLen:]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
	return nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
func (o UnmarshalOptions) unmarshalSingular(b []byte, wtyp protowire.Type, m protoreflect.Message, fd protoreflect.FieldDescriptor) (n int, err error) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
	v, n, err := o.unmarshalScalar(b, wtyp, fd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
	if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
		return 0, err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   195
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   196
	switch fd.Kind() {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   197
	case protoreflect.GroupKind, protoreflect.MessageKind:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   198
		m2 := m.Mutable(fd).Message()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   199
		if err := o.unmarshalMessage(v.Bytes(), m2); err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   200
			return n, err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
	default:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
		// Non-message scalars replace the previous value.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
		m.Set(fd, v)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
	return n, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv protoreflect.Map, fd protoreflect.FieldDescriptor) (n int, err error) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
	if wtyp != protowire.BytesType {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
		return 0, errUnknown
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
	b, n = protowire.ConsumeBytes(b)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
	if n < 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
		return 0, errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
	var (
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
		keyField = fd.MapKey()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
		valField = fd.MapValue()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
		key      protoreflect.Value
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
		val      protoreflect.Value
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
		haveKey  bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
		haveVal  bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
	)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
	switch valField.Kind() {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
	case protoreflect.GroupKind, protoreflect.MessageKind:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
		val = mapv.NewValue()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
	// Map entries are represented as a two-element message with fields
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
	// containing the key and value.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
	for len(b) > 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
		num, wtyp, n := protowire.ConsumeTag(b)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
		if n < 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
			return 0, errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
		if num > protowire.MaxValidNumber {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
			return 0, errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
		b = b[n:]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
		err = errUnknown
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
		switch num {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
		case genid.MapEntry_Key_field_number:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
			key, n, err = o.unmarshalScalar(b, wtyp, keyField)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
			if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
				break
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
			haveKey = true
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
		case genid.MapEntry_Value_field_number:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
			var v protoreflect.Value
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
			v, n, err = o.unmarshalScalar(b, wtyp, valField)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
			if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
				break
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
			switch valField.Kind() {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
			case protoreflect.GroupKind, protoreflect.MessageKind:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
				if err := o.unmarshalMessage(v.Bytes(), val.Message()); err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
					return 0, err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
				}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   259
			default:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   260
				val = v
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   261
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   262
			haveVal = true
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   263
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   264
		if err == errUnknown {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   265
			n = protowire.ConsumeFieldValue(num, wtyp, b)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   266
			if n < 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   267
				return 0, errDecode
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   268
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   269
		} else if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
			return 0, err
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
		b = b[n:]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
	// Every map entry should have entries for key and value, but this is not strictly required.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
	if !haveKey {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
		key = keyField.Default()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   277
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   278
	if !haveVal {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   279
		switch valField.Kind() {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   280
		case protoreflect.GroupKind, protoreflect.MessageKind:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   281
		default:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   282
			val = valField.Default()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
	mapv.Set(key.MapKey(), val)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
	return n, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
// errUnknown is used internally to indicate fields which should be added
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
// to the unknown field set of a message. It is never returned from an exported
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
// function.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
var errUnknown = errors.New("BUG: internal error (unknown)")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
var errDecode = errors.New("cannot parse invalid wire-format data")