Skip to content

Commit

Permalink
API Generator: generate for each generated type an comment to describ…
Browse files Browse the repository at this point in the history
…es this type
  • Loading branch information
donutloop committed Mar 4, 2018
1 parent 97ba4ba commit 3b6ce30
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 16 deletions.
35 changes: 24 additions & 11 deletions generator/proto/go/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ func (a *API) generateClient(name string, fileDescriptor *descriptor.FileDescrip
if err != nil {
return nil, err
}
structGenerator.StructMetaData.Comment = append(structGenerator.StructMetaData.Comment, fmt.Sprintf("%s wraps an http.client and sends %s objects", structName, name))

structGenerator.AddUnexportedField("client", types.NewUnsafeTypeReference("transport.HTTPClient"), "")
structGenerator.AddUnexportedField("urls", types.NewUnsafeTypeReference(fmt.Sprintf("[%s]string", methCnt)), "")
Expand All @@ -363,6 +364,7 @@ func (a *API) generateClientConstructor(newClientFuncName, structName string, se

pathPrefixConst := serviceName(service) + "PathPrefix"

comment := fmt.Sprintf("%s constructs a new client, which wraps the http.client and implements %s", newClientFuncName, serviceName(service))
f, err := types.NewGoFunc(newClientFuncName, []*types.Parameter{
{
NameOfParameter: "addr",
Expand All @@ -375,7 +377,7 @@ func (a *API) generateClientConstructor(newClientFuncName, structName string, se
},
[]types.TypeReference{
types.NewUnsafeTypeReference(serviceName(service)),
})
}, comment)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -432,7 +434,7 @@ func (a *API) generateClientConstructor(newClientFuncName, structName string, se
return goFile, nil
}

func (a *API) generateClientEndpoints(name string, fileDescriptor *descriptor.FileDescriptorProto, service *descriptor.ServiceDescriptorProto, structGenerator *types.StructGenerator) (*types.StructGenerator, error) {
func (a *API) generateClientEndpoints(contentType string, fileDescriptor *descriptor.FileDescriptorProto, service *descriptor.ServiceDescriptorProto, structGenerator *types.StructGenerator) (*types.StructGenerator, error) {

for i, method := range service.Method {
methName := methodName(method)
Expand All @@ -447,6 +449,7 @@ func (a *API) generateClientEndpoints(name string, fileDescriptor *descriptor.Fi
return nil, err
}

comment := fmt.Sprintf("%s sends an %s %s object to the server", methName, inputType, contentType)
method, err := types.NewGoMethod("c", fmt.Sprintf("*%s", structGenerator.StructMetaData.Name), methName, []*types.Parameter{
{
NameOfParameter: "ctx",
Expand All @@ -459,7 +462,7 @@ func (a *API) generateClientEndpoints(name string, fileDescriptor *descriptor.Fi
}, []types.TypeReference{
types.NewUnsafeTypeReference(fmt.Sprintf("*%s", outputType)),
types.NewUnsafeTypeReference("error"),
}, "")
}, comment)

if err != nil {
return nil, err
Expand All @@ -469,7 +472,7 @@ func (a *API) generateClientEndpoints(name string, fileDescriptor *descriptor.Fi
method.DefCall([]string{"ctx"}, types.NewUnsafeTypeReference("xcontext.WithServiceName"), []string{"ctx", `"` + servName + `"`})
method.DefCall([]string{"ctx"}, types.NewUnsafeTypeReference("xcontext.WithMethodName"), []string{"ctx", `"` + methName + `"`})
method.DefNew("out", types.NewUnsafeTypeReference(outputType))
method.DefAssginCall([]string{"err"}, types.NewUnsafeTypeReference(fmt.Sprintf("transport.Do%sRequest", name)), []string{"ctx", "c.client", fmt.Sprintf("c.urls[%s]", strconv.Itoa(i)), "in", "out"})
method.DefAssginCall([]string{"err"}, types.NewUnsafeTypeReference(fmt.Sprintf("transport.Do%sRequest", contentType)), []string{"ctx", "c.client", fmt.Sprintf("c.urls[%s]", strconv.Itoa(i)), "in", "out"})
method.Return([]string{"out", "err"})
structGenerator.AddMethod(method)
}
Expand All @@ -484,6 +487,8 @@ func (a *API) generateServer(fileDescriptor *descriptor.FileDescriptorProto, ser
return nil, err
}

structGenerator.StructMetaData.Comment = append(structGenerator.StructMetaData.Comment, fmt.Sprintf("%s wraps an endpoint and implements http.Handler.", serviceStruct(service)))

structGenerator.Type(types.NewUnsafeTypeReference(serviceName(service)), "")
structGenerator.AddUnexportedField("hooks", types.NewUnsafeTypeReference("*hooks.ServerHooks"), "")
structGenerator.AddUnexportedField("logErrorFunc", types.NewUnsafeTypeReference("transport.LogErrorFunc"), "")
Expand Down Expand Up @@ -527,6 +532,7 @@ func (a *API) generateServerConstructor(serverName, serverStructName string, goF

constructorName := fmt.Sprintf("New%sServer", serverName)

comment := fmt.Sprintf("%s constructs a new server, and implements %s", constructorName, serverName)
f, err := types.NewGoFunc(constructorName, []*types.Parameter{
{
NameOfParameter: "svc",
Expand All @@ -543,7 +549,7 @@ func (a *API) generateServerConstructor(serverName, serverStructName string, goF
},
[]types.TypeReference{
types.NewUnsafeTypeReference("server.Server"),
})
}, comment)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -619,6 +625,7 @@ func (a *API) generateServerRouting(file *descriptor.FileDescriptorProto, servic
return nil, err
}

comment := "ServeHTTP implements http.Handler."
method, err := types.NewGoMethod("s", fmt.Sprintf("*%s", structGenerator.StructMetaData.Name), "ServeHTTP", []*types.Parameter{
{
NameOfParameter: "resp",
Expand All @@ -628,7 +635,7 @@ func (a *API) generateServerRouting(file *descriptor.FileDescriptorProto, servic
NameOfParameter: "req",
Typ: types.NewUnsafeTypeReference("*http.Request"),
},
}, nil, "")
}, nil, comment)

if err != nil {
return nil, err
Expand Down Expand Up @@ -690,8 +697,10 @@ func (a *API) generateServerRouting(file *descriptor.FileDescriptorProto, servic

func (a *API) generateServerMethod(service *descriptor.ServiceDescriptorProto, method *descriptor.MethodDescriptorProto, structGenerator *types.StructGenerator) (*types.StructGenerator, error) {
methName := types.CamelCase(method.GetName())
methNameServe := fmt.Sprintf("serve%s", methName)

dispatcherMethod, err := types.NewGoMethod("s", fmt.Sprintf("*%s", structGenerator.StructMetaData.Name), fmt.Sprintf("serve%s", methName), []*types.Parameter{
comment := fmt.Sprintf("%s is used to set an decoder and encoder for a given content type", methNameServe)
dispatcherMethod, err := types.NewGoMethod("s", fmt.Sprintf("*%s", structGenerator.StructMetaData.Name), methNameServe, []*types.Parameter{
{
NameOfParameter: "ctx",
Typ: types.NewUnsafeTypeReference("context.Context"),
Expand All @@ -704,7 +713,7 @@ func (a *API) generateServerMethod(service *descriptor.ServiceDescriptorProto, m
NameOfParameter: "req",
Typ: types.NewUnsafeTypeReference("*http.Request"),
},
}, nil, "")
}, nil, comment)

if err != nil {
return nil, err
Expand Down Expand Up @@ -743,7 +752,9 @@ func (a *API) generateServerMethod(service *descriptor.ServiceDescriptorProto, m

func (a *API) generateServerServeMethod(service *descriptor.ServiceDescriptorProto, method *descriptor.MethodDescriptorProto, structGenerator *types.StructGenerator) (*types.StructGenerator, error) {
methName := types.CamelCase(method.GetName())
methServe := fmt.Sprintf("serve%sContent", methName)

comment := fmt.Sprintf("%s sends object to requester", methServe)
serveMethod, err := types.NewGoMethod("s", fmt.Sprintf("*%s", structGenerator.StructMetaData.Name), fmt.Sprintf("serve%sContent", methName), []*types.Parameter{
{
NameOfParameter: "ctx",
Expand All @@ -765,7 +776,7 @@ func (a *API) generateServerServeMethod(service *descriptor.ServiceDescriptorPro
NameOfParameter: "encodeResponse",
Typ: types.NewUnsafeTypeReference("transport.EncodeResponseFunc"),
},
}, nil, "")
}, nil, comment)

if err != nil {
return nil, err
Expand Down Expand Up @@ -853,11 +864,12 @@ func (a *API) generateServiceMetadataAccessors(file *descriptor.FileDescriptorPr

structName := structGenerator.StructMetaData.Name

comment := "ServiceDescriptor describes an service."
serviceDescriptorMethod, err := types.NewGoMethod("s", fmt.Sprintf("*%s", structName), "ServiceDescriptor", nil,
[]types.TypeReference{
types.TypeReferenceFromInstance([]byte(nil)),
types.TypeReferenceFromInstance(int(0)),
}, "")
}, comment)

if err != nil {
return nil, err
Expand All @@ -866,10 +878,11 @@ func (a *API) generateServiceMetadataAccessors(file *descriptor.FileDescriptorPr
serviceDescriptorMethod.Return([]string{a.serviceMetadataVarName(), strconv.Itoa(index)})
structGenerator.AddMethod(serviceDescriptorMethod)

comment = "ProtocGenXServiceVersion returns which xservice version was used to generate that service"
protocGenXServiceVersionMethod, err := types.NewGoMethod("s", fmt.Sprintf("*%s", structName), "ProtocGenXServiceVersion", nil,
[]types.TypeReference{
types.TypeReferenceFromInstance(string("")),
}, "")
}, comment)

if err != nil {
return nil, err
Expand Down
15 changes: 15 additions & 0 deletions integration_tests/api_hello_world/helloworld.proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ type HelloWorld interface {
Hello(ctx context.Context, req *HelloReq) (*HelloResp, error)
}

// helloWorldJSONClient wraps an http.client and sends JSON objects
type helloWorldJSONClient struct {
client transport.HTTPClient
urls [1]string
}

// Hello sends an HelloReq JSON object to the server
func (c *helloWorldJSONClient) Hello(ctx context.Context, in *HelloReq) (*HelloResp, error) {
ctx = xcontext.WithPackageName(ctx, "example.helloworld")
ctx = xcontext.WithServiceName(ctx, "HelloWorld")
Expand All @@ -49,11 +51,13 @@ func (c *helloWorldJSONClient) Hello(ctx context.Context, in *HelloReq) (*HelloR
return out, err
}

// helloWorldProtobufferClient wraps an http.client and sends Protobuffer objects
type helloWorldProtobufferClient struct {
client transport.HTTPClient
urls [1]string
}

// Hello sends an HelloReq Protobuffer object to the server
func (c *helloWorldProtobufferClient) Hello(ctx context.Context, in *HelloReq) (*HelloResp, error) {
ctx = xcontext.WithPackageName(ctx, "example.helloworld")
ctx = xcontext.WithServiceName(ctx, "HelloWorld")
Expand All @@ -63,6 +67,7 @@ func (c *helloWorldProtobufferClient) Hello(ctx context.Context, in *HelloReq) (
return out, err
}

// helloWorldServer wraps an endpoint and implements http.Handler.
type helloWorldServer struct {
HelloWorld
hooks *hooks.ServerHooks
Expand All @@ -73,6 +78,7 @@ func (s *helloWorldServer) writeError(ctx context.Context, resp http.ResponseWri
transport.WriteErrorAndTriggerHooks(ctx, resp, err, s.hooks)
}

// ServeHTTP implements http.Handler.
func (s *helloWorldServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
ctx := req.Context()
ctx = xcontext.WithPackageName(ctx, "example.helloworld")
Expand Down Expand Up @@ -105,6 +111,7 @@ func (s *helloWorldServer) ServeHTTP(resp http.ResponseWriter, req *http.Request

}

// serveHello is used to set an decoder and encoder for a given content type
func (s *helloWorldServer) serveHello(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
header := req.Header.Get(xhttp.ContentTypeHeader)
i := strings.Index(header, ";")
Expand All @@ -126,6 +133,7 @@ func (s *helloWorldServer) serveHello(ctx context.Context, resp http.ResponseWri
}
}

// serveHelloContent sends object to requester
func (s *helloWorldServer) serveHelloContent(ctx context.Context, resp http.ResponseWriter, req *http.Request, decodeRequest transport.DecodeRequestFunc, encodeResponse transport.EncodeResponseFunc) {
var err error
ctx = xcontext.WithMethodName(ctx, "Hello")
Expand Down Expand Up @@ -178,14 +186,17 @@ func (s *helloWorldServer) serveHelloContent(ctx context.Context, resp http.Resp
transport.CallResponseSent(ctx, s.hooks)
}

// ServiceDescriptor describes an service.
func (s *helloWorldServer) ServiceDescriptor() ([]uint8, int) {
return xserviceFileDescriptor0, 0
}

// ProtocGenXServiceVersion returns which xservice version was used to generate that service
func (s *helloWorldServer) ProtocGenXServiceVersion() string {
return "v0.1.0"
}

// NewHelloWorldJSONClient constructs a new client, which wraps the http.client and implements HelloWorld
func NewHelloWorldJSONClient(addr string, client transport.HTTPClient) HelloWorld {
URLBase := transport.UrlBase(addr)
prefix := URLBase + HelloWorldPathPrefix
Expand All @@ -205,6 +216,8 @@ func NewHelloWorldJSONClient(addr string, client transport.HTTPClient) HelloWorl
urls: urls,
}
}

// NewHelloWorldProtobufferClient constructs a new client, which wraps the http.client and implements HelloWorld
func NewHelloWorldProtobufferClient(addr string, client transport.HTTPClient) HelloWorld {
URLBase := transport.UrlBase(addr)
prefix := URLBase + HelloWorldPathPrefix
Expand All @@ -224,6 +237,8 @@ func NewHelloWorldProtobufferClient(addr string, client transport.HTTPClient) He
urls: urls,
}
}

// NewHelloWorldServer constructs a new server, and implements HelloWorld
func NewHelloWorldServer(svc HelloWorld, hooks *hooks.ServerHooks, errorFunc ...transport.LogErrorFunc) server.Server {
server := &helloWorldServer{
HelloWorld: svc,
Expand Down
2 changes: 1 addition & 1 deletion internal/xgenerator/types/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type({{range $i, $typ := .Types}}
{{end}}
{{range $i, $func := .Funcs}}
{{- $func}}
{{- $func }}
{{end}}
`

Expand Down
10 changes: 6 additions & 4 deletions internal/xgenerator/types/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type FuncGeneratorMetaData struct {
MethodOfTyp string
TypShortcut string
Fnc string
Comment []string
Comment string
}

type FuncGenerator struct {
Expand All @@ -32,13 +32,14 @@ type FuncGenerator struct {

const funcTplName = "func"
const funcTpl string = `
{{ if .Comment }} // {{ .Comment }} {{ end }}
func {{ .Name }} ({{ .Params }}) {{if .Returns }} ({{- .Returns }}) {{end}} {
{{range $i, $line := .Lines}}
{{- $line | safe }}
{{- end -}}
}`

func NewGoFunc(name string, parameters []*Parameter, returns []TypeReference) (*FuncGenerator, error) {
func NewGoFunc(name string, parameters []*Parameter, returns []TypeReference, comment string) (*FuncGenerator, error) {

gen := &FuncGenerator{}

Expand All @@ -55,8 +56,9 @@ func NewGoFunc(name string, parameters []*Parameter, returns []TypeReference) (*
}

gen.TypeFuncMetadata = FuncGeneratorMetaData{
Name: Identifier(name),
Params: paramList(parameters),
Name: Identifier(name),
Params: paramList(parameters),
Comment: comment,
}

if len(returns) > 0 {
Expand Down
1 change: 1 addition & 0 deletions internal/xgenerator/types/func_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func TestNewFuncAndRender(t *testing.T) {
types.String,
types.String,
},
"",
)
if err != nil {
t.Error(err)
Expand Down

0 comments on commit 3b6ce30

Please sign in to comment.