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 := ®istry.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 := ®istry.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 }