...

Source file src/google.golang.org/protobuf/encoding/prototext/decode.go

Documentation: google.golang.org/protobuf/encoding/prototext

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

View as plain text