api.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. package ast
  2. import (
  3. "fmt"
  4. "sort"
  5. "github.com/tal-tech/go-zero/tools/goctl/api/parser/g4/gen/api"
  6. )
  7. type Api struct {
  8. LinePrefix string
  9. Syntax *SyntaxExpr
  10. Import []*ImportExpr
  11. importM map[string]PlaceHolder
  12. Info *InfoExpr
  13. Type []TypeExpr
  14. typeM map[string]PlaceHolder
  15. Service []*Service
  16. serviceM map[string]PlaceHolder
  17. handlerM map[string]PlaceHolder
  18. routeM map[string]PlaceHolder
  19. }
  20. func (v *ApiVisitor) VisitApi(ctx *api.ApiContext) interface{} {
  21. var final Api
  22. final.importM = map[string]PlaceHolder{}
  23. final.typeM = map[string]PlaceHolder{}
  24. final.serviceM = map[string]PlaceHolder{}
  25. final.handlerM = map[string]PlaceHolder{}
  26. final.routeM = map[string]PlaceHolder{}
  27. for _, each := range ctx.AllSpec() {
  28. root := each.Accept(v).(*Api)
  29. v.acceptSyntax(root, &final)
  30. v.accetpImport(root, &final)
  31. v.acceptInfo(root, &final)
  32. v.acceptType(root, &final)
  33. v.acceptService(root, &final)
  34. }
  35. return &final
  36. }
  37. func (v *ApiVisitor) acceptService(root *Api, final *Api) {
  38. for _, service := range root.Service {
  39. if _, ok := final.serviceM[service.ServiceApi.Name.Text()]; !ok && len(final.serviceM) > 0 {
  40. v.panic(service.ServiceApi.Name, fmt.Sprintf("mutiple service declaration"))
  41. }
  42. v.duplicateServerItemCheck(service)
  43. for _, route := range service.ServiceApi.ServiceRoute {
  44. uniqueRoute := fmt.Sprintf("%s %s", route.Route.Method.Text(), route.Route.Path.Text())
  45. if _, ok := final.routeM[uniqueRoute]; ok {
  46. v.panic(route.Route.Method, fmt.Sprintf("duplicate route '%s'", uniqueRoute))
  47. }
  48. final.routeM[uniqueRoute] = Holder
  49. var handlerExpr Expr
  50. if route.AtServer != nil {
  51. atServerM := map[string]PlaceHolder{}
  52. for _, kv := range route.AtServer.Kv {
  53. if _, ok := atServerM[kv.Key.Text()]; ok {
  54. v.panic(kv.Key, fmt.Sprintf("duplicate key '%s'", kv.Key.Text()))
  55. }
  56. atServerM[kv.Key.Text()] = Holder
  57. if kv.Key.Text() == "handler" {
  58. handlerExpr = kv.Value
  59. }
  60. }
  61. }
  62. if route.AtHandler != nil {
  63. handlerExpr = route.AtHandler.Name
  64. }
  65. if handlerExpr == nil {
  66. v.panic(route.Route.Method, fmt.Sprintf("mismtached handler"))
  67. }
  68. if handlerExpr.Text() == "" {
  69. v.panic(handlerExpr, fmt.Sprintf("mismtached handler"))
  70. }
  71. if _, ok := final.handlerM[handlerExpr.Text()]; ok {
  72. v.panic(handlerExpr, fmt.Sprintf("duplicate handler '%s'", handlerExpr.Text()))
  73. }
  74. final.handlerM[handlerExpr.Text()] = Holder
  75. }
  76. final.Service = append(final.Service, service)
  77. }
  78. }
  79. func (v *ApiVisitor) duplicateServerItemCheck(service *Service) {
  80. if service.AtServer != nil {
  81. atServerM := map[string]PlaceHolder{}
  82. for _, kv := range service.AtServer.Kv {
  83. if _, ok := atServerM[kv.Key.Text()]; ok {
  84. v.panic(kv.Key, fmt.Sprintf("duplicate key '%s'", kv.Key.Text()))
  85. }
  86. atServerM[kv.Key.Text()] = Holder
  87. }
  88. }
  89. }
  90. func (v *ApiVisitor) acceptType(root *Api, final *Api) {
  91. for _, tp := range root.Type {
  92. if _, ok := final.typeM[tp.NameExpr().Text()]; ok {
  93. v.panic(tp.NameExpr(), fmt.Sprintf("duplicate type '%s'", tp.NameExpr().Text()))
  94. }
  95. final.typeM[tp.NameExpr().Text()] = Holder
  96. final.Type = append(final.Type, tp)
  97. }
  98. }
  99. func (v *ApiVisitor) acceptInfo(root *Api, final *Api) {
  100. if root.Info != nil {
  101. infoM := map[string]PlaceHolder{}
  102. if final.Info != nil {
  103. v.panic(root.Info.Info, fmt.Sprintf("mutiple info declaration"))
  104. }
  105. for _, value := range root.Info.Kvs {
  106. if _, ok := infoM[value.Key.Text()]; ok {
  107. v.panic(value.Key, fmt.Sprintf("duplicate key '%s'", value.Key.Text()))
  108. }
  109. infoM[value.Key.Text()] = Holder
  110. }
  111. final.Info = root.Info
  112. }
  113. }
  114. func (v *ApiVisitor) accetpImport(root *Api, final *Api) {
  115. for _, imp := range root.Import {
  116. if _, ok := final.importM[imp.Value.Text()]; ok {
  117. v.panic(imp.Import, fmt.Sprintf("duplicate import '%s'", imp.Value.Text()))
  118. }
  119. final.importM[imp.Value.Text()] = Holder
  120. final.Import = append(final.Import, imp)
  121. }
  122. }
  123. func (v *ApiVisitor) acceptSyntax(root *Api, final *Api) {
  124. if root.Syntax != nil {
  125. if final.Syntax != nil {
  126. v.panic(root.Syntax.Syntax, fmt.Sprintf("mutiple syntax declaration"))
  127. }
  128. final.Syntax = root.Syntax
  129. }
  130. }
  131. func (v *ApiVisitor) VisitSpec(ctx *api.SpecContext) interface{} {
  132. var root Api
  133. if ctx.SyntaxLit() != nil {
  134. root.Syntax = ctx.SyntaxLit().Accept(v).(*SyntaxExpr)
  135. }
  136. if ctx.ImportSpec() != nil {
  137. root.Import = ctx.ImportSpec().Accept(v).([]*ImportExpr)
  138. }
  139. if ctx.InfoSpec() != nil {
  140. root.Info = ctx.InfoSpec().Accept(v).(*InfoExpr)
  141. }
  142. if ctx.TypeSpec() != nil {
  143. tp := ctx.TypeSpec().Accept(v)
  144. root.Type = tp.([]TypeExpr)
  145. }
  146. if ctx.ServiceSpec() != nil {
  147. root.Service = []*Service{ctx.ServiceSpec().Accept(v).(*Service)}
  148. }
  149. return &root
  150. }
  151. func (a *Api) Format() error {
  152. // todo
  153. return nil
  154. }
  155. func (a *Api) Equal(v interface{}) bool {
  156. if v == nil {
  157. return false
  158. }
  159. root, ok := v.(*Api)
  160. if !ok {
  161. return false
  162. }
  163. if !a.Syntax.Equal(root.Syntax) {
  164. return false
  165. }
  166. if len(a.Import) != len(root.Import) {
  167. return false
  168. }
  169. var expectingImport, actualImport []*ImportExpr
  170. expectingImport = append(expectingImport, a.Import...)
  171. actualImport = append(actualImport, root.Import...)
  172. sort.Slice(expectingImport, func(i, j int) bool {
  173. return expectingImport[i].Value.Text() < expectingImport[j].Value.Text()
  174. })
  175. sort.Slice(actualImport, func(i, j int) bool {
  176. return actualImport[i].Value.Text() < actualImport[j].Value.Text()
  177. })
  178. for index, each := range expectingImport {
  179. ac := actualImport[index]
  180. if !each.Equal(ac) {
  181. return false
  182. }
  183. }
  184. if !a.Info.Equal(root.Info) {
  185. return false
  186. }
  187. if len(a.Type) != len(root.Type) {
  188. return false
  189. }
  190. var expectingType, actualType []TypeExpr
  191. expectingType = append(expectingType, a.Type...)
  192. actualType = append(actualType, root.Type...)
  193. sort.Slice(expectingType, func(i, j int) bool {
  194. return expectingType[i].NameExpr().Text() < expectingType[j].NameExpr().Text()
  195. })
  196. sort.Slice(actualType, func(i, j int) bool {
  197. return actualType[i].NameExpr().Text() < actualType[j].NameExpr().Text()
  198. })
  199. for index, each := range expectingType {
  200. ac := actualType[index]
  201. if !each.Equal(ac) {
  202. return false
  203. }
  204. }
  205. if len(a.Service) != len(root.Service) {
  206. return false
  207. }
  208. var expectingService, actualService []*Service
  209. expectingService = append(expectingService, a.Service...)
  210. actualService = append(actualService, root.Service...)
  211. for index, each := range expectingService {
  212. ac := actualService[index]
  213. if !each.Equal(ac) {
  214. return false
  215. }
  216. }
  217. return true
  218. }