service.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  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. // Service describes service for api syntax
  8. type Service struct {
  9. AtServer *AtServer
  10. ServiceApi *ServiceApi
  11. }
  12. // KV defines a slice for KvExpr
  13. type KV []*KvExpr
  14. // AtServer describes server metadata for api syntax
  15. type AtServer struct {
  16. AtServerToken Expr
  17. Lp Expr
  18. Rp Expr
  19. Kv KV
  20. }
  21. // ServiceApi describes service ast for api syntax
  22. type ServiceApi struct {
  23. ServiceToken Expr
  24. Name Expr
  25. Lbrace Expr
  26. Rbrace Expr
  27. ServiceRoute []*ServiceRoute
  28. }
  29. // ServiceRoute describes service route ast for api syntax
  30. type ServiceRoute struct {
  31. AtDoc *AtDoc
  32. AtServer *AtServer
  33. AtHandler *AtHandler
  34. Route *Route
  35. }
  36. // AtDoc describes service comments ast for api syntax
  37. type AtDoc struct {
  38. AtDocToken Expr
  39. Lp Expr
  40. Rp Expr
  41. LineDoc Expr
  42. Kv []*KvExpr
  43. }
  44. // AtHandler describes service hander ast for api syntax
  45. type AtHandler struct {
  46. AtHandlerToken Expr
  47. Name Expr
  48. DocExpr []Expr
  49. CommentExpr Expr
  50. }
  51. // Route describes route ast for api syntax
  52. type Route struct {
  53. Method Expr
  54. Path Expr
  55. Req *Body
  56. ReturnToken Expr
  57. Reply *Body
  58. DocExpr []Expr
  59. CommentExpr Expr
  60. }
  61. // Body describes request,response body ast for api syntax
  62. type Body struct {
  63. Lp Expr
  64. Rp Expr
  65. Name DataType
  66. }
  67. // VisitServiceSpec implements from api.BaseApiParserVisitor
  68. func (v *ApiVisitor) VisitServiceSpec(ctx *api.ServiceSpecContext) interface{} {
  69. var serviceSpec Service
  70. if ctx.AtServer() != nil {
  71. serviceSpec.AtServer = ctx.AtServer().Accept(v).(*AtServer)
  72. }
  73. serviceSpec.ServiceApi = ctx.ServiceApi().Accept(v).(*ServiceApi)
  74. return &serviceSpec
  75. }
  76. // VisitAtServer implements from api.BaseApiParserVisitor
  77. func (v *ApiVisitor) VisitAtServer(ctx *api.AtServerContext) interface{} {
  78. var atServer AtServer
  79. atServer.AtServerToken = v.newExprWithTerminalNode(ctx.ATSERVER())
  80. atServer.Lp = v.newExprWithToken(ctx.GetLp())
  81. atServer.Rp = v.newExprWithToken(ctx.GetRp())
  82. for _, each := range ctx.AllKvLit() {
  83. atServer.Kv = append(atServer.Kv, each.Accept(v).(*KvExpr))
  84. }
  85. return &atServer
  86. }
  87. // VisitServiceApi implements from api.BaseApiParserVisitor
  88. func (v *ApiVisitor) VisitServiceApi(ctx *api.ServiceApiContext) interface{} {
  89. var serviceApi ServiceApi
  90. serviceApi.ServiceToken = v.newExprWithToken(ctx.GetServiceToken())
  91. serviceName := ctx.ServiceName()
  92. serviceApi.Name = v.newExprWithText(serviceName.GetText(), serviceName.GetStart().GetLine(), serviceName.GetStart().GetColumn(), serviceName.GetStart().GetStart(), serviceName.GetStop().GetStop())
  93. serviceApi.Lbrace = v.newExprWithToken(ctx.GetLbrace())
  94. serviceApi.Rbrace = v.newExprWithToken(ctx.GetRbrace())
  95. for _, each := range ctx.AllServiceRoute() {
  96. serviceApi.ServiceRoute = append(serviceApi.ServiceRoute, each.Accept(v).(*ServiceRoute))
  97. }
  98. return &serviceApi
  99. }
  100. // VisitServiceRoute implements from api.BaseApiParserVisitor
  101. func (v *ApiVisitor) VisitServiceRoute(ctx *api.ServiceRouteContext) interface{} {
  102. var serviceRoute ServiceRoute
  103. if ctx.AtDoc() != nil {
  104. serviceRoute.AtDoc = ctx.AtDoc().Accept(v).(*AtDoc)
  105. }
  106. if ctx.AtServer() != nil {
  107. serviceRoute.AtServer = ctx.AtServer().Accept(v).(*AtServer)
  108. } else if ctx.AtHandler() != nil {
  109. serviceRoute.AtHandler = ctx.AtHandler().Accept(v).(*AtHandler)
  110. }
  111. serviceRoute.Route = ctx.Route().Accept(v).(*Route)
  112. return &serviceRoute
  113. }
  114. // VisitAtDoc implements from api.BaseApiParserVisitor
  115. func (v *ApiVisitor) VisitAtDoc(ctx *api.AtDocContext) interface{} {
  116. var atDoc AtDoc
  117. atDoc.AtDocToken = v.newExprWithTerminalNode(ctx.ATDOC())
  118. if ctx.STRING() != nil {
  119. atDoc.LineDoc = v.newExprWithTerminalNode(ctx.STRING())
  120. } else {
  121. for _, each := range ctx.AllKvLit() {
  122. atDoc.Kv = append(atDoc.Kv, each.Accept(v).(*KvExpr))
  123. }
  124. }
  125. atDoc.Lp = v.newExprWithToken(ctx.GetLp())
  126. atDoc.Rp = v.newExprWithToken(ctx.GetRp())
  127. if ctx.GetLp() != nil {
  128. if ctx.GetRp() == nil {
  129. v.panic(atDoc.Lp, "mismatched ')'")
  130. }
  131. }
  132. if ctx.GetRp() != nil {
  133. if ctx.GetLp() == nil {
  134. v.panic(atDoc.Rp, "mismatched '('")
  135. }
  136. }
  137. return &atDoc
  138. }
  139. // VisitAtHandler implements from api.BaseApiParserVisitor
  140. func (v *ApiVisitor) VisitAtHandler(ctx *api.AtHandlerContext) interface{} {
  141. var atHandler AtHandler
  142. astHandlerExpr := v.newExprWithTerminalNode(ctx.ATHANDLER())
  143. atHandler.AtHandlerToken = astHandlerExpr
  144. atHandler.Name = v.newExprWithTerminalNode(ctx.ID())
  145. atHandler.DocExpr = v.getDoc(ctx)
  146. atHandler.CommentExpr = v.getComment(ctx)
  147. return &atHandler
  148. }
  149. // VisitRoute implements from api.BaseApiParserVisitor
  150. func (v *ApiVisitor) VisitRoute(ctx *api.RouteContext) interface{} {
  151. var route Route
  152. path := ctx.Path()
  153. methodExpr := v.newExprWithToken(ctx.GetHttpMethod())
  154. route.Method = methodExpr
  155. route.Path = v.newExprWithText(path.GetText(), path.GetStart().GetLine(), path.GetStart().GetColumn(), path.GetStart().GetStart(), path.GetStop().GetStop())
  156. if ctx.GetRequest() != nil {
  157. req := ctx.GetRequest().Accept(v)
  158. if req != nil {
  159. route.Req = req.(*Body)
  160. }
  161. }
  162. if ctx.GetResponse() != nil {
  163. reply := ctx.GetResponse().Accept(v)
  164. if reply != nil {
  165. route.Reply = reply.(*Body)
  166. }
  167. }
  168. if ctx.GetReturnToken() != nil {
  169. returnExpr := v.newExprWithToken(ctx.GetReturnToken())
  170. if ctx.GetReturnToken().GetText() != "returns" {
  171. v.panic(returnExpr, fmt.Sprintf("expecting returns, found input '%s'", ctx.GetReturnToken().GetText()))
  172. }
  173. route.ReturnToken = returnExpr
  174. }
  175. route.DocExpr = v.getDoc(ctx)
  176. route.CommentExpr = v.getComment(ctx)
  177. return &route
  178. }
  179. // VisitBody implements from api.BaseApiParserVisitor
  180. func (v *ApiVisitor) VisitBody(ctx *api.BodyContext) interface{} {
  181. if ctx.ID() == nil {
  182. return nil
  183. }
  184. idRxpr := v.newExprWithTerminalNode(ctx.ID())
  185. if api.IsGolangKeyWord(idRxpr.Text()) {
  186. v.panic(idRxpr, fmt.Sprintf("expecting 'ID', but found golang keyword '%s'", idRxpr.Text()))
  187. }
  188. v.exportCheck(idRxpr)
  189. return &Body{
  190. Lp: v.newExprWithToken(ctx.GetLp()),
  191. Rp: v.newExprWithToken(ctx.GetRp()),
  192. Name: &Literal{Literal: idRxpr},
  193. }
  194. }
  195. // VisitReplybody implements from api.BaseApiParserVisitor
  196. func (v *ApiVisitor) VisitReplybody(ctx *api.ReplybodyContext) interface{} {
  197. if ctx.DataType() == nil {
  198. return nil
  199. }
  200. dt := ctx.DataType().Accept(v).(DataType)
  201. if dt == nil {
  202. return nil
  203. }
  204. switch dataType := dt.(type) {
  205. case *Array:
  206. lit := dataType.Literal
  207. switch lit.(type) {
  208. case *Literal, *Pointer:
  209. if api.IsGolangKeyWord(lit.Expr().Text()) {
  210. v.panic(lit.Expr(), fmt.Sprintf("expecting 'ID', but found golang keyword '%s'", lit.Expr().Text()))
  211. }
  212. default:
  213. v.panic(dt.Expr(), fmt.Sprintf("unsupport %s", dt.Expr().Text()))
  214. }
  215. v.log.Warning("%s %d:%d deprecated array type near '%s'", v.prefix, dataType.ArrayExpr.Line(), dataType.ArrayExpr.Column(), dataType.ArrayExpr.Text())
  216. case *Literal:
  217. lit := dataType.Literal.Text()
  218. if api.IsGolangKeyWord(dataType.Literal.Text()) {
  219. v.panic(dataType.Literal, fmt.Sprintf("expecting 'ID', but found golang keyword '%s'", dataType.Literal.Text()))
  220. }
  221. if api.IsBasicType(lit) {
  222. v.panic(dt.Expr(), fmt.Sprintf("unsupport %s", dt.Expr().Text()))
  223. }
  224. default:
  225. v.panic(dt.Expr(), fmt.Sprintf("unsupport %s", dt.Expr().Text()))
  226. }
  227. return &Body{
  228. Lp: v.newExprWithToken(ctx.GetLp()),
  229. Rp: v.newExprWithToken(ctx.GetRp()),
  230. Name: dt,
  231. }
  232. }
  233. // Format provides a formatter for api command, now nothing to do
  234. func (b *Body) Format() error {
  235. // todo
  236. return nil
  237. }
  238. // Equal compares whether the element literals in two Body are equal
  239. func (b *Body) Equal(v interface{}) bool {
  240. if v == nil {
  241. return false
  242. }
  243. body, ok := v.(*Body)
  244. if !ok {
  245. return false
  246. }
  247. if !b.Lp.Equal(body.Lp) {
  248. return false
  249. }
  250. if !b.Rp.Equal(body.Rp) {
  251. return false
  252. }
  253. return b.Name.Equal(body.Name)
  254. }
  255. // Format provides a formatter for api command, now nothing to do
  256. func (r *Route) Format() error {
  257. // todo
  258. return nil
  259. }
  260. // Doc returns the document of Route, like // some text
  261. func (r *Route) Doc() []Expr {
  262. return r.DocExpr
  263. }
  264. // Comment returns the comment of Route, like // some text
  265. func (r *Route) Comment() Expr {
  266. return r.CommentExpr
  267. }
  268. // Equal compares whether the element literals in two Route are equal
  269. func (r *Route) Equal(v interface{}) bool {
  270. if v == nil {
  271. return false
  272. }
  273. route, ok := v.(*Route)
  274. if !ok {
  275. return false
  276. }
  277. if !r.Method.Equal(route.Method) {
  278. return false
  279. }
  280. if !r.Path.Equal(route.Path) {
  281. return false
  282. }
  283. if r.Req != nil {
  284. if !r.Req.Equal(route.Req) {
  285. return false
  286. }
  287. }
  288. if r.ReturnToken != nil {
  289. if !r.ReturnToken.Equal(route.ReturnToken) {
  290. return false
  291. }
  292. }
  293. if r.Reply != nil {
  294. if !r.Reply.Equal(route.Reply) {
  295. return false
  296. }
  297. }
  298. return EqualDoc(r, route)
  299. }
  300. // Doc returns the document of AtHandler, like // some text
  301. func (a *AtHandler) Doc() []Expr {
  302. return a.DocExpr
  303. }
  304. // Comment returns the comment of AtHandler, like // some text
  305. func (a *AtHandler) Comment() Expr {
  306. return a.CommentExpr
  307. }
  308. // Format provides a formatter for api command, now nothing to do
  309. func (a *AtHandler) Format() error {
  310. // todo
  311. return nil
  312. }
  313. // Equal compares whether the element literals in two AtHandler are equal
  314. func (a *AtHandler) Equal(v interface{}) bool {
  315. if v == nil {
  316. return false
  317. }
  318. atHandler, ok := v.(*AtHandler)
  319. if !ok {
  320. return false
  321. }
  322. if !a.AtHandlerToken.Equal(atHandler.AtHandlerToken) {
  323. return false
  324. }
  325. if !a.Name.Equal(atHandler.Name) {
  326. return false
  327. }
  328. return EqualDoc(a, atHandler)
  329. }
  330. // Format provides a formatter for api command, now nothing to do
  331. func (a *AtDoc) Format() error {
  332. // todo
  333. return nil
  334. }
  335. // Equal compares whether the element literals in two AtDoc are equal
  336. func (a *AtDoc) Equal(v interface{}) bool {
  337. if v == nil {
  338. return false
  339. }
  340. atDoc, ok := v.(*AtDoc)
  341. if !ok {
  342. return false
  343. }
  344. if !a.AtDocToken.Equal(atDoc.AtDocToken) {
  345. return false
  346. }
  347. if a.Lp.IsNotNil() {
  348. if !a.Lp.Equal(atDoc.Lp) {
  349. return false
  350. }
  351. }
  352. if a.Rp.IsNotNil() {
  353. if !a.Rp.Equal(atDoc.Rp) {
  354. return false
  355. }
  356. }
  357. if a.LineDoc != nil {
  358. if !a.LineDoc.Equal(atDoc.LineDoc) {
  359. return false
  360. }
  361. }
  362. var expecting, actual []*KvExpr
  363. expecting = append(expecting, a.Kv...)
  364. actual = append(actual, atDoc.Kv...)
  365. if len(expecting) != len(actual) {
  366. return false
  367. }
  368. for index, each := range expecting {
  369. ac := actual[index]
  370. if !each.Equal(ac) {
  371. return false
  372. }
  373. }
  374. return true
  375. }
  376. // Format provides a formatter for api command, now nothing to do
  377. func (a *AtServer) Format() error {
  378. // todo
  379. return nil
  380. }
  381. // Equal compares whether the element literals in two AtServer are equal
  382. func (a *AtServer) Equal(v interface{}) bool {
  383. if v == nil {
  384. return false
  385. }
  386. atServer, ok := v.(*AtServer)
  387. if !ok {
  388. return false
  389. }
  390. if !a.AtServerToken.Equal(atServer.AtServerToken) {
  391. return false
  392. }
  393. if !a.Lp.Equal(atServer.Lp) {
  394. return false
  395. }
  396. if !a.Rp.Equal(atServer.Rp) {
  397. return false
  398. }
  399. var expecting, actual []*KvExpr
  400. expecting = append(expecting, a.Kv...)
  401. actual = append(actual, atServer.Kv...)
  402. if len(expecting) != len(actual) {
  403. return false
  404. }
  405. sort.Slice(expecting, func(i, j int) bool {
  406. return expecting[i].Key.Text() < expecting[j].Key.Text()
  407. })
  408. sort.Slice(actual, func(i, j int) bool {
  409. return actual[i].Key.Text() < actual[j].Key.Text()
  410. })
  411. for index, each := range expecting {
  412. ac := actual[index]
  413. if !each.Equal(ac) {
  414. return false
  415. }
  416. }
  417. return true
  418. }
  419. // Equal compares whether the element literals in two ServiceRoute are equal
  420. func (s *ServiceRoute) Equal(v interface{}) bool {
  421. if v == nil {
  422. return false
  423. }
  424. sr, ok := v.(*ServiceRoute)
  425. if !ok {
  426. return false
  427. }
  428. if !s.AtDoc.Equal(sr.AtDoc) {
  429. return false
  430. }
  431. if s.AtServer != nil {
  432. if !s.AtServer.Equal(sr.AtServer) {
  433. return false
  434. }
  435. }
  436. if s.AtHandler != nil {
  437. if !s.AtHandler.Equal(sr.AtHandler) {
  438. return false
  439. }
  440. }
  441. return s.Route.Equal(sr.Route)
  442. }
  443. // Format provides a formatter for api command, now nothing to do
  444. func (s *ServiceRoute) Format() error {
  445. // todo
  446. return nil
  447. }
  448. // GetHandler returns handler name of api route
  449. func (s *ServiceRoute) GetHandler() Expr {
  450. if s.AtHandler != nil {
  451. return s.AtHandler.Name
  452. }
  453. return s.AtServer.Kv.Get("handler")
  454. }
  455. // Format provides a formatter for api command, now nothing to do
  456. func (a *ServiceApi) Format() error {
  457. // todo
  458. return nil
  459. }
  460. // Equal compares whether the element literals in two ServiceApi are equal
  461. func (a *ServiceApi) Equal(v interface{}) bool {
  462. if v == nil {
  463. return false
  464. }
  465. api, ok := v.(*ServiceApi)
  466. if !ok {
  467. return false
  468. }
  469. if !a.ServiceToken.Equal(api.ServiceToken) {
  470. return false
  471. }
  472. if !a.Name.Equal(api.Name) {
  473. return false
  474. }
  475. if !a.Lbrace.Equal(api.Lbrace) {
  476. return false
  477. }
  478. if !a.Rbrace.Equal(api.Rbrace) {
  479. return false
  480. }
  481. var expecting, acutal []*ServiceRoute
  482. expecting = append(expecting, a.ServiceRoute...)
  483. acutal = append(acutal, api.ServiceRoute...)
  484. if len(expecting) != len(acutal) {
  485. return false
  486. }
  487. sort.Slice(expecting, func(i, j int) bool {
  488. return expecting[i].Route.Path.Text() < expecting[j].Route.Path.Text()
  489. })
  490. sort.Slice(acutal, func(i, j int) bool {
  491. return acutal[i].Route.Path.Text() < acutal[j].Route.Path.Text()
  492. })
  493. for index, each := range expecting {
  494. ac := acutal[index]
  495. if !each.Equal(ac) {
  496. return false
  497. }
  498. }
  499. return true
  500. }
  501. // Format provides a formatter for api command, now nothing to do
  502. func (s *Service) Format() error {
  503. // todo
  504. return nil
  505. }
  506. // Equal compares whether the element literals in two Service are equal
  507. func (s *Service) Equal(v interface{}) bool {
  508. if v == nil {
  509. return false
  510. }
  511. service, ok := v.(*Service)
  512. if !ok {
  513. return false
  514. }
  515. if s.AtServer != nil {
  516. if !s.AtServer.Equal(service.AtServer) {
  517. return false
  518. }
  519. }
  520. return s.ServiceApi.Equal(service.ServiceApi)
  521. }
  522. // Get returns the tergate KV by specified key
  523. func (kv KV) Get(key string) Expr {
  524. for _, each := range kv {
  525. if each.Key.Text() == key {
  526. return each.Value
  527. }
  528. }
  529. return nil
  530. }