func prepareEndpoint(method reflect.Method) *methodType {
	mtype := method.Type
	mname := method.Name
	var replyType, argType, contextType reflect.Type
	var stream bool
	if method.PkgPath != "" {
		return nil
	}
	switch mtype.NumIn() {
	case 3:
		argType = mtype.In(2)
		contextType = mtype.In(1)
		stream = true
	case 4:
		argType = mtype.In(2)
		replyType = mtype.In(3)
		contextType = mtype.In(1)
	default:
		if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
			logger.Errorf("method %v of %v has wrong number of ins: %v", mname, mtype, mtype.NumIn())
		}
		return nil
	}
	if stream {
		streamType := reflect.TypeOf((*server.Stream)(nil)).Elem()
		if !argType.Implements(streamType) {
			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
				logger.Errorf("%v argument does not implement Streamer interface: %v", mname, argType)
			}
			return nil
		}
	} else {
		if !isExportedOrBuiltinType(argType) {
			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
				logger.Errorf("%v argument type not exported: %v", mname, argType)
			}
			return nil
		}
		if replyType.Kind() != reflect.Ptr {
			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
				logger.Errorf("method %v reply type not a pointer: %v", mname, replyType)
			}
			return nil
		}
		if !isExportedOrBuiltinType(replyType) {
			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
				logger.Errorf("method %v reply type not exported: %v", mname, replyType)
			}
			return nil
		}
	}
	if mtype.NumOut() != 1 {
		if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
			logger.Errorf("method %v has wrong number of outs: %v", mname, mtype.NumOut())
		}
		return nil
	}
	if returnType := mtype.Out(0); returnType != typeOfError {
		if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
			logger.Errorf("method %v returns %v not error", mname, returnType.String())
		}
		return nil
	}
	return &methodType{method: method, ArgType: argType, ReplyType: replyType, ContextType: contextType, stream: stream}
}
prepareEndpoint() returns a methodType for the provided method or nil
in case if the method was unsuitable.
package grpc
import (
	"context"
	"errors"
	"reflect"
	"sync"
	"unicode"
	"unicode/utf8"
	"github.com/micro/micro/v3/service/logger"
	"github.com/micro/micro/v3/service/server"
)
var (
	typeOfError = reflect.TypeOf((*error)(nil)).Elem()
)
type methodType struct {
	method      reflect.Method
	ArgType     reflect.Type
	ReplyType   reflect.Type
	ContextType reflect.Type
	stream      bool
}
type service struct {
	name   string                  
	rcvr   reflect.Value           
	typ    reflect.Type            
	method map[string]*methodType  
}
type rServer struct {
	mu         sync.Mutex  
	serviceMap map[string]*service
}
func isExported(name string) bool {
	rune, _ := utf8.DecodeRuneInString(name)
	return unicode.IsUpper(rune)
}
func isExportedOrBuiltinType(t reflect.Type) bool {
	for t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	return isExported(t.Name()) || t.PkgPath() == ""
}