service.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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 handler 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. if v.debug {
  183. msg := fmt.Sprintf(
  184. `%s line %d: expr "()" is deprecated, if there has no request body, please omit it`,
  185. v.prefix,
  186. ctx.GetStart().GetLine(),
  187. )
  188. v.log.Warning(msg)
  189. }
  190. return nil
  191. }
  192. idExpr := v.newExprWithTerminalNode(ctx.ID())
  193. if api.IsGolangKeyWord(idExpr.Text()) {
  194. v.panic(idExpr, fmt.Sprintf("expecting 'ID', but found golang keyword '%s'", idExpr.Text()))
  195. }
  196. return &Body{
  197. Lp: v.newExprWithToken(ctx.GetLp()),
  198. Rp: v.newExprWithToken(ctx.GetRp()),
  199. Name: &Literal{Literal: idExpr},
  200. }
  201. }
  202. // VisitReplybody implements from api.BaseApiParserVisitor
  203. func (v *ApiVisitor) VisitReplybody(ctx *api.ReplybodyContext) interface{} {
  204. if ctx.DataType() == nil {
  205. if v.debug {
  206. msg := fmt.Sprintf(
  207. `%s line %d: expr "returns ()" or "()" is deprecated, if there has no response body, please omit it`,
  208. v.prefix,
  209. ctx.GetStart().GetLine(),
  210. )
  211. v.log.Warning(msg)
  212. }
  213. return nil
  214. }
  215. dt := ctx.DataType().Accept(v).(DataType)
  216. if dt == nil {
  217. return nil
  218. }
  219. switch dataType := dt.(type) {
  220. case *Array:
  221. lit := dataType.Literal
  222. switch lit.(type) {
  223. case *Literal, *Pointer:
  224. if api.IsGolangKeyWord(lit.Expr().Text()) {
  225. v.panic(lit.Expr(), fmt.Sprintf("expecting 'ID', but found golang keyword '%s'", lit.Expr().Text()))
  226. }
  227. default:
  228. v.panic(dt.Expr(), fmt.Sprintf("unsupport %s", dt.Expr().Text()))
  229. }
  230. case *Literal:
  231. lit := dataType.Literal.Text()
  232. if api.IsGolangKeyWord(dataType.Literal.Text()) {
  233. v.panic(dataType.Literal, fmt.Sprintf("expecting 'ID', but found golang keyword '%s'", dataType.Literal.Text()))
  234. }
  235. if api.IsBasicType(lit) {
  236. v.panic(dt.Expr(), fmt.Sprintf("unsupport %s", dt.Expr().Text()))
  237. }
  238. default:
  239. v.panic(dt.Expr(), fmt.Sprintf("unsupport %s", dt.Expr().Text()))
  240. }
  241. return &Body{
  242. Lp: v.newExprWithToken(ctx.GetLp()),
  243. Rp: v.newExprWithToken(ctx.GetRp()),
  244. Name: dt,
  245. }
  246. }
  247. // Format provides a formatter for api command, now nothing to do
  248. func (b *Body) Format() error {
  249. // todo
  250. return nil
  251. }
  252. // Equal compares whether the element literals in two Body are equal
  253. func (b *Body) Equal(v interface{}) bool {
  254. if v == nil {
  255. return false
  256. }
  257. body, ok := v.(*Body)
  258. if !ok {
  259. return false
  260. }
  261. if !b.Lp.Equal(body.Lp) {
  262. return false
  263. }
  264. if !b.Rp.Equal(body.Rp) {
  265. return false
  266. }
  267. return b.Name.Equal(body.Name)
  268. }
  269. // Format provides a formatter for api command, now nothing to do
  270. func (r *Route) Format() error {
  271. // todo
  272. return nil
  273. }
  274. // Doc returns the document of Route, like // some text
  275. func (r *Route) Doc() []Expr {
  276. return r.DocExpr
  277. }
  278. // Comment returns the comment of Route, like // some text
  279. func (r *Route) Comment() Expr {
  280. return r.CommentExpr
  281. }
  282. // Equal compares whether the element literals in two Route are equal
  283. func (r *Route) Equal(v interface{}) bool {
  284. if v == nil {
  285. return false
  286. }
  287. route, ok := v.(*Route)
  288. if !ok {
  289. return false
  290. }
  291. if !r.Method.Equal(route.Method) {
  292. return false
  293. }
  294. if !r.Path.Equal(route.Path) {
  295. return false
  296. }
  297. if r.Req != nil {
  298. if !r.Req.Equal(route.Req) {
  299. return false
  300. }
  301. }
  302. if r.ReturnToken != nil {
  303. if !r.ReturnToken.Equal(route.ReturnToken) {
  304. return false
  305. }
  306. }
  307. if r.Reply != nil {
  308. if !r.Reply.Equal(route.Reply) {
  309. return false
  310. }
  311. }
  312. return EqualDoc(r, route)
  313. }
  314. // Doc returns the document of AtHandler, like // some text
  315. func (a *AtHandler) Doc() []Expr {
  316. return a.DocExpr
  317. }
  318. // Comment returns the comment of AtHandler, like // some text
  319. func (a *AtHandler) Comment() Expr {
  320. return a.CommentExpr
  321. }
  322. // Format provides a formatter for api command, now nothing to do
  323. func (a *AtHandler) Format() error {
  324. // todo
  325. return nil
  326. }
  327. // Equal compares whether the element literals in two AtHandler are equal
  328. func (a *AtHandler) Equal(v interface{}) bool {
  329. if v == nil {
  330. return false
  331. }
  332. atHandler, ok := v.(*AtHandler)
  333. if !ok {
  334. return false
  335. }
  336. if !a.AtHandlerToken.Equal(atHandler.AtHandlerToken) {
  337. return false
  338. }
  339. if !a.Name.Equal(atHandler.Name) {
  340. return false
  341. }
  342. return EqualDoc(a, atHandler)
  343. }
  344. // Format provides a formatter for api command, now nothing to do
  345. func (a *AtDoc) Format() error {
  346. // todo
  347. return nil
  348. }
  349. // Equal compares whether the element literals in two AtDoc are equal
  350. func (a *AtDoc) Equal(v interface{}) bool {
  351. if v == nil {
  352. return false
  353. }
  354. atDoc, ok := v.(*AtDoc)
  355. if !ok {
  356. return false
  357. }
  358. if !a.AtDocToken.Equal(atDoc.AtDocToken) {
  359. return false
  360. }
  361. if a.Lp.IsNotNil() {
  362. if !a.Lp.Equal(atDoc.Lp) {
  363. return false
  364. }
  365. }
  366. if a.Rp.IsNotNil() {
  367. if !a.Rp.Equal(atDoc.Rp) {
  368. return false
  369. }
  370. }
  371. if a.LineDoc != nil {
  372. if !a.LineDoc.Equal(atDoc.LineDoc) {
  373. return false
  374. }
  375. }
  376. var expecting, actual []*KvExpr
  377. expecting = append(expecting, a.Kv...)
  378. actual = append(actual, atDoc.Kv...)
  379. if len(expecting) != len(actual) {
  380. return false
  381. }
  382. for index, each := range expecting {
  383. ac := actual[index]
  384. if !each.Equal(ac) {
  385. return false
  386. }
  387. }
  388. return true
  389. }
  390. // Format provides a formatter for api command, now nothing to do
  391. func (a *AtServer) Format() error {
  392. // todo
  393. return nil
  394. }
  395. // Equal compares whether the element literals in two AtServer are equal
  396. func (a *AtServer) Equal(v interface{}) bool {
  397. if v == nil {
  398. return false
  399. }
  400. atServer, ok := v.(*AtServer)
  401. if !ok {
  402. return false
  403. }
  404. if !a.AtServerToken.Equal(atServer.AtServerToken) {
  405. return false
  406. }
  407. if !a.Lp.Equal(atServer.Lp) {
  408. return false
  409. }
  410. if !a.Rp.Equal(atServer.Rp) {
  411. return false
  412. }
  413. var expecting, actual []*KvExpr
  414. expecting = append(expecting, a.Kv...)
  415. actual = append(actual, atServer.Kv...)
  416. if len(expecting) != len(actual) {
  417. return false
  418. }
  419. sort.Slice(expecting, func(i, j int) bool {
  420. return expecting[i].Key.Text() < expecting[j].Key.Text()
  421. })
  422. sort.Slice(actual, func(i, j int) bool {
  423. return actual[i].Key.Text() < actual[j].Key.Text()
  424. })
  425. for index, each := range expecting {
  426. ac := actual[index]
  427. if !each.Equal(ac) {
  428. return false
  429. }
  430. }
  431. return true
  432. }
  433. // Equal compares whether the element literals in two ServiceRoute are equal
  434. func (s *ServiceRoute) Equal(v interface{}) bool {
  435. if v == nil {
  436. return false
  437. }
  438. sr, ok := v.(*ServiceRoute)
  439. if !ok {
  440. return false
  441. }
  442. if !s.AtDoc.Equal(sr.AtDoc) {
  443. return false
  444. }
  445. if s.AtServer != nil {
  446. if !s.AtServer.Equal(sr.AtServer) {
  447. return false
  448. }
  449. }
  450. if s.AtHandler != nil {
  451. if !s.AtHandler.Equal(sr.AtHandler) {
  452. return false
  453. }
  454. }
  455. return s.Route.Equal(sr.Route)
  456. }
  457. // Format provides a formatter for api command, now nothing to do
  458. func (s *ServiceRoute) Format() error {
  459. // todo
  460. return nil
  461. }
  462. // GetHandler returns handler name of api route
  463. func (s *ServiceRoute) GetHandler() Expr {
  464. if s.AtHandler != nil {
  465. return s.AtHandler.Name
  466. }
  467. return s.AtServer.Kv.Get("handler")
  468. }
  469. // Format provides a formatter for api command, now nothing to do
  470. func (a *ServiceApi) Format() error {
  471. // todo
  472. return nil
  473. }
  474. // Equal compares whether the element literals in two ServiceApi are equal
  475. func (a *ServiceApi) Equal(v interface{}) bool {
  476. if v == nil {
  477. return false
  478. }
  479. api, ok := v.(*ServiceApi)
  480. if !ok {
  481. return false
  482. }
  483. if !a.ServiceToken.Equal(api.ServiceToken) {
  484. return false
  485. }
  486. if !a.Name.Equal(api.Name) {
  487. return false
  488. }
  489. if !a.Lbrace.Equal(api.Lbrace) {
  490. return false
  491. }
  492. if !a.Rbrace.Equal(api.Rbrace) {
  493. return false
  494. }
  495. var expecting, acutal []*ServiceRoute
  496. expecting = append(expecting, a.ServiceRoute...)
  497. acutal = append(acutal, api.ServiceRoute...)
  498. if len(expecting) != len(acutal) {
  499. return false
  500. }
  501. sort.Slice(expecting, func(i, j int) bool {
  502. return expecting[i].Route.Path.Text() < expecting[j].Route.Path.Text()
  503. })
  504. sort.Slice(acutal, func(i, j int) bool {
  505. return acutal[i].Route.Path.Text() < acutal[j].Route.Path.Text()
  506. })
  507. for index, each := range expecting {
  508. ac := acutal[index]
  509. if !each.Equal(ac) {
  510. return false
  511. }
  512. }
  513. return true
  514. }
  515. // Format provides a formatter for api command, now nothing to do
  516. func (s *Service) Format() error {
  517. // todo
  518. return nil
  519. }
  520. // Equal compares whether the element literals in two Service are equal
  521. func (s *Service) Equal(v interface{}) bool {
  522. if v == nil {
  523. return false
  524. }
  525. service, ok := v.(*Service)
  526. if !ok {
  527. return false
  528. }
  529. if s.AtServer != nil {
  530. if !s.AtServer.Equal(service.AtServer) {
  531. return false
  532. }
  533. }
  534. return s.ServiceApi.Equal(service.ServiceApi)
  535. }
  536. // Get returns the target KV by specified key
  537. func (kv KV) Get(key string) Expr {
  538. for _, each := range kv {
  539. if each.Key.Text() == key {
  540. return each.Value
  541. }
  542. }
  543. return nil
  544. }