func (r *ImportResolver) LoadMessageDescriptorForType(msgType reflect.Type) (*MessageDescriptor, error) {
	return loadMessageDescriptorForType(msgType, r)
}
LoadMessageDescriptorForType is the same as the package function of the same
name, but any alternate paths configured in this resolver are used when
linking files for the returned descriptor.
package desc
import (
	"fmt"
	"path/filepath"
	"reflect"
	"strings"
	"sync"
	"github.com/golang/protobuf/proto"
	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
)
var (
	globalImportPathConf map[string]string
	globalImportPathMu   sync.RWMutex
)
func RegisterImportPath(registerPath, importPath string) {
	if len(importPath) == 0 {
		panic("import path cannot be empty")
	}
	desc := proto.FileDescriptor(registerPath)
	if len(desc) == 0 {
		panic(fmt.Sprintf("path %q is not a registered proto file", registerPath))
	}
	globalImportPathMu.Lock()
	defer globalImportPathMu.Unlock()
	if reg := globalImportPathConf[importPath]; reg != "" {
		panic(fmt.Sprintf("import path %q already registered for %s", importPath, reg))
	}
	if globalImportPathConf == nil {
		globalImportPathConf = map[string]string{}
	}
	globalImportPathConf[importPath] = registerPath
}
func ResolveImport(importPath string) string {
	importPath = clean(importPath)
	globalImportPathMu.RLock()
	defer globalImportPathMu.RUnlock()
	reg := globalImportPathConf[importPath]
	if reg == "" {
		return importPath
	}
	return reg
}
type ImportResolver struct {
	children    map[string]*ImportResolver
	importPaths map[string]string
}
func (r *ImportResolver) ResolveImport(source, importPath string) string {
	if r != nil {
		res := r.resolveImport(clean(source), clean(importPath))
		if res != "" {
			return res
		}
	}
	return ResolveImport(importPath)
}
func (r *ImportResolver) resolveImport(source, importPath string) string {
	if source == "" {
		return r.importPaths[importPath]
	}
	var car, cdr string
	idx := strings.IndexRune(source, filepath.Separator)
	if idx < 0 {
		car, cdr = source, ""
	} else {
		car, cdr = source[:idx], source[idx+1:]
	}
	ch := r.children[car]
	if ch != nil {
		if reg := ch.resolveImport(cdr, importPath); reg != "" {
			return reg
		}
	}
	return r.importPaths[importPath]
}
func (r *ImportResolver) RegisterImportPath(registerPath, importPath string) {
	r.RegisterImportPathFrom(registerPath, importPath, "")
}
func (r *ImportResolver) RegisterImportPathFrom(registerPath, importPath, source string) {
	importPath = clean(importPath)
	if len(importPath) == 0 {
		panic("import path cannot be empty")
	}
	registerPath = clean(registerPath)
	if len(registerPath) == 0 {
		panic("registered path cannot be empty")
	}
	r.registerImportPathFrom(registerPath, importPath, clean(source))
}
func (r *ImportResolver) registerImportPathFrom(registerPath, importPath, source string) {
	if source == "" {
		if r.importPaths == nil {
			r.importPaths = map[string]string{}
		} else if reg := r.importPaths[importPath]; reg != "" {
			panic(fmt.Sprintf("already registered import path %q as %q", importPath, registerPath))
		}
		r.importPaths[importPath] = registerPath
		return
	}
	var car, cdr string
	idx := strings.IndexRune(source, filepath.Separator)
	if idx < 0 {
		car, cdr = source, ""
	} else {
		car, cdr = source[:idx], source[idx+1:]
	}
	ch := r.children[car]
	if ch == nil {
		if r.children == nil {
			r.children = map[string]*ImportResolver{}
		}
		ch = &ImportResolver{}
		r.children[car] = ch
	}
	ch.registerImportPathFrom(registerPath, importPath, cdr)
}
func (r *ImportResolver) LoadFileDescriptor(filePath string) (*FileDescriptor, error) {
	return loadFileDescriptor(filePath, r)
}
func (r *ImportResolver) LoadMessageDescriptor(msgName string) (*MessageDescriptor, error) {
	return loadMessageDescriptor(msgName, r)
}
func (r *ImportResolver) LoadMessageDescriptorForMessage(msg proto.Message) (*MessageDescriptor, error) {
	return loadMessageDescriptorForMessage(msg, r)
}