You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-zero/tools/goctl/api/parser/rootstate.go

108 lines
2.2 KiB
Go

4 years ago
package parser
import (
"bufio"
"fmt"
"strings"
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
4 years ago
)
type rootState struct {
*baseState
}
func newRootState(r *bufio.Reader, lineNumber *int) state {
var state = newBaseState(r, lineNumber)
return rootState{
baseState: state,
}
}
func (s rootState) process(api *spec.ApiSpec) (state, error) {
var annos []spec.Annotation
var builder strings.Builder
for {
ch, err := s.read()
if err != nil {
return nil, err
}
switch {
case isSpace(ch):
if builder.Len() == 0 {
continue
}
token := builder.String()
builder.Reset()
return s.processToken(token, annos)
case ch == at:
if builder.Len() > 0 {
return nil, fmt.Errorf("%q before %q", builder.String(), at)
}
var annoName string
annoLoop:
for {
next, err := s.read()
if err != nil {
return nil, err
}
switch {
case isSpace(next):
if builder.Len() > 0 {
annoName = builder.String()
builder.Reset()
}
case next == leftParenthesis:
if err := s.unread(); err != nil {
return nil, err
}
if builder.Len() > 0 {
annoName = builder.String()
builder.Reset()
}
attrs, err := s.parseProperties()
if err != nil {
return nil, err
}
annos = append(annos, spec.Annotation{
Name: annoName,
Properties: attrs,
})
break annoLoop
default:
builder.WriteRune(next)
}
}
case ch == leftParenthesis:
if builder.Len() == 0 {
return nil, fmt.Errorf("incorrect %q at the beginning of the line", leftParenthesis)
}
if err := s.unread(); err != nil {
return nil, err
}
token := builder.String()
builder.Reset()
return s.processToken(token, annos)
case isLetterDigit(ch):
builder.WriteRune(ch)
case isNewline(ch):
if builder.Len() > 0 {
return nil, fmt.Errorf("incorrect newline after %q", builder.String())
}
}
}
}
func (s rootState) processToken(token string, annos []spec.Annotation) (state, error) {
switch token {
case infoDirective:
return newInfoState(s.baseState), nil
case serviceDirective:
return newServiceState(s.baseState, annos), nil
default:
return nil, fmt.Errorf("wrong directive %q", token)
}
}