高级排程
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.7 KiB

  1. package rpc
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. )
  7. var errorType = reflect.TypeOf((*error)(nil)).Elem()
  8. func getFullName(t reflect.Type) string {
  9. if "" == t.PkgPath() {
  10. return t.Name()
  11. } else {
  12. return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name())
  13. }
  14. }
  15. type MethodInvokerBuilder struct {
  16. valueParserBuilder *ValueParserBuilder
  17. presetTypes map[reflect.Type]valueParser
  18. }
  19. func (builder *MethodInvokerBuilder) checkOutType(parameterType reflect.Type) (bool, string) {
  20. switch parameterType.Kind() {
  21. case reflect.Invalid:
  22. return false, parameterType.Name()
  23. case reflect.Bool:
  24. return true, parameterType.Name()
  25. case reflect.Int:
  26. return true, parameterType.Name()
  27. case reflect.Int8:
  28. return true, parameterType.Name()
  29. case reflect.Int16:
  30. return true, parameterType.Name()
  31. case reflect.Int32:
  32. return true, parameterType.Name()
  33. case reflect.Int64:
  34. return true, parameterType.Name()
  35. case reflect.Uint:
  36. return true, parameterType.Name()
  37. case reflect.Uint8:
  38. return true, parameterType.Name()
  39. case reflect.Uint16:
  40. return true, parameterType.Name()
  41. case reflect.Uint32:
  42. return true, parameterType.Name()
  43. case reflect.Uint64:
  44. return true, parameterType.Name()
  45. case reflect.Uintptr:
  46. return false, parameterType.Name()
  47. case reflect.Float32:
  48. return true, parameterType.Name()
  49. case reflect.Float64:
  50. return true, parameterType.Name()
  51. case reflect.Complex64:
  52. return false, parameterType.Name()
  53. case reflect.Complex128:
  54. return false, parameterType.Name()
  55. case reflect.Array:
  56. if ok, typeText := builder.checkOutType(parameterType.Elem()); ok {
  57. return true, fmt.Sprintf("[%d]%s", parameterType.Len(), typeText)
  58. } else {
  59. return false, fmt.Sprintf("[%d]%s", parameterType.Len(), typeText)
  60. }
  61. case reflect.Chan:
  62. return false, parameterType.Name()
  63. case reflect.Func:
  64. return false, parameterType.Name()
  65. case reflect.Interface:
  66. return true, getFullName(parameterType)
  67. case reflect.Map:
  68. keyOk, keyTypeText := builder.checkOutType(parameterType.Key())
  69. valueOk, valueTypeText := builder.checkOutType(parameterType.Elem())
  70. if keyOk && valueOk {
  71. return true, fmt.Sprintf("*map[%s]%s", keyTypeText, valueTypeText)
  72. } else {
  73. return false, fmt.Sprintf("*map[%s]%s", keyTypeText, valueTypeText)
  74. }
  75. case reflect.Ptr:
  76. if ok, typeText := builder.checkOutType(parameterType.Elem()); ok {
  77. return true, fmt.Sprintf("*%s", typeText)
  78. } else {
  79. return false, fmt.Sprintf("*%s", typeText)
  80. }
  81. case reflect.Slice:
  82. if ok, typeText := builder.checkOutType(parameterType.Elem()); ok {
  83. return true, fmt.Sprintf("[]%s", typeText)
  84. } else {
  85. return false, fmt.Sprintf("[]%s", typeText)
  86. }
  87. case reflect.String:
  88. return true, parameterType.Name()
  89. case reflect.Struct:
  90. return true, getFullName(parameterType)
  91. case reflect.UnsafePointer:
  92. return false, parameterType.Name()
  93. default:
  94. return false, "Unknown"
  95. }
  96. }
  97. func (builder *MethodInvokerBuilder) buildParameterParser(serviceName string, parameterType reflect.Type, parameterIndex int) (valueParser, error) {
  98. if presetParameterParser, ok := builder.presetTypes[parameterType]; ok {
  99. return presetParameterParser, nil
  100. } else if parameterParser, err := builder.valueParserBuilder.Build(fmt.Sprintf("%s-in#%d", serviceName, parameterIndex), parameterType); err != nil {
  101. return nil, err
  102. } else {
  103. return parameterParser, nil
  104. }
  105. }
  106. func (builder *MethodInvokerBuilder) buildParameterParsers(serviceMethodName string, methodType reflect.Type) ([]valueParser, error) {
  107. if methodType.NumOut() < 1 || 2 < methodType.NumOut() {
  108. return nil, errors.New(fmt.Sprintf("返回值数量错误! Service: %s 返回值数量: %d", serviceMethodName, methodType.NumOut()))
  109. }
  110. if methodType.Out(methodType.NumOut()-1) != errorType {
  111. return nil, errors.New(fmt.Sprintf("最后一个返回值类型错误! Service: %s 类型:%s", serviceMethodName, methodType.Out(methodType.NumOut()-1)))
  112. }
  113. for i := 0; i < methodType.NumOut(); i++ {
  114. if ok, typeText := builder.checkOutType(methodType.Out(i)); !ok {
  115. return nil, errors.New(fmt.Sprintf("不支持的返回值类型! Service: %s 参数: #%d 类型: %s", serviceMethodName, i+1, typeText))
  116. }
  117. }
  118. parameterParsers := make([]valueParser, 0, 10)
  119. for i := 0; i < methodType.NumIn(); i++ {
  120. if parameterParser, err := builder.buildParameterParser(serviceMethodName, methodType.In(i), i); err != nil {
  121. return nil, err
  122. } else {
  123. parameterParsers = append(parameterParsers, parameterParser)
  124. }
  125. }
  126. return parameterParsers, nil
  127. }
  128. func (builder *MethodInvokerBuilder) buildMethodInvoker(serviceName string, methodType reflect.Type, call func([]reflect.Value) []reflect.Value) (*MethodInvoker, error) {
  129. parameterParsers, err := builder.buildParameterParsers(serviceName, methodType)
  130. if err != nil {
  131. return nil, err
  132. }
  133. return NewMethodInvoker(call, parameterParsers), nil
  134. }