From 5a8293c573beae1b755cd410e29a0f06e2189d36 Mon Sep 17 00:00:00 2001 From: jhayotte Date: Wed, 8 Aug 2018 16:38:58 +0200 Subject: [PATCH] feat: enhance the function of typing field with their package --- .../output/models/article/article.pb.go | 66 +++++++++++++------ .../import/output/models/common/common.pb.go | 3 +- examples/import/output/output.go | 35 +++++++++- examples/import/proto/article.proto | 18 ++++- examples/import/templates/output.go.tmpl | 32 ++++++++- helpers/helpers.go | 47 ++++++++++++- 6 files changed, 171 insertions(+), 30 deletions(-) diff --git a/examples/import/output/models/article/article.pb.go b/examples/import/output/models/article/article.pb.go index 0c67abb..eaa6c2b 100644 --- a/examples/import/output/models/article/article.pb.go +++ b/examples/import/output/models/article/article.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-go. +// Code generated by protoc-gen-go. DO NOT EDIT. // source: proto/article.proto -// DO NOT EDIT! /* Package article is a generated protocol buffer package. @@ -49,6 +48,8 @@ func (m *GetArticleRequest) GetGetarticle() *common.GetArticle { type GetArticleResponse struct { Article *Article `protobuf:"bytes,1,opt,name=article" json:"article,omitempty"` + // The generated output should write []*GetArticleResponse_Storage.Storage for this field. + Storages []*GetArticleResponse_Storage `protobuf:"bytes,2,rep,name=storages" json:"storages,omitempty"` } func (m *GetArticleResponse) Reset() { *m = GetArticleResponse{} } @@ -63,6 +64,29 @@ func (m *GetArticleResponse) GetArticle() *Article { return nil } +func (m *GetArticleResponse) GetStorages() []*GetArticleResponse_Storage { + if m != nil { + return m.Storages + } + return nil +} + +type GetArticleResponse_Storage struct { + Code string `protobuf:"bytes,1,opt,name=code" json:"code,omitempty"` +} + +func (m *GetArticleResponse_Storage) Reset() { *m = GetArticleResponse_Storage{} } +func (m *GetArticleResponse_Storage) String() string { return proto.CompactTextString(m) } +func (*GetArticleResponse_Storage) ProtoMessage() {} +func (*GetArticleResponse_Storage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} } + +func (m *GetArticleResponse_Storage) GetCode() string { + if m != nil { + return m.Code + } + return "" +} + type Article struct { Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` @@ -88,26 +112,30 @@ func (m *Article) GetName() string { } func init() { - proto.RegisterType((*GetArticleRequest)(nil), "article.GetArticleRequest") - proto.RegisterType((*GetArticleResponse)(nil), "article.GetArticleResponse") - proto.RegisterType((*Article)(nil), "article.Article") + proto.RegisterType((*GetArticleRequest)(nil), "company.GetArticleRequest") + proto.RegisterType((*GetArticleResponse)(nil), "company.GetArticleResponse") + proto.RegisterType((*GetArticleResponse_Storage)(nil), "company.GetArticleResponse.Storage") + proto.RegisterType((*Article)(nil), "company.Article") } func init() { proto.RegisterFile("proto/article.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 208 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xca, 0x2f, - 0xc9, 0xd7, 0x4f, 0x2c, 0x2a, 0xc9, 0x4c, 0xce, 0x49, 0xd5, 0x03, 0xf3, 0x84, 0xd8, 0xa1, 0x5c, - 0x29, 0x21, 0x88, 0x6c, 0x72, 0x7e, 0x6e, 0x6e, 0x7e, 0x1e, 0x44, 0x52, 0xc9, 0x9d, 0x4b, 0xd0, - 0x3d, 0xb5, 0xc4, 0x11, 0xa2, 0x22, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0xc8, 0x88, 0x8b, - 0x2b, 0x3d, 0xb5, 0x04, 0xaa, 0x4d, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x48, 0x0f, 0xaa, - 0x0f, 0x49, 0x39, 0x92, 0x2a, 0x25, 0x07, 0x2e, 0x21, 0x64, 0x83, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, - 0x53, 0x85, 0xb4, 0xb8, 0xd8, 0x51, 0x8d, 0x11, 0xd0, 0x83, 0x39, 0x0e, 0xa6, 0x14, 0xa6, 0x40, - 0x49, 0x97, 0x8b, 0x1d, 0x2a, 0x26, 0xc4, 0xc7, 0xc5, 0x94, 0x99, 0x02, 0xd6, 0xc1, 0x19, 0xc4, - 0x94, 0x99, 0x22, 0x24, 0xc4, 0xc5, 0x92, 0x97, 0x98, 0x9b, 0x2a, 0xc1, 0x04, 0x16, 0x01, 0xb3, - 0x8d, 0x42, 0xb9, 0xb8, 0xa0, 0x3a, 0x8b, 0xcb, 0x92, 0x85, 0xdc, 0xb9, 0xb8, 0x10, 0xd6, 0x0b, - 0x49, 0xc1, 0x6d, 0xc1, 0xf0, 0x9c, 0x94, 0x34, 0x56, 0x39, 0x88, 0x7b, 0x95, 0x18, 0x9c, 0x24, - 0xa2, 0xc4, 0x72, 0xf3, 0x53, 0x52, 0x73, 0x8a, 0x61, 0xa1, 0x68, 0x0d, 0xa5, 0x93, 0xd8, 0xc0, - 0x21, 0x66, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x16, 0x18, 0x87, 0xc4, 0x65, 0x01, 0x00, 0x00, + // 256 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0x41, 0x4b, 0xc4, 0x30, + 0x10, 0x85, 0x6d, 0x15, 0xab, 0xb3, 0x20, 0x3a, 0x82, 0x94, 0x8a, 0xb0, 0xd4, 0xcb, 0x22, 0x18, + 0xa1, 0x1e, 0x3d, 0x88, 0x5e, 0x7a, 0xaf, 0x78, 0xf1, 0x56, 0xd3, 0x61, 0x29, 0x6c, 0x3a, 0xb5, + 0x89, 0x82, 0xff, 0xc6, 0x9f, 0x2a, 0x9b, 0x4c, 0xd7, 0x8a, 0xb2, 0xa7, 0x4e, 0xf3, 0xbe, 0xf7, + 0xf2, 0xc8, 0xc0, 0x69, 0x3f, 0xb0, 0xe3, 0x9b, 0x7a, 0x70, 0xad, 0x5e, 0x91, 0xf2, 0x7f, 0x98, + 0x68, 0x36, 0x7d, 0xdd, 0x7d, 0x66, 0x18, 0x54, 0xcd, 0xc6, 0x70, 0x17, 0xc4, 0xbc, 0x84, 0x93, + 0x92, 0xdc, 0x43, 0x30, 0x54, 0xf4, 0xf6, 0x4e, 0xd6, 0x61, 0x01, 0xb0, 0x24, 0x27, 0x29, 0x69, + 0x34, 0x8f, 0x16, 0xb3, 0x02, 0x95, 0xf8, 0x26, 0xf8, 0x84, 0xca, 0xbf, 0x22, 0xc0, 0x69, 0x92, + 0xed, 0xb9, 0xb3, 0x84, 0x57, 0x90, 0xfc, 0xce, 0x39, 0x56, 0x52, 0x47, 0x8d, 0xe8, 0x08, 0xe0, + 0x3d, 0x1c, 0x58, 0xc7, 0x43, 0xbd, 0x24, 0x9b, 0xc6, 0xf3, 0xdd, 0xc5, 0xac, 0xb8, 0xdc, 0xc0, + 0x7f, 0xa3, 0xd5, 0x53, 0x60, 0xab, 0x8d, 0x29, 0xbb, 0x80, 0x44, 0x0e, 0x11, 0x61, 0x4f, 0x73, + 0x13, 0x2e, 0x3d, 0xac, 0xfc, 0x9c, 0x5f, 0x43, 0x22, 0x19, 0x78, 0x04, 0x71, 0xdb, 0x88, 0x18, + 0xb7, 0xcd, 0x1a, 0xef, 0x6a, 0x43, 0x69, 0x1c, 0xf0, 0xf5, 0x5c, 0x3c, 0x03, 0x48, 0x33, 0xfb, + 0xa1, 0xb1, 0x04, 0xf8, 0xe9, 0x80, 0xd9, 0xbf, 0xc5, 0xfc, 0xeb, 0x65, 0xe7, 0x5b, 0x4a, 0xe7, + 0x3b, 0x8f, 0xe9, 0xcb, 0x99, 0xe1, 0x86, 0x56, 0x76, 0x5c, 0xd3, 0x9d, 0x7c, 0x5f, 0xf7, 0xfd, + 0x4a, 0x6e, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x93, 0xb5, 0x4a, 0x95, 0xc6, 0x01, 0x00, 0x00, } diff --git a/examples/import/output/models/common/common.pb.go b/examples/import/output/models/common/common.pb.go index 3c0c9ed..6cfb9ba 100644 --- a/examples/import/output/models/common/common.pb.go +++ b/examples/import/output/models/common/common.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-go. +// Code generated by protoc-gen-go. DO NOT EDIT. // source: proto/common.proto -// DO NOT EDIT! /* Package common is a generated protocol buffer package. diff --git a/examples/import/output/output.go b/examples/import/output/output.go index b15bdb1..79026a7 100644 --- a/examples/import/output/output.go +++ b/examples/import/output/output.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gotemplate -package article +package company import ( "github.com/moul/protoc-gen-gotemplate/examples/import/output/models/article" @@ -7,5 +7,34 @@ import ( ) type Repository interface { - GetArticle(getarticle *common.GetArticle ) (*article.Article, error) -} \ No newline at end of file + GetArticle(getarticle *common.GetArticle ) (*company.Article, []*company.Storage, error) +} + + + + + + + +// ------------------------- Public SDK ----------------------------- + + + + + + + +// GetArticle : proto: missing extension proto: missing extension +func (sdk *Sdk) GetArticle(ctx context.Context, + getarticle *GetArticle.GetArticle, token, requestID string)(article *Article.Article, storages []*GetArticleResponse_Storage.Storage, err error) { + + out := &pb.GetArticleResponse{} + _ = out + + + return out.Article, out.Storages, nil + +} + + + \ No newline at end of file diff --git a/examples/import/proto/article.proto b/examples/import/proto/article.proto index abe4afd..2c8858f 100644 --- a/examples/import/proto/article.proto +++ b/examples/import/proto/article.proto @@ -1,13 +1,25 @@ syntax = "proto3"; -package article; +package company; option go_package = "models/article;article"; import "proto/common.proto"; -message GetArticleRequest { common.GetArticle getarticle = 1;} -message GetArticleResponse { Article article = 1;} +message GetArticleRequest { + common.GetArticle getarticle = 1; +} + + +message GetArticleResponse { + Article article = 1; + + message Storage { + string code = 1; + } + // The generated output should write []*GetArticleResponse_Storage.Storage for this field. + repeated Storage storages = 2; +} message Article{ string id = 1; diff --git a/examples/import/templates/output.go.tmpl b/examples/import/templates/output.go.tmpl index 341b297..cb1076a 100644 --- a/examples/import/templates/output.go.tmpl +++ b/examples/import/templates/output.go.tmpl @@ -1,4 +1,5 @@ // Code generated by protoc-gen-gotemplate +{{- $file := .File}} package {{.File.Package}} import ( @@ -8,4 +9,33 @@ import ( type Repository interface { {{range $m := .Service.Method}}{{with $t := $m.InputType | getMessageType $.File}} {{$m.Name}}({{range $f := $t.Field}}{{$f.Name|lowerCamelCase}} {{$f| goTypeWithPackage }} {{end}}) ({{with $out := $m.OutputType | getMessageType $.File}}{{range $f := $out.Field}}{{$f | goTypeWithPackage}}, {{end}}{{end}} error){{end}}{{end}} -} \ No newline at end of file +} + + + + + + + +// ------------------------- Public SDK ----------------------------- +{{$pkg := "pb"}} + + +{{range $m := .Service.Method}} +{{with $t := $m.InputType | getMessageType $.File}} +{{if and (not $m.ServerStreaming) (not $m.ClientStreaming)}} +{{/* ----------------------------- nominal case ---------------------------- */}} +// {{$m.Name}} : {{$m | httpVerb}} {{$m | httpPath}} +func (sdk *Sdk) {{$m.Name}}(ctx context.Context, {{if $t.OneofDecl}} req *{{$pkg}}.{{$m.Name}}Request,{{else}}{{range $f := $t.Field}} + {{$f.Name|lowerCamelCase}} {{$f| goTypeWithPackageV2 $.File}},{{end}}{{end}} token, requestID string)({{with $out := $m.OutputType | getMessageType $.File}}{{range $f := $out.Field}}{{$f.Name|lowerCamelCase}} {{$f | goTypeWithPackageV2 $.File}}, {{end}}{{end}}err error) { + + out := &{{$pkg}}.{{$m.Name}}Response{} + _ = out + +{{with $out := $m.OutputType | getMessageType $.File}} + return {{range $f := $out.Field}}out.{{$f.Name|camelCase}}, {{end}}nil +{{end}} {{/* with */}} +} + +{{end}} {{/* streaming ifs */}} +{{end}}{{end}} {{/* range with */}} \ No newline at end of file diff --git a/helpers/helpers.go b/helpers/helpers.go index a2777e5..26be065 100644 --- a/helpers/helpers.go +++ b/helpers/helpers.go @@ -137,6 +137,7 @@ var ProtoHelpersFuncMap = template.FuncMap{ "goType": goType, "goZeroValue": goZeroValue, "goTypeWithPackage": goTypeWithPackage, + "goTypeWithPackageV2": goTypeWithPackageV2, "jsType": jsType, "jsSuffixReserved": jsSuffixReservedKeyword, "namespacedFlowType": namespacedFlowType, @@ -555,9 +556,47 @@ func fieldMapValueType(f *descriptor.FieldDescriptorProto, m *descriptor.Descrip } +// goTypeWithPackageV2 type the field given with its package name. +// This method is an evolution of goTypeWithPackage. It allows you to type a field with a message embedded. +// +// exemple: +// ```proto +// message GetArticleResponse { +// Article article = 1; +// message Storage { +// string code = 1; +// } +// repeated Storage storages = 2; +// } +// ``` +// Then the type of `storages` is `GetArticleResponse_Storage` for the go language. +func goTypeWithPackageV2(p *descriptor.FileDescriptorProto, f *descriptor.FieldDescriptorProto) string { + pkg := "" + if *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE || *f.Type == descriptor.FieldDescriptorProto_TYPE_ENUM { + if isTimestampPackage(*f.TypeName) { + return "timestamp" + } + + fieldPackage := strings.Split(*f.TypeName, ".") + filePackage := strings.Split(*p.Package, ".") + // check if we are working with a message embedded. + if len(fieldPackage) > 1 && len(fieldPackage)+1 > len(filePackage)+1 { + pkg = strings.Join(fieldPackage[len(filePackage)+1:len(fieldPackage)], "_") + } else { + pkg = getPackageTypeName(*f.TypeName) + } + } + res := goType(pkg, f) + return res +} + +// Deprecated. Instead use goTypeWithPackageV2 func goTypeWithPackage(f *descriptor.FieldDescriptorProto) string { pkg := "" if *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE || *f.Type == descriptor.FieldDescriptorProto_TYPE_ENUM { + if isTimestampPackage(*f.TypeName) { + return "timestamp" + } pkg = getPackageTypeName(*f.TypeName) } return goType(pkg, f) @@ -758,10 +797,14 @@ func jsSuffixReservedKeyword(s string) string { return jsReservedRe.ReplaceAllString(s, "${1}${2}_${3}") } -func getPackageTypeName(s string) string { +func isTimestampPackage(s string) bool { if strings.Compare(s, ".google.protobuf.Timestamp") == 0 { - return "timestamp" + return true } + return false +} + +func getPackageTypeName(s string) string { if strings.Contains(s, ".") { return strings.Split(s, ".")[1] }