func()

in proto/text_decode.go [171:256]


func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error {
	name, err := p.consumeExtensionOrAnyName()
	if err != nil {
		return err
	}

	// If it contains a slash, it's an Any type URL.
	if slashIdx := strings.LastIndex(name, "/"); slashIdx >= 0 {
		tok := p.next()
		if tok.err != nil {
			return tok.err
		}
		// consume an optional colon
		if tok.value == ":" {
			tok = p.next()
			if tok.err != nil {
				return tok.err
			}
		}

		var terminator string
		switch tok.value {
		case "<":
			terminator = ">"
		case "{":
			terminator = "}"
		default:
			return p.errorf("expected '{' or '<', found %q", tok.value)
		}

		mt, err := protoregistry.GlobalTypes.FindMessageByURL(name)
		if err != nil {
			return p.errorf("unrecognized message %q in google.protobuf.Any", name[slashIdx+len("/"):])
		}
		m2 := mt.New()
		if err := p.unmarshalMessage(m2, terminator); err != nil {
			return err
		}
		b, err := protoV2.Marshal(m2.Interface())
		if err != nil {
			return p.errorf("failed to marshal message of type %q: %v", name[slashIdx+len("/"):], err)
		}

		urlFD := m.Descriptor().Fields().ByName("type_url")
		valFD := m.Descriptor().Fields().ByName("value")
		if seen[urlFD.Number()] {
			return p.errorf("Any message unpacked multiple times, or %q already set", urlFD.Name())
		}
		if seen[valFD.Number()] {
			return p.errorf("Any message unpacked multiple times, or %q already set", valFD.Name())
		}
		m.Set(urlFD, protoreflect.ValueOfString(name))
		m.Set(valFD, protoreflect.ValueOfBytes(b))
		seen[urlFD.Number()] = true
		seen[valFD.Number()] = true
		return nil
	}

	xname := protoreflect.FullName(name)
	xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
	if xt == nil && isMessageSet(m.Descriptor()) {
		xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
	}
	if xt == nil {
		return p.errorf("unrecognized extension %q", name)
	}
	fd := xt.TypeDescriptor()
	if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
		return p.errorf("extension field %q does not extend message %q", name, m.Descriptor().FullName())
	}

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

	v := m.Get(fd)
	if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) {
		v = m.Mutable(fd)
	}
	v, err = p.unmarshalValue(v, fd)
	if err != nil {
		return err
	}
	m.Set(fd, v)
	return p.consumeOptionalSeparator()
}