xref: /aosp_15_r20/external/golang-protobuf/encoding/prototext/decode.go (revision 1c12ee1efe575feb122dbf939ff15148a3b3e8f2)
1*1c12ee1eSDan Willemsen// Copyright 2018 The Go Authors. All rights reserved.
2*1c12ee1eSDan Willemsen// Use of this source code is governed by a BSD-style
3*1c12ee1eSDan Willemsen// license that can be found in the LICENSE file.
4*1c12ee1eSDan Willemsen
5*1c12ee1eSDan Willemsenpackage prototext
6*1c12ee1eSDan Willemsen
7*1c12ee1eSDan Willemsenimport (
8*1c12ee1eSDan Willemsen	"fmt"
9*1c12ee1eSDan Willemsen	"unicode/utf8"
10*1c12ee1eSDan Willemsen
11*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/encoding/messageset"
12*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/encoding/text"
13*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/errors"
14*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/flags"
15*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/genid"
16*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/pragma"
17*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/set"
18*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/internal/strs"
19*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/proto"
20*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoreflect"
21*1c12ee1eSDan Willemsen	"google.golang.org/protobuf/reflect/protoregistry"
22*1c12ee1eSDan Willemsen)
23*1c12ee1eSDan Willemsen
24*1c12ee1eSDan Willemsen// Unmarshal reads the given []byte into the given proto.Message.
25*1c12ee1eSDan Willemsen// The provided message must be mutable (e.g., a non-nil pointer to a message).
26*1c12ee1eSDan Willemsenfunc Unmarshal(b []byte, m proto.Message) error {
27*1c12ee1eSDan Willemsen	return UnmarshalOptions{}.Unmarshal(b, m)
28*1c12ee1eSDan Willemsen}
29*1c12ee1eSDan Willemsen
30*1c12ee1eSDan Willemsen// UnmarshalOptions is a configurable textproto format unmarshaler.
31*1c12ee1eSDan Willemsentype UnmarshalOptions struct {
32*1c12ee1eSDan Willemsen	pragma.NoUnkeyedLiterals
33*1c12ee1eSDan Willemsen
34*1c12ee1eSDan Willemsen	// AllowPartial accepts input for messages that will result in missing
35*1c12ee1eSDan Willemsen	// required fields. If AllowPartial is false (the default), Unmarshal will
36*1c12ee1eSDan Willemsen	// return error if there are any missing required fields.
37*1c12ee1eSDan Willemsen	AllowPartial bool
38*1c12ee1eSDan Willemsen
39*1c12ee1eSDan Willemsen	// DiscardUnknown specifies whether to ignore unknown fields when parsing.
40*1c12ee1eSDan Willemsen	// An unknown field is any field whose field name or field number does not
41*1c12ee1eSDan Willemsen	// resolve to any known or extension field in the message.
42*1c12ee1eSDan Willemsen	// By default, unmarshal rejects unknown fields as an error.
43*1c12ee1eSDan Willemsen	DiscardUnknown bool
44*1c12ee1eSDan Willemsen
45*1c12ee1eSDan Willemsen	// Resolver is used for looking up types when unmarshaling
46*1c12ee1eSDan Willemsen	// google.protobuf.Any messages or extension fields.
47*1c12ee1eSDan Willemsen	// If nil, this defaults to using protoregistry.GlobalTypes.
48*1c12ee1eSDan Willemsen	Resolver interface {
49*1c12ee1eSDan Willemsen		protoregistry.MessageTypeResolver
50*1c12ee1eSDan Willemsen		protoregistry.ExtensionTypeResolver
51*1c12ee1eSDan Willemsen	}
52*1c12ee1eSDan Willemsen}
53*1c12ee1eSDan Willemsen
54*1c12ee1eSDan Willemsen// Unmarshal reads the given []byte and populates the given proto.Message
55*1c12ee1eSDan Willemsen// using options in the UnmarshalOptions object.
56*1c12ee1eSDan Willemsen// The provided message must be mutable (e.g., a non-nil pointer to a message).
57*1c12ee1eSDan Willemsenfunc (o UnmarshalOptions) Unmarshal(b []byte, m proto.Message) error {
58*1c12ee1eSDan Willemsen	return o.unmarshal(b, m)
59*1c12ee1eSDan Willemsen}
60*1c12ee1eSDan Willemsen
61*1c12ee1eSDan Willemsen// unmarshal is a centralized function that all unmarshal operations go through.
62*1c12ee1eSDan Willemsen// For profiling purposes, avoid changing the name of this function or
63*1c12ee1eSDan Willemsen// introducing other code paths for unmarshal that do not go through this.
64*1c12ee1eSDan Willemsenfunc (o UnmarshalOptions) unmarshal(b []byte, m proto.Message) error {
65*1c12ee1eSDan Willemsen	proto.Reset(m)
66*1c12ee1eSDan Willemsen
67*1c12ee1eSDan Willemsen	if o.Resolver == nil {
68*1c12ee1eSDan Willemsen		o.Resolver = protoregistry.GlobalTypes
69*1c12ee1eSDan Willemsen	}
70*1c12ee1eSDan Willemsen
71*1c12ee1eSDan Willemsen	dec := decoder{text.NewDecoder(b), o}
72*1c12ee1eSDan Willemsen	if err := dec.unmarshalMessage(m.ProtoReflect(), false); err != nil {
73*1c12ee1eSDan Willemsen		return err
74*1c12ee1eSDan Willemsen	}
75*1c12ee1eSDan Willemsen	if o.AllowPartial {
76*1c12ee1eSDan Willemsen		return nil
77*1c12ee1eSDan Willemsen	}
78*1c12ee1eSDan Willemsen	return proto.CheckInitialized(m)
79*1c12ee1eSDan Willemsen}
80*1c12ee1eSDan Willemsen
81*1c12ee1eSDan Willemsentype decoder struct {
82*1c12ee1eSDan Willemsen	*text.Decoder
83*1c12ee1eSDan Willemsen	opts UnmarshalOptions
84*1c12ee1eSDan Willemsen}
85*1c12ee1eSDan Willemsen
86*1c12ee1eSDan Willemsen// newError returns an error object with position info.
87*1c12ee1eSDan Willemsenfunc (d decoder) newError(pos int, f string, x ...interface{}) error {
88*1c12ee1eSDan Willemsen	line, column := d.Position(pos)
89*1c12ee1eSDan Willemsen	head := fmt.Sprintf("(line %d:%d): ", line, column)
90*1c12ee1eSDan Willemsen	return errors.New(head+f, x...)
91*1c12ee1eSDan Willemsen}
92*1c12ee1eSDan Willemsen
93*1c12ee1eSDan Willemsen// unexpectedTokenError returns a syntax error for the given unexpected token.
94*1c12ee1eSDan Willemsenfunc (d decoder) unexpectedTokenError(tok text.Token) error {
95*1c12ee1eSDan Willemsen	return d.syntaxError(tok.Pos(), "unexpected token: %s", tok.RawString())
96*1c12ee1eSDan Willemsen}
97*1c12ee1eSDan Willemsen
98*1c12ee1eSDan Willemsen// syntaxError returns a syntax error for given position.
99*1c12ee1eSDan Willemsenfunc (d decoder) syntaxError(pos int, f string, x ...interface{}) error {
100*1c12ee1eSDan Willemsen	line, column := d.Position(pos)
101*1c12ee1eSDan Willemsen	head := fmt.Sprintf("syntax error (line %d:%d): ", line, column)
102*1c12ee1eSDan Willemsen	return errors.New(head+f, x...)
103*1c12ee1eSDan Willemsen}
104*1c12ee1eSDan Willemsen
105*1c12ee1eSDan Willemsen// unmarshalMessage unmarshals into the given protoreflect.Message.
106*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error {
107*1c12ee1eSDan Willemsen	messageDesc := m.Descriptor()
108*1c12ee1eSDan Willemsen	if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) {
109*1c12ee1eSDan Willemsen		return errors.New("no support for proto1 MessageSets")
110*1c12ee1eSDan Willemsen	}
111*1c12ee1eSDan Willemsen
112*1c12ee1eSDan Willemsen	if messageDesc.FullName() == genid.Any_message_fullname {
113*1c12ee1eSDan Willemsen		return d.unmarshalAny(m, checkDelims)
114*1c12ee1eSDan Willemsen	}
115*1c12ee1eSDan Willemsen
116*1c12ee1eSDan Willemsen	if checkDelims {
117*1c12ee1eSDan Willemsen		tok, err := d.Read()
118*1c12ee1eSDan Willemsen		if err != nil {
119*1c12ee1eSDan Willemsen			return err
120*1c12ee1eSDan Willemsen		}
121*1c12ee1eSDan Willemsen
122*1c12ee1eSDan Willemsen		if tok.Kind() != text.MessageOpen {
123*1c12ee1eSDan Willemsen			return d.unexpectedTokenError(tok)
124*1c12ee1eSDan Willemsen		}
125*1c12ee1eSDan Willemsen	}
126*1c12ee1eSDan Willemsen
127*1c12ee1eSDan Willemsen	var seenNums set.Ints
128*1c12ee1eSDan Willemsen	var seenOneofs set.Ints
129*1c12ee1eSDan Willemsen	fieldDescs := messageDesc.Fields()
130*1c12ee1eSDan Willemsen
131*1c12ee1eSDan Willemsen	for {
132*1c12ee1eSDan Willemsen		// Read field name.
133*1c12ee1eSDan Willemsen		tok, err := d.Read()
134*1c12ee1eSDan Willemsen		if err != nil {
135*1c12ee1eSDan Willemsen			return err
136*1c12ee1eSDan Willemsen		}
137*1c12ee1eSDan Willemsen		switch typ := tok.Kind(); typ {
138*1c12ee1eSDan Willemsen		case text.Name:
139*1c12ee1eSDan Willemsen			// Continue below.
140*1c12ee1eSDan Willemsen		case text.EOF:
141*1c12ee1eSDan Willemsen			if checkDelims {
142*1c12ee1eSDan Willemsen				return text.ErrUnexpectedEOF
143*1c12ee1eSDan Willemsen			}
144*1c12ee1eSDan Willemsen			return nil
145*1c12ee1eSDan Willemsen		default:
146*1c12ee1eSDan Willemsen			if checkDelims && typ == text.MessageClose {
147*1c12ee1eSDan Willemsen				return nil
148*1c12ee1eSDan Willemsen			}
149*1c12ee1eSDan Willemsen			return d.unexpectedTokenError(tok)
150*1c12ee1eSDan Willemsen		}
151*1c12ee1eSDan Willemsen
152*1c12ee1eSDan Willemsen		// Resolve the field descriptor.
153*1c12ee1eSDan Willemsen		var name protoreflect.Name
154*1c12ee1eSDan Willemsen		var fd protoreflect.FieldDescriptor
155*1c12ee1eSDan Willemsen		var xt protoreflect.ExtensionType
156*1c12ee1eSDan Willemsen		var xtErr error
157*1c12ee1eSDan Willemsen		var isFieldNumberName bool
158*1c12ee1eSDan Willemsen
159*1c12ee1eSDan Willemsen		switch tok.NameKind() {
160*1c12ee1eSDan Willemsen		case text.IdentName:
161*1c12ee1eSDan Willemsen			name = protoreflect.Name(tok.IdentName())
162*1c12ee1eSDan Willemsen			fd = fieldDescs.ByTextName(string(name))
163*1c12ee1eSDan Willemsen
164*1c12ee1eSDan Willemsen		case text.TypeName:
165*1c12ee1eSDan Willemsen			// Handle extensions only. This code path is not for Any.
166*1c12ee1eSDan Willemsen			xt, xtErr = d.opts.Resolver.FindExtensionByName(protoreflect.FullName(tok.TypeName()))
167*1c12ee1eSDan Willemsen
168*1c12ee1eSDan Willemsen		case text.FieldNumber:
169*1c12ee1eSDan Willemsen			isFieldNumberName = true
170*1c12ee1eSDan Willemsen			num := protoreflect.FieldNumber(tok.FieldNumber())
171*1c12ee1eSDan Willemsen			if !num.IsValid() {
172*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "invalid field number: %d", num)
173*1c12ee1eSDan Willemsen			}
174*1c12ee1eSDan Willemsen			fd = fieldDescs.ByNumber(num)
175*1c12ee1eSDan Willemsen			if fd == nil {
176*1c12ee1eSDan Willemsen				xt, xtErr = d.opts.Resolver.FindExtensionByNumber(messageDesc.FullName(), num)
177*1c12ee1eSDan Willemsen			}
178*1c12ee1eSDan Willemsen		}
179*1c12ee1eSDan Willemsen
180*1c12ee1eSDan Willemsen		if xt != nil {
181*1c12ee1eSDan Willemsen			fd = xt.TypeDescriptor()
182*1c12ee1eSDan Willemsen			if !messageDesc.ExtensionRanges().Has(fd.Number()) || fd.ContainingMessage().FullName() != messageDesc.FullName() {
183*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "message %v cannot be extended by %v", messageDesc.FullName(), fd.FullName())
184*1c12ee1eSDan Willemsen			}
185*1c12ee1eSDan Willemsen		} else if xtErr != nil && xtErr != protoregistry.NotFound {
186*1c12ee1eSDan Willemsen			return d.newError(tok.Pos(), "unable to resolve [%s]: %v", tok.RawString(), xtErr)
187*1c12ee1eSDan Willemsen		}
188*1c12ee1eSDan Willemsen		if flags.ProtoLegacy {
189*1c12ee1eSDan Willemsen			if fd != nil && fd.IsWeak() && fd.Message().IsPlaceholder() {
190*1c12ee1eSDan Willemsen				fd = nil // reset since the weak reference is not linked in
191*1c12ee1eSDan Willemsen			}
192*1c12ee1eSDan Willemsen		}
193*1c12ee1eSDan Willemsen
194*1c12ee1eSDan Willemsen		// Handle unknown fields.
195*1c12ee1eSDan Willemsen		if fd == nil {
196*1c12ee1eSDan Willemsen			if d.opts.DiscardUnknown || messageDesc.ReservedNames().Has(name) {
197*1c12ee1eSDan Willemsen				d.skipValue()
198*1c12ee1eSDan Willemsen				continue
199*1c12ee1eSDan Willemsen			}
200*1c12ee1eSDan Willemsen			return d.newError(tok.Pos(), "unknown field: %v", tok.RawString())
201*1c12ee1eSDan Willemsen		}
202*1c12ee1eSDan Willemsen
203*1c12ee1eSDan Willemsen		// Handle fields identified by field number.
204*1c12ee1eSDan Willemsen		if isFieldNumberName {
205*1c12ee1eSDan Willemsen			// TODO: Add an option to permit parsing field numbers.
206*1c12ee1eSDan Willemsen			//
207*1c12ee1eSDan Willemsen			// This requires careful thought as the MarshalOptions.EmitUnknown
208*1c12ee1eSDan Willemsen			// option allows formatting unknown fields as the field number and the
209*1c12ee1eSDan Willemsen			// best-effort textual representation of the field value.  In that case,
210*1c12ee1eSDan Willemsen			// it may not be possible to unmarshal the value from a parser that does
211*1c12ee1eSDan Willemsen			// have information about the unknown field.
212*1c12ee1eSDan Willemsen			return d.newError(tok.Pos(), "cannot specify field by number: %v", tok.RawString())
213*1c12ee1eSDan Willemsen		}
214*1c12ee1eSDan Willemsen
215*1c12ee1eSDan Willemsen		switch {
216*1c12ee1eSDan Willemsen		case fd.IsList():
217*1c12ee1eSDan Willemsen			kind := fd.Kind()
218*1c12ee1eSDan Willemsen			if kind != protoreflect.MessageKind && kind != protoreflect.GroupKind && !tok.HasSeparator() {
219*1c12ee1eSDan Willemsen				return d.syntaxError(tok.Pos(), "missing field separator :")
220*1c12ee1eSDan Willemsen			}
221*1c12ee1eSDan Willemsen
222*1c12ee1eSDan Willemsen			list := m.Mutable(fd).List()
223*1c12ee1eSDan Willemsen			if err := d.unmarshalList(fd, list); err != nil {
224*1c12ee1eSDan Willemsen				return err
225*1c12ee1eSDan Willemsen			}
226*1c12ee1eSDan Willemsen
227*1c12ee1eSDan Willemsen		case fd.IsMap():
228*1c12ee1eSDan Willemsen			mmap := m.Mutable(fd).Map()
229*1c12ee1eSDan Willemsen			if err := d.unmarshalMap(fd, mmap); err != nil {
230*1c12ee1eSDan Willemsen				return err
231*1c12ee1eSDan Willemsen			}
232*1c12ee1eSDan Willemsen
233*1c12ee1eSDan Willemsen		default:
234*1c12ee1eSDan Willemsen			kind := fd.Kind()
235*1c12ee1eSDan Willemsen			if kind != protoreflect.MessageKind && kind != protoreflect.GroupKind && !tok.HasSeparator() {
236*1c12ee1eSDan Willemsen				return d.syntaxError(tok.Pos(), "missing field separator :")
237*1c12ee1eSDan Willemsen			}
238*1c12ee1eSDan Willemsen
239*1c12ee1eSDan Willemsen			// If field is a oneof, check if it has already been set.
240*1c12ee1eSDan Willemsen			if od := fd.ContainingOneof(); od != nil {
241*1c12ee1eSDan Willemsen				idx := uint64(od.Index())
242*1c12ee1eSDan Willemsen				if seenOneofs.Has(idx) {
243*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "error parsing %q, oneof %v is already set", tok.RawString(), od.FullName())
244*1c12ee1eSDan Willemsen				}
245*1c12ee1eSDan Willemsen				seenOneofs.Set(idx)
246*1c12ee1eSDan Willemsen			}
247*1c12ee1eSDan Willemsen
248*1c12ee1eSDan Willemsen			num := uint64(fd.Number())
249*1c12ee1eSDan Willemsen			if seenNums.Has(num) {
250*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "non-repeated field %q is repeated", tok.RawString())
251*1c12ee1eSDan Willemsen			}
252*1c12ee1eSDan Willemsen
253*1c12ee1eSDan Willemsen			if err := d.unmarshalSingular(fd, m); err != nil {
254*1c12ee1eSDan Willemsen				return err
255*1c12ee1eSDan Willemsen			}
256*1c12ee1eSDan Willemsen			seenNums.Set(num)
257*1c12ee1eSDan Willemsen		}
258*1c12ee1eSDan Willemsen	}
259*1c12ee1eSDan Willemsen
260*1c12ee1eSDan Willemsen	return nil
261*1c12ee1eSDan Willemsen}
262*1c12ee1eSDan Willemsen
263*1c12ee1eSDan Willemsen// unmarshalSingular unmarshals a non-repeated field value specified by the
264*1c12ee1eSDan Willemsen// given FieldDescriptor.
265*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalSingular(fd protoreflect.FieldDescriptor, m protoreflect.Message) error {
266*1c12ee1eSDan Willemsen	var val protoreflect.Value
267*1c12ee1eSDan Willemsen	var err error
268*1c12ee1eSDan Willemsen	switch fd.Kind() {
269*1c12ee1eSDan Willemsen	case protoreflect.MessageKind, protoreflect.GroupKind:
270*1c12ee1eSDan Willemsen		val = m.NewField(fd)
271*1c12ee1eSDan Willemsen		err = d.unmarshalMessage(val.Message(), true)
272*1c12ee1eSDan Willemsen	default:
273*1c12ee1eSDan Willemsen		val, err = d.unmarshalScalar(fd)
274*1c12ee1eSDan Willemsen	}
275*1c12ee1eSDan Willemsen	if err == nil {
276*1c12ee1eSDan Willemsen		m.Set(fd, val)
277*1c12ee1eSDan Willemsen	}
278*1c12ee1eSDan Willemsen	return err
279*1c12ee1eSDan Willemsen}
280*1c12ee1eSDan Willemsen
281*1c12ee1eSDan Willemsen// unmarshalScalar unmarshals a scalar/enum protoreflect.Value specified by the
282*1c12ee1eSDan Willemsen// given FieldDescriptor.
283*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalScalar(fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
284*1c12ee1eSDan Willemsen	tok, err := d.Read()
285*1c12ee1eSDan Willemsen	if err != nil {
286*1c12ee1eSDan Willemsen		return protoreflect.Value{}, err
287*1c12ee1eSDan Willemsen	}
288*1c12ee1eSDan Willemsen
289*1c12ee1eSDan Willemsen	if tok.Kind() != text.Scalar {
290*1c12ee1eSDan Willemsen		return protoreflect.Value{}, d.unexpectedTokenError(tok)
291*1c12ee1eSDan Willemsen	}
292*1c12ee1eSDan Willemsen
293*1c12ee1eSDan Willemsen	kind := fd.Kind()
294*1c12ee1eSDan Willemsen	switch kind {
295*1c12ee1eSDan Willemsen	case protoreflect.BoolKind:
296*1c12ee1eSDan Willemsen		if b, ok := tok.Bool(); ok {
297*1c12ee1eSDan Willemsen			return protoreflect.ValueOfBool(b), nil
298*1c12ee1eSDan Willemsen		}
299*1c12ee1eSDan Willemsen
300*1c12ee1eSDan Willemsen	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
301*1c12ee1eSDan Willemsen		if n, ok := tok.Int32(); ok {
302*1c12ee1eSDan Willemsen			return protoreflect.ValueOfInt32(n), nil
303*1c12ee1eSDan Willemsen		}
304*1c12ee1eSDan Willemsen
305*1c12ee1eSDan Willemsen	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
306*1c12ee1eSDan Willemsen		if n, ok := tok.Int64(); ok {
307*1c12ee1eSDan Willemsen			return protoreflect.ValueOfInt64(n), nil
308*1c12ee1eSDan Willemsen		}
309*1c12ee1eSDan Willemsen
310*1c12ee1eSDan Willemsen	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
311*1c12ee1eSDan Willemsen		if n, ok := tok.Uint32(); ok {
312*1c12ee1eSDan Willemsen			return protoreflect.ValueOfUint32(n), nil
313*1c12ee1eSDan Willemsen		}
314*1c12ee1eSDan Willemsen
315*1c12ee1eSDan Willemsen	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
316*1c12ee1eSDan Willemsen		if n, ok := tok.Uint64(); ok {
317*1c12ee1eSDan Willemsen			return protoreflect.ValueOfUint64(n), nil
318*1c12ee1eSDan Willemsen		}
319*1c12ee1eSDan Willemsen
320*1c12ee1eSDan Willemsen	case protoreflect.FloatKind:
321*1c12ee1eSDan Willemsen		if n, ok := tok.Float32(); ok {
322*1c12ee1eSDan Willemsen			return protoreflect.ValueOfFloat32(n), nil
323*1c12ee1eSDan Willemsen		}
324*1c12ee1eSDan Willemsen
325*1c12ee1eSDan Willemsen	case protoreflect.DoubleKind:
326*1c12ee1eSDan Willemsen		if n, ok := tok.Float64(); ok {
327*1c12ee1eSDan Willemsen			return protoreflect.ValueOfFloat64(n), nil
328*1c12ee1eSDan Willemsen		}
329*1c12ee1eSDan Willemsen
330*1c12ee1eSDan Willemsen	case protoreflect.StringKind:
331*1c12ee1eSDan Willemsen		if s, ok := tok.String(); ok {
332*1c12ee1eSDan Willemsen			if strs.EnforceUTF8(fd) && !utf8.ValidString(s) {
333*1c12ee1eSDan Willemsen				return protoreflect.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8")
334*1c12ee1eSDan Willemsen			}
335*1c12ee1eSDan Willemsen			return protoreflect.ValueOfString(s), nil
336*1c12ee1eSDan Willemsen		}
337*1c12ee1eSDan Willemsen
338*1c12ee1eSDan Willemsen	case protoreflect.BytesKind:
339*1c12ee1eSDan Willemsen		if b, ok := tok.String(); ok {
340*1c12ee1eSDan Willemsen			return protoreflect.ValueOfBytes([]byte(b)), nil
341*1c12ee1eSDan Willemsen		}
342*1c12ee1eSDan Willemsen
343*1c12ee1eSDan Willemsen	case protoreflect.EnumKind:
344*1c12ee1eSDan Willemsen		if lit, ok := tok.Enum(); ok {
345*1c12ee1eSDan Willemsen			// Lookup EnumNumber based on name.
346*1c12ee1eSDan Willemsen			if enumVal := fd.Enum().Values().ByName(protoreflect.Name(lit)); enumVal != nil {
347*1c12ee1eSDan Willemsen				return protoreflect.ValueOfEnum(enumVal.Number()), nil
348*1c12ee1eSDan Willemsen			}
349*1c12ee1eSDan Willemsen		}
350*1c12ee1eSDan Willemsen		if num, ok := tok.Int32(); ok {
351*1c12ee1eSDan Willemsen			return protoreflect.ValueOfEnum(protoreflect.EnumNumber(num)), nil
352*1c12ee1eSDan Willemsen		}
353*1c12ee1eSDan Willemsen
354*1c12ee1eSDan Willemsen	default:
355*1c12ee1eSDan Willemsen		panic(fmt.Sprintf("invalid scalar kind %v", kind))
356*1c12ee1eSDan Willemsen	}
357*1c12ee1eSDan Willemsen
358*1c12ee1eSDan Willemsen	return protoreflect.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString())
359*1c12ee1eSDan Willemsen}
360*1c12ee1eSDan Willemsen
361*1c12ee1eSDan Willemsen// unmarshalList unmarshals into given protoreflect.List. A list value can
362*1c12ee1eSDan Willemsen// either be in [] syntax or simply just a single scalar/message value.
363*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflect.List) error {
364*1c12ee1eSDan Willemsen	tok, err := d.Peek()
365*1c12ee1eSDan Willemsen	if err != nil {
366*1c12ee1eSDan Willemsen		return err
367*1c12ee1eSDan Willemsen	}
368*1c12ee1eSDan Willemsen
369*1c12ee1eSDan Willemsen	switch fd.Kind() {
370*1c12ee1eSDan Willemsen	case protoreflect.MessageKind, protoreflect.GroupKind:
371*1c12ee1eSDan Willemsen		switch tok.Kind() {
372*1c12ee1eSDan Willemsen		case text.ListOpen:
373*1c12ee1eSDan Willemsen			d.Read()
374*1c12ee1eSDan Willemsen			for {
375*1c12ee1eSDan Willemsen				tok, err := d.Peek()
376*1c12ee1eSDan Willemsen				if err != nil {
377*1c12ee1eSDan Willemsen					return err
378*1c12ee1eSDan Willemsen				}
379*1c12ee1eSDan Willemsen
380*1c12ee1eSDan Willemsen				switch tok.Kind() {
381*1c12ee1eSDan Willemsen				case text.ListClose:
382*1c12ee1eSDan Willemsen					d.Read()
383*1c12ee1eSDan Willemsen					return nil
384*1c12ee1eSDan Willemsen				case text.MessageOpen:
385*1c12ee1eSDan Willemsen					pval := list.NewElement()
386*1c12ee1eSDan Willemsen					if err := d.unmarshalMessage(pval.Message(), true); err != nil {
387*1c12ee1eSDan Willemsen						return err
388*1c12ee1eSDan Willemsen					}
389*1c12ee1eSDan Willemsen					list.Append(pval)
390*1c12ee1eSDan Willemsen				default:
391*1c12ee1eSDan Willemsen					return d.unexpectedTokenError(tok)
392*1c12ee1eSDan Willemsen				}
393*1c12ee1eSDan Willemsen			}
394*1c12ee1eSDan Willemsen
395*1c12ee1eSDan Willemsen		case text.MessageOpen:
396*1c12ee1eSDan Willemsen			pval := list.NewElement()
397*1c12ee1eSDan Willemsen			if err := d.unmarshalMessage(pval.Message(), true); err != nil {
398*1c12ee1eSDan Willemsen				return err
399*1c12ee1eSDan Willemsen			}
400*1c12ee1eSDan Willemsen			list.Append(pval)
401*1c12ee1eSDan Willemsen			return nil
402*1c12ee1eSDan Willemsen		}
403*1c12ee1eSDan Willemsen
404*1c12ee1eSDan Willemsen	default:
405*1c12ee1eSDan Willemsen		switch tok.Kind() {
406*1c12ee1eSDan Willemsen		case text.ListOpen:
407*1c12ee1eSDan Willemsen			d.Read()
408*1c12ee1eSDan Willemsen			for {
409*1c12ee1eSDan Willemsen				tok, err := d.Peek()
410*1c12ee1eSDan Willemsen				if err != nil {
411*1c12ee1eSDan Willemsen					return err
412*1c12ee1eSDan Willemsen				}
413*1c12ee1eSDan Willemsen
414*1c12ee1eSDan Willemsen				switch tok.Kind() {
415*1c12ee1eSDan Willemsen				case text.ListClose:
416*1c12ee1eSDan Willemsen					d.Read()
417*1c12ee1eSDan Willemsen					return nil
418*1c12ee1eSDan Willemsen				case text.Scalar:
419*1c12ee1eSDan Willemsen					pval, err := d.unmarshalScalar(fd)
420*1c12ee1eSDan Willemsen					if err != nil {
421*1c12ee1eSDan Willemsen						return err
422*1c12ee1eSDan Willemsen					}
423*1c12ee1eSDan Willemsen					list.Append(pval)
424*1c12ee1eSDan Willemsen				default:
425*1c12ee1eSDan Willemsen					return d.unexpectedTokenError(tok)
426*1c12ee1eSDan Willemsen				}
427*1c12ee1eSDan Willemsen			}
428*1c12ee1eSDan Willemsen
429*1c12ee1eSDan Willemsen		case text.Scalar:
430*1c12ee1eSDan Willemsen			pval, err := d.unmarshalScalar(fd)
431*1c12ee1eSDan Willemsen			if err != nil {
432*1c12ee1eSDan Willemsen				return err
433*1c12ee1eSDan Willemsen			}
434*1c12ee1eSDan Willemsen			list.Append(pval)
435*1c12ee1eSDan Willemsen			return nil
436*1c12ee1eSDan Willemsen		}
437*1c12ee1eSDan Willemsen	}
438*1c12ee1eSDan Willemsen
439*1c12ee1eSDan Willemsen	return d.unexpectedTokenError(tok)
440*1c12ee1eSDan Willemsen}
441*1c12ee1eSDan Willemsen
442*1c12ee1eSDan Willemsen// unmarshalMap unmarshals into given protoreflect.Map. A map value is a
443*1c12ee1eSDan Willemsen// textproto message containing {key: <kvalue>, value: <mvalue>}.
444*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error {
445*1c12ee1eSDan Willemsen	// Determine ahead whether map entry is a scalar type or a message type in
446*1c12ee1eSDan Willemsen	// order to call the appropriate unmarshalMapValue func inside
447*1c12ee1eSDan Willemsen	// unmarshalMapEntry.
448*1c12ee1eSDan Willemsen	var unmarshalMapValue func() (protoreflect.Value, error)
449*1c12ee1eSDan Willemsen	switch fd.MapValue().Kind() {
450*1c12ee1eSDan Willemsen	case protoreflect.MessageKind, protoreflect.GroupKind:
451*1c12ee1eSDan Willemsen		unmarshalMapValue = func() (protoreflect.Value, error) {
452*1c12ee1eSDan Willemsen			pval := mmap.NewValue()
453*1c12ee1eSDan Willemsen			if err := d.unmarshalMessage(pval.Message(), true); err != nil {
454*1c12ee1eSDan Willemsen				return protoreflect.Value{}, err
455*1c12ee1eSDan Willemsen			}
456*1c12ee1eSDan Willemsen			return pval, nil
457*1c12ee1eSDan Willemsen		}
458*1c12ee1eSDan Willemsen	default:
459*1c12ee1eSDan Willemsen		unmarshalMapValue = func() (protoreflect.Value, error) {
460*1c12ee1eSDan Willemsen			return d.unmarshalScalar(fd.MapValue())
461*1c12ee1eSDan Willemsen		}
462*1c12ee1eSDan Willemsen	}
463*1c12ee1eSDan Willemsen
464*1c12ee1eSDan Willemsen	tok, err := d.Read()
465*1c12ee1eSDan Willemsen	if err != nil {
466*1c12ee1eSDan Willemsen		return err
467*1c12ee1eSDan Willemsen	}
468*1c12ee1eSDan Willemsen	switch tok.Kind() {
469*1c12ee1eSDan Willemsen	case text.MessageOpen:
470*1c12ee1eSDan Willemsen		return d.unmarshalMapEntry(fd, mmap, unmarshalMapValue)
471*1c12ee1eSDan Willemsen
472*1c12ee1eSDan Willemsen	case text.ListOpen:
473*1c12ee1eSDan Willemsen		for {
474*1c12ee1eSDan Willemsen			tok, err := d.Read()
475*1c12ee1eSDan Willemsen			if err != nil {
476*1c12ee1eSDan Willemsen				return err
477*1c12ee1eSDan Willemsen			}
478*1c12ee1eSDan Willemsen			switch tok.Kind() {
479*1c12ee1eSDan Willemsen			case text.ListClose:
480*1c12ee1eSDan Willemsen				return nil
481*1c12ee1eSDan Willemsen			case text.MessageOpen:
482*1c12ee1eSDan Willemsen				if err := d.unmarshalMapEntry(fd, mmap, unmarshalMapValue); err != nil {
483*1c12ee1eSDan Willemsen					return err
484*1c12ee1eSDan Willemsen				}
485*1c12ee1eSDan Willemsen			default:
486*1c12ee1eSDan Willemsen				return d.unexpectedTokenError(tok)
487*1c12ee1eSDan Willemsen			}
488*1c12ee1eSDan Willemsen		}
489*1c12ee1eSDan Willemsen
490*1c12ee1eSDan Willemsen	default:
491*1c12ee1eSDan Willemsen		return d.unexpectedTokenError(tok)
492*1c12ee1eSDan Willemsen	}
493*1c12ee1eSDan Willemsen}
494*1c12ee1eSDan Willemsen
495*1c12ee1eSDan Willemsen// unmarshalMap unmarshals into given protoreflect.Map. A map value is a
496*1c12ee1eSDan Willemsen// textproto message containing {key: <kvalue>, value: <mvalue>}.
497*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalMapEntry(fd protoreflect.FieldDescriptor, mmap protoreflect.Map, unmarshalMapValue func() (protoreflect.Value, error)) error {
498*1c12ee1eSDan Willemsen	var key protoreflect.MapKey
499*1c12ee1eSDan Willemsen	var pval protoreflect.Value
500*1c12ee1eSDan WillemsenLoop:
501*1c12ee1eSDan Willemsen	for {
502*1c12ee1eSDan Willemsen		// Read field name.
503*1c12ee1eSDan Willemsen		tok, err := d.Read()
504*1c12ee1eSDan Willemsen		if err != nil {
505*1c12ee1eSDan Willemsen			return err
506*1c12ee1eSDan Willemsen		}
507*1c12ee1eSDan Willemsen		switch tok.Kind() {
508*1c12ee1eSDan Willemsen		case text.Name:
509*1c12ee1eSDan Willemsen			if tok.NameKind() != text.IdentName {
510*1c12ee1eSDan Willemsen				if !d.opts.DiscardUnknown {
511*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "unknown map entry field %q", tok.RawString())
512*1c12ee1eSDan Willemsen				}
513*1c12ee1eSDan Willemsen				d.skipValue()
514*1c12ee1eSDan Willemsen				continue Loop
515*1c12ee1eSDan Willemsen			}
516*1c12ee1eSDan Willemsen			// Continue below.
517*1c12ee1eSDan Willemsen		case text.MessageClose:
518*1c12ee1eSDan Willemsen			break Loop
519*1c12ee1eSDan Willemsen		default:
520*1c12ee1eSDan Willemsen			return d.unexpectedTokenError(tok)
521*1c12ee1eSDan Willemsen		}
522*1c12ee1eSDan Willemsen
523*1c12ee1eSDan Willemsen		switch name := protoreflect.Name(tok.IdentName()); name {
524*1c12ee1eSDan Willemsen		case genid.MapEntry_Key_field_name:
525*1c12ee1eSDan Willemsen			if !tok.HasSeparator() {
526*1c12ee1eSDan Willemsen				return d.syntaxError(tok.Pos(), "missing field separator :")
527*1c12ee1eSDan Willemsen			}
528*1c12ee1eSDan Willemsen			if key.IsValid() {
529*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "map entry %q cannot be repeated", name)
530*1c12ee1eSDan Willemsen			}
531*1c12ee1eSDan Willemsen			val, err := d.unmarshalScalar(fd.MapKey())
532*1c12ee1eSDan Willemsen			if err != nil {
533*1c12ee1eSDan Willemsen				return err
534*1c12ee1eSDan Willemsen			}
535*1c12ee1eSDan Willemsen			key = val.MapKey()
536*1c12ee1eSDan Willemsen
537*1c12ee1eSDan Willemsen		case genid.MapEntry_Value_field_name:
538*1c12ee1eSDan Willemsen			if kind := fd.MapValue().Kind(); (kind != protoreflect.MessageKind) && (kind != protoreflect.GroupKind) {
539*1c12ee1eSDan Willemsen				if !tok.HasSeparator() {
540*1c12ee1eSDan Willemsen					return d.syntaxError(tok.Pos(), "missing field separator :")
541*1c12ee1eSDan Willemsen				}
542*1c12ee1eSDan Willemsen			}
543*1c12ee1eSDan Willemsen			if pval.IsValid() {
544*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "map entry %q cannot be repeated", name)
545*1c12ee1eSDan Willemsen			}
546*1c12ee1eSDan Willemsen			pval, err = unmarshalMapValue()
547*1c12ee1eSDan Willemsen			if err != nil {
548*1c12ee1eSDan Willemsen				return err
549*1c12ee1eSDan Willemsen			}
550*1c12ee1eSDan Willemsen
551*1c12ee1eSDan Willemsen		default:
552*1c12ee1eSDan Willemsen			if !d.opts.DiscardUnknown {
553*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "unknown map entry field %q", name)
554*1c12ee1eSDan Willemsen			}
555*1c12ee1eSDan Willemsen			d.skipValue()
556*1c12ee1eSDan Willemsen		}
557*1c12ee1eSDan Willemsen	}
558*1c12ee1eSDan Willemsen
559*1c12ee1eSDan Willemsen	if !key.IsValid() {
560*1c12ee1eSDan Willemsen		key = fd.MapKey().Default().MapKey()
561*1c12ee1eSDan Willemsen	}
562*1c12ee1eSDan Willemsen	if !pval.IsValid() {
563*1c12ee1eSDan Willemsen		switch fd.MapValue().Kind() {
564*1c12ee1eSDan Willemsen		case protoreflect.MessageKind, protoreflect.GroupKind:
565*1c12ee1eSDan Willemsen			// If value field is not set for message/group types, construct an
566*1c12ee1eSDan Willemsen			// empty one as default.
567*1c12ee1eSDan Willemsen			pval = mmap.NewValue()
568*1c12ee1eSDan Willemsen		default:
569*1c12ee1eSDan Willemsen			pval = fd.MapValue().Default()
570*1c12ee1eSDan Willemsen		}
571*1c12ee1eSDan Willemsen	}
572*1c12ee1eSDan Willemsen	mmap.Set(key, pval)
573*1c12ee1eSDan Willemsen	return nil
574*1c12ee1eSDan Willemsen}
575*1c12ee1eSDan Willemsen
576*1c12ee1eSDan Willemsen// unmarshalAny unmarshals an Any textproto. It can either be in expanded form
577*1c12ee1eSDan Willemsen// or non-expanded form.
578*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalAny(m protoreflect.Message, checkDelims bool) error {
579*1c12ee1eSDan Willemsen	var typeURL string
580*1c12ee1eSDan Willemsen	var bValue []byte
581*1c12ee1eSDan Willemsen	var seenTypeUrl bool
582*1c12ee1eSDan Willemsen	var seenValue bool
583*1c12ee1eSDan Willemsen	var isExpanded bool
584*1c12ee1eSDan Willemsen
585*1c12ee1eSDan Willemsen	if checkDelims {
586*1c12ee1eSDan Willemsen		tok, err := d.Read()
587*1c12ee1eSDan Willemsen		if err != nil {
588*1c12ee1eSDan Willemsen			return err
589*1c12ee1eSDan Willemsen		}
590*1c12ee1eSDan Willemsen
591*1c12ee1eSDan Willemsen		if tok.Kind() != text.MessageOpen {
592*1c12ee1eSDan Willemsen			return d.unexpectedTokenError(tok)
593*1c12ee1eSDan Willemsen		}
594*1c12ee1eSDan Willemsen	}
595*1c12ee1eSDan Willemsen
596*1c12ee1eSDan WillemsenLoop:
597*1c12ee1eSDan Willemsen	for {
598*1c12ee1eSDan Willemsen		// Read field name. Can only have 3 possible field names, i.e. type_url,
599*1c12ee1eSDan Willemsen		// value and type URL name inside [].
600*1c12ee1eSDan Willemsen		tok, err := d.Read()
601*1c12ee1eSDan Willemsen		if err != nil {
602*1c12ee1eSDan Willemsen			return err
603*1c12ee1eSDan Willemsen		}
604*1c12ee1eSDan Willemsen		if typ := tok.Kind(); typ != text.Name {
605*1c12ee1eSDan Willemsen			if checkDelims {
606*1c12ee1eSDan Willemsen				if typ == text.MessageClose {
607*1c12ee1eSDan Willemsen					break Loop
608*1c12ee1eSDan Willemsen				}
609*1c12ee1eSDan Willemsen			} else if typ == text.EOF {
610*1c12ee1eSDan Willemsen				break Loop
611*1c12ee1eSDan Willemsen			}
612*1c12ee1eSDan Willemsen			return d.unexpectedTokenError(tok)
613*1c12ee1eSDan Willemsen		}
614*1c12ee1eSDan Willemsen
615*1c12ee1eSDan Willemsen		switch tok.NameKind() {
616*1c12ee1eSDan Willemsen		case text.IdentName:
617*1c12ee1eSDan Willemsen			// Both type_url and value fields require field separator :.
618*1c12ee1eSDan Willemsen			if !tok.HasSeparator() {
619*1c12ee1eSDan Willemsen				return d.syntaxError(tok.Pos(), "missing field separator :")
620*1c12ee1eSDan Willemsen			}
621*1c12ee1eSDan Willemsen
622*1c12ee1eSDan Willemsen			switch name := protoreflect.Name(tok.IdentName()); name {
623*1c12ee1eSDan Willemsen			case genid.Any_TypeUrl_field_name:
624*1c12ee1eSDan Willemsen				if seenTypeUrl {
625*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "duplicate %v field", genid.Any_TypeUrl_field_fullname)
626*1c12ee1eSDan Willemsen				}
627*1c12ee1eSDan Willemsen				if isExpanded {
628*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "conflict with [%s] field", typeURL)
629*1c12ee1eSDan Willemsen				}
630*1c12ee1eSDan Willemsen				tok, err := d.Read()
631*1c12ee1eSDan Willemsen				if err != nil {
632*1c12ee1eSDan Willemsen					return err
633*1c12ee1eSDan Willemsen				}
634*1c12ee1eSDan Willemsen				var ok bool
635*1c12ee1eSDan Willemsen				typeURL, ok = tok.String()
636*1c12ee1eSDan Willemsen				if !ok {
637*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "invalid %v field value: %v", genid.Any_TypeUrl_field_fullname, tok.RawString())
638*1c12ee1eSDan Willemsen				}
639*1c12ee1eSDan Willemsen				seenTypeUrl = true
640*1c12ee1eSDan Willemsen
641*1c12ee1eSDan Willemsen			case genid.Any_Value_field_name:
642*1c12ee1eSDan Willemsen				if seenValue {
643*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "duplicate %v field", genid.Any_Value_field_fullname)
644*1c12ee1eSDan Willemsen				}
645*1c12ee1eSDan Willemsen				if isExpanded {
646*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "conflict with [%s] field", typeURL)
647*1c12ee1eSDan Willemsen				}
648*1c12ee1eSDan Willemsen				tok, err := d.Read()
649*1c12ee1eSDan Willemsen				if err != nil {
650*1c12ee1eSDan Willemsen					return err
651*1c12ee1eSDan Willemsen				}
652*1c12ee1eSDan Willemsen				s, ok := tok.String()
653*1c12ee1eSDan Willemsen				if !ok {
654*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "invalid %v field value: %v", genid.Any_Value_field_fullname, tok.RawString())
655*1c12ee1eSDan Willemsen				}
656*1c12ee1eSDan Willemsen				bValue = []byte(s)
657*1c12ee1eSDan Willemsen				seenValue = true
658*1c12ee1eSDan Willemsen
659*1c12ee1eSDan Willemsen			default:
660*1c12ee1eSDan Willemsen				if !d.opts.DiscardUnknown {
661*1c12ee1eSDan Willemsen					return d.newError(tok.Pos(), "invalid field name %q in %v message", tok.RawString(), genid.Any_message_fullname)
662*1c12ee1eSDan Willemsen				}
663*1c12ee1eSDan Willemsen			}
664*1c12ee1eSDan Willemsen
665*1c12ee1eSDan Willemsen		case text.TypeName:
666*1c12ee1eSDan Willemsen			if isExpanded {
667*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "cannot have more than one type")
668*1c12ee1eSDan Willemsen			}
669*1c12ee1eSDan Willemsen			if seenTypeUrl {
670*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "conflict with type_url field")
671*1c12ee1eSDan Willemsen			}
672*1c12ee1eSDan Willemsen			typeURL = tok.TypeName()
673*1c12ee1eSDan Willemsen			var err error
674*1c12ee1eSDan Willemsen			bValue, err = d.unmarshalExpandedAny(typeURL, tok.Pos())
675*1c12ee1eSDan Willemsen			if err != nil {
676*1c12ee1eSDan Willemsen				return err
677*1c12ee1eSDan Willemsen			}
678*1c12ee1eSDan Willemsen			isExpanded = true
679*1c12ee1eSDan Willemsen
680*1c12ee1eSDan Willemsen		default:
681*1c12ee1eSDan Willemsen			if !d.opts.DiscardUnknown {
682*1c12ee1eSDan Willemsen				return d.newError(tok.Pos(), "invalid field name %q in %v message", tok.RawString(), genid.Any_message_fullname)
683*1c12ee1eSDan Willemsen			}
684*1c12ee1eSDan Willemsen		}
685*1c12ee1eSDan Willemsen	}
686*1c12ee1eSDan Willemsen
687*1c12ee1eSDan Willemsen	fds := m.Descriptor().Fields()
688*1c12ee1eSDan Willemsen	if len(typeURL) > 0 {
689*1c12ee1eSDan Willemsen		m.Set(fds.ByNumber(genid.Any_TypeUrl_field_number), protoreflect.ValueOfString(typeURL))
690*1c12ee1eSDan Willemsen	}
691*1c12ee1eSDan Willemsen	if len(bValue) > 0 {
692*1c12ee1eSDan Willemsen		m.Set(fds.ByNumber(genid.Any_Value_field_number), protoreflect.ValueOfBytes(bValue))
693*1c12ee1eSDan Willemsen	}
694*1c12ee1eSDan Willemsen	return nil
695*1c12ee1eSDan Willemsen}
696*1c12ee1eSDan Willemsen
697*1c12ee1eSDan Willemsenfunc (d decoder) unmarshalExpandedAny(typeURL string, pos int) ([]byte, error) {
698*1c12ee1eSDan Willemsen	mt, err := d.opts.Resolver.FindMessageByURL(typeURL)
699*1c12ee1eSDan Willemsen	if err != nil {
700*1c12ee1eSDan Willemsen		return nil, d.newError(pos, "unable to resolve message [%v]: %v", typeURL, err)
701*1c12ee1eSDan Willemsen	}
702*1c12ee1eSDan Willemsen	// Create new message for the embedded message type and unmarshal the value
703*1c12ee1eSDan Willemsen	// field into it.
704*1c12ee1eSDan Willemsen	m := mt.New()
705*1c12ee1eSDan Willemsen	if err := d.unmarshalMessage(m, true); err != nil {
706*1c12ee1eSDan Willemsen		return nil, err
707*1c12ee1eSDan Willemsen	}
708*1c12ee1eSDan Willemsen	// Serialize the embedded message and return the resulting bytes.
709*1c12ee1eSDan Willemsen	b, err := proto.MarshalOptions{
710*1c12ee1eSDan Willemsen		AllowPartial:  true, // Never check required fields inside an Any.
711*1c12ee1eSDan Willemsen		Deterministic: true,
712*1c12ee1eSDan Willemsen	}.Marshal(m.Interface())
713*1c12ee1eSDan Willemsen	if err != nil {
714*1c12ee1eSDan Willemsen		return nil, d.newError(pos, "error in marshaling message into Any.value: %v", err)
715*1c12ee1eSDan Willemsen	}
716*1c12ee1eSDan Willemsen	return b, nil
717*1c12ee1eSDan Willemsen}
718*1c12ee1eSDan Willemsen
719*1c12ee1eSDan Willemsen// skipValue makes the decoder parse a field value in order to advance the read
720*1c12ee1eSDan Willemsen// to the next field. It relies on Read returning an error if the types are not
721*1c12ee1eSDan Willemsen// in valid sequence.
722*1c12ee1eSDan Willemsenfunc (d decoder) skipValue() error {
723*1c12ee1eSDan Willemsen	tok, err := d.Read()
724*1c12ee1eSDan Willemsen	if err != nil {
725*1c12ee1eSDan Willemsen		return err
726*1c12ee1eSDan Willemsen	}
727*1c12ee1eSDan Willemsen	// Only need to continue reading for messages and lists.
728*1c12ee1eSDan Willemsen	switch tok.Kind() {
729*1c12ee1eSDan Willemsen	case text.MessageOpen:
730*1c12ee1eSDan Willemsen		return d.skipMessageValue()
731*1c12ee1eSDan Willemsen
732*1c12ee1eSDan Willemsen	case text.ListOpen:
733*1c12ee1eSDan Willemsen		for {
734*1c12ee1eSDan Willemsen			tok, err := d.Read()
735*1c12ee1eSDan Willemsen			if err != nil {
736*1c12ee1eSDan Willemsen				return err
737*1c12ee1eSDan Willemsen			}
738*1c12ee1eSDan Willemsen			switch tok.Kind() {
739*1c12ee1eSDan Willemsen			case text.ListClose:
740*1c12ee1eSDan Willemsen				return nil
741*1c12ee1eSDan Willemsen			case text.MessageOpen:
742*1c12ee1eSDan Willemsen				return d.skipMessageValue()
743*1c12ee1eSDan Willemsen			default:
744*1c12ee1eSDan Willemsen				// Skip items. This will not validate whether skipped values are
745*1c12ee1eSDan Willemsen				// of the same type or not, same behavior as C++
746*1c12ee1eSDan Willemsen				// TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
747*1c12ee1eSDan Willemsen			}
748*1c12ee1eSDan Willemsen		}
749*1c12ee1eSDan Willemsen	}
750*1c12ee1eSDan Willemsen	return nil
751*1c12ee1eSDan Willemsen}
752*1c12ee1eSDan Willemsen
753*1c12ee1eSDan Willemsen// skipMessageValue makes the decoder parse and skip over all fields in a
754*1c12ee1eSDan Willemsen// message. It assumes that the previous read type is MessageOpen.
755*1c12ee1eSDan Willemsenfunc (d decoder) skipMessageValue() error {
756*1c12ee1eSDan Willemsen	for {
757*1c12ee1eSDan Willemsen		tok, err := d.Read()
758*1c12ee1eSDan Willemsen		if err != nil {
759*1c12ee1eSDan Willemsen			return err
760*1c12ee1eSDan Willemsen		}
761*1c12ee1eSDan Willemsen		switch tok.Kind() {
762*1c12ee1eSDan Willemsen		case text.MessageClose:
763*1c12ee1eSDan Willemsen			return nil
764*1c12ee1eSDan Willemsen		case text.Name:
765*1c12ee1eSDan Willemsen			if err := d.skipValue(); err != nil {
766*1c12ee1eSDan Willemsen				return err
767*1c12ee1eSDan Willemsen			}
768*1c12ee1eSDan Willemsen		}
769*1c12ee1eSDan Willemsen	}
770*1c12ee1eSDan Willemsen}
771