// 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"

	pragma "github.com/golang/protobuf/v2/internal/pragma"
	pfmt "github.com/golang/protobuf/v2/internal/typefmt"
	pref "github.com/golang/protobuf/v2/reflect/protoreflect"
)

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

func (m *inheritedMeta) init(nb *nameBuilder, parent pref.Descriptor, index int, 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.index = index
	m.syntax = parent.Syntax()
	m.fullName = nb.Append(prefix, name)
}

type fileMeta struct {
	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) Index() int                                       { return 0 }
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 nil, false }
func (t fileDesc) Options() pref.ProtoMessage                       { return t.f.Options }
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)                       { pfmt.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
	mo messageOptions
}
type messageDesc struct{ m *Message }

func (t messageDesc) Parent() (pref.Descriptor, bool)       { return t.m.parent, true }
func (t messageDesc) Index() int                            { return t.m.index }
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 nil, false }
func (t messageDesc) Options() pref.ProtoMessage            { return t.m.Options }
func (t messageDesc) IsMapEntry() bool                      { return t.m.mo.lazyInit(t).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)            { pfmt.FormatDesc(s, r, t) }
func (t messageDesc) ProtoType(pref.MessageDescriptor)      {}
func (t messageDesc) ProtoInternal(pragma.DoNotImplement)   {}

type messageOptions struct {
	once       sync.Once
	isMapEntry bool
}

func (p *messageOptions) lazyInit(m pref.MessageDescriptor) *messageOptions {
	p.once.Do(func() {
		if m.Options() != nil {
			const mapEntryFieldNumber = 7 // google.protobuf.MessageOptions.map_entry
			fs := m.Options().ProtoReflect().KnownFields()
			p.isMapEntry = fs.Get(mapEntryFieldNumber).Bool()
		}
	})
	return p
}

type fieldMeta struct {
	inheritedMeta

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

func (t fieldDesc) Parent() (pref.Descriptor, bool)            { return t.f.parent, true }
func (t fieldDesc) Index() int                                 { return t.f.index }
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 nil, false }
func (t fieldDesc) Options() pref.ProtoMessage                 { return t.f.Options }
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.fo.lazyInit(t).isPacked }
func (t fieldDesc) IsWeak() bool                               { return t.f.fo.lazyInit(t).isWeak }
func (t fieldDesc) IsMap() bool                                { return t.f.fo.lazyInit(t).isMap }
func (t fieldDesc) Default() pref.Value                        { return t.f.dv.value(t, t.f.Default) }
func (t fieldDesc) DefaultEnumValue() pref.EnumValueDescriptor { return t.f.dv.enum(t, t.f.Default) }
func (t fieldDesc) HasDefault() bool                           { return t.f.Default.IsValid() }
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)                 { pfmt.FormatDesc(s, r, t) }
func (t fieldDesc) ProtoType(pref.FieldDescriptor)             {}
func (t fieldDesc) ProtoInternal(pragma.DoNotImplement)        {}

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 fieldOptions struct {
	once     sync.Once
	isPacked bool
	isWeak   bool
	isMap    bool
}

func (p *fieldOptions) lazyInit(f pref.FieldDescriptor) *fieldOptions {
	p.once.Do(func() {
		if f.Cardinality() == pref.Repeated {
			// In proto3, repeated fields of scalar numeric types use
			// packed encoding by default.
			// See https://developers.google.com/protocol-buffers/docs/proto3
			if f.Syntax() == pref.Proto3 {
				p.isPacked = isScalarNumeric[f.Kind()]
			}
			if f.Kind() == pref.MessageKind {
				p.isMap = f.MessageType().IsMapEntry()
			}
		}

		if f.Options() != nil {
			const packedFieldNumber = 2 // google.protobuf.FieldOptions.packed
			const weakFieldNumber = 10  // google.protobuf.FieldOptions.weak
			fs := f.Options().ProtoReflect().KnownFields()
			if fs.Has(packedFieldNumber) {
				p.isPacked = fs.Get(packedFieldNumber).Bool()
			}
			p.isWeak = fs.Get(weakFieldNumber).Bool()
		}
	})
	return p
}

// isPacked reports whether the packed options is set.
func isPacked(m pref.ProtoMessage) (isPacked bool) {
	if m != nil {
		const packedFieldNumber = 2 // google.protobuf.FieldOptions.packed
		fs := m.ProtoReflect().KnownFields()
		isPacked = fs.Get(packedFieldNumber).Bool()
	}
	return isPacked
}

// isWeak reports whether the weak options is set.
func isWeak(m pref.ProtoMessage) (isWeak bool) {
	if m != nil {
		const weakFieldNumber = 10 // google.protobuf.FieldOptions.weak
		fs := m.ProtoReflect().KnownFields()
		isWeak = fs.Get(weakFieldNumber).Bool()
	}
	return isWeak
}

var isScalarNumeric = map[pref.Kind]bool{
	pref.BoolKind:     true,
	pref.EnumKind:     true,
	pref.Int32Kind:    true,
	pref.Sint32Kind:   true,
	pref.Uint32Kind:   true,
	pref.Int64Kind:    true,
	pref.Sint64Kind:   true,
	pref.Uint64Kind:   true,
	pref.Sfixed32Kind: true,
	pref.Fixed32Kind:  true,
	pref.FloatKind:    true,
	pref.Sfixed64Kind: true,
	pref.Fixed64Kind:  true,
	pref.DoubleKind:   true,
}

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) Index() int                            { return t.o.index }
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 nil, false }
func (t oneofDesc) Options() pref.ProtoMessage            { return t.o.Options }
func (t oneofDesc) Fields() pref.FieldDescriptors         { return t.o.fs.lazyInit(t) }
func (t oneofDesc) Format(s fmt.State, r rune)            { pfmt.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) Index() int                                 { return t.x.index }
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 nil, false }
func (t extensionDesc) Options() pref.ProtoMessage                 { return t.x.Options }
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 isPacked(t.Options()) }
func (t extensionDesc) IsWeak() bool                               { return false }
func (t extensionDesc) IsMap() bool                                { return false }
func (t extensionDesc) Default() pref.Value                        { return t.x.dv.value(t, t.x.Default) }
func (t extensionDesc) DefaultEnumValue() pref.EnumValueDescriptor { return t.x.dv.enum(t, t.x.Default) }
func (t extensionDesc) HasDefault() bool                           { return t.x.Default.IsValid() }
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)          { pfmt.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) Index() int                            { return t.e.index }
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 nil, false }
func (t enumDesc) Options() pref.ProtoMessage            { return t.e.Options }
func (t enumDesc) Values() pref.EnumValueDescriptors     { return t.e.vs.lazyInit(t, t.e.Values) }
func (t enumDesc) Format(s fmt.State, r rune)            { pfmt.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) Index() int                            { return t.v.index }
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 nil, false }
func (t enumValueDesc) Options() pref.ProtoMessage            { return t.v.Options }
func (t enumValueDesc) Number() pref.EnumNumber               { return t.v.Number }
func (t enumValueDesc) Format(s fmt.State, r rune)            { pfmt.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) Index() int                            { return t.s.index }
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 nil, false }
func (t serviceDesc) Options() pref.ProtoMessage            { return t.s.Options }
func (t serviceDesc) Methods() pref.MethodDescriptors       { return t.s.ms.lazyInit(t, t.s.Methods) }
func (t serviceDesc) Format(s fmt.State, r rune)            { pfmt.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) Index() int                            { return t.m.index }
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 nil, false }
func (t methodDesc) Options() pref.ProtoMessage            { return t.m.Options }
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)            { pfmt.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
	eval pref.EnumValueDescriptor
	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) {
	p.once.Do(func() {
		p.val = v
		if v.IsValid() {
			switch t.Kind() {
			case pref.EnumKind:
				// Treat a string value as an identifier referencing some enum
				// value by name and extract the enum number.
				// If this fails, validateMessage will later detect that the
				// default value for an enum value is the wrong type.
				switch v := v.Interface().(type) {
				case string:
					if ev := t.EnumType().Values().ByName(pref.Name(v)); ev != nil {
						p.eval = ev
						p.val = pref.ValueOf(p.eval.Number())
					}
				case pref.EnumNumber:
					p.eval = t.EnumType().Values().ByNumber(v)
				}
			case pref.BytesKind:
				// Store a copy of the default bytes, so that we can detect
				// accidental mutations of the original value.
				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()))
	}
}

func (p *defaultValue) value(t pref.FieldDescriptor, v pref.Value) pref.Value {
	p.lazyInit(t, v)
	return p.val
}

func (p *defaultValue) enum(t pref.FieldDescriptor, v pref.Value) pref.EnumValueDescriptor {
	p.lazyInit(t, v)
	return p.eval
}

// 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
			} else if len(curName) == 0 {
				break // FileDescriptor has no package name
			}
			// 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
}
