func LoadMessageDescriptorForMessage(message proto.Message) (*MessageDescriptor, error) {
	return loadMessageDescriptorForMessage(message, nil)
}
LoadMessageDescriptorForMessage loads descriptor using the encoded descriptor proto
returned by message.Descriptor(). If the given type is not recognized, then a nil
descriptor is returned.
package desc
import (
	"fmt"
	"reflect"
	"sync"
	"github.com/golang/protobuf/proto"
	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/jhump/protoreflect/internal"
)
var (
	cacheMu       sync.RWMutex
	filesCache    = map[string]*FileDescriptor{}
	messagesCache = map[string]*MessageDescriptor{}
	enumCache     = map[reflect.Type]*EnumDescriptor{}
)
func LoadFileDescriptor(file string) (*FileDescriptor, error) {
	return loadFileDescriptor(file, nil)
}
func loadFileDescriptor(file string, r *ImportResolver) (*FileDescriptor, error) {
	f := getFileFromCache(file)
	if f != nil {
		return f, nil
	}
	cacheMu.Lock()
	defer cacheMu.Unlock()
	return loadFileDescriptorLocked(file, r)
}
func loadFileDescriptorLocked(file string, r *ImportResolver) (*FileDescriptor, error) {
	f := filesCache[file]
	if f != nil {
		return f, nil
	}
	fd, err := internal.LoadFileDescriptor(file)
	if err != nil {
		return nil, err
	}
	f, err = toFileDescriptorLocked(fd, r)
	if err != nil {
		return nil, err
	}
	putCacheLocked(file, f)
	return f, nil
}
func toFileDescriptorLocked(fd *dpb.FileDescriptorProto, r *ImportResolver) (*FileDescriptor, error) {
	deps := make([]*FileDescriptor, len(fd.GetDependency()))
	for i, dep := range fd.GetDependency() {
		resolvedDep := r.ResolveImport(fd.GetName(), dep)
		var err error
		deps[i], err = loadFileDescriptorLocked(resolvedDep, r)
		if _, ok := err.(internal.ErrNoSuchFile); ok && resolvedDep != dep {
			deps[i], err = loadFileDescriptorLocked(dep, r)
		}
		if err != nil {
			return nil, err
		}
	}
	return CreateFileDescriptor(fd, deps...)
}
func getFileFromCache(file string) *FileDescriptor {
	cacheMu.RLock()
	defer cacheMu.RUnlock()
	return filesCache[file]
}
func putCacheLocked(filename string, fd *FileDescriptor) {
	filesCache[filename] = fd
	putMessageCacheLocked(fd.messages)
}
func putMessageCacheLocked(mds []*MessageDescriptor) {
	for _, md := range mds {
		messagesCache[md.fqn] = md
		putMessageCacheLocked(md.nested)
	}
}
type protoMessage interface {
	proto.Message
	Descriptor() ([]byte, []int)
}
func LoadMessageDescriptor(message string) (*MessageDescriptor, error) {
	return loadMessageDescriptor(message, nil)
}
func loadMessageDescriptor(message string, r *ImportResolver) (*MessageDescriptor, error) {
	m := getMessageFromCache(message)
	if m != nil {
		return m, nil
	}
	pt := proto.MessageType(message)
	if pt == nil {
		return nil, nil
	}
	msg, err := messageFromType(pt)
	if err != nil {
		return nil, err
	}
	cacheMu.Lock()
	defer cacheMu.Unlock()
	return loadMessageDescriptorForTypeLocked(message, msg, r)
}
func LoadMessageDescriptorForType(messageType reflect.Type) (*MessageDescriptor, error) {
	return loadMessageDescriptorForType(messageType, nil)
}
func loadMessageDescriptorForType(messageType reflect.Type, r *ImportResolver) (*MessageDescriptor, error) {
	m, err := messageFromType(messageType)
	if err != nil {
		return nil, err
	}
	return loadMessageDescriptorForMessage(m, r)
}