@ -3,19 +3,19 @@ package parser
import (
import (
"bufio"
"bufio"
"errors"
"errors"
"regexp"
"strings"
"strings"
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
"github.com/tal-tech/go-zero/tools/goctl/api/spec"
)
)
// struct match
var emptyType spec . Type
const typeRegex = ` (?m)(?m)(^ *type\s+[a-zA-Z][a-zA-Z0-9_-]+\s+(((struct)\s*?\ { [\w\W]*?[^\ { ]\})|([a-zA-Z][a-zA-Z0-9_-]+)))|(^ *type\s*?\([\w\W]+\}\s*\)) `
var (
type ApiStruct struct {
emptyStrcut = errors . New ( "struct body not found" )
Info string
emptyType spec . Type
StructBody string
)
Service string
Imports string
}
func GetType ( api * spec . ApiSpec , t string ) spec . Type {
func GetType ( api * spec . ApiSpec , t string ) spec . Type {
for _ , tp := range api . Types {
for _ , tp := range api . Types {
@ -69,32 +69,56 @@ func unread(r *bufio.Reader) error {
return r . UnreadRune ( )
return r . UnreadRune ( )
}
}
func MatchStruct ( api string ) ( info , structBody , service string , err error ) {
func MatchStruct ( api string ) ( * ApiStruct , error ) {
r := regexp . MustCompile ( typeRegex )
var result ApiStruct
indexes := r . FindAllStringIndex ( api , - 1 )
scanner := bufio . NewScanner ( strings . NewReader ( api ) )
if len ( indexes ) == 0 {
var parseInfo = false
return "" , "" , "" , emptyStrcut
var parseImport = false
}
var parseType = false
startIndexes := indexes [ 0 ]
var parseSevice = false
endIndexes := indexes [ len ( indexes ) - 1 ]
var segment string
for scanner . Scan ( ) {
line := strings . TrimSpace ( scanner . Text ( ) )
if line == "@doc(" {
parseInfo = true
}
if line == ")" && parseInfo {
parseInfo = false
result . Info = segment + ")"
segment = ""
continue
}
info = api [ : startIndexes [ 0 ] ]
if strings . HasPrefix ( line , "import" ) {
structBody = api [ startIndexes [ 0 ] : endIndexes [ len ( endIndexes ) - 1 ] ]
parseImport = true
service = api [ endIndexes [ len ( endIndexes ) - 1 ] : ]
}
if parseImport && ( strings . HasPrefix ( line , "type" ) || strings . HasPrefix ( line , "@server" ) ||
strings . HasPrefix ( line , "service" ) ) {
parseImport = false
result . Imports = segment
segment = line + "\n"
continue
}
firstIIndex := strings . Index ( info , "i" )
if strings . HasPrefix ( line , "type" ) {
if firstIIndex > 0 {
parseType = true
info = info [ firstIIndex : ]
}
if strings . HasPrefix ( line , "@server" ) || strings . HasPrefix ( line , "service" ) {
if parseType {
parseType = false
result . StructBody = segment
segment = line + "\n"
continue
}
parseSevice = true
}
segment += scanner . Text ( ) + "\n"
}
}
lastServiceRightBraceIndex := strings . LastIndex ( service , "}" ) + 1
if ! parseSevice {
var firstServiceIndex int
return nil , errors . New ( "no service defined" )
for index , char := range service {
if ! isSpace ( char ) && ! isNewline ( char ) {
firstServiceIndex = index
break
}
}
}
service = service [ firstServiceIndex : lastServiceRightBraceIndex ]
result . Service = segment
return
return & result , nil
}
}