parser.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package parser
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "path/filepath"
  9. "strings"
  10. "github.com/tal-tech/go-zero/tools/goctl/api/spec"
  11. "github.com/tal-tech/go-zero/tools/goctl/util"
  12. )
  13. type Parser struct {
  14. r *bufio.Reader
  15. typeDef string
  16. }
  17. func NewParser(filename string) (*Parser, error) {
  18. apiAbsPath, err := filepath.Abs(filename)
  19. if err != nil {
  20. return nil, err
  21. }
  22. api, err := ioutil.ReadFile(filename)
  23. if err != nil {
  24. return nil, err
  25. }
  26. apiStruct, err := MatchStruct(string(api))
  27. if err != nil {
  28. return nil, err
  29. }
  30. for _, item := range strings.Split(apiStruct.Imports, "\n") {
  31. ip := strings.TrimSpace(item)
  32. if len(ip) > 0 {
  33. item := strings.TrimPrefix(item, "import")
  34. item = strings.TrimSpace(item)
  35. var path = item
  36. if !util.FileExists(item) {
  37. path = filepath.Join(filepath.Dir(apiAbsPath), item)
  38. }
  39. content, err := ioutil.ReadFile(path)
  40. if err != nil {
  41. return nil, err
  42. }
  43. apiStruct.StructBody += "\n" + string(content)
  44. }
  45. }
  46. var buffer = new(bytes.Buffer)
  47. buffer.WriteString(apiStruct.Service)
  48. return &Parser{
  49. r: bufio.NewReader(buffer),
  50. typeDef: apiStruct.StructBody,
  51. }, nil
  52. }
  53. func (p *Parser) Parse() (api *spec.ApiSpec, err error) {
  54. api = new(spec.ApiSpec)
  55. types, err := parseStructAst(p.typeDef)
  56. if err != nil {
  57. return nil, err
  58. }
  59. api.Types = types
  60. var lineNumber = 1
  61. st := newRootState(p.r, &lineNumber)
  62. for {
  63. st, err = st.process(api)
  64. if err == io.EOF {
  65. return api, p.validate(api)
  66. }
  67. if err != nil {
  68. return nil, fmt.Errorf("near line: %d, %s", lineNumber, err.Error())
  69. }
  70. if st == nil {
  71. return api, p.validate(api)
  72. }
  73. }
  74. }