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