// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package prototype

import (
	"bytes"
	"fmt"
	"strings"
	"sync"

	"google.golang.org/proto/internal/pragma"
	pref "google.golang.org/proto/reflect/protoreflect"
)

// inheritedMeta is information inherited from the parent.
type inheritedMeta struct {
	parent   pref.Descriptor
	syntax   pref.Syntax
	fullName pref.FullName

	desc descriptorSubMeta
	opts descriptorOptionsMeta
}

func (m *inheritedMeta) init(nb *nameBuilder, parent pref.Descriptor, name pref.Name, child bool) {
	// Most descriptors are namespaced as a child of their parent.
	// However, EnumValues are the exception in that they are namespaced
	// as a sibling of the parent Enum type.
	prefix := parent.FullName()
	if child {
		prefix = prefix.Parent()
	}

	m.parent = parent
	m.syntax = parent.Syntax()
	m.fullName = nb.Append(prefix, name)
}

type fileMeta struct {
	desc descriptorFileMeta
	opts descriptorOptionsMeta

	ms messagesMeta
	es enumsMeta
	xs extensionsMeta
	ss servicesMeta
	ds descriptorsMeta
}
type fileDesc struct{ f *File }

func newFile(f *File) fileDesc {
	if f.fileMeta != nil {
		panic("already initialized")
	}
	f.fileMeta = new(fileMeta)
	return fileDesc{f}
}
func (t fileDesc) Parent() (pref.Descriptor, bool)                   { return nil, false }
func (t fileDesc) Syntax() pref.Syntax                               { return t.f.Syntax }
func (t fileDesc) Name() pref.Name                                   { return t.f.Package.Name() }
func (t fileDesc) FullName() pref.FullName                           { return t.f.Package }
func (t fileDesc) IsPlaceholder() bool                               { return false }
func (t fileDesc) DescriptorProto() (pref.Message, bool)             { return t.f.desc.lazyInit(t) }
func (t fileDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.f.opts.lazyInit(t) }
func (t fileDesc) Path() string                                      { return t.f.Path }
func (t fileDesc) Package() pref.FullName                            { return t.f.Package }
func (t fileDesc) Imports() pref.FileImports                         { return (*fileImports)(&t.f.Imports) }
func (t fileDesc) Messages() pref.MessageDescriptors                 { return t.f.ms.lazyInit(t, t.f.Messages) }
func (t fileDesc) Enums() pref.EnumDescriptors                       { return t.f.es.lazyInit(t, t.f.Enums) }
func (t fileDesc) Extensions() pref.ExtensionDescriptors             { return t.f.xs.lazyInit(t, t.f.Extensions) }
func (t fileDesc) Services() pref.ServiceDescriptors                 { return t.f.ss.lazyInit(t, t.f.Services) }
func (t fileDesc) DescriptorByName(s pref.FullName) pref.Descriptor  { return t.f.ds.lookup(t, s) }
func (t fileDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t fileDesc) ProtoType(pref.FileDescriptor)                     {}
func (t fileDesc) ProtoInternal(pragma.DoNotImplement)               {}

// descriptorsMeta is a lazily initialized map of all descriptors declared in
// the file by full name.
type descriptorsMeta struct {
	once sync.Once
	m    map[pref.FullName]pref.Descriptor
}

func (m *descriptorsMeta) lookup(fd pref.FileDescriptor, s pref.FullName) pref.Descriptor {
	m.once.Do(func() {
		m.m = make(map[pref.FullName]pref.Descriptor)
		m.initMap(fd)
		delete(m.m, fd.Package()) // avoid registering the file descriptor itself
	})
	return m.m[s]
}
func (m *descriptorsMeta) initMap(d pref.Descriptor) {
	m.m[d.FullName()] = d
	if ds, ok := d.(interface {
		Enums() pref.EnumDescriptors
	}); ok {
		for i := 0; i < ds.Enums().Len(); i++ {
			m.initMap(ds.Enums().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Values() pref.EnumValueDescriptors
	}); ok {
		for i := 0; i < ds.Values().Len(); i++ {
			m.initMap(ds.Values().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Messages() pref.MessageDescriptors
	}); ok {
		for i := 0; i < ds.Messages().Len(); i++ {
			m.initMap(ds.Messages().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Fields() pref.FieldDescriptors
	}); ok {
		for i := 0; i < ds.Fields().Len(); i++ {
			m.initMap(ds.Fields().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Oneofs() pref.OneofDescriptors
	}); ok {
		for i := 0; i < ds.Oneofs().Len(); i++ {
			m.initMap(ds.Oneofs().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Extensions() pref.ExtensionDescriptors
	}); ok {
		for i := 0; i < ds.Extensions().Len(); i++ {
			m.initMap(ds.Extensions().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Services() pref.ServiceDescriptors
	}); ok {
		for i := 0; i < ds.Services().Len(); i++ {
			m.initMap(ds.Services().Get(i))
		}
	}
	if ds, ok := d.(interface {
		Methods() pref.MethodDescriptors
	}); ok {
		for i := 0; i < ds.Methods().Len(); i++ {
			m.initMap(ds.Methods().Get(i))
		}
	}
}

type messageMeta struct {
	inheritedMeta

	fs fieldsMeta
	os oneofsMeta
	ns numbersMeta
	ms messagesMeta
	es enumsMeta
	xs extensionsMeta
}
type messageDesc struct{ m *Message }

func (t messageDesc) Parent() (pref.Descriptor, bool)                   { return t.m.parent, true }
func (t messageDesc) Syntax() pref.Syntax                               { return t.m.syntax }
func (t messageDesc) Name() pref.Name                                   { return t.m.Name }
func (t messageDesc) FullName() pref.FullName                           { return t.m.fullName }
func (t messageDesc) IsPlaceholder() bool                               { return false }
func (t messageDesc) DescriptorProto() (pref.Message, bool)             { return t.m.desc.lazyInit(t) }
func (t messageDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.m.opts.lazyInit(t) }
func (t messageDesc) IsMapEntry() bool                                  { return t.m.IsMapEntry }
func (t messageDesc) Fields() pref.FieldDescriptors                     { return t.m.fs.lazyInit(t, t.m.Fields) }
func (t messageDesc) Oneofs() pref.OneofDescriptors                     { return t.m.os.lazyInit(t, t.m.Oneofs) }
func (t messageDesc) RequiredNumbers() pref.FieldNumbers                { return t.m.ns.lazyInit(t.m.Fields) }
func (t messageDesc) ExtensionRanges() pref.FieldRanges                 { return (*ranges)(&t.m.ExtensionRanges) }
func (t messageDesc) Messages() pref.MessageDescriptors                 { return t.m.ms.lazyInit(t, t.m.Messages) }
func (t messageDesc) Enums() pref.EnumDescriptors                       { return t.m.es.lazyInit(t, t.m.Enums) }
func (t messageDesc) Extensions() pref.ExtensionDescriptors             { return t.m.xs.lazyInit(t, t.m.Extensions) }
func (t messageDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t messageDesc) ProtoType(pref.MessageDescriptor)                  {}
func (t messageDesc) ProtoInternal(pragma.DoNotImplement)               {}

type fieldMeta struct {
	inheritedMeta

	js jsonName
	dv defaultValue
	ot oneofReference
	mt messageReference
	et enumReference
}
type fieldDesc struct{ f *Field }

func (t fieldDesc) Parent() (pref.Descriptor, bool)                   { return t.f.parent, true }
func (t fieldDesc) Syntax() pref.Syntax                               { return t.f.syntax }
func (t fieldDesc) Name() pref.Name                                   { return t.f.Name }
func (t fieldDesc) FullName() pref.FullName                           { return t.f.fullName }
func (t fieldDesc) IsPlaceholder() bool                               { return false }
func (t fieldDesc) DescriptorProto() (pref.Message, bool)             { return t.f.desc.lazyInit(t) }
func (t fieldDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.f.opts.lazyInit(t) }
func (t fieldDesc) Number() pref.FieldNumber                          { return t.f.Number }
func (t fieldDesc) Cardinality() pref.Cardinality                     { return t.f.Cardinality }
func (t fieldDesc) Kind() pref.Kind                                   { return t.f.Kind }
func (t fieldDesc) JSONName() string                                  { return t.f.js.lazyInit(t.f) }
func (t fieldDesc) IsPacked() bool                                    { return t.f.IsPacked }
func (t fieldDesc) IsMap() bool                                       { return isMap(t) }
func (t fieldDesc) IsWeak() bool                                      { return t.f.IsWeak }
func (t fieldDesc) Default() pref.Value                               { return t.f.dv.lazyInit(t, t.f.Default) }
func (t fieldDesc) OneofType() pref.OneofDescriptor                   { return t.f.ot.lazyInit(t, t.f.OneofName) }
func (t fieldDesc) ExtendedType() pref.MessageDescriptor              { return nil }
func (t fieldDesc) MessageType() pref.MessageDescriptor               { return t.f.mt.lazyInit(t, &t.f.MessageType) }
func (t fieldDesc) EnumType() pref.EnumDescriptor                     { return t.f.et.lazyInit(t, &t.f.EnumType) }
func (t fieldDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t fieldDesc) ProtoType(pref.FieldDescriptor)                    {}
func (t fieldDesc) ProtoInternal(pragma.DoNotImplement)               {}

func isMap(t pref.FieldDescriptor) bool {
	if t.Cardinality() == pref.Repeated && t.Kind() == pref.MessageKind {
		if mt := t.MessageType(); mt != nil {
			return mt.IsMapEntry()
		}
	}
	return false
}

type jsonName struct{ once sync.Once }

func (p *jsonName) lazyInit(f *Field) string {
	p.once.Do(func() {
		// TODO: We may need to share this logic with jsonpb for implementation
		// of the FieldMask well-known type.
		if f.JSONName != "" {
			return
		}
		var b []byte
		var wasUnderscore bool
		for i := 0; i < len(f.Name); i++ { // proto identifiers are always ASCII
			c := f.Name[i]
			if c != '_' {
				isLower := 'a' <= c && c <= 'z'
				if wasUnderscore && isLower {
					c -= 'a' - 'A'
				}
				b = append(b, c)
			}
			wasUnderscore = c == '_'
		}
		f.JSONName = string(b)
	})
	return f.JSONName
}

// oneofReference resolves the name of a oneof by searching the parent
// message for the matching OneofDescriptor declaration.
type oneofReference struct {
	once sync.Once
	otyp pref.OneofDescriptor
}

func (p *oneofReference) lazyInit(parent pref.Descriptor, name pref.Name) pref.OneofDescriptor {
	p.once.Do(func() {
		if name != "" {
			mtyp, _ := parent.Parent()
			p.otyp = mtyp.(pref.MessageDescriptor).Oneofs().ByName(name)
			// TODO: We need validate to detect this mismatch.
		}
	})
	return p.otyp
}

type oneofMeta struct {
	inheritedMeta

	fs oneofFieldsMeta
}
type oneofDesc struct{ o *Oneof }

func (t oneofDesc) Parent() (pref.Descriptor, bool)                   { return t.o.parent, true }
func (t oneofDesc) Syntax() pref.Syntax                               { return t.o.syntax }
func (t oneofDesc) Name() pref.Name                                   { return t.o.Name }
func (t oneofDesc) FullName() pref.FullName                           { return t.o.fullName }
func (t oneofDesc) IsPlaceholder() bool                               { return false }
func (t oneofDesc) DescriptorProto() (pref.Message, bool)             { return t.o.desc.lazyInit(t) }
func (t oneofDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.o.opts.lazyInit(t) }
func (t oneofDesc) Fields() pref.FieldDescriptors                     { return t.o.fs.lazyInit(t) }
func (t oneofDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t oneofDesc) ProtoType(pref.OneofDescriptor)                    {}
func (t oneofDesc) ProtoInternal(pragma.DoNotImplement)               {}

type extensionMeta struct {
	inheritedMeta

	dv defaultValue
	xt messageReference
	mt messageReference
	et enumReference
}
type extensionDesc struct{ x *Extension }

func (t extensionDesc) Parent() (pref.Descriptor, bool)                   { return t.x.parent, true }
func (t extensionDesc) Syntax() pref.Syntax                               { return t.x.syntax }
func (t extensionDesc) Name() pref.Name                                   { return t.x.Name }
func (t extensionDesc) FullName() pref.FullName                           { return t.x.fullName }
func (t extensionDesc) IsPlaceholder() bool                               { return false }
func (t extensionDesc) DescriptorProto() (pref.Message, bool)             { return t.x.desc.lazyInit(t) }
func (t extensionDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.x.opts.lazyInit(t) }
func (t extensionDesc) Number() pref.FieldNumber                          { return t.x.Number }
func (t extensionDesc) Cardinality() pref.Cardinality                     { return t.x.Cardinality }
func (t extensionDesc) Kind() pref.Kind                                   { return t.x.Kind }
func (t extensionDesc) JSONName() string                                  { return "" }
func (t extensionDesc) IsPacked() bool                                    { return t.x.IsPacked }
func (t extensionDesc) IsMap() bool                                       { return false }
func (t extensionDesc) IsWeak() bool                                      { return false }
func (t extensionDesc) Default() pref.Value                               { return t.x.dv.lazyInit(t, t.x.Default) }
func (t extensionDesc) OneofType() pref.OneofDescriptor                   { return nil }
func (t extensionDesc) ExtendedType() pref.MessageDescriptor {
	return t.x.xt.lazyInit(t, &t.x.ExtendedType)
}
func (t extensionDesc) MessageType() pref.MessageDescriptor {
	return t.x.mt.lazyInit(t, &t.x.MessageType)
}
func (t extensionDesc) EnumType() pref.EnumDescriptor       { return t.x.et.lazyInit(t, &t.x.EnumType) }
func (t extensionDesc) Format(s fmt.State, r rune)          { formatDesc(s, r, t) }
func (t extensionDesc) ProtoType(pref.FieldDescriptor)      {}
func (t extensionDesc) ProtoInternal(pragma.DoNotImplement) {}

type enumMeta struct {
	inheritedMeta

	vs enumValuesMeta
}
type enumDesc struct{ e *Enum }

func (t enumDesc) Parent() (pref.Descriptor, bool)                   { return t.e.parent, true }
func (t enumDesc) Syntax() pref.Syntax                               { return t.e.syntax }
func (t enumDesc) Name() pref.Name                                   { return t.e.Name }
func (t enumDesc) FullName() pref.FullName                           { return t.e.fullName }
func (t enumDesc) IsPlaceholder() bool                               { return false }
func (t enumDesc) DescriptorProto() (pref.Message, bool)             { return t.e.desc.lazyInit(t) }
func (t enumDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.e.opts.lazyInit(t) }
func (t enumDesc) Values() pref.EnumValueDescriptors                 { return t.e.vs.lazyInit(t, t.e.Values) }
func (t enumDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t enumDesc) ProtoType(pref.EnumDescriptor)                     {}
func (t enumDesc) ProtoInternal(pragma.DoNotImplement)               {}

type enumValueMeta struct {
	inheritedMeta
}
type enumValueDesc struct{ v *EnumValue }

func (t enumValueDesc) Parent() (pref.Descriptor, bool)                   { return t.v.parent, true }
func (t enumValueDesc) Syntax() pref.Syntax                               { return t.v.syntax }
func (t enumValueDesc) Name() pref.Name                                   { return t.v.Name }
func (t enumValueDesc) FullName() pref.FullName                           { return t.v.fullName }
func (t enumValueDesc) IsPlaceholder() bool                               { return false }
func (t enumValueDesc) DescriptorProto() (pref.Message, bool)             { return t.v.desc.lazyInit(t) }
func (t enumValueDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.v.opts.lazyInit(t) }
func (t enumValueDesc) Number() pref.EnumNumber                           { return t.v.Number }
func (t enumValueDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t enumValueDesc) ProtoType(pref.EnumValueDescriptor)                {}
func (t enumValueDesc) ProtoInternal(pragma.DoNotImplement)               {}

type serviceMeta struct {
	inheritedMeta

	ms methodsMeta
}
type serviceDesc struct{ s *Service }

func (t serviceDesc) Parent() (pref.Descriptor, bool)                   { return t.s.parent, true }
func (t serviceDesc) Syntax() pref.Syntax                               { return t.s.syntax }
func (t serviceDesc) Name() pref.Name                                   { return t.s.Name }
func (t serviceDesc) FullName() pref.FullName                           { return t.s.fullName }
func (t serviceDesc) IsPlaceholder() bool                               { return false }
func (t serviceDesc) DescriptorProto() (pref.Message, bool)             { return t.s.desc.lazyInit(t) }
func (t serviceDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.s.opts.lazyInit(t) }
func (t serviceDesc) Methods() pref.MethodDescriptors                   { return t.s.ms.lazyInit(t, t.s.Methods) }
func (t serviceDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t serviceDesc) ProtoType(pref.ServiceDescriptor)                  {}
func (t serviceDesc) ProtoInternal(pragma.DoNotImplement)               {}

type methodMeta struct {
	inheritedMeta

	mit messageReference
	mot messageReference
}
type methodDesc struct{ m *Method }

func (t methodDesc) Parent() (pref.Descriptor, bool)                   { return t.m.parent, true }
func (t methodDesc) Syntax() pref.Syntax                               { return t.m.syntax }
func (t methodDesc) Name() pref.Name                                   { return t.m.Name }
func (t methodDesc) FullName() pref.FullName                           { return t.m.fullName }
func (t methodDesc) IsPlaceholder() bool                               { return false }
func (t methodDesc) DescriptorProto() (pref.Message, bool)             { return t.m.desc.lazyInit(t) }
func (t methodDesc) DescriptorOptions() (pref.DescriptorOptions, bool) { return t.m.opts.lazyInit(t) }
func (t methodDesc) InputType() pref.MessageDescriptor                 { return t.m.mit.lazyInit(t, &t.m.InputType) }
func (t methodDesc) OutputType() pref.MessageDescriptor                { return t.m.mot.lazyInit(t, &t.m.OutputType) }
func (t methodDesc) IsStreamingClient() bool                           { return t.m.IsStreamingClient }
func (t methodDesc) IsStreamingServer() bool                           { return t.m.IsStreamingServer }
func (t methodDesc) Format(s fmt.State, r rune)                        { formatDesc(s, r, t) }
func (t methodDesc) ProtoType(pref.MethodDescriptor)                   {}
func (t methodDesc) ProtoInternal(pragma.DoNotImplement)               {}

type defaultValue struct {
	once sync.Once
	val  pref.Value
	buf  []byte
}

var (
	zeroBool    = pref.ValueOf(false)
	zeroInt32   = pref.ValueOf(int32(0))
	zeroInt64   = pref.ValueOf(int64(0))
	zeroUint32  = pref.ValueOf(uint32(0))
	zeroUint64  = pref.ValueOf(uint64(0))
	zeroFloat32 = pref.ValueOf(float32(0))
	zeroFloat64 = pref.ValueOf(float64(0))
	zeroString  = pref.ValueOf(string(""))
	zeroBytes   = pref.ValueOf([]byte(nil))
	zeroEnum    = pref.ValueOf(pref.EnumNumber(0))
)

func (p *defaultValue) lazyInit(t pref.FieldDescriptor, v pref.Value) pref.Value {
	p.once.Do(func() {
		p.val = v
		if !v.IsNull() {
			if t.Kind() == pref.BytesKind {
				if b, ok := v.Interface().([]byte); ok && len(b) > 0 {
					p.buf = append([]byte(nil), b...)
				}
			}
			return
		}
		switch t.Kind() {
		case pref.BoolKind:
			p.val = zeroBool
		case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
			p.val = zeroInt32
		case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
			p.val = zeroInt64
		case pref.Uint32Kind, pref.Fixed32Kind:
			p.val = zeroUint32
		case pref.Uint64Kind, pref.Fixed64Kind:
			p.val = zeroUint64
		case pref.FloatKind:
			p.val = zeroFloat32
		case pref.DoubleKind:
			p.val = zeroFloat64
		case pref.StringKind:
			p.val = zeroString
		case pref.BytesKind:
			p.val = zeroBytes
		case pref.EnumKind:
			p.val = zeroEnum
			if t.Syntax() == pref.Proto2 {
				if et := t.EnumType(); et != nil {
					if vs := et.Values(); vs.Len() > 0 {
						p.val = pref.ValueOf(vs.Get(0).Number())
					}
				}
			}
		}
	})
	if len(p.buf) > 0 && !bytes.Equal(p.buf, p.val.Bytes()) {
		// TODO: Avoid panic if we're running with the race detector and instead
		// spawn a goroutine that periodically resets this value back to the
		// original to induce a race that can be detected by the detector.
		panic(fmt.Sprintf("proto: detected mutation on the default bytes for %v", t.FullName()))
	}
	return p.val
}

// messageReference resolves PlaceholderMessages that reference declarations
// within the FileDescriptor tree that parent is a member of.
type messageReference struct{ once sync.Once }

func (p *messageReference) lazyInit(parent pref.Descriptor, pt *pref.MessageDescriptor) pref.MessageDescriptor {
	p.once.Do(func() {
		if t := *pt; t != nil && t.IsPlaceholder() {
			if d, ok := resolveReference(parent, t.FullName()).(pref.MessageDescriptor); ok {
				*pt = d
			}
		}
	})
	return *pt
}

// enumReference resolves PlaceholderEnums that reference declarations
// within the FileDescriptor tree that parent is a member of.
type enumReference struct{ once sync.Once }

func (p *enumReference) lazyInit(parent pref.Descriptor, pt *pref.EnumDescriptor) pref.EnumDescriptor {
	p.once.Do(func() {
		if t := *pt; t != nil && t.IsPlaceholder() {
			if d, ok := resolveReference(parent, t.FullName()).(pref.EnumDescriptor); ok {
				*pt = d
			}
		}
	})
	return *pt
}

// resolveReference searches parent for the MessageDescriptor or EnumDescriptor
// declaration identified by refName. This returns nil if not found.
func resolveReference(parent pref.Descriptor, refName pref.FullName) pref.Descriptor {
	// Ascend upwards until a prefix match is found.
	cur := parent
	for cur != nil {
		curName := cur.FullName()
		if strings.HasPrefix(string(refName), string(curName)) {
			if len(refName) == len(curName) {
				refName = refName[len(curName):]
				break // e.g., refName: foo.firetruck, curName: foo.firetruck
			} else if refName[len(curName)] == '.' {
				refName = refName[len(curName)+len("."):]
				break // e.g., refName: foo.firetruck.driver, curName: foo.firetruck
			}
			// No match. (e.g., refName: foo.firetruck, curName: foo.fire)
		}
		cur, _ = cur.Parent() // nil after ascending above FileDescriptor
	}

	// Descend downwards to resolve all relative names.
	for cur != nil && len(refName) > 0 {
		var head pref.Name
		head, refName = pref.Name(refName), ""
		if i := strings.IndexByte(string(head), '.'); i >= 0 {
			head, refName = head[:i], pref.FullName(head[i+len("."):])
		}

		// Search the current descriptor for the nested declaration.
		var next pref.Descriptor
		if t, ok := cur.(interface {
			Messages() pref.MessageDescriptors
		}); ok && next == nil {
			if d := t.Messages().ByName(head); d != nil {
				next = d
			}
		}
		if t, ok := cur.(interface {
			Enums() pref.EnumDescriptors
		}); ok && next == nil {
			if d := t.Enums().ByName(head); d != nil {
				next = d
			}
		}
		cur = next // nil if not found
	}
	return cur
}

var nameBuilderPool = sync.Pool{
	New: func() interface{} { return new(nameBuilder) },
}

type nameBuilder struct {
	sb strings.Builder

	// TODO: See https://golang.org/issue/26269
	rem int // conservative approximation for Cap-Len
}

// Append is equivalent to protoreflect.FullName.Append, but is optimized for
// large batches of operations where each name has a shared lifetime.
func (b *nameBuilder) Append(prefix pref.FullName, name pref.Name) pref.FullName {
	const batchSize = 1 << 12
	n := len(prefix) + len(".") + len(name)
	if b.rem < n {
		b.sb.Reset()
		b.sb.Grow(batchSize)
		b.rem = batchSize - n
	}
	if !strings.HasSuffix(b.sb.String(), string(prefix)) {
		b.sb.WriteString(string(prefix))
	}
	b.sb.WriteByte('.')
	b.sb.WriteString(string(name))
	s := b.sb.String()
	return pref.FullName(strings.TrimPrefix(s[len(s)-n:], "."))
}
