// Copyright 2019 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 filedesc

import (
	"bytes"
	"fmt"
	"strings"
	"sync"
	"sync/atomic"

	"google.golang.org/protobuf/internal/descfmt"
	"google.golang.org/protobuf/internal/descopts"
	"google.golang.org/protobuf/internal/encoding/defval"
	"google.golang.org/protobuf/internal/encoding/messageset"
	"google.golang.org/protobuf/internal/genid"
	"google.golang.org/protobuf/internal/pragma"
	"google.golang.org/protobuf/internal/strs"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
)

// Edition is an Enum for proto2.Edition
type Edition int32

// These values align with the value of Enum in descriptor.proto which allows
// direct conversion between the proto enum and this enum.
const (
	EditionUnknown     Edition = 0
	EditionProto2      Edition = 998
	EditionProto3      Edition = 999
	Edition2023        Edition = 1000
	EditionUnsupported Edition = 100000
)

// The types in this file may have a suffix:
//	• L0: Contains fields common to all descriptors (except File) and
//	must be initialized up front.
//	• L1: Contains fields specific to a descriptor and
//	must be initialized up front. If the associated proto uses Editions, the
//  Editions features must always be resolved. If not explicitly set, the
//  appropriate default must be resolved and set.
//	• L2: Contains fields that are lazily initialized when constructing
//	from the raw file descriptor. When constructing as a literal, the L2
//	fields must be initialized up front.
//
// The types are exported so that packages like reflect/protodesc can
// directly construct descriptors.

type (
	File struct {
		fileRaw
		L1 FileL1

		once uint32     // atomically set if L2 is valid
		mu   sync.Mutex // protects L2
		L2   *FileL2
	}
	FileL1 struct {
		Syntax  protoreflect.Syntax
		Edition Edition // Only used if Syntax == Editions
		Path    string
		Package protoreflect.FullName

		Enums      Enums
		Messages   Messages
		Extensions Extensions
		Services   Services

		EditionFeatures EditionFeatures
	}
	FileL2 struct {
		Options   func() protoreflect.ProtoMessage
		Imports   FileImports
		Locations SourceLocations
	}

	EditionFeatures struct {
		// IsFieldPresence is true if field_presence is EXPLICIT
		// https://protobuf.dev/editions/features/#field_presence
		IsFieldPresence bool
		// IsFieldPresence is true if field_presence is LEGACY_REQUIRED
		// https://protobuf.dev/editions/features/#field_presence
		IsLegacyRequired bool
		// IsOpenEnum is true if enum_type is OPEN
		// https://protobuf.dev/editions/features/#enum_type
		IsOpenEnum bool
		// IsPacked is true if repeated_field_encoding is PACKED
		// https://protobuf.dev/editions/features/#repeated_field_encoding
		IsPacked bool
		// IsUTF8Validated is true if utf_validation is VERIFY
		// https://protobuf.dev/editions/features/#utf8_validation
		IsUTF8Validated bool
		// IsDelimitedEncoded is true if message_encoding is DELIMITED
		// https://protobuf.dev/editions/features/#message_encoding
		IsDelimitedEncoded bool
		// IsJSONCompliant is true if json_format is ALLOW
		// https://protobuf.dev/editions/features/#json_format
		IsJSONCompliant bool
		// GenerateLegacyUnmarshalJSON determines if the plugin generates the
		// UnmarshalJSON([]byte) error method for enums.
		GenerateLegacyUnmarshalJSON bool
	}
)

func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd }
func (fd *File) Parent() protoreflect.Descriptor         { return nil }
func (fd *File) Index() int                              { return 0 }
func (fd *File) Syntax() protoreflect.Syntax             { return fd.L1.Syntax }

// Not exported and just used to reconstruct the original FileDescriptor proto
func (fd *File) Edition() int32                  { return int32(fd.L1.Edition) }
func (fd *File) Name() protoreflect.Name         { return fd.L1.Package.Name() }
func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package }
func (fd *File) IsPlaceholder() bool             { return false }
func (fd *File) Options() protoreflect.ProtoMessage {
	if f := fd.lazyInit().Options; f != nil {
		return f()
	}
	return descopts.File
}
func (fd *File) Path() string                                  { return fd.L1.Path }
func (fd *File) Package() protoreflect.FullName                { return fd.L1.Package }
func (fd *File) Imports() protoreflect.FileImports             { return &fd.lazyInit().Imports }
func (fd *File) Enums() protoreflect.EnumDescriptors           { return &fd.L1.Enums }
func (fd *File) Messages() protoreflect.MessageDescriptors     { return &fd.L1.Messages }
func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions }
func (fd *File) Services() protoreflect.ServiceDescriptors     { return &fd.L1.Services }
func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations }
func (fd *File) Format(s fmt.State, r rune)                    { descfmt.FormatDesc(s, r, fd) }
func (fd *File) ProtoType(protoreflect.FileDescriptor)         {}
func (fd *File) ProtoInternal(pragma.DoNotImplement)           {}

func (fd *File) lazyInit() *FileL2 {
	if atomic.LoadUint32(&fd.once) == 0 {
		fd.lazyInitOnce()
	}
	return fd.L2
}

func (fd *File) lazyInitOnce() {
	fd.mu.Lock()
	if fd.L2 == nil {
		fd.lazyRawInit() // recursively initializes all L2 structures
	}
	atomic.StoreUint32(&fd.once, 1)
	fd.mu.Unlock()
}

// GoPackagePath is a pseudo-internal API for determining the Go package path
// that this file descriptor is declared in.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *File) GoPackagePath() string {
	return fd.builder.GoPackagePath
}

type (
	Enum struct {
		Base
		L1 EnumL1
		L2 *EnumL2 // protected by fileDesc.once
	}
	EnumL1 struct {
		eagerValues bool // controls whether EnumL2.Values is already populated

		EditionFeatures EditionFeatures
	}
	EnumL2 struct {
		Options        func() protoreflect.ProtoMessage
		Values         EnumValues
		ReservedNames  Names
		ReservedRanges EnumRanges
	}

	EnumValue struct {
		Base
		L1 EnumValueL1
	}
	EnumValueL1 struct {
		Options func() protoreflect.ProtoMessage
		Number  protoreflect.EnumNumber
	}
)

func (ed *Enum) Options() protoreflect.ProtoMessage {
	if f := ed.lazyInit().Options; f != nil {
		return f()
	}
	return descopts.Enum
}
func (ed *Enum) Values() protoreflect.EnumValueDescriptors {
	if ed.L1.eagerValues {
		return &ed.L2.Values
	}
	return &ed.lazyInit().Values
}
func (ed *Enum) ReservedNames() protoreflect.Names       { return &ed.lazyInit().ReservedNames }
func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges }
func (ed *Enum) Format(s fmt.State, r rune)              { descfmt.FormatDesc(s, r, ed) }
func (ed *Enum) ProtoType(protoreflect.EnumDescriptor)   {}
func (ed *Enum) lazyInit() *EnumL2 {
	ed.L0.ParentFile.lazyInit() // implicitly initializes L2
	return ed.L2
}
func (ed *Enum) IsClosed() bool {
	return !ed.L1.EditionFeatures.IsOpenEnum
}

func (ed *EnumValue) Options() protoreflect.ProtoMessage {
	if f := ed.L1.Options; f != nil {
		return f()
	}
	return descopts.EnumValue
}
func (ed *EnumValue) Number() protoreflect.EnumNumber            { return ed.L1.Number }
func (ed *EnumValue) Format(s fmt.State, r rune)                 { descfmt.FormatDesc(s, r, ed) }
func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {}

type (
	Message struct {
		Base
		L1 MessageL1
		L2 *MessageL2 // protected by fileDesc.once
	}
	MessageL1 struct {
		Enums        Enums
		Messages     Messages
		Extensions   Extensions
		IsMapEntry   bool // promoted from google.protobuf.MessageOptions
		IsMessageSet bool // promoted from google.protobuf.MessageOptions

		EditionFeatures EditionFeatures
	}
	MessageL2 struct {
		Options               func() protoreflect.ProtoMessage
		Fields                Fields
		Oneofs                Oneofs
		ReservedNames         Names
		ReservedRanges        FieldRanges
		RequiredNumbers       FieldNumbers // must be consistent with Fields.Cardinality
		ExtensionRanges       FieldRanges
		ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges
	}

	Field struct {
		Base
		L1 FieldL1
	}
	FieldL1 struct {
		Options          func() protoreflect.ProtoMessage
		Number           protoreflect.FieldNumber
		Cardinality      protoreflect.Cardinality // must be consistent with Message.RequiredNumbers
		Kind             protoreflect.Kind
		StringName       stringName
		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
		IsWeak           bool // promoted from google.protobuf.FieldOptions
		Default          defaultValue
		ContainingOneof  protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields
		Enum             protoreflect.EnumDescriptor
		Message          protoreflect.MessageDescriptor

		EditionFeatures EditionFeatures
	}

	Oneof struct {
		Base
		L1 OneofL1
	}
	OneofL1 struct {
		Options func() protoreflect.ProtoMessage
		Fields  OneofFields // must be consistent with Message.Fields.ContainingOneof

		EditionFeatures EditionFeatures
	}
)

func (md *Message) Options() protoreflect.ProtoMessage {
	if f := md.lazyInit().Options; f != nil {
		return f()
	}
	return descopts.Message
}
func (md *Message) IsMapEntry() bool                           { return md.L1.IsMapEntry }
func (md *Message) Fields() protoreflect.FieldDescriptors      { return &md.lazyInit().Fields }
func (md *Message) Oneofs() protoreflect.OneofDescriptors      { return &md.lazyInit().Oneofs }
func (md *Message) ReservedNames() protoreflect.Names          { return &md.lazyInit().ReservedNames }
func (md *Message) ReservedRanges() protoreflect.FieldRanges   { return &md.lazyInit().ReservedRanges }
func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers }
func (md *Message) ExtensionRanges() protoreflect.FieldRanges  { return &md.lazyInit().ExtensionRanges }
func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage {
	if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil {
		return f()
	}
	return descopts.ExtensionRange
}
func (md *Message) Enums() protoreflect.EnumDescriptors           { return &md.L1.Enums }
func (md *Message) Messages() protoreflect.MessageDescriptors     { return &md.L1.Messages }
func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions }
func (md *Message) ProtoType(protoreflect.MessageDescriptor)      {}
func (md *Message) Format(s fmt.State, r rune)                    { descfmt.FormatDesc(s, r, md) }
func (md *Message) lazyInit() *MessageL2 {
	md.L0.ParentFile.lazyInit() // implicitly initializes L2
	return md.L2
}

// IsMessageSet is a pseudo-internal API for checking whether a message
// should serialize in the proto1 message format.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (md *Message) IsMessageSet() bool {
	return md.L1.IsMessageSet
}

func (fd *Field) Options() protoreflect.ProtoMessage {
	if f := fd.L1.Options; f != nil {
		return f()
	}
	return descopts.Field
}
func (fd *Field) Number() protoreflect.FieldNumber      { return fd.L1.Number }
func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality }
func (fd *Field) Kind() protoreflect.Kind {
	return fd.L1.Kind
}
func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON }
func (fd *Field) JSONName() string  { return fd.L1.StringName.getJSON(fd) }
func (fd *Field) TextName() string  { return fd.L1.StringName.getText(fd) }
func (fd *Field) HasPresence() bool {
	if fd.L1.Cardinality == protoreflect.Repeated {
		return false
	}
	return fd.IsExtension() || fd.L1.EditionFeatures.IsFieldPresence || fd.L1.Message != nil || fd.L1.ContainingOneof != nil
}
func (fd *Field) HasOptionalKeyword() bool {
	return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional
}
func (fd *Field) IsPacked() bool {
	if fd.L1.Cardinality != protoreflect.Repeated {
		return false
	}
	switch fd.L1.Kind {
	case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
		return false
	}
	return fd.L1.EditionFeatures.IsPacked
}
func (fd *Field) IsExtension() bool { return false }
func (fd *Field) IsWeak() bool      { return fd.L1.IsWeak }
func (fd *Field) IsList() bool      { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() }
func (fd *Field) IsMap() bool       { return fd.Message() != nil && fd.Message().IsMapEntry() }
func (fd *Field) MapKey() protoreflect.FieldDescriptor {
	if !fd.IsMap() {
		return nil
	}
	return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number)
}
func (fd *Field) MapValue() protoreflect.FieldDescriptor {
	if !fd.IsMap() {
		return nil
	}
	return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number)
}
func (fd *Field) HasDefault() bool                                   { return fd.L1.Default.has }
func (fd *Field) Default() protoreflect.Value                        { return fd.L1.Default.get(fd) }
func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum }
func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor      { return fd.L1.ContainingOneof }
func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor {
	return fd.L0.Parent.(protoreflect.MessageDescriptor)
}
func (fd *Field) Enum() protoreflect.EnumDescriptor {
	return fd.L1.Enum
}
func (fd *Field) Message() protoreflect.MessageDescriptor {
	if fd.L1.IsWeak {
		if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil {
			return d.(protoreflect.MessageDescriptor)
		}
	}
	return fd.L1.Message
}
func (fd *Field) Format(s fmt.State, r rune)             { descfmt.FormatDesc(s, r, fd) }
func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {}

// EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8
// validation for the string field. This exists for Google-internal use only
// since proto3 did not enforce UTF-8 validity prior to the open-source release.
// If this method does not exist, the default is to enforce valid UTF-8.
//
// WARNING: This method is exempt from the compatibility promise and may be
// removed in the future without warning.
func (fd *Field) EnforceUTF8() bool {
	return fd.L1.EditionFeatures.IsUTF8Validated
}

func (od *Oneof) IsSynthetic() bool {
	return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword()
}
func (od *Oneof) Options() protoreflect.ProtoMessage {
	if f := od.L1.Options; f != nil {
		return f()
	}
	return descopts.Oneof
}
func (od *Oneof) Fields() protoreflect.FieldDescriptors  { return &od.L1.Fields }
func (od *Oneof) Format(s fmt.State, r rune)             { descfmt.FormatDesc(s, r, od) }
func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {}

type (
	Extension struct {
		Base
		L1 ExtensionL1
		L2 *ExtensionL2 // protected by fileDesc.once
	}
	ExtensionL1 struct {
		Number          protoreflect.FieldNumber
		Extendee        protoreflect.MessageDescriptor
		Cardinality     protoreflect.Cardinality
		Kind            protoreflect.Kind
		EditionFeatures EditionFeatures
		// To resolve the EditionFeatures we need to resolve the Extendee which
		// happens at the end of the initialization of L1. Thus, we need to buffer
		// the unresolved features (which are parsed when starting to initialize
		// L1). We cannot move this to L2 because it is required to initialize
		// Kind properly. Because some of the options (i.e. packed) affect the
		// EditionFeatures we need to unmarshal the full options after resolving
		// the Extendee.
		rawOptions []byte
	}
	ExtensionL2 struct {
		Options          func() protoreflect.ProtoMessage
		StringName       stringName
		IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto
		Default          defaultValue
		Enum             protoreflect.EnumDescriptor
		Message          protoreflect.MessageDescriptor
	}
)

func (xd *Extension) Options() protoreflect.ProtoMessage {
	if f := xd.lazyInit().Options; f != nil {
		return f()
	}
	return descopts.Field
}
func (xd *Extension) Number() protoreflect.FieldNumber      { return xd.L1.Number }
func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality }
func (xd *Extension) Kind() protoreflect.Kind               { return xd.L1.Kind }
func (xd *Extension) HasJSONName() bool                     { return xd.lazyInit().StringName.hasJSON }
func (xd *Extension) JSONName() string                      { return xd.lazyInit().StringName.getJSON(xd) }
func (xd *Extension) TextName() string                      { return xd.lazyInit().StringName.getText(xd) }
func (xd *Extension) HasPresence() bool                     { return xd.L1.Cardinality != protoreflect.Repeated }
func (xd *Extension) HasOptionalKeyword() bool {
	return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional
}
func (xd *Extension) IsPacked() bool                         { return xd.L1.EditionFeatures.IsPacked }
func (xd *Extension) IsExtension() bool                      { return true }
func (xd *Extension) IsWeak() bool                           { return false }
func (xd *Extension) IsList() bool                           { return xd.Cardinality() == protoreflect.Repeated }
func (xd *Extension) IsMap() bool                            { return false }
func (xd *Extension) MapKey() protoreflect.FieldDescriptor   { return nil }
func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil }
func (xd *Extension) HasDefault() bool                       { return xd.lazyInit().Default.has }
func (xd *Extension) Default() protoreflect.Value            { return xd.lazyInit().Default.get(xd) }
func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor {
	return xd.lazyInit().Default.enum
}
func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor     { return nil }
func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee }
func (xd *Extension) Enum() protoreflect.EnumDescriptor                 { return xd.lazyInit().Enum }
func (xd *Extension) Message() protoreflect.MessageDescriptor           { return xd.lazyInit().Message }
func (xd *Extension) Format(s fmt.State, r rune)                        { descfmt.FormatDesc(s, r, xd) }
func (xd *Extension) ProtoType(protoreflect.FieldDescriptor)            {}
func (xd *Extension) ProtoInternal(pragma.DoNotImplement)               {}
func (xd *Extension) lazyInit() *ExtensionL2 {
	xd.L0.ParentFile.lazyInit() // implicitly initializes L2
	return xd.L2
}

type (
	Service struct {
		Base
		L1 ServiceL1
		L2 *ServiceL2 // protected by fileDesc.once
	}
	ServiceL1 struct{}
	ServiceL2 struct {
		Options func() protoreflect.ProtoMessage
		Methods Methods
	}

	Method struct {
		Base
		L1 MethodL1
	}
	MethodL1 struct {
		Options           func() protoreflect.ProtoMessage
		Input             protoreflect.MessageDescriptor
		Output            protoreflect.MessageDescriptor
		IsStreamingClient bool
		IsStreamingServer bool
	}
)

func (sd *Service) Options() protoreflect.ProtoMessage {
	if f := sd.lazyInit().Options; f != nil {
		return f()
	}
	return descopts.Service
}
func (sd *Service) Methods() protoreflect.MethodDescriptors  { return &sd.lazyInit().Methods }
func (sd *Service) Format(s fmt.State, r rune)               { descfmt.FormatDesc(s, r, sd) }
func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {}
func (sd *Service) ProtoInternal(pragma.DoNotImplement)      {}
func (sd *Service) lazyInit() *ServiceL2 {
	sd.L0.ParentFile.lazyInit() // implicitly initializes L2
	return sd.L2
}

func (md *Method) Options() protoreflect.ProtoMessage {
	if f := md.L1.Options; f != nil {
		return f()
	}
	return descopts.Method
}
func (md *Method) Input() protoreflect.MessageDescriptor   { return md.L1.Input }
func (md *Method) Output() protoreflect.MessageDescriptor  { return md.L1.Output }
func (md *Method) IsStreamingClient() bool                 { return md.L1.IsStreamingClient }
func (md *Method) IsStreamingServer() bool                 { return md.L1.IsStreamingServer }
func (md *Method) Format(s fmt.State, r rune)              { descfmt.FormatDesc(s, r, md) }
func (md *Method) ProtoType(protoreflect.MethodDescriptor) {}
func (md *Method) ProtoInternal(pragma.DoNotImplement)     {}

// Surrogate files are can be used to create standalone descriptors
// where the syntax is only information derived from the parent file.
var (
	SurrogateProto2      = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}}
	SurrogateProto3      = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}}
	SurrogateEdition2023 = &File{L1: FileL1{Syntax: protoreflect.Editions, Edition: Edition2023}, L2: &FileL2{}}
)

type (
	Base struct {
		L0 BaseL0
	}
	BaseL0 struct {
		FullName   protoreflect.FullName // must be populated
		ParentFile *File                 // must be populated
		Parent     protoreflect.Descriptor
		Index      int
	}
)

func (d *Base) Name() protoreflect.Name         { return d.L0.FullName.Name() }
func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName }
func (d *Base) ParentFile() protoreflect.FileDescriptor {
	if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 {
		return nil // surrogate files are not real parents
	}
	return d.L0.ParentFile
}
func (d *Base) Parent() protoreflect.Descriptor     { return d.L0.Parent }
func (d *Base) Index() int                          { return d.L0.Index }
func (d *Base) Syntax() protoreflect.Syntax         { return d.L0.ParentFile.Syntax() }
func (d *Base) IsPlaceholder() bool                 { return false }
func (d *Base) ProtoInternal(pragma.DoNotImplement) {}

type stringName struct {
	hasJSON  bool
	once     sync.Once
	nameJSON string
	nameText string
}

// InitJSON initializes the name. It is exported for use by other internal packages.
func (s *stringName) InitJSON(name string) {
	s.hasJSON = true
	s.nameJSON = name
}

// Returns true if this field is structured like the synthetic field of a proto2
// group. This allows us to expand our treatment of delimited fields without
// breaking proto2 files that have been upgraded to editions.
func isGroupLike(fd protoreflect.FieldDescriptor) bool {
	// Groups are always group types.
	if fd.Kind() != protoreflect.GroupKind {
		return false
	}

	// Group fields are always the lowercase type name.
	if strings.ToLower(string(fd.Message().Name())) != string(fd.Name()) {
		return false
	}

	// Groups could only be defined in the same file they're used.
	if fd.Message().ParentFile() != fd.ParentFile() {
		return false
	}

	// Group messages are always defined in the same scope as the field.  File
	// level extensions will compare NULL == NULL here, which is why the file
	// comparison above is necessary to ensure both come from the same file.
	if fd.IsExtension() {
		return fd.Parent() == fd.Message().Parent()
	}
	return fd.ContainingMessage() == fd.Message().Parent()
}

func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName {
	s.once.Do(func() {
		if fd.IsExtension() {
			// For extensions, JSON and text are formatted the same way.
			var name string
			if messageset.IsMessageSetExtension(fd) {
				name = string("[" + fd.FullName().Parent() + "]")
			} else {
				name = string("[" + fd.FullName() + "]")
			}
			s.nameJSON = name
			s.nameText = name
		} else {
			// Format the JSON name.
			if !s.hasJSON {
				s.nameJSON = strs.JSONCamelCase(string(fd.Name()))
			}

			// Format the text name.
			s.nameText = string(fd.Name())
			if isGroupLike(fd) {
				s.nameText = string(fd.Message().Name())
			}
		}
	})
	return s
}

func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON }
func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText }

func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue {
	dv := defaultValue{has: v.IsValid(), val: v, enum: ev}
	if b, ok := v.Interface().([]byte); ok {
		// Store a copy of the default bytes, so that we can detect
		// accidental mutations of the original value.
		dv.bytes = append([]byte(nil), b...)
	}
	return dv
}

func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue {
	var evs protoreflect.EnumValueDescriptors
	if k == protoreflect.EnumKind {
		// If the enum is declared within the same file, be careful not to
		// blindly call the Values method, lest we bind ourselves in a deadlock.
		if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf {
			evs = &e.L2.Values
		} else {
			evs = ed.Values()
		}

		// If we are unable to resolve the enum dependency, use a placeholder
		// enum value since we will not be able to parse the default value.
		if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() {
			v := protoreflect.ValueOfEnum(0)
			ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b)))
			return DefaultValue(v, ev)
		}
	}

	v, ev, err := defval.Unmarshal(string(b), k, evs, defval.Descriptor)
	if err != nil {
		panic(err)
	}
	return DefaultValue(v, ev)
}

type defaultValue struct {
	has   bool
	val   protoreflect.Value
	enum  protoreflect.EnumValueDescriptor
	bytes []byte
}

func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value {
	// Return the zero value as the default if unpopulated.
	if !dv.has {
		if fd.Cardinality() == protoreflect.Repeated {
			return protoreflect.Value{}
		}
		switch fd.Kind() {
		case protoreflect.BoolKind:
			return protoreflect.ValueOfBool(false)
		case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
			return protoreflect.ValueOfInt32(0)
		case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
			return protoreflect.ValueOfInt64(0)
		case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
			return protoreflect.ValueOfUint32(0)
		case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
			return protoreflect.ValueOfUint64(0)
		case protoreflect.FloatKind:
			return protoreflect.ValueOfFloat32(0)
		case protoreflect.DoubleKind:
			return protoreflect.ValueOfFloat64(0)
		case protoreflect.StringKind:
			return protoreflect.ValueOfString("")
		case protoreflect.BytesKind:
			return protoreflect.ValueOfBytes(nil)
		case protoreflect.EnumKind:
			if evs := fd.Enum().Values(); evs.Len() > 0 {
				return protoreflect.ValueOfEnum(evs.Get(0).Number())
			}
			return protoreflect.ValueOfEnum(0)
		}
	}

	if len(dv.bytes) > 0 && !bytes.Equal(dv.bytes, dv.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.
		panic(fmt.Sprintf("detected mutation on the default bytes for %v", fd.FullName()))
	}
	return dv.val
}
