feat(goctl): Add api parser (#2585)

This commit is contained in:
anqiansong
2023-03-28 23:45:26 +08:00
committed by GitHub
parent 455a6c8f97
commit 50bc361430
59 changed files with 11633 additions and 6 deletions

View File

@@ -0,0 +1,5 @@
@doc(
foo: "foo"
bar: "bar"
baz: ""
)

View File

@@ -0,0 +1,3 @@
@doc ""
@doc "foo"
@doc "bar"

View File

@@ -0,0 +1,3 @@
@handler foo
@handler foo1
@handler _bar

View File

@@ -0,0 +1,16 @@
@server(
foo: bar
bar: baz
baz: foo
qux: /v1
quux: /v1/v2
middleware: M1,M2
timeout1: 1h
timeout2: 10m
timeout3: 10s
timeout4: 10ms
timeout5: 10µs
timeout6: 10ns
timeout7: 1h10m10s10ms10µs10ns
maxBytes: 1024
)

View File

@@ -0,0 +1,11 @@
syntax = "v1"
import "base1.api"
info (
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)

View File

@@ -0,0 +1,11 @@
syntax = "v1"
import "base2.api"
info (
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)

View File

@@ -0,0 +1,11 @@
syntax = "v1"
import "base.api"
info (
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)

View File

@@ -0,0 +1,4 @@
// foo
// bar
/*foo*/
/*bar*/ //baz

View File

@@ -0,0 +1,167 @@
syntax = "v1"
import "example_base1.api"
import (
"example_base2.api"
)
info (
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)
type GetFormReq {
Name string `form:"name"`
Age int `form:"age"`
Hobbits []string `form:"hobbits"`
}
type GetFormREsp {
Name string `json:"name"`
Age int `json:"age"`
Hobbits []string `json:"hobbits"`
}
type (
PostFormReq {
Name string `form:"name"`
Age int `form:"age"`
Hobbits []string `form:"hobbits"`
}
PostFormResp {
Name string `json:"name"`
Age int `json:"age"`
Hobbits []string `json:"hobbits"`
}
)
type (
PostJsonReq {
Name string `json:"name"`
Age int `json:"age"`
Hobbits []string `json:"hobbits"`
}
PostJsonResp {
Name string `json:"name"`
Age int `json:"age"`
Hobbits []string `json:"hobbits"`
Extra map[string]string `json:"extra"`
Data interface{} `json:"data"`
}
)
type (
PostPathReq {
Id string `path:"id"`
}
PostPathResp {
Name string `json:"name"`
Age int `json:"age"`
Hobbits []string `json:"hobbits"`
Hobbits2 [2]string `json:"hobbits2"`
Extra map[string]string `json:"extra"`
Data interface{} `json:"data"`
}
)
type (
DemoOfArrayReq {
In string `json:"in"`
}
DemoOfArrayResp {
Out string `json:"out"`
}
)
type (
Nest {
Name string `json:"name"`
}
NestDemoReq1 {
Nest *Nest `json:"nest"`
}
NestDemoResp1 {
Nest []*Nest `json:"nest"`
}
NestDemoReq2 {
*Nest
}
NestDemoResp2 {
*Nest `json:"nest"`
}
)
@server (
group: form
timeout: 3s
)
service example {
@handler getForm
get /example/form (GetFormReq) returns (GetFormREsp)
@handler postForm
post /example/form (PostFormReq) returns (PostFormResp)
}
@server (
group: json
jwt: Auth
timeout: 3m
)
service example {
@doc "json demo"
@handler postJson
post /example/json (PostJsonReq) returns (PostJsonResp)
}
@server (
group: path
middleware: Path
prefix: /v1/v2
timeout: 100ms
)
service example {
@doc (
desc: "path demo"
)
@handler postPath
post /example/path (PostPathReq) returns (PostPathResp)
}
@server (
group: array
prefix: /array
maxBytes: 1024
)
service example {
@doc (
desc: "array response demo"
)
@handler getArray
post /example/array (DemoOfArrayReq) returns ([]DemoOfArrayResp)
@doc (
desc: "array pointer response demo"
)
@handler getArrayPointer
post /example/array/pointer (DemoOfArrayReq) returns ([]*DemoOfArrayResp)
@doc (
desc: "array base response demo"
)
@handler getArrayBase
post /example/array/base (DemoOfArrayReq) returns ([]string)
}
service example {
@handler nestDemo1
post /example/nest (NestDemoReq1) returns (NestDemoResp1)
@handler nestDemo2
post /example/nest2 (NestDemoReq2) returns (NestDemoResp2)
}

View File

@@ -0,0 +1,12 @@
syntax = "v1"
info(
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)
type BaseReq1{}
type BaseResp1{}

View File

@@ -0,0 +1,12 @@
syntax = "v1"
info(
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)
type BaseReq2{}
type BaseResp2{}

View File

@@ -0,0 +1,5 @@
import (
""
"foo"
"bar"
)

View File

@@ -0,0 +1,3 @@
import ""
import "foo"
import "bar"

View File

@@ -0,0 +1,7 @@
info(
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)

View File

@@ -0,0 +1,136 @@
// test case: expected syntax statement
info ()
-----
// test case: duplicate syntax statement
syntax = "v1"
syntax = "v1"
-----
// test case: duplicate info statement
syntax = "v1"
info()
info()
-----
// test case: duplicate type
syntax = "v1"
type Foo{}
type Foo{}
-----
// test case: duplicate type
syntax = "v1"
type Baz{}
type (
Baz{}
)
-----
// test case: multiple service name
syntax = "v1"
service foo{
@handler foo
get /foo
}
service bar{
@handler foo
get /foo
}
-----
// test case: duplicate handler
syntax = "v1"
service foo{
@handler foo
get /foo
@handler foo
get /bar
}
-----
// test case: duplicate path
syntax = "v1"
service foo{
@handler foo
get /foo
@handler bar
get /foo
@handler qux
get /v1/baz
}
@server(
prefix: /v1
)
service foo{
@handler qux
get /baz
@handler quux
get /baz
}
-----
// test case: type declare context
syntax = "v1"
type Foo {
Bar Bar `json:"bar"`
}
-----
// test case: map key expected literal type
syntax = "v1"
type Foo {
Bar map[[]int]string `json:"bar"`
}
-----
// test case: map key expected literal type
syntax = "v1"
type Foo {
Bar map[[]int]string `json:"bar"`
}
-----
// test case: map key expected literal type
syntax = "v1"
type Foo {
Bar *map[[]int]string `json:"bar"`
}
-----
// test case: map valu expected literal type
syntax = "v1"
type Foo {
Bar *map[string]{} `json:"bar"`
}
-----
// test case: invalid slice
syntax = "v1"
type Foo {
Bar []map[[]int]string `json:"bar"`
}
-----
// test case: array
syntax = "v1"
type Foo {
Bar [...]int `json:"bar"`
}
-----
// test case: any
syntax = "v1"
type Foo {
Bar any `json:"bar"`
}
-----
// test case: unresolved type
syntax = "v1"
service example {
@handler nestDemo
post /example/nest (NestDemoReq) returns (NestDemoResp)
}

View File

@@ -0,0 +1,37 @@
service foo {
@handler bar
get /ping
@handler bar
get /ping;
}
service bar {
@doc "bar"
@handler foo
get /foo/:bar (Foo)
@doc "bar"
@handler foo
get /foo/:bar (Foo) returns ();
@handler foo
get /foo/:bar returns (Foo)
@handler foo
get /foo/:bar () returns (Foo);
}
service baz-api {
@handler foo
post /foo/:bar/foo-bar-baz (Foo) returns (*Bar)
@handler foo
post /foo/:bar/foo-bar-baz (Foo) returns (*Bar);
@handler bar
post /foo ([]Foo) returns ([]*Bar)
@handler bar
post /foo ([]Foo) returns ([]*Bar);
}

View File

@@ -0,0 +1,160 @@
// aaaa
/*bb*/ syntax /*cc*/ = /*dd*/ "v1" /*syntax doc*/ // syntax stmt
// bbb
info ( // info stmt
title: "type title here" // title expr
/*ee*/
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)
type AliasInt int
type AliasString = string
type AliasArray [2]int8
type AliasArray2 [...]int8
type AliasSlice []int8
type AliasMap map[string]int
type Any interface{}
type AliasMapKeyStruct map[{
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
}
}
}
}]int
type AliasMapValueStruct map[string]{
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
}
}
}
}
type Foo {
Bar {
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
Bar {
Name string `json:"name"`
Age int `json:"age"`
}
}
}
}
type Bar {
Base int `json:"base"`
Array1 [2]int `json:"array1"`
Array2 [...]int `json:"array2"`
Slice []int `json:"slice"`
Map1 map[string]int `json:"map1"`
Map2 map[string]*int `json:"map2"`
Map3 map[string][]int `json:"map3"`
Map4 map[string][]*int `json:"map4"`
Map5 map[string][2]int `json:"map5"`
Map6 map[string][...]int `json:"map6"`
Interface interface{} `json:"interface"`
Any any `json:"any"`
Foo Foo `json:"foo"`
Baz {
F1 int `json:"f1"`
F2 int `json:"f2"`
} `json:"baz"`
Qux *string `json:"qux"`
Quux bool `json:"quux"`
}
type (
GroupAliasInt int
GroupAliasString = string
GroupAliasArray [2]int8
GroupAliasArray2 [...]int8
GroupAliasSlice []int8
GroupAliasMap map[string]int
GroupAny interface{}
GroupFoo {}
GroupBar {
Base int `json:"base"`
Array1 [2]int `json:"array1"`
Array2 [...]int `json:"array2"`
Slice []int `json:"slice"`
Map1 map[string]int `json:"map1"`
Map2 map[string]*int `json:"map2"`
Map3 map[string][]int `json:"map3"`
Map4 map[string][]*int `json:"map4"`
Map5 map[string][2]int `json:"map5"`
Map6 map[string][...]int `json:"map6"`
Interface interface{} `json:"interface"`
Any any `json:"any"`
Foo Foo `json:"foo"`
Baz {
F1 int `json:"f1"`
F2 int `json:"f2"`
} `json:"baz"`
Qux *string `json:"qux"`
Quux bool `json:"quux"`
}
)
@server ()
service test {
@handler foo
get /test/foo
}
@server (
jwt: Auth
group: Group1
)
service test {
@doc "ping"
@handler foo
get /test/foo
@doc (
key1: "value1"
key2: "value2"
)
@handler bar
get /test/foo (Foo)
@handler baz
post /test/foo/baz returns (Bar)
@handler qux
post /test/foo/baz/:qux (Foo) returns (Bar)
@handler quux
post /test/foo/baz/:qux/qu-ux (Foo) returns (Bar)
@handler foobar
post /foo/bar (*Foo) returns ([]Bar)
@handler barbaz
post /bar/baz ([]*Foo) returns ([]int)
}
// terminal
// terminal2
/*
kkk
*/

View File

@@ -0,0 +1,50 @@
// format api demo
syntax ="v1" // dd
info()
info(foo:"")
info(foo:""
bar: ""
quux: "")
info(foo:""
bar: ""
quux: ""
)
// info statement
// info statement
info (// Info bloack
title: "type title here" // title comment
desc: "type desc here"
author: "type author here"
/*aaa*/
/*
bbb
*/
email: "type email here" // eamil comment
/*aaa*/version:/*bbb*/ "type version here"// version comment
)
import ""
import "aaa"
import"bb"
import "cc"
import()
import(
)
import (
)
import ("aa")
import ("aa" "bb")
import ("aa"
"bb"
)
import ("aa"
"bb")
import (
"aa"
"bb"
)