From ee45b0a459f97180fbaf0740e06455f4164a6fe6 Mon Sep 17 00:00:00 2001 From: kingxt Date: Mon, 14 Sep 2020 11:44:53 +0800 Subject: [PATCH] optimize route parse (#70) * rebase upstream * rebase * trim no need line * trim no need line * trim no need line * update doc * remove update * optimized route parser Co-authored-by: kingxt --- tools/goctl/api/parser/servicestate.go | 62 +++++++++++++++++--------- tools/goctl/api/parser/vars.go | 3 ++ 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/tools/goctl/api/parser/servicestate.go b/tools/goctl/api/parser/servicestate.go index 03caecb2..31f3c90e 100644 --- a/tools/goctl/api/parser/servicestate.go +++ b/tools/goctl/api/parser/servicestate.go @@ -1,7 +1,10 @@ package parser import ( + "bufio" + "bytes" "fmt" + "io" "strings" "github.com/tal-tech/go-zero/tools/goctl/api/spec" @@ -54,32 +57,49 @@ type serviceEntityParser struct { } func (p *serviceEntityParser) parseLine(line string, api *spec.ApiSpec, annos []spec.Annotation) error { - fields := strings.Fields(line) - if len(fields) < 2 { - return fmt.Errorf("wrong line %q", line) + line = strings.TrimSpace(line) + + var buffer = new(bytes.Buffer) + buffer.WriteString(line) + reader := bufio.NewReader(buffer) + var builder strings.Builder + var fields []string + for { + ch, _, err := reader.ReadRune() + if err != nil { + if err == io.EOF { + 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) + } + } + + if len(fields) < 3 { + return fmt.Errorf("wrong line %q, %q", line, routeSyntax) } method := fields[0] - pathAndRequest := fields[1] - pos := strings.Index(pathAndRequest, "(") - if pos < 0 { - return fmt.Errorf("wrong line %q", line) - } - path := strings.TrimSpace(pathAndRequest[:pos]) - pathAndRequest = pathAndRequest[pos+1:] - pos = strings.Index(pathAndRequest, ")") - if pos < 0 { - return fmt.Errorf("wrong line %q", line) - } - req := pathAndRequest[:pos] + path := fields[1] + req := fields[2] var returns string - if len(fields) > 2 { - returns = fields[2] + if len(fields) > 4 { + returns = fields[4] + if fields[3] != returnsTag { + return fmt.Errorf("wrong line %q, %q", line, routeSyntax) + } } - returns = strings.ReplaceAll(returns, "returns", "") - returns = strings.ReplaceAll(returns, "(", "") - returns = strings.ReplaceAll(returns, ")", "") - returns = strings.TrimSpace(returns) p.acceptRoute(spec.Route{ Annotations: annos, diff --git a/tools/goctl/api/parser/vars.go b/tools/goctl/api/parser/vars.go index f1793137..ba6ed42b 100644 --- a/tools/goctl/api/parser/vars.go +++ b/tools/goctl/api/parser/vars.go @@ -5,6 +5,8 @@ const ( serviceDirective = "service" typeDirective = "type" typeStruct = "struct" + routeSyntax = "route syntax: [get/post/delete] /path(request) returns[(response)]" + returnsTag = "returns" at = '@' colon = ':' leftParenthesis = '(' @@ -13,4 +15,5 @@ const ( rightBrace = '}' multilineBeginTag = '>' multilineEndTag = '<' + semicolon = ';' )