servicestate.go 2.3 KB

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