123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package parser
- import (
- "errors"
- "fmt"
- "strings"
- "github.com/tal-tech/go-zero/tools/goctl/api/spec"
- )
- type (
- entity struct {
- state *baseState
- api *spec.ApiSpec
- parser entityParser
- }
- entityParser interface {
- parseLine(line string, api *spec.ApiSpec, annos []spec.Annotation) error
- setEntityName(name string)
- }
- )
- func newEntity(state *baseState, api *spec.ApiSpec, parser entityParser) entity {
- return entity{
- state: state,
- api: api,
- parser: parser,
- }
- }
- func (s *entity) process() error {
- line, err := s.state.readLineSkipComment()
- if err != nil {
- return err
- }
- fields := strings.Fields(line)
- if len(fields) < 2 {
- return fmt.Errorf("invalid type definition for %q",
- strings.TrimSpace(strings.Trim(string(line), "{")))
- }
- if len(fields) == 2 {
- if fields[1] != leftBrace {
- return fmt.Errorf("bad string %q after type", fields[1])
- }
- } else if len(fields) == 3 {
- if fields[1] != typeStruct {
- return fmt.Errorf("bad string %q after type", fields[1])
- }
- if fields[2] != leftBrace {
- return fmt.Errorf("bad string %q after type", fields[2])
- }
- }
- s.parser.setEntityName(fields[0])
- var annos []spec.Annotation
- memberLoop:
- for {
- ch, err := s.state.readSkipComment()
- if err != nil {
- return err
- }
- var annoName string
- var builder strings.Builder
- switch {
- case ch == at:
- annotationLoop:
- for {
- next, err := s.state.readSkipComment()
- if err != nil {
- return err
- }
- switch {
- case isSpace(next):
- if builder.Len() > 0 && annoName == "" {
- annoName = builder.String()
- builder.Reset()
- }
- case isNewline(next):
- if builder.Len() == 0 {
- return errors.New("invalid annotation format")
- }
- if len(annoName) > 0 {
- value := builder.String()
- if value != string(leftParenthesis) {
- builder.Reset()
- annos = append(annos, spec.Annotation{
- Name: annoName,
- Value: value,
- })
- annoName = ""
- break annotationLoop
- }
- }
- case next == leftParenthesis:
- if builder.Len() == 0 {
- return errors.New("invalid annotation format")
- }
- annoName = builder.String()
- builder.Reset()
- if err := s.state.unread(); err != nil {
- return err
- }
- attrs, err := s.state.parseProperties()
- if err != nil {
- return err
- }
- annos = append(annos, spec.Annotation{
- Name: annoName,
- Properties: attrs,
- })
- annoName = ""
- break annotationLoop
- default:
- builder.WriteRune(next)
- }
- }
- case ch == rightBrace:
- break memberLoop
- case isLetterDigit(ch):
- if err := s.state.unread(); err != nil {
- return err
- }
- var line string
- line, err = s.state.readLineSkipComment()
- if err != nil {
- return err
- }
- line = strings.TrimSpace(line)
- if err := s.parser.parseLine(line, s.api, annos); err != nil {
- return err
- }
- annos = nil
- }
- }
- return nil
- }
|