func()

in proto/text_decode.go [91:169]


func (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) {
	md := m.Descriptor()
	fds := md.Fields()

	// A struct is a sequence of "name: value", terminated by one of
	// '>' or '}', or the end of the input.  A name may also be
	// "[extension]" or "[type/url]".
	//
	// The whole struct can also be an expanded Any message, like:
	// [type/url] < ... struct contents ... >
	seen := make(map[protoreflect.FieldNumber]bool)
	for {
		tok := p.next()
		if tok.err != nil {
			return tok.err
		}
		if tok.value == terminator {
			break
		}
		if tok.value == "[" {
			if err := p.unmarshalExtensionOrAny(m, seen); err != nil {
				return err
			}
			continue
		}

		// This is a normal, non-extension field.
		name := protoreflect.Name(tok.value)
		fd := fds.ByName(name)
		switch {
		case fd == nil:
			gd := fds.ByName(protoreflect.Name(strings.ToLower(string(name))))
			if gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name {
				fd = gd
			}
		case fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name:
			fd = nil
		case fd.IsWeak() && fd.Message().IsPlaceholder():
			fd = nil
		}
		if fd == nil {
			typeName := string(md.FullName())
			if m, ok := m.Interface().(Message); ok {
				t := reflect.TypeOf(m)
				if t.Kind() == reflect.Ptr {
					typeName = t.Elem().String()
				}
			}
			return p.errorf("unknown field name %q in %v", name, typeName)
		}
		if od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil {
			return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, od.Name())
		}
		if fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] {
			return p.errorf("non-repeated field %q was repeated", fd.Name())
		}
		seen[fd.Number()] = true

		// Consume any colon.
		if err := p.checkForColon(fd); err != nil {
			return err
		}

		// Parse into the field.
		v := m.Get(fd)
		if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) {
			v = m.Mutable(fd)
		}
		if v, err = p.unmarshalValue(v, fd); err != nil {
			return err
		}
		m.Set(fd, v)

		if err := p.consumeOptionalSeparator(); err != nil {
			return err
		}
	}
	return nil
}