servicestate.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. Annotations: append(api.Service.Annotations, s.annos...),
  39. Routes: append(api.Service.Routes, routes...),
  40. Groups: append(api.Service.Groups, spec.Group{
  41. Annotations: s.annos,
  42. Routes: routes,
  43. }),
  44. }
  45. return newRootState(s.r, s.lineNumber), nil
  46. }
  47. type serviceEntityParser struct {
  48. acceptName func(name string)
  49. acceptRoute func(route spec.Route)
  50. }
  51. func (p *serviceEntityParser) parseLine(line string, api *spec.ApiSpec, annos []spec.Annotation) error {
  52. var defaultErr = fmt.Errorf("wrong line %q, %q", line, routeSyntax)
  53. line = strings.TrimSpace(line)
  54. var buffer = new(bytes.Buffer)
  55. buffer.WriteString(line)
  56. reader := bufio.NewReader(buffer)
  57. var builder strings.Builder
  58. var fields = make([]string, 0)
  59. for {
  60. ch, _, err := reader.ReadRune()
  61. if err != nil {
  62. if err == io.EOF {
  63. break
  64. }
  65. return err
  66. }
  67. switch {
  68. case isSpace(ch), ch == leftParenthesis, ch == rightParenthesis, ch == semicolon:
  69. if builder.Len() == 0 {
  70. continue
  71. }
  72. token := builder.String()
  73. builder.Reset()
  74. fields = append(fields, token)
  75. default:
  76. builder.WriteRune(ch)
  77. }
  78. }
  79. if len(fields) < 2 {
  80. return defaultErr
  81. }
  82. method := fields[0]
  83. path := fields[1]
  84. var req string
  85. var resp string
  86. if len(fields) > 2 {
  87. req = fields[2]
  88. }
  89. if stringx.Contains(fields, returnsTag) {
  90. if fields[len(fields)-1] != returnsTag {
  91. resp = fields[len(fields)-1]
  92. } else {
  93. return defaultErr
  94. }
  95. if fields[2] == returnsTag {
  96. req = ""
  97. }
  98. }
  99. p.acceptRoute(spec.Route{
  100. Annotations: annos,
  101. Method: method,
  102. Path: path,
  103. RequestType: GetType(api, req),
  104. ResponseType: GetType(api, resp),
  105. })
  106. return nil
  107. }
  108. func (p *serviceEntityParser) setEntityName(name string) {
  109. p.acceptName(name)
  110. }