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/servicestate.go

133 lines
2.7 KiB
Go

4 years ago
package parser
import (
"bufio"
"bytes"
4 years ago
"fmt"
"io"
4 years ago
"strings"
"github.com/tal-tech/go-zero/core/stringx"
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
4 years ago
)
type serviceState struct {
*baseState
annos []spec.Annotation
}
func newServiceState(state *baseState, annos []spec.Annotation) state {
return &serviceState{
baseState: state,
annos: annos,
}
}
func (s *serviceState) process(api *spec.ApiSpec) (state, error) {
var name string
var routes []spec.Route
parser := &serviceEntityParser{
acceptName: func(n string) {
name = n
},
acceptRoute: func(route spec.Route) {
routes = append(routes, route)
},
}
ent := newEntity(s.baseState, api, parser)
if err := ent.process(); err != nil {
return nil, err
}
api.Service = spec.Service{
Name: name,
Annotations: append(api.Service.Annotations, s.annos...),
Routes: append(api.Service.Routes, routes...),
Groups: append(api.Service.Groups, spec.Group{
Annotations: s.annos,
Routes: routes,
}),
}
return newRootState(s.r, s.lineNumber), nil
}
type serviceEntityParser struct {
acceptName func(name string)
acceptRoute func(route spec.Route)
}
func (p *serviceEntityParser) parseLine(line string, api *spec.ApiSpec, annos []spec.Annotation) error {
var defaultErr = fmt.Errorf("wrong line %q, %q", line, routeSyntax)
4 years ago
line = strings.TrimSpace(line)
var buffer = new(bytes.Buffer)
buffer.WriteString(line)
reader := bufio.NewReader(buffer)
var builder strings.Builder
var fields = make([]string, 0)
for {
ch, _, err := reader.ReadRune()
if err != nil {
if err == io.EOF {
if builder.Len() > 0 {
token := strings.TrimSpace(builder.String())
if len(token) > 0 && token != returnsTag {
fields = append(fields, token)
}
}
break
}
return err
}
switch {
case isSpace(ch), ch == leftParenthesis, ch == rightParenthesis, ch == semicolon:
if builder.Len() == 0 {
continue
}
token := builder.String()
builder.Reset()
fields = append(fields, token)
default:
builder.WriteRune(ch)
}
4 years ago
}
if len(fields) < 2 {
return defaultErr
4 years ago
}
method := fields[0]
path := fields[1]
var req string
var resp string
if len(fields) > 2 {
req = fields[2]
}
if stringx.Contains(fields, returnsTag) {
if fields[len(fields)-1] != returnsTag {
resp = fields[len(fields)-1]
} else {
return defaultErr
}
if fields[2] == returnsTag {
req = ""
}
4 years ago
}
p.acceptRoute(spec.Route{
Annotations: annos,
Method: method,
Path: path,
RequestType: GetType(api, req),
ResponseType: GetType(api, resp),
4 years ago
})
return nil
}
func (p *serviceEntityParser) setEntityName(name string) {
p.acceptName(name)
}