gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/server/grpc/extractor.go (about)

     1  package grpc
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  
     8  	"gitee.com/liuxuezhan/go-micro-v1.18.0/registry"
     9  )
    10  
    11  func extractValue(v reflect.Type, d int) *registry.Value {
    12  	if d == 3 {
    13  		return nil
    14  	}
    15  	if v == nil {
    16  		return nil
    17  	}
    18  
    19  	if v.Kind() == reflect.Ptr {
    20  		v = v.Elem()
    21  	}
    22  
    23  	arg := &registry.Value{
    24  		Name: v.Name(),
    25  		Type: v.Name(),
    26  	}
    27  
    28  	switch v.Kind() {
    29  	case reflect.Struct:
    30  		for i := 0; i < v.NumField(); i++ {
    31  			f := v.Field(i)
    32  			val := extractValue(f.Type, d+1)
    33  			if val == nil {
    34  				continue
    35  			}
    36  
    37  			// if we can find a json tag use it
    38  			if tags := f.Tag.Get("json"); len(tags) > 0 {
    39  				parts := strings.Split(tags, ",")
    40  				if parts[0] == "-" || parts[0] == "omitempty" {
    41  					continue
    42  				}
    43  				val.Name = parts[0]
    44  			}
    45  
    46  			// if there's no name default it
    47  			if len(val.Name) == 0 {
    48  				val.Name = v.Field(i).Name
    49  			}
    50  
    51  			arg.Values = append(arg.Values, val)
    52  		}
    53  	case reflect.Slice:
    54  		p := v.Elem()
    55  		if p.Kind() == reflect.Ptr {
    56  			p = p.Elem()
    57  		}
    58  		arg.Type = "[]" + p.Name()
    59  	}
    60  
    61  	return arg
    62  }
    63  
    64  func extractEndpoint(method reflect.Method) *registry.Endpoint {
    65  	if method.PkgPath != "" {
    66  		return nil
    67  	}
    68  
    69  	var rspType, reqType reflect.Type
    70  	var stream bool
    71  	mt := method.Type
    72  
    73  	switch mt.NumIn() {
    74  	case 3:
    75  		reqType = mt.In(1)
    76  		rspType = mt.In(2)
    77  	case 4:
    78  		reqType = mt.In(2)
    79  		rspType = mt.In(3)
    80  	default:
    81  		return nil
    82  	}
    83  
    84  	// are we dealing with a stream?
    85  	switch rspType.Kind() {
    86  	case reflect.Func, reflect.Interface:
    87  		stream = true
    88  	}
    89  
    90  	request := extractValue(reqType, 0)
    91  	response := extractValue(rspType, 0)
    92  
    93  	ep := &registry.Endpoint{
    94  		Name:     method.Name,
    95  		Request:  request,
    96  		Response: response,
    97  		Metadata: make(map[string]string),
    98  	}
    99  
   100  	if stream {
   101  		ep.Metadata = map[string]string{
   102  			"stream": fmt.Sprintf("%v", stream),
   103  		}
   104  	}
   105  
   106  	return ep
   107  }
   108  
   109  func extractSubValue(typ reflect.Type) *registry.Value {
   110  	var reqType reflect.Type
   111  	switch typ.NumIn() {
   112  	case 1:
   113  		reqType = typ.In(0)
   114  	case 2:
   115  		reqType = typ.In(1)
   116  	case 3:
   117  		reqType = typ.In(2)
   118  	default:
   119  		return nil
   120  	}
   121  	return extractValue(reqType, 0)
   122  }