diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1f1c36f..6052bdf 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,6 +10,7 @@ Fixes # (issue) - [ ] Bug fix (non-breaking change which fixes an issue) [title: 'fix:'] - [ ] New feature (non-breaking change which adds functionality) [title: 'feat:'] +- [ ] Refactor (non-breaking code changes that do not add new functionality or break existing functionality) [title: 'refactor:'] - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update diff --git a/.trunk/.gitignore b/.trunk/.gitignore index 97108a4..507283d 100644 --- a/.trunk/.gitignore +++ b/.trunk/.gitignore @@ -1,2 +1,3 @@ *out -*logs \ No newline at end of file +*logs +external diff --git a/.trunk/plugins/trunk b/.trunk/plugins/trunk new file mode 120000 index 0000000..0109ed7 --- /dev/null +++ b/.trunk/plugins/trunk @@ -0,0 +1 @@ +/Users/shivanshvij/.cache/trunk/plugins/https---github-com-trunk-io-plugins/v0.0.3 \ No newline at end of file diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index a9805aa..3886671 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -1,6 +1,6 @@ version: 0.1 cli: - version: 0.15.0-beta + version: 0.16.1-beta lint: enabled: - actionlint@1.6.13 diff --git a/CHANGELOG.md b/CHANGELOG.md index f79001b..8224a89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [v0.6.0] - 2022-08-24 (Beta) + +## Changes + +- Refactoring the generated code to use the [polyglot-go](https://github.com/loopholelabs/polyglot-go) library to generate message encode/decode functions. ([#3](https://github.com/loopholelabs/frpc-go/pull/3)) + +## Fixes + +- Fixed an issue with the generated code that caused compilation issues when the names of two methods in different services + were the same ([#5](https://github.com/loopholelabs/frpc-go/issues/5)) + ## [v0.5.1] - 2022-07-20 (Beta) ## Fixes @@ -16,6 +27,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). > Changelogs for [v0.5.0] and before can be found at https://github.com/loopholelabs/frisbee-go -[unreleased]: https://github.com/loopholelabs/frpc-go/compare/v0.5.1...HEAD +[unreleased]: https://github.com/loopholelabs/frpc-go/compare/v0.6.0...HEAD +[v0.6.0]: https://github.com/loopholelabs/frpc-go/releases/tag/v0.6.0 [v0.5.1]: https://github.com/loopholelabs/frpc-go/releases/tag/v0.5.1 [v0.5.0]: https://github.com/loopholelabs/frisbee-go/compare/v0.4.6...v0.5.0 diff --git a/README.md b/README.md index 445d3bd..f18847d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Tests](https://github.com/loopholelabs/frpc-go/actions/workflows/tests.yaml/badge.svg)](https://github.com/loopholelabs/frpc-go/actions/workflows/tests.yaml) This is the [Go](http://golang.org) implementation of [fRPC](https://frpc.io), a high-performance RPC framework for -designed for performance and stability, and it uses [frisbee-go](https://frpc.io/frisbee) messaging framework under the hood. +designed for performance and stability, and it uses the [frisbee-go](https://github.com/loopholelabs/frisbee-go) messaging framework under the hood. **This library requires Go1.18 or later.** @@ -19,12 +19,8 @@ same is true for selected other new features explicitly marked as Usage instructions and documentation for fRPC is available at [https://frpc.io/](https://frpc.io/). -The fRPC is still in very early **Alpha**. While it is functional and being used within other products -we're building at [Loophole Labs][loophomepage], the `proto3` spec has a myriad of edge-cases that make it difficult to -guarantee validity of generated RPC code without extensive real-world use. - -That being said, as the library matures and usage of fRPC grows we'll be able to increase our testing -coverage and fix any edge cases and bugs. One of the major benefits to the RPC framework is that reading the generated code +fRPC is still in very early \*_Alpha_. There may be bug in the library that will be fixed +as the library matures and usage of fRPC grows. One of the major benefits to fRPC is that reading the generated code is extremely straight forward, making it easy to debug potential issues down the line. ### Unsupported Features diff --git a/examples/echo/echo.proto b/examples/echo/echo.proto index 13ea515..8a7658f 100644 --- a/examples/echo/echo.proto +++ b/examples/echo/echo.proto @@ -6,8 +6,17 @@ service EchoService { rpc Echo(Request) returns (Response); } +service TestService { + rpc Echo(Request) returns (Response); +} + +message Array { + repeated string value = 1; +} + message Request { - string Message = 1; + map metadata = 1; + string Message = 2; } message Response{ diff --git a/go.mod b/go.mod index e72bc3c..b932d63 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module github.com/loopholelabs/frpc-go go 1.18 -require google.golang.org/protobuf v1.28.0 +require ( + github.com/loopholelabs/polyglot-go v0.4.0 + google.golang.org/protobuf v1.28.0 +) diff --git a/go.sum b/go.sum index 231604f..ade1024 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/loopholelabs/polyglot-go v0.4.0 h1:HavI5O6lMKF7urRgnVk+8vM4WqCpJGkH81dxLnhFGAA= +github.com/loopholelabs/polyglot-go v0.4.0/go.mod h1:Z0QiNv4KRuWjQWpUerMhmkvRh6ks1pYmEH4SGpG0EHQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= diff --git a/internal/utils/utils.go b/internal/utils/utils.go deleted file mode 100644 index 3e5bfa1..0000000 --- a/internal/utils/utils.go +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright 2022 Loophole Labs - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package utils - -import ( - "google.golang.org/protobuf/reflect/protoreflect" - "strings" - "unicode" - "unicode/utf8" -) - -// CamelCase returns the CamelCased name. -// If there is an interior underscore followed by a lower case letter, -// drop the underscore and convert the letter to upper case. -// There is a remote possibility of this rewrite causing a name collision, -// but it's so remote we're prepared to pretend it's nonexistent - since the -// C++ generator lowercases names, it's extremely unlikely to have two fields -// with different capitalizations. -// In short, _my_field_name_2 becomes XMyFieldName_2. -func CamelCase(s string) string { - if s == "" { - return "" - } - t := make([]byte, 0, 32) - i := 0 - if s[0] == '_' { // Keep the initial _ if it exists - i++ - } - // Invariant: if the next letter is lower case, it must be converted - // to upper case. - // That is, we process a word at a time, where words are marked by _ or - // upper case letter. Digits are treated as words. - for ; i < len(s); i++ { - c := s[i] - if c == '_' && i+1 < len(s) && 'a' <= s[i+1] && s[i+1] <= 'z' { - continue // Skip the underscore in s. - } - if c == '.' { - continue - } - if '0' <= c && c <= '9' { - t = append(t, c) - continue - } - // Assume we have a letter now - if not, it's a bogus identifier. - // The next word is a sequence of characters that must start upper case. - if 'a' <= c && c <= 'z' { - c ^= ' ' // Make it a capital letter. - } - t = append(t, c) // Guaranteed not lower case. - // Accept lower case sequence that follows. - for i+1 < len(s) && 'a' <= s[i+1] && s[i+1] <= 'z' { - i++ - t = append(t, s[i]) - } - } - return string(t) -} - -func CamelCaseFullName(name protoreflect.FullName) string { - return CamelCase(string(name)) -} - -func CamelCaseName(name protoreflect.Name) string { - return CamelCase(string(name)) -} - -func AppendString(inputs ...string) string { - builder := new(strings.Builder) - for _, s := range inputs { - builder.WriteString(s) - } - - return builder.String() -} - -func FirstLowerCase(s string) string { - if s == "" { - return "" - } - r, n := utf8.DecodeRuneInString(s) - return string(unicode.ToLower(r)) + s[n:] -} - -func FirstLowerCaseName(name protoreflect.Name) string { - return FirstLowerCase(string(name)) -} - -func MakeIterable(length int) []struct{} { - return make([]struct{}, length) -} - -func Counter(initial int) func() int { - i := initial - return func() int { - i++ - return i - } -} diff --git a/internal/version/version.go b/internal/version/version.go index a0464a0..8f4b7b4 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -17,5 +17,5 @@ package version const ( - Version = "v0.5.1" + Version = "v0.6.0" ) diff --git a/pkg/generator/defaults.go b/pkg/generator/defaults.go deleted file mode 100644 index 43dd8b8..0000000 --- a/pkg/generator/defaults.go +++ /dev/null @@ -1,27 +0,0 @@ -/* - Copyright 2022 Loophole Labs - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package generator - -const ( - extension = ".frpc.go" - pointer = "*" - space = " " - comma = "," - mapSuffix = "Map" - slice = "[]" - polyglotAnyKind = "polyglot.AnyKind" -) diff --git a/pkg/generator/file.go b/pkg/generator/file.go deleted file mode 100644 index cccbeb4..0000000 --- a/pkg/generator/file.go +++ /dev/null @@ -1,21 +0,0 @@ -/* - Copyright 2022 Loophole Labs - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package generator - -type File interface { - P(v ...interface{}) -} diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index dba0037..1672780 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -17,11 +17,13 @@ package generator import ( + "bytes" "text/template" - "github.com/loopholelabs/frpc-go/internal/utils" "github.com/loopholelabs/frpc-go/internal/version" "github.com/loopholelabs/frpc-go/templates" + "github.com/loopholelabs/polyglot-go/pkg/generator" + "github.com/loopholelabs/polyglot-go/pkg/utils" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/pluginpb" @@ -41,13 +43,6 @@ func init() { "Counter": utils.Counter, "FirstLowerCase": utils.FirstLowerCase, "FirstLowerCaseName": utils.FirstLowerCaseName, - "FindValue": findValue, - "GetKind": getKind, - "GetLUTEncoder": getLUTEncoder, - "GetLUTDecoder": getLUTDecoder, - "GetEncodingFields": getEncodingFields, - "GetDecodingFields": getDecodingFields, - "GetKindLUT": getKindLUT, "GetServerFields": getServerFields, }).ParseFS(templates.FS, "*")) } @@ -76,11 +71,40 @@ func (g *Generator) Generate(req *pluginpb.CodeGeneratorRequest) (res *pluginpb. return nil, err } + var tplBuffer bytes.Buffer + if err := templ.ExecuteTemplate(&tplBuffer, "customEncode.templ", nil); err != nil { + return nil, err + } + customEncode := tplBuffer.String() + tplBuffer.Reset() + + if err := templ.ExecuteTemplate(&tplBuffer, "customDecode.templ", nil); err != nil { + return nil, err + } + customDecode := tplBuffer.String() + tplBuffer.Reset() + + if err := templ.ExecuteTemplate(&tplBuffer, "customFields.templ", nil); err != nil { + return nil, err + } + customFields := tplBuffer.String() + + gen := generator.New() + gen.CustomEncode = func() string { + return customEncode + } + gen.CustomDecode = func() string { + return customDecode + } + gen.CustomFields = func() string { + return customFields + } + for _, f := range plugin.Files { if !f.Generate { continue } - genFile := plugin.NewGeneratedFile(fileName(f.GeneratedFilenamePrefix), f.GoImportPath) + genFile := plugin.NewGeneratedFile(FileName(f.GeneratedFilenamePrefix), f.GoImportPath) packageName := string(f.Desc.Package().Name()) if packageName == "" { @@ -91,25 +115,39 @@ func (g *Generator) Generate(req *pluginpb.CodeGeneratorRequest) (res *pluginpb. numMethods := 0 for i := 0; i < numServices; i++ { - numMethods += f.Desc.Services().Get(i).Methods().Len() + nM := f.Desc.Services().Get(i).Methods().Len() + numMethods += nM } - err = templ.ExecuteTemplate(genFile, "base.templ", map[string]interface{}{ + err = templ.ExecuteTemplate(genFile, "prebase.templ", map[string]interface{}{ "pluginVersion": version.Version, "sourcePath": f.Desc.Path(), "package": packageName, "requiredImports": requiredImports, "serviceImports": serviceImports, "methodImports": methodImports, - "enums": f.Desc.Enums(), - "messages": f.Desc.Messages(), - "services": f.Desc.Services(), "numServices": numServices, "numMethods": numMethods, }) if err != nil { return nil, err } + + err = gen.ExecuteTemplate(genFile, f, packageName, false) + if err != nil { + return nil, err + } + + err = templ.ExecuteTemplate(genFile, "base.templ", map[string]interface{}{ + "enums": f.Desc.Enums(), + "messages": f.Desc.Messages(), + "services": f.Desc.Services(), + "numServices": numServices, + "numMethods": numMethods, + }) + if err != nil { + return nil, err + } } return plugin.Response(), nil diff --git a/pkg/generator/headers.go b/pkg/generator/headers.go index 0a6df06..d5952fe 100644 --- a/pkg/generator/headers.go +++ b/pkg/generator/headers.go @@ -16,10 +16,10 @@ package generator -import ( - "github.com/loopholelabs/frpc-go/internal/utils" -) +import "github.com/loopholelabs/polyglot-go/pkg/utils" -func fileName(name string) string { +const extension = ".frpc.go" + +func FileName(name string) string { return utils.AppendString(name, extension) } diff --git a/pkg/generator/imports.go b/pkg/generator/imports.go index 993e2f5..ef8daff 100644 --- a/pkg/generator/imports.go +++ b/pkg/generator/imports.go @@ -24,14 +24,13 @@ var ( serviceImports = []string{ "github.com/loopholelabs/frisbee-go", + "github.com/loopholelabs/frisbee-go/pkg/packet", "github.com/rs/zerolog", "crypto/tls", "context", } methodImports = []string{ - "github.com/loopholelabs/frisbee-go/pkg/packet", "sync", - "sync/atomic", } ) diff --git a/pkg/generator/server.go b/pkg/generator/server.go index ac47507..d0e103f 100644 --- a/pkg/generator/server.go +++ b/pkg/generator/server.go @@ -17,7 +17,7 @@ package generator import ( - "github.com/loopholelabs/frpc-go/internal/utils" + "github.com/loopholelabs/polyglot-go/pkg/utils" "google.golang.org/protobuf/reflect/protoreflect" "strings" ) @@ -28,10 +28,10 @@ func getServerFields(services protoreflect.ServiceDescriptors) string { service := services.Get(i) serviceName := utils.CamelCase(string(service.Name())) builder.WriteString(utils.FirstLowerCase(serviceName)) - builder.WriteString(space) + builder.WriteString(" ") builder.WriteString(serviceName) - builder.WriteString(comma) - builder.WriteString(space) + builder.WriteString(",") + builder.WriteString(" ") } serverFields := builder.String() serverFields = serverFields[:len(serverFields)-2] diff --git a/pkg/generator/structs.go b/pkg/generator/structs.go deleted file mode 100644 index a668355..0000000 --- a/pkg/generator/structs.go +++ /dev/null @@ -1,243 +0,0 @@ -/* - Copyright 2022 Loophole Labs - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package generator - -import ( - "errors" - "fmt" - "github.com/loopholelabs/frpc-go/internal/utils" - "google.golang.org/protobuf/reflect/protoreflect" -) - -var ( - errUnknownKind = errors.New("unknown or unsupported protoreflect.Kind") - errUnknownCardinality = errors.New("unknown or unsupported protoreflect.Cardinality") -) - -var ( - typeLUT = map[protoreflect.Kind]string{ - protoreflect.BoolKind: "bool", - protoreflect.Int32Kind: "int32", - protoreflect.Sint32Kind: "int32", - protoreflect.Uint32Kind: "uint32", - protoreflect.Int64Kind: "int64", - protoreflect.Sint64Kind: "int64", - protoreflect.Uint64Kind: "uint64", - protoreflect.Sfixed32Kind: "int32", - protoreflect.Sfixed64Kind: "int64", - protoreflect.Fixed32Kind: "uint32", - protoreflect.Fixed64Kind: "uint64", - protoreflect.FloatKind: "float32", - protoreflect.DoubleKind: "float64", - protoreflect.StringKind: "string", - protoreflect.BytesKind: "[]byte", - } - - encodeLUT = map[protoreflect.Kind]string{ - protoreflect.BoolKind: ".Bool", - protoreflect.Int32Kind: ".Int32", - protoreflect.Sint32Kind: ".Int32", - protoreflect.Uint32Kind: ".Uint32", - protoreflect.Int64Kind: ".Int64", - protoreflect.Sint64Kind: ".Int64", - protoreflect.Uint64Kind: ".Uint64", - protoreflect.Sfixed32Kind: ".Int32", - protoreflect.Sfixed64Kind: ".Int64", - protoreflect.Fixed32Kind: ".Uint32", - protoreflect.Fixed64Kind: ".Uint64", - protoreflect.StringKind: ".String", - protoreflect.FloatKind: ".Float32", - protoreflect.DoubleKind: ".Float64", - protoreflect.BytesKind: ".Bytes", - protoreflect.EnumKind: ".Uint32", - } - - decodeLUT = map[protoreflect.Kind]string{ - protoreflect.BoolKind: ".Bool", - protoreflect.Int32Kind: ".Int32", - protoreflect.Sint32Kind: ".Int32", - protoreflect.Uint32Kind: ".Uint32", - protoreflect.Int64Kind: ".Int64", - protoreflect.Sint64Kind: ".Int64", - protoreflect.Uint64Kind: ".Uint64", - protoreflect.Sfixed32Kind: ".Int32", - protoreflect.Sfixed64Kind: ".Int64", - protoreflect.Fixed32Kind: ".Uint32", - protoreflect.Fixed64Kind: ".Uint64", - protoreflect.StringKind: ".String", - protoreflect.FloatKind: ".Float32", - protoreflect.DoubleKind: ".Float64", - protoreflect.BytesKind: ".Bytes", - protoreflect.EnumKind: ".Uint32", - } - - kindLUT = map[protoreflect.Kind]string{ - protoreflect.BoolKind: "polyglot.BoolKind", - protoreflect.Int32Kind: "polyglot.Int32Kind", - protoreflect.Sint32Kind: "polyglot.Int32Kind", - protoreflect.Uint32Kind: "polyglot.Uint32Kind", - protoreflect.Int64Kind: "polyglot.Int64Kind", - protoreflect.Sint64Kind: "polyglot.Int64Kind", - protoreflect.Uint64Kind: "polyglot.Uint64Kind", - protoreflect.Sfixed32Kind: "polyglot.Int32Kind", - protoreflect.Sfixed64Kind: "polyglot.Int64Kind", - protoreflect.Fixed32Kind: "polyglot.Uint32Kind", - protoreflect.Fixed64Kind: "polyglot.Uint64Kind", - protoreflect.StringKind: "polyglot.StringKind", - protoreflect.FloatKind: "polyglot.Float32Kind", - protoreflect.DoubleKind: "polyglot.Float64Kind", - protoreflect.BytesKind: "polyglot.BytesKind", - protoreflect.EnumKind: "polyglot.Uint32Kind", - } -) - -func findValue(field protoreflect.FieldDescriptor) string { - if kind, ok := typeLUT[field.Kind()]; !ok { - switch field.Kind() { - case protoreflect.EnumKind: - switch field.Cardinality() { - case protoreflect.Optional, protoreflect.Required: - return utils.CamelCase(string(field.Enum().FullName())) - case protoreflect.Repeated: - return utils.CamelCase(utils.AppendString(slice, string(field.Enum().FullName()))) - default: - panic(errUnknownCardinality) - } - case protoreflect.MessageKind: - if field.IsMap() { - return utils.CamelCase(utils.AppendString(string(field.FullName()), mapSuffix)) - } else { - switch field.Cardinality() { - case protoreflect.Optional, protoreflect.Required: - return utils.AppendString(pointer, utils.CamelCase(string(field.Message().FullName()))) - case protoreflect.Repeated: - return utils.AppendString(slice, pointer, utils.CamelCase(string(field.Message().FullName()))) - default: - panic(errUnknownCardinality) - } - } - default: - panic(errUnknownKind) - } - } else { - if field.Cardinality() == protoreflect.Repeated { - kind = slice + kind - } - return kind - } -} - -type encodingFields struct { - MessageFields []protoreflect.FieldDescriptor - SliceFields []protoreflect.FieldDescriptor - Values []string -} - -func getEncodingFields(fields protoreflect.FieldDescriptors) encodingFields { - var messageFields []protoreflect.FieldDescriptor - var sliceFields []protoreflect.FieldDescriptor - var values []string - - for i := 0; i < fields.Len(); i++ { - field := fields.Get(i) - if field.Cardinality() == protoreflect.Repeated && !field.IsMap() { - sliceFields = append(sliceFields, field) - } else { - if encoder, ok := encodeLUT[field.Kind()]; !ok { - switch field.Kind() { - case protoreflect.MessageKind: - messageFields = append(messageFields, field) - default: - panic(errUnknownKind) - } - } else { - if field.Kind() == protoreflect.EnumKind { - values = append(values, fmt.Sprintf("%s(uint32(x.%s))", encoder, utils.CamelCase(string(field.Name())))) - } else { - values = append(values, fmt.Sprintf("%s(x.%s)", encoder, utils.CamelCase(string(field.Name())))) - } - } - } - } - return encodingFields{ - MessageFields: messageFields, - SliceFields: sliceFields, - Values: values, - } -} - -type decodingFields struct { - MessageFields []protoreflect.FieldDescriptor - SliceFields []protoreflect.FieldDescriptor - Other []protoreflect.FieldDescriptor -} - -func getDecodingFields(fields protoreflect.FieldDescriptors) decodingFields { - var messageFields []protoreflect.FieldDescriptor - var sliceFields []protoreflect.FieldDescriptor - var other []protoreflect.FieldDescriptor - - for i := 0; i < fields.Len(); i++ { - field := fields.Get(i) - if field.Cardinality() == protoreflect.Repeated && !field.IsMap() { - sliceFields = append(sliceFields, field) - } else { - if _, ok := decodeLUT[field.Kind()]; !ok { - switch field.Kind() { - case protoreflect.MessageKind: - messageFields = append(messageFields, field) - default: - panic(errUnknownKind) - } - } else { - other = append(other, field) - } - } - } - - return decodingFields{ - MessageFields: messageFields, - SliceFields: sliceFields, - Other: other, - } -} - -func getKind(kind protoreflect.Kind) string { - var outKind string - var ok bool - if outKind, ok = kindLUT[kind]; !ok { - switch kind { - case protoreflect.MessageKind: - outKind = polyglotAnyKind - default: - panic(errUnknownKind) - } - } - return outKind -} - -func getLUTEncoder(kind protoreflect.Kind) string { - return encodeLUT[kind] -} - -func getLUTDecoder(kind protoreflect.Kind) string { - return decodeLUT[kind] -} - -func getKindLUT(kind protoreflect.Kind) string { - return kindLUT[kind] -} diff --git a/templates/base.templ b/templates/base.templ index 2366cd8..1c841f6 100644 --- a/templates/base.templ +++ b/templates/base.templ @@ -1,13 +1,3 @@ -{{template "headers" .}} - -{{template "imports" .}} - -{{template "errors" .}} - -{{template "enums" .}} - -{{template "messages" .}} - {{template "interfaces" .}} {{ if .numServices }} diff --git a/templates/client.templ b/templates/client.templ index 9e5cd28..8d22c62 100644 --- a/templates/client.templ +++ b/templates/client.templ @@ -1,14 +1,24 @@ {{define "client"}} +{{ range $i, $v := (MakeIterable .services.Len) -}} + {{ $service := $.services.Get $i -}} + type sub{{ CamelCaseName $service.Name }}Client struct { + client *frisbee.Client + {{ range $i, $v := (MakeIterable $service.Methods.Len) -}} + {{ $method := $service.Methods.Get $i -}} + next{{ CamelCaseName $method.Name }} uint16 + next{{ CamelCaseName $method.Name }}Mu sync.RWMutex + inflight{{ CamelCaseName $method.Name }} map[uint16]chan *{{ CamelCase $method.Output.FullName }} + inflight{{ CamelCaseName $method.Name }}Mu sync.RWMutex + {{end -}} + } +{{end -}} + + type Client struct { *frisbee.Client {{ range $i, $v := (MakeIterable .services.Len) -}} {{ $service := $.services.Get $i -}} - {{ range $i, $v := (MakeIterable $service.Methods.Len) -}} - {{ $method := $service.Methods.Get $i -}} - next{{ CamelCaseName $method.Name }} atomic.Value - inflight{{ CamelCaseName $method.Name }}Mu sync.RWMutex - inflight{{ CamelCaseName $method.Name }} map[uint16]chan *{{ CamelCase $method.Output.FullName }} - {{end -}} + {{ CamelCaseName $service.Name }} *sub{{ CamelCaseName $service.Name }}Client {{end -}} } @@ -32,17 +42,25 @@ func NewClient (tlsConfig *tls.Config, logger *zerolog.Logger) (*Client, error) {{ range $i, $v := (MakeIterable .services.Len) -}} {{ $service := $.services.Get $i -}} + c.{{ CamelCaseName $service.Name }} = new(sub{{ CamelCaseName $service.Name }}Client) + c.{{ CamelCaseName $service.Name }}.client = c.Client {{ range $i, $v := (MakeIterable $service.Methods.Len) -}} {{ $method := $service.Methods.Get $i -}} - c.next{{ CamelCaseName $method.Name }}.Store(uint16(0)) - c.inflight{{ CamelCaseName $method.Name }} = make(map[uint16]chan *{{ CamelCase $method.Output.FullName }}) + c.{{ CamelCaseName $service.Name }}.inflight{{ CamelCaseName $method.Name }} = make(map[uint16]chan *{{ CamelCase $method.Output.FullName }}) + {{end -}} + {{ range $i, $v := (MakeIterable $service.Methods.Len) -}} + {{ $method := $service.Methods.Get $i -}} + c.{{ CamelCaseName $service.Name }}.next{{ CamelCaseName $method.Name }}Mu.Lock() + c.{{ CamelCaseName $service.Name }}.next{{ CamelCaseName $method.Name }} = 0 + c.{{ CamelCaseName $service.Name }}.next{{ CamelCaseName $method.Name }}Mu.Unlock() + c.{{ CamelCaseName $service.Name }}.inflight{{ CamelCaseName $method.Name }} = make(map[uint16]chan *{{ CamelCase $method.Output.FullName }}) {{end -}} {{end -}} return c, nil } {{template "clientmethods" .services }} -{{end}} +{{ end -}} {{define "clienthandlers"}} {{ $counter := Counter 9 -}} @@ -52,20 +70,20 @@ func NewClient (tlsConfig *tls.Config, logger *zerolog.Logger) (*Client, error) {{ $method := $service.Methods.Get $i -}} {{ $count := call $counter -}} table[{{ $count }}] = func(ctx context.Context, incoming *packet.Packet) (outgoing *packet.Packet, action frisbee.Action) { - c.inflight{{ CamelCaseName $method.Name }}Mu.RLock() - if ch, ok := c.inflight{{ CamelCaseName $method.Name }}[incoming.Metadata.Id]; ok { - c.inflight{{ CamelCaseName $method.Name }}Mu.RUnlock() + c.{{ CamelCaseName $service.Name }}.inflight{{ CamelCaseName $method.Name }}Mu.RLock() + if ch, ok := c.{{ CamelCaseName $service.Name }}.inflight{{ CamelCaseName $method.Name }}[incoming.Metadata.Id]; ok { + c.{{ CamelCaseName $service.Name }}.inflight{{ CamelCaseName $method.Name }}Mu.RUnlock() res := New{{ CamelCase $method.Output.FullName }}() res.Decode((*incoming.Content)[:incoming.Metadata.ContentLength]) ch <- res } else { - c.inflight{{ CamelCaseName $method.Name }}Mu.RUnlock() + c.{{ CamelCaseName $service.Name }}.inflight{{ CamelCaseName $method.Name }}Mu.RUnlock() } return } {{end -}} {{end -}} -{{end}} +{{ end -}} {{define "clientmethods"}} {{ $counter := Counter 9 -}} @@ -74,21 +92,23 @@ func NewClient (tlsConfig *tls.Config, logger *zerolog.Logger) (*Client, error) {{ range $i, $v := (MakeIterable $service.Methods.Len) }} {{ $method := $service.Methods.Get $i -}} {{ $opIndex := call $counter -}} - func (c *Client) {{ CamelCaseName $method.Name }}(ctx context.Context, req *{{ CamelCase $method.Input.FullName }}) (res *{{ CamelCase $method.Output.FullName }}, err error) { + func (c *sub{{ CamelCaseName $service.Name }}Client) {{ CamelCaseName $method.Name }}(ctx context.Context, req *{{ CamelCase $method.Input.FullName }}) (res *{{ CamelCase $method.Output.FullName }}, err error) { ch := make(chan *{{ CamelCase $method.Output.FullName }}, 1) p := packet.Get() p.Metadata.Operation = {{ $opIndex }} - LOOP: - p.Metadata.Id = c.next{{ CamelCaseName $method.Name }}.Load().(uint16) - if !c.next{{ CamelCaseName $method.Name }}.CompareAndSwap(p.Metadata.Id, p.Metadata.Id+1) { - goto LOOP - } + + c.next{{ CamelCaseName $method.Name }}Mu.Lock() + c.next{{ CamelCaseName $method.Name }} += 1 + id := c.next{{ CamelCaseName $method.Name }} + c.next{{ CamelCaseName $method.Name }}Mu.Unlock() + p.Metadata.Id = id + req.Encode(p.Content) p.Metadata.ContentLength = uint32(len(*p.Content)) c.inflight{{ CamelCaseName $method.Name }}Mu.Lock() - c.inflight{{ CamelCaseName $method.Name }}[p.Metadata.Id] = ch + c.inflight{{ CamelCaseName $method.Name }}[id] = ch c.inflight{{ CamelCaseName $method.Name }}Mu.Unlock() - err = c.Client.WritePacket(p) + err = c.client.WritePacket(p) if err != nil { packet.Put(p) return @@ -100,11 +120,11 @@ func NewClient (tlsConfig *tls.Config, logger *zerolog.Logger) (*Client, error) err = ctx.Err() } c.inflight{{ CamelCaseName $method.Name }}Mu.Lock() - delete(c.inflight{{ CamelCaseName $method.Name }}, p.Metadata.Id) + delete(c.inflight{{ CamelCaseName $method.Name }}, id) c.inflight{{ CamelCaseName $method.Name }}Mu.Unlock() packet.Put(p) return } - {{end -}} {{end -}} -{{end}} +{{end -}} +{{end}} \ No newline at end of file diff --git a/templates/customDecode.templ b/templates/customDecode.templ new file mode 100644 index 0000000..4f14573 --- /dev/null +++ b/templates/customDecode.templ @@ -0,0 +1,8 @@ +x.error, err = d.Error() +if err == nil { + return nil +} +x.ignore, err = d.Bool() +if err != nil { + return err +} \ No newline at end of file diff --git a/templates/customEncode.templ b/templates/customEncode.templ new file mode 100644 index 0000000..062b54b --- /dev/null +++ b/templates/customEncode.templ @@ -0,0 +1,5 @@ +if x.error != nil { + polyglot.Encoder(b).Error(x.error) + return +} +polyglot.Encoder(b).Bool(x.ignore) \ No newline at end of file diff --git a/templates/customFields.templ b/templates/customFields.templ new file mode 100644 index 0000000..a37a725 --- /dev/null +++ b/templates/customFields.templ @@ -0,0 +1,2 @@ +error error +ignore bool \ No newline at end of file diff --git a/templates/decode.templ b/templates/decode.templ deleted file mode 100644 index f95659d..0000000 --- a/templates/decode.templ +++ /dev/null @@ -1,97 +0,0 @@ -{{define "decode"}} -func (x *{{ CamelCase .FullName }}) Decode (b []byte) error { - if x == nil { - return NilDecode - } - d := polyglot.GetDecoder(b) - defer d.Return() - return x.decode(d) -} -{{end}} - -{{define "internalDecode"}} -func (x *{{CamelCase .FullName}}) decode(d *polyglot.Decoder) error { - if d.Nil() { - return nil - } - var err error - x.error, err = d.Error() - if err != nil { - x.ignore, err = d.Bool() - if err != nil { - return err - } - {{ $decoding := GetDecodingFields .Fields -}} - {{ range $field := $decoding.Other -}} - {{ $decoder := GetLUTDecoder $field.Kind -}} - {{ if eq $field.Kind 12 -}} {{/* protoreflect.BytesKind */ -}} - x.{{ CamelCaseName $field.Name }}, err = d{{ $decoder }}(nil) - {{ else if eq $field.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - var {{ CamelCaseName $field.Name }}Temp uint32 - {{ CamelCaseName $field.Name }}Temp, err = d{{ $decoder }}() - x.{{ CamelCaseName $field.Name }} = {{ FindValue $field }}({{ CamelCaseName $field.Name }}Temp) - {{ else -}} - x.{{ CamelCaseName $field.Name }}, err = d{{ $decoder }}() - {{end -}} - if err != nil { - return err - } - {{end -}} - - {{ if $decoding.SliceFields -}} - var sliceSize uint32 - {{end -}} - {{ range $field := $decoding.SliceFields -}} - {{ $kind := GetKind $field.Kind -}} - sliceSize, err = d.Slice({{ $kind }}) - if err != nil { - return err - } - if uint32(len(x.{{ CamelCaseName $field.Name }})) != sliceSize { - x.{{ CamelCaseName $field.Name }} = make({{ FindValue $field }}, sliceSize) - } - for i := uint32(0); i < sliceSize; i++ { - {{ $decoder := GetLUTDecoder $field.Kind -}} - {{ if eq $field.Kind 11 -}} {{/* protoreflect.MessageKind */ -}} - if x.{{ CamelCaseName $field.Name }}[i] == nil { - x.{{ CamelCaseName $field.Name }}[i] = New{{ CamelCase $field.Message.FullName }}() - } - err = x.{{ CamelCaseName $field.Name }}[i].decode(d) - {{ else -}} - x.{{ CamelCaseName $field.Name }}[i], err = d{{ $decoder }}() - {{end -}} - if err != nil { - return err - } - } - {{end -}} - {{ range $field := $decoding.MessageFields -}} - {{ if $field.IsMap -}} - if !d.Nil() { - {{ $keyKind := GetKind $field.MapKey.Kind -}} - {{ $valKind := GetKind $field.MapValue.Kind -}} - - {{ CamelCaseName $field.Name }}Size, err := d.Map({{ $keyKind }}, {{ $valKind }}) - if err != nil { - return err - } - x.{{ CamelCaseName $field.Name }} = New{{ CamelCase $field.FullName }}Map({{ CamelCaseName $field.Name }}Size) - err = x.{{ CamelCaseName $field.Name }}.decode(d, {{ CamelCaseName $field.Name }}Size) - if err != nil { - return err - } - } - {{ else -}} - if x.{{ CamelCaseName $field.Name }} == nil { - x.{{ CamelCaseName $field.Name }} = New{{ CamelCase $field.Message.FullName }}() - } - err = x.{{ CamelCaseName $field.Name }}.decode(d) - if err != nil { - return err - } - {{end -}} - {{end -}} - } - return nil -} -{{end}} \ No newline at end of file diff --git a/templates/decodeMap.templ b/templates/decodeMap.templ deleted file mode 100644 index 93bff31..0000000 --- a/templates/decodeMap.templ +++ /dev/null @@ -1,51 +0,0 @@ -{{define "decodeMap"}} -func (x {{CamelCase .FullName}}Map) decode(d *polyglot.Decoder, size uint32) error { - if size == 0 { - return nil - } - var k {{ FindValue .MapKey }} - {{ if eq .MapKey.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - var {{ CamelCase .MapKey.Name }}Temp uint32 - {{end -}} - var v {{ FindValue .MapValue }} - {{ if eq .MapValue.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - var {{ CamelCaseName .MapValue.Name }}Temp uint32 - {{end -}} - var err error - for i := uint32(0); i < size; i++ { - {{ $keyDecoder := GetLUTDecoder .MapKey.Kind -}} - {{ if and (eq $keyDecoder "") (eq .MapKey.Kind 11) -}} {{/* protoreflect.MessageKind */ -}} - k = New{{ CamelCase .MapKey.Message.FullName }}() - err = k.decode(d) - {{else -}} - {{ if eq .MapKey.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - {{ CamelCase .MapKey.Name }}Temp, err = d{{$keyDecoder}}() - k = {{ FindValue .MapKey }}({{ CamelCase .MapKey.Name }}Temp) - {{else -}} - k, err = d{{$keyDecoder}}() - {{end -}} - {{end -}} - if err != nil { - return err - } - {{ $valDecoder := GetLUTDecoder .MapValue.Kind -}} - {{ if and (eq $valDecoder "") (eq .MapValue.Kind 11) -}} {{/* protoreflect.MessageKind */ -}} - v = New{{ CamelCase .MapValue.Message.FullName }}() - err = v.decode(d) - {{else -}} - {{ if eq .MapValue.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - {{CamelCaseName .MapValue.Name}}Temp, err = d{{$valDecoder}}() - v = {{ FindValue .MapValue }}({{ CamelCaseName .MapValue.Name }}Temp) - {{else -}} - v, err = d{{$valDecoder}}() - {{end -}} - {{end -}} - - if err != nil { - return err - } - x[k] = v - } - return nil -} -{{end}} \ No newline at end of file diff --git a/templates/encode.templ b/templates/encode.templ deleted file mode 100644 index 7e6cafb..0000000 --- a/templates/encode.templ +++ /dev/null @@ -1,41 +0,0 @@ -{{define "encode"}} -func (x *{{ CamelCase .FullName }}) Encode (b *polyglot.Buffer) { - if x == nil { - polyglot.Encoder(b).Nil() - } else if x.error != nil { - polyglot.Encoder(b).Error(x.error) - } else { - {{ $encoding := GetEncodingFields .Fields -}} - polyglot.Encoder(b).Bool(x.ignore){{ range $val := $encoding.Values -}}{{ $val -}}{{end -}} - {{ if $encoding.SliceFields -}} - {{template "encodeSlices" $encoding -}} - {{end -}} - {{ if $encoding.MessageFields -}} - {{template "encodeMessages" $encoding -}} - {{end -}} - } -} -{{end}} - -{{define "encodeSlices"}} - {{ range $field := .SliceFields -}} - {{ $encoder := GetLUTEncoder $field.Kind -}} - {{ if and (eq $encoder "") (eq $field.Kind 11) -}} {{/* protoreflect.MessageKind */ -}} - polyglot.Encoder(b).Slice(uint32(len(x.{{ CamelCaseName $field.Name }})), polyglot.AnyKind) - for _, v := range x.{{CamelCaseName $field.Name}} { - v.Encode(b) - } - {{else -}} - polyglot.Encoder(b).Slice(uint32(len(x.{{ CamelCaseName $field.Name }})), {{ GetKindLUT $field.Kind }}) - for _, v := range x.{{ CamelCaseName $field.Name }} { - polyglot.Encoder(b){{$encoder}}(v) - } - {{end -}} - {{end -}} -{{end}} - -{{define "encodeMessages"}} - {{ range $field := .MessageFields -}} - x.{{ CamelCaseName $field.Name }}.Encode(b) - {{end -}} -{{end}} \ No newline at end of file diff --git a/templates/encodeMap.templ b/templates/encodeMap.templ deleted file mode 100644 index 3976164..0000000 --- a/templates/encodeMap.templ +++ /dev/null @@ -1,33 +0,0 @@ -{{define "encodeMap"}} - func (x {{ CamelCase .FullName }}Map) Encode (b *polyglot.Buffer) { - if x == nil { - polyglot.Encoder(b).Nil() - } else { - {{ $keyKind := GetKind .MapKey.Kind -}} - {{ $valKind := GetKind .MapValue.Kind -}} - polyglot.Encoder(b).Map(uint32(len(x)), {{$keyKind}}, {{$valKind}}) - for k, v := range x { - {{ $keyEncoder := GetLUTEncoder .MapKey.Kind -}} - {{ if and (eq $keyEncoder "") (eq .MapKey.Kind 11) -}} {{/* protoreflect.MessageKind */ -}} - k.Encode(b) - {{else -}} - {{ if eq .MapKey.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - polyglot.Encoder(b) {{$keyEncoder}} (uint32(k)) - {{else -}} - polyglot.Encoder(b) {{$keyEncoder}} (k) - {{end -}} - {{end -}} - {{ $valEncoder := GetLUTEncoder .MapValue.Kind -}} - {{ if and (eq $valEncoder "") (eq .MapValue.Kind 11) -}} {{/* protoreflect.MessageKind */ -}} - v.Encode(b) - {{else -}} - {{ if eq .MapValue.Kind 14 -}} {{/* protoreflect.EnumKind */ -}} - polyglot.Encoder(b) {{$valEncoder}} (uint32(v)) - {{else -}} - polyglot.Encoder(b) {{$valEncoder}} (v) - {{end -}} - {{end -}} - } - } - } -{{end}} diff --git a/templates/enums.templ b/templates/enums.templ deleted file mode 100644 index 18cd31a..0000000 --- a/templates/enums.templ +++ /dev/null @@ -1,19 +0,0 @@ -{{define "enums"}} -{{range $i, $e := (MakeIterable .enums.Len) -}} -{{ $enum := ($.enums.Get $i) }} -{{template "enum" $enum}} -{{end -}} -{{end}} - -{{define "enum"}} -{{ $enumName := (CamelCase $.FullName) }} -type {{ $enumName }} uint32 - -const ( -{{range $i, $v := (MakeIterable $.Values.Len) -}} - {{ $val := ($.Values.Get $i) -}} - {{CamelCase $val.FullName}} = {{ $enumName }}({{ $i }}) -{{end -}} -) -{{end}} - diff --git a/templates/errors.templ b/templates/errors.templ deleted file mode 100644 index 1539649..0000000 --- a/templates/errors.templ +++ /dev/null @@ -1,5 +0,0 @@ -{{define "errors"}} -var ( - NilDecode = errors.New("cannot decode into a nil root struct") -) -{{end}} \ No newline at end of file diff --git a/templates/messages.templ b/templates/messages.templ deleted file mode 100644 index 1c8c74b..0000000 --- a/templates/messages.templ +++ /dev/null @@ -1,10 +0,0 @@ -{{define "messages"}} -{{range $i, $e := (MakeIterable .messages.Len) -}} - {{ $message := $.messages.Get $i }} - {{range $i, $e := (MakeIterable $message.Enums.Len) -}} - {{ $enum := ($message.Enums.Get $i) }} - {{template "enum" $enum}} - {{end}} - {{template "structs" $message}} -{{end}} -{{end}} \ No newline at end of file diff --git a/templates/prebase.templ b/templates/prebase.templ new file mode 100644 index 0000000..e96e8dc --- /dev/null +++ b/templates/prebase.templ @@ -0,0 +1,3 @@ +{{template "headers" .}} + +{{template "imports" .}} \ No newline at end of file diff --git a/templates/server.templ b/templates/server.templ index 97450a3..03a281d 100644 --- a/templates/server.templ +++ b/templates/server.templ @@ -4,26 +4,29 @@ type Server struct { } func NewServer({{ GetServerFields .services }}, tlsConfig *tls.Config, logger *zerolog.Logger) (*Server, error) { + var s *Server table := make(frisbee.HandlerTable) {{template "serverhandlers" .services -}} - var s *frisbee.Server + var fsrv *frisbee.Server var err error if tlsConfig != nil { - s, err = frisbee.NewServer(table, frisbee.WithTLS(tlsConfig), frisbee.WithLogger(logger)) + fsrv, err = frisbee.NewServer(table, frisbee.WithTLS(tlsConfig), frisbee.WithLogger(logger)) if err != nil { return nil, err } } else { - s, err = frisbee.NewServer(table, frisbee.WithLogger(logger)) + fsrv, err = frisbee.NewServer(table, frisbee.WithLogger(logger)) if err != nil { return nil, err } } - return &Server{ - Server: s, + + s, err = &Server{ + Server: fsrv, }, nil + return s, err } -{{end}} +{{ end -}} {{define "serverhandlers"}} {{ $counter := Counter 9 -}} @@ -38,18 +41,18 @@ func NewServer({{ GetServerFields .services }}, tlsConfig *tls.Config, logger *z if err == nil { if req.ignore { {{ FirstLowerCaseName $service.Name }}.{{ CamelCaseName $method.Name }}(ctx, req) + return + } + var res *{{ CamelCase $method.Output.FullName }} + outgoing = incoming + outgoing.Content.Reset() + res, err = {{ FirstLowerCase (CamelCaseName $service.Name) }}.{{ CamelCaseName $method.Name }}(ctx, req) + if err != nil { + res.Error(outgoing.Content, err) } else { - var res *{{ CamelCase $method.Output.FullName }} - outgoing = incoming - outgoing.Content.Reset() - res, err = {{ FirstLowerCase (CamelCaseName $service.Name) }}.{{ CamelCaseName $method.Name }}(ctx, req) - if err != nil { - res.Error(outgoing.Content, err) - } else { - res.Encode(outgoing.Content) - } - outgoing.Metadata.ContentLength = uint32(len(*outgoing.Content)) + res.Encode(outgoing.Content) } + outgoing.Metadata.ContentLength = uint32(len(*outgoing.Content)) } return } diff --git a/templates/structs.templ b/templates/structs.templ deleted file mode 100644 index ece6a2c..0000000 --- a/templates/structs.templ +++ /dev/null @@ -1,57 +0,0 @@ -{{define "structs"}} - {{ range $i, $v := (MakeIterable $.Messages.Len) }} - {{ $message := $.Messages.Get $i }} - {{ if not $message.IsMapEntry }} - {{template "structs" $message}} - {{end}} - {{end}} - {{ range $i, $v := (MakeIterable $.Fields.Len) -}} - {{ $field := $.Fields.Get $i }} - {{ if $field.IsMap }} - {{ $mapKeyValue := FindValue $field.MapKey }} - {{ $mapValueValue := FindValue $field.MapValue }} - type {{ CamelCase $field.FullName }}Map map[{{ $mapKeyValue }}]{{ $mapValueValue }} - func New{{ CamelCase $field.FullName }}Map (size uint32) map[{{ $mapKeyValue }}]{{$mapValueValue}} { - return make(map[{{ $mapKeyValue }}]{{ $mapValueValue }}, size) - } - - {{template "encodeMap" $field}} - {{template "decodeMap" $field}} - {{end}} - {{end -}} - type {{ CamelCase .FullName }} struct { - error error - ignore bool - - {{ range $i, $v := (MakeIterable $.Fields.Len) -}} - {{ $field := $.Fields.Get $i -}} - {{ $value := FindValue $field -}} - {{ CamelCaseName $field.Name }} {{ $value }} - {{end -}} - } - - {{template "getFunc" .}} - {{template "error" .}} - {{template "encode" .}} - {{template "decode" .}} - {{template "internalDecode" .}} -{{end}} - -{{define "getFunc"}} -func New{{ CamelCase .FullName }}() *{{ CamelCase .FullName }} { - return &{{ CamelCase .FullName }}{ - {{ range $i, $v := (MakeIterable .Fields.Len) -}} - {{ $field := $.Fields.Get $i -}} - {{ if and (eq $field.Kind 11) (ne $field.Cardinality 3) -}} {{/* protoreflect.MessageKind protoreflect.Repeated */ -}} - {{ CamelCaseName $field.Name }}: New{{ CamelCase $field.Message.FullName }}(), - {{end -}} - {{end -}} - } -} -{{end}} - -{{define "error"}} -func (x *{{CamelCase .FullName}}) Error(b *polyglot.Buffer, err error) { - polyglot.Encoder(b).Error(err) -} -{{end}} \ No newline at end of file