parser.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. var sp = StructParser{Src: p.typeDef}
  56. types, err := sp.Parse()
  57. if err != nil {
  58. return nil, err
  59. }
  60. api.Types = types
  61. var lineNumber = 1
  62. st := newRootState(p.r, &lineNumber)
  63. for {
  64. st, err = st.process(api)
  65. if err == io.EOF {
  66. return api, p.validate(api)
  67. }
  68. if err != nil {
  69. return nil, fmt.Errorf("near line: %d, %s", lineNumber, err.Error())
  70. }
  71. if st == nil {
  72. return api, p.validate(api)
  73. }
  74. }
  75. }