servicestate.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package parser
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "github.com/tal-tech/go-zero/core/stringx"
  9. "github.com/tal-tech/go-zero/tools/goctl/api/spec"
  10. )
  11. type serviceState struct {
  12. *baseState
  13. annos []spec.Annotation
  14. }
  15. func newServiceState(state *baseState, annos []spec.Annotation) state {
  16. return &serviceState{
  17. baseState: state,
  18. annos: annos,
  19. }
  20. }
  21. func (s *serviceState) process(api *spec.ApiSpec) (state, error) {
  22. var name string
  23. var routes []spec.Route
  24. parser := &serviceEntityParser{
  25. acceptName: func(n string) {
  26. name = n
  27. },
  28. acceptRoute: func(route spec.Route) {
  29. routes = append(routes, route)
  30. },
  31. }
  32. ent := newEntity(s.baseState, api, parser)
  33. if err := ent.process(); err != nil {
  34. return nil, err
  35. }
  36. api.Service = spec.Service{
  37. Name: name,
  38. Groups: append(api.Service.Groups, spec.Group{
  39. Annotations: s.annos,
  40. Routes: routes,
  41. }),
  42. }
  43. return newRootState(s.r, s.lineNumber), nil
  44. }
  45. type serviceEntityParser struct {
  46. acceptName func(name string)
  47. acceptRoute func(route spec.Route)
  48. }
  49. func (p *serviceEntityParser) parseLine(line string, api *spec.ApiSpec, annos []spec.Annotation) error {
  50. var defaultErr = fmt.Errorf("wrong line %q, %q", line, routeSyntax)
  51. line = strings.TrimSpace(line)
  52. var buffer = new(bytes.Buffer)
  53. buffer.WriteString(line)
  54. reader := bufio.NewReader(buffer)
  55. var builder strings.Builder
  56. var fields = make([]string, 0)
  57. for {
  58. ch, _, err := reader.ReadRune()
  59. if err != nil {
  60. if err == io.EOF {
  61. if builder.Len() > 0 {
  62. token := strings.TrimSpace(builder.String())
  63. if len(token) > 0 && token != returnsTag {
  64. fields = append(fields, token)
  65. }
  66. }
  67. break
  68. }
  69. return err
  70. }
  71. switch {
  72. case isSpace(ch), ch == leftParenthesis, ch == rightParenthesis, ch == semicolon:
  73. if builder.Len() == 0 {
  74. continue
  75. }
  76. token := builder.String()
  77. builder.Reset()
  78. fields = append(fields, token)
  79. default:
  80. builder.WriteRune(ch)
  81. }
  82. }
  83. if len(fields) < 2 {
  84. return defaultErr
  85. }
  86. method := fields[0]
  87. path := fields[1]
  88. var req string
  89. var resp string
  90. if len(fields) > 2 {
  91. req = fields[2]
  92. }
  93. if stringx.Contains(fields, returnsTag) {
  94. if fields[len(fields)-1] != returnsTag {
  95. resp = fields[len(fields)-1]
  96. } else {
  97. return defaultErr
  98. }
  99. if fields[2] == returnsTag {
  100. req = ""
  101. }
  102. }
  103. p.acceptRoute(spec.Route{
  104. Annotations: annos,
  105. Method: method,
  106. Path: path,
  107. RequestType: GetType(api, req),
  108. ResponseType: GetType(api, resp),
  109. })
  110. return nil
  111. }
  112. func (p *serviceEntityParser) setEntityName(name string) {
  113. p.acceptName(name)
  114. }