servicestate.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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) < 3 {
  80. return defaultErr
  81. }
  82. method := fields[0]
  83. path := fields[1]
  84. req := fields[2]
  85. var returns string
  86. if stringx.Contains(fields, returnsTag) {
  87. if fields[len(fields)-1] != returnsTag {
  88. returns = fields[len(fields)-1]
  89. } else {
  90. return defaultErr
  91. }
  92. if fields[2] == returnsTag {
  93. req = ""
  94. }
  95. }
  96. p.acceptRoute(spec.Route{
  97. Annotations: annos,
  98. Method: method,
  99. Path: path,
  100. RequestType: GetType(api, req),
  101. ResponseType: GetType(api, returns),
  102. })
  103. return nil
  104. }
  105. func (p *serviceEntityParser) setEntityName(name string) {
  106. p.acceptName(name)
  107. }