func (fd *FieldDescriptor) IsMap() bool {
	return fd.isMap
}
IsMap returns true if this is a map field. If so, it will have the "repeated"
label its type will be a message that represents a map entry. The map entry
message will have exactly two fields: tag #1 is the key and tag #2 is the value.
package desc
import (
	"bytes"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"unicode/utf8"
	"github.com/golang/protobuf/proto"
	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/jhump/protoreflect/desc/internal"
)
type Descriptor interface {
	GetName() string
	GetFullyQualifiedName() string
	GetParent() Descriptor
	GetFile() *FileDescriptor
	GetOptions() proto.Message
	GetSourceInfo() *dpb.SourceCodeInfo_Location
	AsProto() proto.Message
}
type sourceInfoRecomputeFunc = internal.SourceInfoComputeFunc
type FileDescriptor struct {
	proto      *dpb.FileDescriptorProto
	symbols    map[string]Descriptor
	deps       []*FileDescriptor
	publicDeps []*FileDescriptor
	weakDeps   []*FileDescriptor
	messages   []*MessageDescriptor
	enums      []*EnumDescriptor
	extensions []*FieldDescriptor
	services   []*ServiceDescriptor
	fieldIndex map[string]map[int32]*FieldDescriptor
	isProto3   bool
	sourceInfo internal.SourceInfoMap
	sourceInfoRecomputeFunc
}
func (fd *FileDescriptor) recomputeSourceInfo() {
	internal.PopulateSourceInfoMap(fd.proto, fd.sourceInfo)
}
func (fd *FileDescriptor) registerField(field *FieldDescriptor) {
	fields := fd.fieldIndex[field.owner.GetFullyQualifiedName()]
	if fields == nil {
		fields = map[int32]*FieldDescriptor{}
		fd.fieldIndex[field.owner.GetFullyQualifiedName()] = fields
	}
	fields[field.GetNumber()] = field
}
func (fd *FileDescriptor) GetName() string {
	return fd.proto.GetName()
}
func (fd *FileDescriptor) GetFullyQualifiedName() string {
	return fd.proto.GetName()
}
func (fd *FileDescriptor) GetPackage() string {
	return fd.proto.GetPackage()
}
func (fd *FileDescriptor) GetParent() Descriptor {
	return nil
}
func (fd *FileDescriptor) GetFile() *FileDescriptor {
	return fd
}
func (fd *FileDescriptor) GetOptions() proto.Message {
	return fd.proto.GetOptions()
}
func (fd *FileDescriptor) GetFileOptions() *dpb.FileOptions {
	return fd.proto.GetOptions()
}
func (fd *FileDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return nil
}
func (fd *FileDescriptor) AsProto() proto.Message {
	return fd.proto
}
func (fd *FileDescriptor) AsFileDescriptorProto() *dpb.FileDescriptorProto {
	return fd.proto
}
func (fd *FileDescriptor) String() string {
	return fd.proto.String()
}
func (fd *FileDescriptor) IsProto3() bool {
	return fd.isProto3
}
func (fd *FileDescriptor) GetDependencies() []*FileDescriptor {
	return fd.deps
}
func (fd *FileDescriptor) GetPublicDependencies() []*FileDescriptor {
	return fd.publicDeps
}
func (fd *FileDescriptor) GetWeakDependencies() []*FileDescriptor {
	return fd.weakDeps
}
func (fd *FileDescriptor) GetMessageTypes() []*MessageDescriptor {
	return fd.messages
}
func (fd *FileDescriptor) GetEnumTypes() []*EnumDescriptor {
	return fd.enums
}
func (fd *FileDescriptor) GetExtensions() []*FieldDescriptor {
	return fd.extensions
}
func (fd *FileDescriptor) GetServices() []*ServiceDescriptor {
	return fd.services
}
func (fd *FileDescriptor) FindSymbol(symbol string) Descriptor {
	if symbol[0] == '.' {
		symbol = symbol[1:]
	}
	return fd.symbols[symbol]
}
func (fd *FileDescriptor) FindMessage(msgName string) *MessageDescriptor {
	if md, ok := fd.symbols[msgName].(*MessageDescriptor); ok {
		return md
	} else {
		return nil
	}
}
func (fd *FileDescriptor) FindEnum(enumName string) *EnumDescriptor {
	if ed, ok := fd.symbols[enumName].(*EnumDescriptor); ok {
		return ed
	} else {
		return nil
	}
}
func (fd *FileDescriptor) FindService(serviceName string) *ServiceDescriptor {
	if sd, ok := fd.symbols[serviceName].(*ServiceDescriptor); ok {
		return sd
	} else {
		return nil
	}
}
func (fd *FileDescriptor) FindExtension(extendeeName string, tagNumber int32) *FieldDescriptor {
	if exd, ok := fd.fieldIndex[extendeeName][tagNumber]; ok && exd.IsExtension() {
		return exd
	} else {
		return nil
	}
}
func (fd *FileDescriptor) FindExtensionByName(extName string) *FieldDescriptor {
	if exd, ok := fd.symbols[extName].(*FieldDescriptor); ok && exd.IsExtension() {
		return exd
	} else {
		return nil
	}
}
type MessageDescriptor struct {
	proto          *dpb.DescriptorProto
	parent         Descriptor
	file           *FileDescriptor
	fields         []*FieldDescriptor
	nested         []*MessageDescriptor
	enums          []*EnumDescriptor
	extensions     []*FieldDescriptor
	oneOfs         []*OneOfDescriptor
	extRanges      extRanges
	fqn            string
	sourceInfoPath []int32
	jsonNames      jsonNameMap
	isProto3       bool
	isMapEntry     bool
}
func createMessageDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, md *dpb.DescriptorProto, symbols map[string]Descriptor) (*MessageDescriptor, string) {
	msgName := merge(enclosing, md.GetName())
	ret := &MessageDescriptor{proto: md, parent: parent, file: fd, fqn: msgName}
	for _, f := range md.GetField() {
		fld, n := createFieldDescriptor(fd, ret, msgName, f)
		symbols[n] = fld
		ret.fields = append(ret.fields, fld)
	}
	for _, nm := range md.NestedType {
		nmd, n := createMessageDescriptor(fd, ret, msgName, nm, symbols)
		symbols[n] = nmd
		ret.nested = append(ret.nested, nmd)
	}
	for _, e := range md.EnumType {
		ed, n := createEnumDescriptor(fd, ret, msgName, e, symbols)
		symbols[n] = ed
		ret.enums = append(ret.enums, ed)
	}
	for _, ex := range md.GetExtension() {
		exd, n := createFieldDescriptor(fd, ret, msgName, ex)
		symbols[n] = exd
		ret.extensions = append(ret.extensions, exd)
	}
	for i, o := range md.GetOneofDecl() {
		od, n := createOneOfDescriptor(fd, ret, i, msgName, o)
		symbols[n] = od
		ret.oneOfs = append(ret.oneOfs, od)
	}
	for _, r := range md.GetExtensionRange() {
		end := r.GetEnd() - 1
		ret.extRanges = append(ret.extRanges, proto.ExtensionRange{
			Start: r.GetStart(),
			End:   end})
	}
	sort.Sort(ret.extRanges)
	ret.isProto3 = fd.isProto3
	ret.isMapEntry = md.GetOptions().GetMapEntry() &&
		len(ret.fields) == 2 &&
		ret.fields[0].GetNumber() == 1 &&
		ret.fields[1].GetNumber() == 2
	return ret, msgName
}
func (md *MessageDescriptor) resolve(path []int32, scopes []scope) error {
	md.sourceInfoPath = append([]int32(nil), path...)  
	path = append(path, internal.Message_nestedMessagesTag)
	scopes = append(scopes, messageScope(md))
	for i, nmd := range md.nested {
		if err := nmd.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	path[len(path)-1] = internal.Message_enumsTag
	for i, ed := range md.enums {
		ed.resolve(append(path, int32(i)))
	}
	path[len(path)-1] = internal.Message_fieldsTag
	for i, fld := range md.fields {
		if err := fld.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	path[len(path)-1] = internal.Message_extensionsTag
	for i, exd := range md.extensions {
		if err := exd.resolve(append(path, int32(i)), scopes); err != nil {
			return err
		}
	}
	path[len(path)-1] = internal.Message_oneOfsTag
	for i, od := range md.oneOfs {
		od.resolve(append(path, int32(i)))
	}
	return nil
}
func (md *MessageDescriptor) GetName() string {
	return md.proto.GetName()
}
func (md *MessageDescriptor) GetFullyQualifiedName() string {
	return md.fqn
}
func (md *MessageDescriptor) GetParent() Descriptor {
	return md.parent
}
func (md *MessageDescriptor) GetFile() *FileDescriptor {
	return md.file
}
func (md *MessageDescriptor) GetOptions() proto.Message {
	return md.proto.GetOptions()
}
func (md *MessageDescriptor) GetMessageOptions() *dpb.MessageOptions {
	return md.proto.GetOptions()
}
func (md *MessageDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return md.file.sourceInfo.Get(md.sourceInfoPath)
}
func (md *MessageDescriptor) AsProto() proto.Message {
	return md.proto
}
func (md *MessageDescriptor) AsDescriptorProto() *dpb.DescriptorProto {
	return md.proto
}
func (md *MessageDescriptor) String() string {
	return md.proto.String()
}
func (md *MessageDescriptor) IsMapEntry() bool {
	return md.isMapEntry
}
func (md *MessageDescriptor) GetFields() []*FieldDescriptor {
	return md.fields
}
func (md *MessageDescriptor) GetNestedMessageTypes() []*MessageDescriptor {
	return md.nested
}
func (md *MessageDescriptor) GetNestedEnumTypes() []*EnumDescriptor {
	return md.enums
}
func (md *MessageDescriptor) GetNestedExtensions() []*FieldDescriptor {
	return md.extensions
}
func (md *MessageDescriptor) GetOneOfs() []*OneOfDescriptor {
	return md.oneOfs
}
func (md *MessageDescriptor) IsProto3() bool {
	return md.isProto3
}
func (md *MessageDescriptor) GetExtensionRanges() []proto.ExtensionRange {
	return md.extRanges
}
func (md *MessageDescriptor) IsExtendable() bool {
	return len(md.extRanges) > 0
}
func (md *MessageDescriptor) IsExtension(tagNumber int32) bool {
	return md.extRanges.IsExtension(tagNumber)
}
type extRanges []proto.ExtensionRange
func (er extRanges) String() string {
	var buf bytes.Buffer
	first := true
	for _, r := range er {
		if first {
			first = false
		} else {
			buf.WriteString(",")
		}
		fmt.Fprintf(&buf, "%d..%d", r.Start, r.End)
	}
	return buf.String()
}
func (er extRanges) IsExtension(tagNumber int32) bool {
	i := sort.Search(len(er), func(i int) bool { return er[i].End >= tagNumber })
	return i < len(er) && tagNumber >= er[i].Start
}
func (er extRanges) Len() int {
	return len(er)
}
func (er extRanges) Less(i, j int) bool {
	return er[i].Start < er[j].Start
}
func (er extRanges) Swap(i, j int) {
	er[i], er[j] = er[j], er[i]
}
func (md *MessageDescriptor) FindFieldByName(fieldName string) *FieldDescriptor {
	fqn := fmt.Sprintf("%s.%s", md.fqn, fieldName)
	if fd, ok := md.file.symbols[fqn].(*FieldDescriptor); ok && !fd.IsExtension() {
		return fd
	} else {
		return nil
	}
}
func (md *MessageDescriptor) FindFieldByNumber(tagNumber int32) *FieldDescriptor {
	if fd, ok := md.file.fieldIndex[md.fqn][tagNumber]; ok && !fd.IsExtension() {
		return fd
	} else {
		return nil
	}
}
type FieldDescriptor struct {
	proto          *dpb.FieldDescriptorProto
	parent         Descriptor
	owner          *MessageDescriptor
	file           *FileDescriptor
	oneOf          *OneOfDescriptor
	msgType        *MessageDescriptor
	enumType       *EnumDescriptor
	fqn            string
	sourceInfoPath []int32
	def            memoizedDefault
	isMap          bool
}
func createFieldDescriptor(fd *FileDescriptor, parent Descriptor, enclosing string, fld *dpb.FieldDescriptorProto) (*FieldDescriptor, string) {
	fldName := merge(enclosing, fld.GetName())
	ret := &FieldDescriptor{proto: fld, parent: parent, file: fd, fqn: fldName}
	if fld.GetExtendee() == "" {
		ret.owner = parent.(*MessageDescriptor)
	}
	return ret, fldName
}
func (fd *FieldDescriptor) resolve(path []int32, scopes []scope) error {
	if fd.proto.OneofIndex != nil && fd.oneOf == nil {
		return fmt.Errorf("could not link field %s to one-of index %d", fd.fqn, *fd.proto.OneofIndex)
	}
	fd.sourceInfoPath = append([]int32(nil), path...)  
	if fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_ENUM {
		if desc, err := resolve(fd.file, fd.proto.GetTypeName(), scopes); err != nil {
			return err
		} else {
			fd.enumType = desc.(*EnumDescriptor)
		}
	}
	if fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE || fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_GROUP {
		if desc, err := resolve(fd.file, fd.proto.GetTypeName(), scopes); err != nil {
			return err
		} else {
			fd.msgType = desc.(*MessageDescriptor)
		}
	}
	if fd.proto.GetExtendee() != "" {
		if desc, err := resolve(fd.file, fd.proto.GetExtendee(), scopes); err != nil {
			return err
		} else {
			fd.owner = desc.(*MessageDescriptor)
		}
	}
	fd.file.registerField(fd)
	fd.isMap = fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED &&
		fd.proto.GetType() == dpb.FieldDescriptorProto_TYPE_MESSAGE &&
		fd.GetMessageType().IsMapEntry()
	return nil
}
func (fd *FieldDescriptor) determineDefault() interface{} {
	if fd.IsMap() {
		return map[interface{}]interface{}(nil)
	} else if fd.IsRepeated() {
		return []interface{}(nil)
	} else if fd.msgType != nil {
		return nil
	}
	proto3 := fd.file.isProto3
	if !proto3 {
		def := fd.AsFieldDescriptorProto().GetDefaultValue()
		if def != "" {
			ret := parseDefaultValue(fd, def)
			if ret != nil {
				return ret
			}
		}
	}
	switch fd.GetType() {
	case dpb.FieldDescriptorProto_TYPE_FIXED32,
		dpb.FieldDescriptorProto_TYPE_UINT32:
		return uint32(0)
	case dpb.FieldDescriptorProto_TYPE_SFIXED32,
		dpb.FieldDescriptorProto_TYPE_INT32,
		dpb.FieldDescriptorProto_TYPE_SINT32:
		return int32(0)
	case dpb.FieldDescriptorProto_TYPE_FIXED64,
		dpb.FieldDescriptorProto_TYPE_UINT64:
		return uint64(0)
	case dpb.FieldDescriptorProto_TYPE_SFIXED64,
		dpb.FieldDescriptorProto_TYPE_INT64,
		dpb.FieldDescriptorProto_TYPE_SINT64:
		return int64(0)
	case dpb.FieldDescriptorProto_TYPE_FLOAT:
		return float32(0.0)
	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
		return float64(0.0)
	case dpb.FieldDescriptorProto_TYPE_BOOL:
		return false
	case dpb.FieldDescriptorProto_TYPE_BYTES:
		return []byte(nil)
	case dpb.FieldDescriptorProto_TYPE_STRING:
		return ""
	case dpb.FieldDescriptorProto_TYPE_ENUM:
		if proto3 {
			return int32(0)
		}
		enumVals := fd.GetEnumType().GetValues()
		if len(enumVals) > 0 {
			return enumVals[0].GetNumber()
		} else {
			return int32(0)  
		}
	default:
		panic(fmt.Sprintf("Unknown field type: %v", fd.GetType()))
	}
}
func parseDefaultValue(fd *FieldDescriptor, val string) interface{} {
	switch fd.GetType() {
	case dpb.FieldDescriptorProto_TYPE_ENUM:
		vd := fd.GetEnumType().FindValueByName(val)
		if vd != nil {
			return vd.GetNumber()
		}
		return nil
	case dpb.FieldDescriptorProto_TYPE_BOOL:
		if val == "true" {
			return true
		} else if val == "false" {
			return false
		}
		return nil
	case dpb.FieldDescriptorProto_TYPE_BYTES:
		return []byte(unescape(val))
	case dpb.FieldDescriptorProto_TYPE_STRING:
		return val
	case dpb.FieldDescriptorProto_TYPE_FLOAT:
		if f, err := strconv.ParseFloat(val, 32); err == nil {
			return float32(f)
		} else {
			return float32(0)
		}
	case dpb.FieldDescriptorProto_TYPE_DOUBLE:
		if f, err := strconv.ParseFloat(val, 64); err == nil {
			return f
		} else {
			return float64(0)
		}
	case dpb.FieldDescriptorProto_TYPE_INT32,
		dpb.FieldDescriptorProto_TYPE_SINT32,
		dpb.FieldDescriptorProto_TYPE_SFIXED32:
		if i, err := strconv.ParseInt(val, 10, 32); err == nil {
			return int32(i)
		} else {
			return int32(0)
		}
	case dpb.FieldDescriptorProto_TYPE_UINT32,
		dpb.FieldDescriptorProto_TYPE_FIXED32:
		if i, err := strconv.ParseUint(val, 10, 32); err == nil {
			return uint32(i)
		} else {
			return uint32(0)
		}
	case dpb.FieldDescriptorProto_TYPE_INT64,
		dpb.FieldDescriptorProto_TYPE_SINT64,
		dpb.FieldDescriptorProto_TYPE_SFIXED64:
		if i, err := strconv.ParseInt(val, 10, 64); err == nil {
			return i
		} else {
			return int64(0)
		}
	case dpb.FieldDescriptorProto_TYPE_UINT64,
		dpb.FieldDescriptorProto_TYPE_FIXED64:
		if i, err := strconv.ParseUint(val, 10, 64); err == nil {
			return i
		} else {
			return uint64(0)
		}
	default:
		return nil
	}
}
func unescape(s string) string {
	out := make([]byte, 0, len(s))
	var buf [4]byte
	for len(s) > 0 {
		if s[0] != '\\' || len(s) < 2 {
			out = append(out, s[0])
			s = s[1:]
		} else if s[1] == 'x' || s[1] == 'X' {
			n := matchPrefix(s[2:], 2, isHex)
			if n == 0 {
				out = append(out, s[:2]...)
				s = s[2:]
			} else {
				c, err := strconv.ParseUint(s[2:2+n], 16, 8)
				if err != nil {
					out = append(out, s[:2+n]...)
				} else {
					out = append(out, byte(c))
				}
				s = s[2+n:]
			}
		} else if s[1] >= '0' && s[1] <= '7' {
			n := 1 + matchPrefix(s[2:], 2, isOctal)
			c, err := strconv.ParseUint(s[1:1+n], 8, 8)
			if err != nil || c > 0xff {
				out = append(out, s[:1+n]...)
			} else {
				out = append(out, byte(c))
			}
			s = s[1+n:]
		} else if s[1] == 'u' {
			if len(s) < 6 {
				out = append(out, s...)
				s = s[len(s):]
			} else {
				c, err := strconv.ParseUint(s[2:6], 16, 16)
				if err != nil {
					out = append(out, s[:6]...)
				} else {
					w := utf8.EncodeRune(buf[:], rune(c))
					out = append(out, buf[:w]...)
				}
				s = s[6:]
			}
		} else if s[1] == 'U' {
			if len(s) < 10 {
				out = append(out, s...)
				s = s[len(s):]
			} else {
				c, err := strconv.ParseUint(s[2:10], 16, 32)
				if err != nil || c > 0x10ffff {
					out = append(out, s[:10]...)
				} else {
					w := utf8.EncodeRune(buf[:], rune(c))
					out = append(out, buf[:w]...)
				}
				s = s[10:]
			}
		} else {
			switch s[1] {
			case 'a':
				out = append(out, '\a')
			case 'b':
				out = append(out, '\b')
			case 'f':
				out = append(out, '\f')
			case 'n':
				out = append(out, '\n')
			case 'r':
				out = append(out, '\r')
			case 't':
				out = append(out, '\t')
			case 'v':
				out = append(out, '\v')
			case '\\':
				out = append(out, '\\')
			case '\'':
				out = append(out, '\'')
			case '"':
				out = append(out, '"')
			case '?':
				out = append(out, '?')
			default:
				out = append(out, s[:2]...)
			}
			s = s[2:]
		}
	}
	return string(out)
}
func isOctal(b byte) bool { return b >= '0' && b <= '7' }
func isHex(b byte) bool {
	return (b >= '0' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F')
}
func matchPrefix(s string, limit int, fn func(byte) bool) int {
	l := len(s)
	if l > limit {
		l = limit
	}
	i := 0
	for ; i < l; i++ {
		if !fn(s[i]) {
			return i
		}
	}
	return i
}
func (fd *FieldDescriptor) GetName() string {
	return fd.proto.GetName()
}
func (fd *FieldDescriptor) GetNumber() int32 {
	return fd.proto.GetNumber()
}
func (fd *FieldDescriptor) GetFullyQualifiedName() string {
	return fd.fqn
}
func (fd *FieldDescriptor) GetParent() Descriptor {
	return fd.parent
}
func (fd *FieldDescriptor) GetFile() *FileDescriptor {
	return fd.file
}
func (fd *FieldDescriptor) GetOptions() proto.Message {
	return fd.proto.GetOptions()
}
func (fd *FieldDescriptor) GetFieldOptions() *dpb.FieldOptions {
	return fd.proto.GetOptions()
}
func (fd *FieldDescriptor) GetSourceInfo() *dpb.SourceCodeInfo_Location {
	return fd.file.sourceInfo.Get(fd.sourceInfoPath)
}
func (fd *FieldDescriptor) AsProto() proto.Message {
	return fd.proto
}
func (fd *FieldDescriptor) AsFieldDescriptorProto() *dpb.FieldDescriptorProto {
	return fd.proto
}
func (fd *FieldDescriptor) String() string {
	return fd.proto.String()
}
func (fd *FieldDescriptor) GetJSONName() string {
	if jsonName := fd.proto.GetJsonName(); jsonName != "" {
		return jsonName
	}
	return fd.proto.GetName()
}
func (fd *FieldDescriptor) GetFullyQualifiedJSONName() string {
	parent := fd.GetParent()
	switch parent := parent.(type) {
	case *FileDescriptor:
		pkg := parent.GetPackage()
		if pkg == "" {
			return fd.GetJSONName()
		}
		return fmt.Sprintf("%s.%s", pkg, fd.GetJSONName())
	default:
		return fmt.Sprintf("%s.%s", parent.GetFullyQualifiedName(), fd.GetJSONName())
	}
}
func (fd *FieldDescriptor) GetOwner() *MessageDescriptor {
	return fd.owner
}
func (fd *FieldDescriptor) IsExtension() bool {
	return fd.proto.GetExtendee() != ""
}
func (fd *FieldDescriptor) GetOneOf() *OneOfDescriptor {
	return fd.oneOf
}
func (fd *FieldDescriptor) GetType() dpb.FieldDescriptorProto_Type {
	return fd.proto.GetType()
}
func (fd *FieldDescriptor) GetLabel() dpb.FieldDescriptorProto_Label {
	return fd.proto.GetLabel()
}
func (fd *FieldDescriptor) IsRequired() bool {
	return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REQUIRED
}
func (fd *FieldDescriptor) IsRepeated() bool {
	return fd.proto.GetLabel() == dpb.FieldDescriptorProto_LABEL_REPEATED
}