diff --git a/.gitignore b/.gitignore index e8b41c2..02b063e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ bin/ # Generated files **/generated/** + +test/bench/proto/ +qtest \ No newline at end of file diff --git a/Makefile b/Makefile index c3268ef..656d74e 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,66 @@ test-compile: build-protoc-gen-litepb mkdir -p ./test/generated rm -rf ./test/generated/* go mod init -C ./test/generated generated - protoc --plugin ./bin/protoc-gen-litepb --litepb_out ./test/ --proto_path=./test/proto/ ./test/proto/test.proto + protoc --plugin ./bin/protoc-gen-litepb --litepb_out ./ --proto_path=./test/proto/ ./test/proto/test.proto + #protoc --plugin ./bin/protoc-gen-litepb --litepb_out ./test/ --proto_path=./test/proto/ ./test/proto/test4.proto + +test-compile-for-bench: build-protoc-gen-litepb + mkdir -p test/bench/proto/google/ + protoc --proto_path=./test/proto/bench/ \ + --proto_path=/usr/local/include/ \ + --proto_path=./ \ + --go_out test/bench/proto/google/ \ + ./test/proto/bench/bench.proto + mkdir -p test/bench/proto/gogo/proto/ + protoc --proto_path=./test/proto/bench/ \ + --proto_path=/usr/local/include/ \ + --proto_path=./ \ + --gogofaster_out test/bench/proto/gogo/ \ + ./test/proto/bench/bench.proto + protoc --proto_path=./ \ + --proto_path=/usr/local/include/ \ + --gogofaster_out test/bench/proto/gogo/proto \ + ./proto/uuid.proto + sed -i -e 's/github.com\/e-tape\/litepb\/proto/bench\/proto\/gogo\/proto\/github.com\/e-tape\/litepb\/proto/g' test/bench/proto/gogo/bench/bench.pb.go + mkdir -p test/bench/proto/litepb_pool/ + protoc --plugin ./bin/protoc-gen-litepb \ + --proto_path=./test/proto/bench/ \ + --proto_path=./ \ + --proto_path=/usr/local/include/ \ + --litepb_out test/bench/proto/litepb_pool/ \ + --litepb_opt test/proto/bench/litepb.yaml \ + --litepb_opt mem_pool_message_all=true \ + --litepb_opt mem_pool_list_all=true \ + --litepb_opt mem_pool_map_all=true \ + --litepb_opt unsafe_all=true \ + ./test/proto/bench/bench.proto + mkdir -p test/bench/proto/litepb_no_pool/ + protoc --plugin ./bin/protoc-gen-litepb \ + --proto_path=./test/proto/bench/ \ + --proto_path=./ \ + --proto_path=/usr/local/include/ \ + --litepb_out test/bench/proto/litepb_no_pool/ \ + --litepb_opt test/proto/bench/litepb.yaml,mem_pool_message_all=false \ + ./test/proto/bench/bench.proto build-protoc-gen-litepb: go build -tags debug -o ./bin/protoc-gen-litepb ./cmd/protoc-gen-litepb + +build-protos: build-protoc-gen-litepb + find ./proto -name '*.proto' | while read file; \ + do protoc \ + --plugin ./bin/protoc-gen-litepb \ + --proto_path=./proto \ + --litepb_out=./proto/ \ + --litepb_opt=proto/litepb.yaml \ + $${file} || exit 1; \ + done +uu: + find ./proto -name '*.proto' | while read file; \ + do protoc \ + --plugin ./bin/protoc-gen-litepb \ + --proto_path=./ \ + --go_out=./ \ + --go_opt=paths=source_relative \ + $${file} || exit 1; \ + done \ No newline at end of file diff --git a/cmd/protoc-gen-litepb/main.go b/cmd/protoc-gen-litepb/main.go index bc20e9b..b2d1dd7 100644 --- a/cmd/protoc-gen-litepb/main.go +++ b/cmd/protoc-gen-litepb/main.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/e-tape/litepb/config" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/pluginpb" @@ -27,16 +28,23 @@ func run() error { return err } + //_ = os.WriteFile(`litepb.git/bin/1.bin`, in, 0666) + request := &pluginpb.CodeGeneratorRequest{} if err = proto.Unmarshal(in, request); err != nil { return err } + cfg, err := config.Parse(request.Parameter) + if err != nil { + return err + } + stderr.Logf("COMPILER: %s", request.GetCompilerVersion()) stderr.Logf("FILES TO GENERATE: %s", strings.Join(request.GetFileToGenerate(), ", ")) start := time.Now() - response := generator.NewGenerator(request).Generate() + response := generator.NewGenerator(cfg, request).Generate() stderr.Logf("GENERATED IN: %s", time.Since(start)) generator.GoFmt(response) diff --git a/cmd/qtest/main.go b/cmd/qtest/main.go new file mode 100644 index 0000000..210e92b --- /dev/null +++ b/cmd/qtest/main.go @@ -0,0 +1,60 @@ +package main + +import ( + _ "embed" + "os" + "path" + "path/filepath" + "strings" + "time" + + "github.com/e-tape/litepb/config" + "github.com/e-tape/litepb/pkg/generator" + "github.com/e-tape/litepb/pkg/stderr" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/pluginpb" +) + +func main() { + if err := run(); err != nil { + stderr.Failf("%s: %s", filepath.Base(os.Args[0]), err) + } +} + +func run() error { + in, err := os.ReadFile(`/tmp/1.bin`) + if err != nil { + return err + } + + request := &pluginpb.CodeGeneratorRequest{} + if err = proto.Unmarshal(in, request); err != nil { + return err + } + cfg, err := config.Parse(request.Parameter) + if err != nil { + return err + } + + stderr.Logf("COMPILER: %s", request.GetCompilerVersion()) + stderr.Logf("FILES TO GENERATE: %s", strings.Join(request.GetFileToGenerate(), ", ")) + + start := time.Now() + response := generator.NewGenerator(cfg, request).Generate() + stderr.Logf("GENERATED IN: %s", time.Since(start)) + + //generator.GoFmt(response) + + for _, f := range response.File { + p := path.Join("test/bench/proto/qtest/", f.GetName()) + err = os.MkdirAll(path.Dir(p), 0766) + if err != nil { + panic(err) + } + err = os.WriteFile(p, []byte(f.GetContent()), 0666) + if err != nil { + panic(err) + } + } + return nil +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..1c372af --- /dev/null +++ b/config/config.go @@ -0,0 +1,12 @@ +package config + +import litepb "github.com/e-tape/litepb/proto" + +type Config struct { + SourceRelative bool `yaml:"source_relative" toml:"source_relative"` + MemPoolMessageAll litepb.Activity `yaml:"mem_pool_message_all" toml:"mem_pool_message_all"` + MemPoolListAll litepb.Activity `yaml:"mem_pool_list_all" toml:"mem_pool_list_all"` + MemPoolMapAll litepb.Activity `yaml:"mem_pool_map_all" toml:"mem_pool_map_all"` + MemPoolOneofAll litepb.Activity `yaml:"mem_pool_oneof_all" toml:"mem_pool_oneof_all"` + UnsafeAll litepb.Activity `yaml:"unsafe_all" toml:"unsafe_all"` +} diff --git a/config/parse.go b/config/parse.go new file mode 100644 index 0000000..bcd2d57 --- /dev/null +++ b/config/parse.go @@ -0,0 +1,69 @@ +package config + +import ( + "fmt" + "os" + "strings" + + "github.com/BurntSushi/toml" + "gopkg.in/yaml.v3" +) + +func Parse( + param *string, +) (Config, error) { + var cfg Config + var setFile bool + if param != nil { + for _, parameter := range strings.Split(*param, ",") { + par := strings.SplitN(parameter, "=", 2) + if len(par) != 1 { + continue + } + switch { + case strings.HasSuffix(par[0], ".yaml") || strings.HasSuffix(par[0], ".yml"): + if cfgData, err := os.ReadFile(par[0]); err == nil { + if err = yaml.Unmarshal(cfgData, &cfg); err != nil { + return cfg, err + } + } + setFile = true + case strings.HasSuffix(par[0], ".toml"): + if cfgData, err := os.ReadFile(par[0]); err == nil { + if err = toml.Unmarshal(cfgData, &cfg); err != nil { + return cfg, err + } + } + setFile = true + } + } + } + if !setFile { + if cfgData, cfgErr := os.ReadFile(`litepb.yml`); cfgErr == nil { + if err := yaml.Unmarshal(cfgData, &cfg); err != nil { + return cfg, err + } + } + if cfgData, cfgErr := os.ReadFile(`litepb.yaml`); cfgErr == nil { + if err := yaml.Unmarshal(cfgData, &cfg); err != nil { + return cfg, err + } + } + if cfgData, cfgErr := os.ReadFile(`litepb.toml`); cfgErr == nil { + if err := toml.Unmarshal(cfgData, &cfg); err != nil { + return cfg, err + } + } + } + if param != nil { + for _, parameter := range strings.Split(*param, ",") { + par := strings.SplitN(parameter, "=", 2) + if len(par) > 1 { + if err := yaml.Unmarshal([]byte(fmt.Sprintf("%s: %s", par[0], par[1])), &cfg); err != nil { + return cfg, err + } + } + } + } + return cfg, nil +} diff --git a/go.mod b/go.mod index 74e3a37..0986331 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,11 @@ module github.com/e-tape/litepb -go 1.22.3 +go 1.22.4 -require google.golang.org/protobuf v1.34.1 +require ( + github.com/BurntSushi/toml v1.4.0 + github.com/golang/protobuf v1.5.4 + golang.org/x/text v0.16.0 + google.golang.org/protobuf v1.34.2 + gopkg.in/yaml.v3 v3.0.1 +) diff --git a/go.sum b/go.sum index 33bede0..ded0b7d 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,16 @@ +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 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.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/common/case.go b/pkg/common/case.go deleted file mode 100644 index 2c047a9..0000000 --- a/pkg/common/case.go +++ /dev/null @@ -1,42 +0,0 @@ -package common - -import ( - "bytes" - "slices" - "strings" -) - -// SnakeCaseToPascalCase converts snake_case to PascalCase -func SnakeCaseToPascalCase(text string) string { - if text == "" { - return "" - } - - data := []byte(strings.ToLower(text)) - if isLowerCaseLetter(data[0]) { - data[0] -= 32 - } - - const replaceChar = '#' - - i := bytes.IndexByte(data, '_') - for ; i >= 0; i = bytes.IndexByte(data, '_') { - if isLowerCaseLetter(data[i+1]) { - data[i+1] -= 32 - data = slices.Delete(data, i, i+1) - } else { - data[i] = replaceChar - } - } - - i = bytes.IndexByte(data, replaceChar) - for ; i >= 0; i = bytes.IndexByte(data, replaceChar) { - data[i] = '_' - } - - return string(data) -} - -func isLowerCaseLetter(c byte) bool { - return c >= 'a' && c <= 'z' -} diff --git a/pkg/common/case_test.go b/pkg/common/case_test.go deleted file mode 100644 index c5f182c..0000000 --- a/pkg/common/case_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package common - -import "testing" - -func TestSnakeCaseToPascalCase(t *testing.T) { - tests := []struct { - name string - text string - want string - }{ - { - name: "empty", - text: "", - want: "", - }, - { - name: "basic", - text: "hello_world", - want: "HelloWorld", - }, - { - name: "with_number", - text: "hello_123_world", - want: "Hello_123World", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := SnakeCaseToPascalCase(tt.text); got != tt.want { - t.Errorf("SnakeCaseToPascalCase(%q) != %q", got, tt.want) - } - }) - } -} diff --git a/pkg/generator/comments.go b/pkg/generator/comments.go index 451d9e9..2de78b7 100644 --- a/pkg/generator/comments.go +++ b/pkg/generator/comments.go @@ -3,30 +3,44 @@ package generator import ( "slices" "strings" - - "google.golang.org/protobuf/types/descriptorpb" ) -func (g *FileGenerator) findMessageComments(sourceCodePath []int32, messageIndex int) string { - return findComments(g.sourceCodeInfo, append(sourceCodePath, int32(messageIndex))) +func (a *generatorFile) findMessageComments( + sourceCodePath []int32, + messageIndex int, +) string { + return a.findComments(append(sourceCodePath, int32(messageIndex))) } -func (g *FileGenerator) findMessageFieldComments(sourceCodePath []int32, messageIndex, fieldIndex int) string { - return findComments(g.sourceCodeInfo, append(sourceCodePath, int32(messageIndex), 2, int32(fieldIndex))) +func (a *generatorFile) findMessageFieldComments( + sourceCodePath []int32, + messageIndex int, + fieldIndex int, +) string { + // TODO rathil move 2 to const + return a.findComments(append(sourceCodePath, int32(messageIndex), 2, int32(fieldIndex))) } -func (g *FileGenerator) findEnumComments(sourceCodePath []int32, enumIndex int) string { - return findComments(g.sourceCodeInfo, append(sourceCodePath, int32(enumIndex))) +func (a *generatorFile) findEnumComments( + sourceCodePath []int32, + enumIndex int, +) string { + return a.findComments(append(sourceCodePath, int32(enumIndex))) } -func (g *FileGenerator) findEnumValueComments(sourceCodePath []int32, enumIndex, valueIndex int) string { - return findComments(g.sourceCodeInfo, append(sourceCodePath, int32(enumIndex), 2, int32(valueIndex))) +func (a *generatorFile) findEnumValueComments( + sourceCodePath []int32, + enumIndex int, + valueIndex int, +) string { + // TODO rathil move 2 to const + return a.findComments(append(sourceCodePath, int32(enumIndex), 2, int32(valueIndex))) } -func findComments(info *descriptorpb.SourceCodeInfo, ps []int32) string { - for _, loc := range info.GetLocation() { +func (a *generatorFile) findComments(ps []int32) string { + for _, loc := range a.sourceCodeInfo.GetLocation() { if slices.Equal(loc.GetPath(), ps) { - return strings.TrimSuffix(loc.GetLeadingComments()+loc.GetTrailingComments(), "\n") + return strings.Trim(loc.GetLeadingComments()+loc.GetTrailingComments(), "\n") } } return "" diff --git a/pkg/generator/fs.go b/pkg/generator/fs.go new file mode 100644 index 0000000..3bea9c6 --- /dev/null +++ b/pkg/generator/fs.go @@ -0,0 +1,50 @@ +package generator + +import ( + "bytes" + "io" + "io/fs" + "path" + "time" + + litepb "github.com/e-tape/litepb/proto" +) + +func TemplateFs(templates []*litepb.Template) fs.FS { + return &templateFs{ + templates: templates, + native: nativeTemplateFiles, + } +} + +type ( + templateFs struct { + templates []*litepb.Template + native fs.FS + } + templateFile struct { + name string + io.Reader + } +) + +func (a *templateFs) Open(name string) (fs.File, error) { + for _, template := range a.templates { + if template.Name == name { + return &templateFile{ + name: template.Name, + Reader: bytes.NewReader(template.Content), + }, nil + } + } + return a.native.Open(name) +} + +func (a *templateFile) Name() string { return path.Base(a.name) } +func (a *templateFile) Size() int64 { return 0 } +func (a *templateFile) Mode() fs.FileMode { return 0444 } +func (a *templateFile) ModTime() time.Time { return time.Time{} } +func (a *templateFile) IsDir() bool { return false } +func (a *templateFile) Sys() any { return nil } +func (a *templateFile) Stat() (fs.FileInfo, error) { return a, nil } +func (a *templateFile) Close() error { return nil } diff --git a/pkg/generator/generate_name.go b/pkg/generator/generate_name.go new file mode 100644 index 0000000..240bf24 --- /dev/null +++ b/pkg/generator/generate_name.go @@ -0,0 +1,37 @@ +package generator + +import ( + "regexp" + "strings" + + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +var casesTitleRegex = regexp.MustCompile("([A-Z])") + +func generateName(value string) string { + pName := strings.TrimLeft(value, "_") + prefix := strings.TrimSuffix(value, pName) + pName = strings.ReplaceAll( + cases.Title(language.English).String( + strings.ReplaceAll( + casesTitleRegex.ReplaceAllString(pName, " $1"), + "_", + " ", + ), + ), + " ", + "", + ) + pName = prefix + pName + pName, ok := strings.CutPrefix(pName, "__") + if ok { + pName = "X" + pName + } + pName, ok = strings.CutPrefix(pName, "_") + if ok { + pName = "X" + pName + } + return pName +} diff --git a/pkg/generator/generator.go b/pkg/generator/generator.go index 8254791..4c947ed 100644 --- a/pkg/generator/generator.go +++ b/pkg/generator/generator.go @@ -1,420 +1,145 @@ package generator import ( - "bytes" - "cmp" - "path" - "slices" + "regexp" "strings" - "google.golang.org/protobuf/types/descriptorpb" + "github.com/e-tape/litepb/config" + litepb "github.com/e-tape/litepb/proto" "google.golang.org/protobuf/types/pluginpb" - "github.com/e-tape/litepb/pkg/common" "github.com/e-tape/litepb/pkg/stderr" ) -// Generator of protobuf bindings -type Generator struct { - request *pluginpb.CodeGeneratorRequest - definedTypes DefinedTypes - protoFileToGoImport ProtoFileToGoImport - goImportPathToAlias GoImportPathToAlias -} - // NewGenerator creates new generator -func NewGenerator(request *pluginpb.CodeGeneratorRequest) *Generator { +func NewGenerator( + cfg config.Config, + request *pluginpb.CodeGeneratorRequest, +) *Generator { return &Generator{ - request: request, - definedTypes: make(DefinedTypes), - protoFileToGoImport: make(ProtoFileToGoImport), - goImportPathToAlias: make(GoImportPathToAlias), - } -} - -type ( - DefinedTypes map[ProtoFullType]GoFullType - ProtoFullType = string // Proto package + type name - GoFullType = string // Go package + type name -) - -type ( - ProtoFileToGoImport map[ProtoFile]GoImport - ProtoFile = string -) - -type ( - GoImportPathToAlias map[GoImportPath]GoImportAlias - GoImportPath = string - GoImportAlias = string -) - -// FileGenerator of protobuf bindings for single file -type FileGenerator struct { - *Generator - importAliases ImportAliases - mapTypes MapTypes - goImport GoImport - protoPackagePrefix string - sourceCodeInfo *descriptorpb.SourceCodeInfo -} - -func NewFileGenerator(g *Generator, protoFile *descriptorpb.FileDescriptorProto) *FileGenerator { - goPackage := protoFile.GetOptions().GetGoPackage() - if goPackage == "" { - stderr.Failf("missing go_package option in %s", protoFile.GetName()) - } - stderr.Logf("\tGO PACKAGE: %s", goPackage) - - importPath := goPackage - goPackage, goPackageName, ok := strings.Cut(goPackage, ";") - if ok { - importPath = goPackage - goPackage = path.Dir(goPackage) + "/" + goPackageName - } else { - goPackageName = path.Base(goPackage) - } - - goImport := GoImport{ - Path: importPath, - Alias: goPackageName, - } - - importAliases := make(ImportAliases, len(additionalImports)) - for _, additionalImport := range additionalImports { - importAliases[additionalImport] = strings.ReplaceAll(additionalImport, "/", "_") - } - - return &FileGenerator{ - Generator: g, - importAliases: importAliases, - mapTypes: make(MapTypes), - goImport: goImport, - protoPackagePrefix: "." + protoFile.GetPackage() + ".", - sourceCodeInfo: protoFile.GetSourceCodeInfo(), + cfg: cfg, + request: request, + allFiles: make(map[Path]*generatorFile), + allTypes: make(map[Package]*litepb.Message_Field_Type_Reflect), + mapTypes: make(map[Package]*litepb.Message_Field_Type_Map), + aliasRegex: regexp.MustCompile(`(?mi)[^a-z0-9]`), } } -type ImportAliases map[GoImportPath]GoImportAlias - -type ( - MapTypes map[MessageName]KeyValueTypes - MessageName = string - KeyValueTypes = [2]string -) - // Generate generates bindings -func (g *Generator) Generate() *pluginpb.CodeGeneratorResponse { - codeFiles := make([]*pluginpb.CodeGeneratorResponse_File, 0, len(g.request.GetProtoFile())) - for _, protoFile := range g.request.ProtoFile { +func (a *Generator) Generate() *pluginpb.CodeGeneratorResponse { + codeFiles := make([]*pluginpb.CodeGeneratorResponse_File, 0, len(a.request.GetProtoFile())) + + pluginData := &litepb.Plugin{} + for _, protoFile := range a.request.ProtoFile { stderr.Logf("FILE START") stderr.Logf("\tNAME: %s", protoFile.GetName()) stderr.Logf("\tPACKAGE: %s", protoFile.GetPackage()) stderr.Logf("\tSYNTAX: %s", protoFile.GetSyntax()) stderr.Logf("\tDEPENDENCIES: %s", strings.Join(protoFile.GetDependency(), ", ")) - fg := NewFileGenerator(g, protoFile) - - g.protoFileToGoImport[protoFile.GetName()] = fg.goImport - g.goImportPathToAlias[fg.goImport.Path] = fg.goImport.Alias + a.generateMessagesFromExtensions(protoFile) + fg := a.newFile(protoFile) + a.allFiles[protoFile.GetName()] = fg - fg.defineTypes( + fg.collectTypes( + protoFile.GetEnumType(), + protoFile.GetMessageType(), + []string{"", protoFile.GetPackage()}, nil, + ) + fg.collectMapTypes( protoFile.GetMessageType(), - protoFile.GetEnumType(), + []string{"", protoFile.GetPackage()}, ) - types, enumTypes := fg.generateTypes( - protoFile.GetMessageType(), + fg.proto.Enums = fg.generateEnums( protoFile.GetEnumType(), - []int32{4}, []int32{5}, + protoFile.GetMessageType(), + []string{"", protoFile.GetPackage()}, + []int32{4}, + []int32{5}, + nil, ) - imports := fg.generateImports(protoFile.GetDependency()) - - buf := bytes.NewBuffer(nil) - err := goTemplate.ExecuteTemplate(buf, mainTemplate, GoFile{ - Package: fg.goImport.Alias, - Source: protoFile.GetName(), - Imports: imports, - Types: types, - EnumTypes: enumTypes, - }) - if err != nil { - stderr.Failf("execute template: %s", err) - } - - protoFileName := path.Base(protoFile.GetName()) - protoFileNameExt := path.Ext(protoFileName) - fileName := path.Join(fg.goImport.Path, strings.TrimSuffix(protoFileName, protoFileNameExt)+".pb.go") - stderr.Logf("\tGO FILE: %s", fileName) - - codeFiles = append(codeFiles, &pluginpb.CodeGeneratorResponse_File{ - Name: &fileName, - Content: common.Ptr(buf.String()), - }) - - stderr.Logf("FILE END") - } - stderr.Logf("FILE TO IMPORT PATH: %v", g.protoFileToGoImport) - stderr.Logf("DEFINED TYPES: %v", g.definedTypes) - return &pluginpb.CodeGeneratorResponse{ - File: codeFiles, - } -} - -func (g *FileGenerator) generateImports(dependencies []string) []GoImport { - slices.Sort(dependencies) - slices.Compact(dependencies) - - imports := make([]GoImport, 0, len(dependencies)+len(additionalImports)) - for _, dependency := range dependencies { - depGoImport, ok := g.protoFileToGoImport[dependency] - if !ok { - stderr.Failf("missing dependency %s for %s", dependency, depGoImport.Path) - } - if depGoImport.Path == g.goImport.Path { - continue + fg.generateMessages( + protoFile.GetMessageType(), + []string{"", protoFile.GetPackage()}, + []int32{4}, + nil, + ) + fg.proto.Messages = fg.messages + + fg.proto.Generates = []litepb.File_Generate{ + litepb.File_STRUCT, + litepb.File_INTERFACE, + litepb.File_POOL, + litepb.File_ENUM, + litepb.File_LIST, + litepb.File_MAP, + litepb.File_NEW, + litepb.File_RETURN_TO_POOL, + litepb.File_PROTO_MESSAGE, + litepb.File_CONVERT_TO, + litepb.File_STRING, + litepb.File_RESET, + litepb.File_CLONE, + litepb.File_GETTER, + litepb.File_SETTER, + litepb.File_SIZE, } - importAlias, ok := g.importAliases[depGoImport.Path] - if !ok { - importAlias = "_" + marshal := *fg.proto // TODO rathil refactoring to litepb clone + marshal.Name = strings.ReplaceAll(marshal.Name, ".lpb.go", "_marshal.lpb.go") + marshal.Generates = []litepb.File_Generate{ + litepb.File_MARSHAL, } - imports = append(imports, GoImport{ - Path: depGoImport.Path, - Alias: importAlias, - }) - } - - for _, additionalImport := range additionalImports { - imports = append(imports, GoImport{ - Path: additionalImport, - Alias: strings.ReplaceAll(additionalImport, "/", "_"), - }) - } - - slices.SortFunc(imports, func(a, b GoImport) int { - return cmp.Compare(a.Path, b.Path) - }) - - return imports -} - -func (g *FileGenerator) defineTypes( - parentMessage *descriptorpb.DescriptorProto, - messages []*descriptorpb.DescriptorProto, enums []*descriptorpb.EnumDescriptorProto, -) { - for _, message := range messages { - if parentMessage != nil { - message.Name = common.Ptr(parentMessage.GetName() + "." + message.GetName()) + unmarshal := *fg.proto // TODO rathil refactoring to litepb clone + unmarshal.Name = strings.ReplaceAll(fg.proto.Name, ".lpb.go", "_unmarshal.lpb.go") + unmarshal.Generates = []litepb.File_Generate{ + litepb.File_UNMARSHAL, } - g.definedTypes[g.protoPackagePrefix+message.GetName()] = g.goImport.Path + "." + - strings.ReplaceAll(message.GetName(), ".", "_") - g.defineTypes(message, message.GetNestedType(), message.GetEnumType()) - } - for _, enum := range enums { - if parentMessage != nil { - enum.Name = common.Ptr(parentMessage.GetName() + "." + enum.GetName()) - } - g.definedTypes[g.protoPackagePrefix+enum.GetName()] = g.goImport.Path + "." + - strings.ReplaceAll(enum.GetName(), ".", "_") + pluginData.Files = append(pluginData.Files, fg.proto, &marshal, &unmarshal) } -} -func (g *FileGenerator) generateTypes( - messages []*descriptorpb.DescriptorProto, enums []*descriptorpb.EnumDescriptorProto, - msgSourceCodePath, enumSourceCodePath []int32, -) ([]GoType, []GoEnumType) { - types := make([]GoType, 0, len(messages)) - enumTypes := make([]GoEnumType, 0, len(enums)) + // ENCODE plugin + // TODO rathil run plugin + // DECODE plugin - for i, enum := range enums { - values := make([]GoEnumTypeValue, 0, len(enum.GetValue())) - for j, value := range enum.GetValue() { - values = append(values, GoEnumTypeValue{ - Name: value.GetName(), - Comments: g.findEnumValueComments(enumSourceCodePath, i, j), - Number: value.GetNumber(), - }) - } + //pluginData.Templates = append(pluginData.Templates, &plugin.Template{ + // Name: "templates/func_name_message_new.gotmpl", + // Content: []byte(` + //{{- define "func_name_message_new" -}} + // SuperNew{{ .GetName }} + //{{- end -}} + //`), + //}) - valuesPrefix := enum.GetName() - if ix := strings.LastIndex(enum.GetName(), "."); ix >= 0 { - valuesPrefix = enum.GetName()[:ix] - } - - enumTypes = append(enumTypes, GoEnumType{ - Name: strings.ReplaceAll(enum.GetName(), ".", "_"), - Comments: g.findEnumComments(enumSourceCodePath, i), - ValuesPrefix: strings.ReplaceAll(valuesPrefix, ".", "_"), - Values: values, - }) - } - - for i, message := range messages { - if message.GetOptions().GetMapEntry() { - g.mapTypes[g.protoPackagePrefix+message.GetName()] = [2]string{ - g.fieldType(message.GetField()[0]), - g.fieldType(message.GetField()[1]), - } - continue + for _, file := range pluginData.Files { + content, err := tmpl.Execute(TemplateFs(pluginData.Templates), file) + if err != nil { + stderr.Failf("generate go file for proto [%s]: %s", file.GetName(), err) } - nestedTypes, nestedEnumTypes := g.generateTypes( - message.GetNestedType(), - message.GetEnumType(), - append(msgSourceCodePath, int32(i), 3), - append(msgSourceCodePath, int32(i), 4), - ) - - fields := make([]GoTypeField, 0, len(message.GetField())) - for j, field := range message.GetField() { - typ := g.fieldType(field) - if field.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED && - !strings.HasPrefix(typ, "map[") { - typ = "[]" + typ - } - fields = append(fields, GoTypeField{ - Name: common.SnakeCaseToPascalCase(field.GetName()), - Comments: g.findMessageFieldComments(msgSourceCodePath, i, j), - SnakeName: field.GetName(), - Type: typ, - ZeroValue: g.fieldZeroValue(field), - }) - } + stderr.Logf("\tGO FILE: %s", file.GetName()) - types = append(types, GoType{ - Name: strings.ReplaceAll(message.GetName(), ".", "_"), - Comments: g.findMessageComments(msgSourceCodePath, i), - Fields: fields, + codeFiles = append(codeFiles, &pluginpb.CodeGeneratorResponse_File{ + Name: &file.Name, + Content: &content, }) - types = append(types, nestedTypes...) - enumTypes = append(enumTypes, nestedEnumTypes...) - } - - return types, enumTypes -} - -func (g *FileGenerator) fieldType(field *descriptorpb.FieldDescriptorProto) string { - switch field.GetType() { - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - return "float64" - case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - return "float32" - case descriptorpb.FieldDescriptorProto_TYPE_INT64: - return "int64" - case descriptorpb.FieldDescriptorProto_TYPE_UINT64: - return "uint64" - case descriptorpb.FieldDescriptorProto_TYPE_INT32: - return "int32" - case descriptorpb.FieldDescriptorProto_TYPE_UINT32: - return "uint32" - case descriptorpb.FieldDescriptorProto_TYPE_FIXED64: - return "uint64" - case descriptorpb.FieldDescriptorProto_TYPE_FIXED32: - return "uint32" - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - return "bool" - case descriptorpb.FieldDescriptorProto_TYPE_STRING: - return "string" - case descriptorpb.FieldDescriptorProto_TYPE_GROUP: - stderr.Failf("groups are not supported") - return "" - case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE: - if kv, ok := g.mapTypes[field.GetTypeName()]; ok { - return "map[" + kv[0] + "]" + kv[1] - } - return "*" + g.fieldTypeMessageOrEnum(field) - case descriptorpb.FieldDescriptorProto_TYPE_BYTES: - return "[]byte" - case descriptorpb.FieldDescriptorProto_TYPE_ENUM: - return g.fieldTypeMessageOrEnum(field) - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: - return "int32" - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: - return "int64" - case descriptorpb.FieldDescriptorProto_TYPE_SINT32: - return "int32" - case descriptorpb.FieldDescriptorProto_TYPE_SINT64: - return "int64" - default: - stderr.Failf("unknown type %d", field.GetType()) - return "" - } -} - -func (g *FileGenerator) fieldTypeMessageOrEnum(field *descriptorpb.FieldDescriptorProto) string { - goType, ok := g.definedTypes[field.GetTypeName()] - if !ok { - stderr.Failf("unknown type %s", field.GetTypeName()) - return "" - } - - ld := strings.LastIndex(goType, ".") - typePackage := goType[:ld] - typeName := goType[ld+1:] - - if typePackage == g.goImport.Path { - return typeName - } - - var importAlias string - if importAlias, ok = g.importAliases[typePackage]; !ok { - importPath := goType[:strings.LastIndex(goType, ".")] - importAlias = g.goImportPathToAlias[importPath] - - aliases := make([]string, 0, len(g.importAliases)) - for _, alias := range g.importAliases { - aliases = append(aliases, alias) - } - - if slices.Contains(aliases, importAlias) { - importPath = path.Dir(importPath) - } - for slices.Contains(aliases, importAlias) { - if importPath == "" || importPath == "." { - panic("unreachable") - } - importAlias = path.Base(importPath) + "_" + importAlias - importPath = path.Dir(importPath) - } - - g.importAliases[typePackage] = importAlias + stderr.Logf("FILE END") } - return importAlias + "." + typeName -} - -func (g *FileGenerator) fieldZeroValue(field *descriptorpb.FieldDescriptorProto) string { - if field.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED { - return "nil" + //stderr.Logf("FILE TO IMPORT PATH: %v", a.protoFileToGoImport) + definedTypes := make([]string, 0, len(a.allTypes)) + for _, t := range a.allTypes { + definedTypes = append(definedTypes, t.Name) } - - switch field.GetType() { - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE, descriptorpb.FieldDescriptorProto_TYPE_FLOAT, - descriptorpb.FieldDescriptorProto_TYPE_INT64, descriptorpb.FieldDescriptorProto_TYPE_UINT64, - descriptorpb.FieldDescriptorProto_TYPE_INT32, descriptorpb.FieldDescriptorProto_TYPE_UINT32, - descriptorpb.FieldDescriptorProto_TYPE_FIXED64, descriptorpb.FieldDescriptorProto_TYPE_FIXED32, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, - descriptorpb.FieldDescriptorProto_TYPE_SINT32, descriptorpb.FieldDescriptorProto_TYPE_SINT64: - return "0" - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - return "false" - case descriptorpb.FieldDescriptorProto_TYPE_STRING: - return `""` - case descriptorpb.FieldDescriptorProto_TYPE_GROUP: - stderr.Failf("groups are not supported") - return "" - case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_BYTES: - return "nil" - case descriptorpb.FieldDescriptorProto_TYPE_ENUM: - return "0" - default: - stderr.Failf("unknown type %d", field.GetType()) - return "" + stderr.Logf("DEFINED TYPES: %v", definedTypes) + return &pluginpb.CodeGeneratorResponse{ + File: codeFiles, } } diff --git a/pkg/generator/generator_extension.go b/pkg/generator/generator_extension.go new file mode 100644 index 0000000..7cc6a92 --- /dev/null +++ b/pkg/generator/generator_extension.go @@ -0,0 +1,33 @@ +package generator + +import ( + "path" + "strings" + + "google.golang.org/protobuf/types/descriptorpb" +) + +func (a *Generator) generateMessagesFromExtensions(protoFile *descriptorpb.FileDescriptorProto) { + if len(protoFile.Extension) == 0 { + return + } + msgNamePrefix := generateName(strings.TrimSuffix( + path.Base(protoFile.GetName()), + path.Ext(protoFile.GetName()), + )) + + msgMap := make(map[string]*descriptorpb.DescriptorProto) + for _, ext := range protoFile.Extension { + msgNameParts := strings.Split(ext.GetExtendee(), ".") + msgName := msgNamePrefix + generateName(msgNameParts[len(msgNameParts)-1]) + if _, ok := msgMap[msgName]; !ok { + msgMap[msgName] = &descriptorpb.DescriptorProto{ + Name: &msgName, + } + } + msgMap[msgName].Field = append(msgMap[msgName].Field, ext) + } + for _, msg := range msgMap { + protoFile.MessageType = append(protoFile.MessageType, msg) + } +} diff --git a/pkg/generator/generator_file.go b/pkg/generator/generator_file.go new file mode 100644 index 0000000..429bfd4 --- /dev/null +++ b/pkg/generator/generator_file.go @@ -0,0 +1,385 @@ +package generator + +import ( + "path" + "slices" + "strings" + + "github.com/e-tape/litepb/pkg/stderr" + litepb "github.com/e-tape/litepb/proto" + "google.golang.org/protobuf/types/descriptorpb" +) + +func (a *Generator) newFile(protoFile *descriptorpb.FileDescriptorProto) *generatorFile { + goPackage := protoFile.GetOptions().GetGoPackage() + if goPackage == "" { + goPackage = strings.ReplaceAll(protoFile.GetPackage(), ".", "/") + } + stderr.Logf("\tGO PACKAGE: %s", goPackage) + + packagePath, pathAlias, ok := strings.Cut(goPackage, ";") + packageName := strings.ToLower(path.Base(packagePath)) + if ok { + packageName = pathAlias + } + alias := a.aliasRegex.ReplaceAllString(packagePath, `_`) + name := strings.ToLower(strings.TrimSuffix( + path.Base(protoFile.GetName()), + path.Ext(protoFile.GetName()), + )) + ".lpb.go" + namePath := packagePath + if a.cfg.SourceRelative { + namePath = path.Dir(protoFile.GetName()) + } + return &generatorFile{ + Generator: a, + proto: &litepb.File{ + Package: &litepb.Package{ + Dependency: &litepb.Dependency{ + Path: packagePath, + Alias: alias, + }, + Name: packageName, + }, + Source: protoFile.GetName(), + Name: path.Join(namePath, name), + Options: protoFile.GetOptions().ProtoReflect().GetUnknown(), + }, + sourceCodeInfo: protoFile.GetSourceCodeInfo(), + } +} + +func (a *generatorFile) generatePackage(packages []string, item string) string { + return a.generateJoin(packages, item, ".") +} +func (a *generatorFile) generateTypeName(names []string, name string) string { + return a.generateJoin(names, name, "_") +} +func (a *generatorFile) generateJoin(items []string, item string, sep string) string { + return strings.Join(slices.Concat(slices.Concat(items, []string{item})), sep) +} + +func (a *generatorFile) collectTypes( + enums []*descriptorpb.EnumDescriptorProto, + messages []*descriptorpb.DescriptorProto, + packages []string, + names []string, +) { + for _, enum := range enums { + a.allTypes[a.generatePackage(packages, enum.GetName())] = &litepb.Message_Field_Type_Reflect{ + Name: a.generateTypeName(names, generateName(enum.GetName())), + Dependency: a.proto.Package.Dependency, + } + } + + for _, message := range messages { + a.allTypes[a.generatePackage(packages, message.GetName())] = &litepb.Message_Field_Type_Reflect{ + Name: a.generateTypeName(names, generateName(message.GetName())), + Dependency: a.proto.Package.Dependency, + } + a.collectTypes( + message.GetEnumType(), + message.GetNestedType(), + append(packages, message.GetName()), + append(names, message.GetName()), + ) + } +} + +func (a *generatorFile) collectMapTypes( + messages []*descriptorpb.DescriptorProto, + packages []string, +) { + for _, message := range messages { + if message.GetOptions().GetMapEntry() { + a.mapTypes[a.generatePackage(packages, message.GetName())] = &litepb.Message_Field_Type_Map{ + Key: &litepb.Message_Field_Type{ + InProto: litepb.Message_Field_Type_Proto(message.GetField()[0].GetType()), + Reflect: a.generateReflect(message.GetField()[0], false), + }, + Value: &litepb.Message_Field_Type{ + InProto: litepb.Message_Field_Type_Proto(message.GetField()[1].GetType()), + Reflect: a.generateReflect(message.GetField()[1], false), + }, + } + continue + } + a.collectMapTypes( + message.GetNestedType(), + append(packages, message.GetName()), + ) + } +} + +func (a *generatorFile) generateEnums( + enums []*descriptorpb.EnumDescriptorProto, + messages []*descriptorpb.DescriptorProto, + packages []string, + messageSourceCodePath []int32, + enumSourceCodePath []int32, + names []string, +) []*litepb.Enum { + result := make([]*litepb.Enum, 0, len(enums)) + for enumIndex, enum := range enums { + values := make([]*litepb.Enum_Value, 0, len(enum.GetValue())) + for valueIndex, value := range enum.GetValue() { + values = append(values, &litepb.Enum_Value{ + Name: value.GetName(), + Comments: a.findEnumValueComments(enumSourceCodePath, enumIndex, valueIndex), + Number: value.GetNumber(), + Options: value.GetOptions().ProtoReflect().GetUnknown(), + }) + } + result = append(result, &litepb.Enum{ + Name: a.generateTypeName(names, generateName(enum.GetName())), + Comments: a.findEnumComments(enumSourceCodePath, enumIndex), + ValuesPrefix: generateName(enum.GetName()), + Values: values, + Options: enum.GetOptions().ProtoReflect().GetUnknown(), + }) + } + + for i, message := range messages { + nestedEnums := a.generateEnums( + message.GetEnumType(), + message.GetNestedType(), + append(packages, message.GetName()), + append(messageSourceCodePath, int32(i), 3), + append(messageSourceCodePath, int32(i), 4), + append(names, message.GetName()), + ) + result = append(result, nestedEnums...) + } + + return result +} + +func (a *generatorFile) generateMessages( + messages []*descriptorpb.DescriptorProto, + packages []string, + messageSourceCodePath []int32, + names []string, +) { + for messageIndex, message := range messages { + if message.GetOptions().GetMapEntry() { + continue + } + + msg := &litepb.Message{ + Name: a.generateTypeName(names, generateName(message.GetName())), + Comments: a.findMessageComments(messageSourceCodePath, messageIndex), + Properties: make([]*litepb.Message_Property, 0, len(message.GetField())), + Options: message.GetOptions().ProtoReflect().GetUnknown(), + // MemPoolMessage: len(message.GetField()) > 0, // TODO rathil add option to disable + // MemPoolList: true, // TODO rathil from options + // MemPoolMap: true, // TODO rathil from options + // Unsafe: true, // TODO rathil from options + } + msg.MemPoolMessage = a.cfg.MemPoolMessageAll == litepb.Activity_Active + msg.MemPoolList = a.cfg.MemPoolListAll == litepb.Activity_Active + msg.MemPoolMap = a.cfg.MemPoolMapAll == litepb.Activity_Active + msg.Unsafe = a.cfg.UnsafeAll == litepb.Activity_Active + // TODO rathil get option to active/inactive all MemPool and Unsafe + a.messages = append(a.messages, msg) + + oneOfs := make([]*litepb.Message_OneOf, 0, len(message.GetOneofDecl())) + for fieldIndex, field := range message.GetField() { + mapField, mapOk := a.mapTypes[field.GetTypeName()] + msgField := &litepb.Message_Field{ + Number: field.GetNumber(), + Name: a.generateFieldName(msg, field.GetName()), + Comments: a.findMessageFieldComments(messageSourceCodePath, messageIndex, fieldIndex), + Type: &litepb.Message_Field_Type{ + InProto: litepb.Message_Field_Type_Proto(field.GetType()), + Reflect: a.generateReflect(field, mapOk), + Repeated: !mapOk && field.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED, + Map: mapField, + }, + ZeroValue: a.fieldZeroValue(field), + Options: field.GetOptions().ProtoReflect().GetUnknown(), + Tags: map[string]string{ + "json": field.GetJsonName(), + }, + } + property := &litepb.Message_Property{} + if field.OneofIndex != nil { + if len(oneOfs) <= int(field.GetOneofIndex()) { + oneofDecl := message.GetOneofDecl()[field.GetOneofIndex()] + oneof := &litepb.Message_OneOf{ + Name: a.generateFieldName(msg, oneofDecl.GetName()), + Comments: "", // TODO rathil implement + Options: oneofDecl.GetOptions().ProtoReflect().GetUnknown(), + Fields: make([]*litepb.Message_Field, 0, 1), + Tags: map[string]string{ + "json": oneofDecl.GetName(), + }, + } + switch { + case a.cfg.MemPoolOneofAll == litepb.Activity_Inactive: + oneof.MemPool = false + case a.cfg.MemPoolOneofAll == litepb.Activity_Active: + oneof.MemPool = true + } + // TODO rathil get option to active/inactive MemPoolMessage + oneOfs = append(oneOfs, oneof) + } + oneOfs[field.GetOneofIndex()].Fields = append(oneOfs[field.GetOneofIndex()].Fields, msgField) + if len(oneOfs[field.GetOneofIndex()].Fields) > 1 { + continue + } + property.Type = &litepb.Message_Property_Oneof{ + Oneof: oneOfs[field.GetOneofIndex()], + } + } else { + property.Type = &litepb.Message_Property_Field{ + Field: msgField, + } + } + msg.Properties = append(msg.Properties, property) + } + a.generateMessages( + message.GetNestedType(), + append(packages, message.GetName()), + append(messageSourceCodePath, int32(messageIndex), 3), + append(names, message.GetName()), + ) + } +} + +func (a *generatorFile) generateFieldName(msg *litepb.Message, name string) string { + pName := generateName(name) + switch pName { + case "String": + pName += "_" + } + for _, p := range msg.Properties { + switch pt := p.Type.(type) { + case *litepb.Message_Property_Field: + if pt.Field.GetName() == pName { + pName += "_" + } + case *litepb.Message_Property_Oneof: + if pt.Oneof.GetName() == pName { + pName += "_" + } + } + } + return pName +} + +func (a *generatorFile) generateWireTypes( + field *descriptorpb.FieldDescriptorProto, + mapOk bool, +) *litepb.Message_Field_Type_Reflect { + if mapOk { + return nil + } + switch field.GetType() { + case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: + return &litepb.Message_Field_Type_Reflect{Name: "float64"} + case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: + return &litepb.Message_Field_Type_Reflect{Name: "float32"} + case descriptorpb.FieldDescriptorProto_TYPE_INT64, + descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, + descriptorpb.FieldDescriptorProto_TYPE_SINT64: + return &litepb.Message_Field_Type_Reflect{Name: "int64"} + case descriptorpb.FieldDescriptorProto_TYPE_UINT64, + descriptorpb.FieldDescriptorProto_TYPE_FIXED64: + return &litepb.Message_Field_Type_Reflect{Name: "uint64"} + case descriptorpb.FieldDescriptorProto_TYPE_INT32, + descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, + descriptorpb.FieldDescriptorProto_TYPE_SINT32: + return &litepb.Message_Field_Type_Reflect{Name: "int32"} + case descriptorpb.FieldDescriptorProto_TYPE_UINT32, + descriptorpb.FieldDescriptorProto_TYPE_FIXED32: + return &litepb.Message_Field_Type_Reflect{Name: "uint32"} + case descriptorpb.FieldDescriptorProto_TYPE_BOOL: + return &litepb.Message_Field_Type_Reflect{Name: "bool"} + case descriptorpb.FieldDescriptorProto_TYPE_STRING: + return &litepb.Message_Field_Type_Reflect{Name: "string"} + case descriptorpb.FieldDescriptorProto_TYPE_GROUP: + stderr.Failf("groups are not supported") + return nil + case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, + descriptorpb.FieldDescriptorProto_TYPE_ENUM: + return a.allTypes[field.GetTypeName()] //.reflect(a.proto.Package.Dependency.Alias) + case descriptorpb.FieldDescriptorProto_TYPE_BYTES: + return &litepb.Message_Field_Type_Reflect{Name: "[]byte"} + default: + stderr.Failf("unknown type %d", field.GetType()) + return nil + } +} + +func (a *generatorFile) generateReflect( + field *descriptorpb.FieldDescriptorProto, + mapOk bool, +) *litepb.Message_Field_Type_Reflect { + if mapOk { + return nil + } + switch field.GetType() { + case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: + return &litepb.Message_Field_Type_Reflect{Name: "float64"} + case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: + return &litepb.Message_Field_Type_Reflect{Name: "float32"} + case descriptorpb.FieldDescriptorProto_TYPE_INT64, + descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, + descriptorpb.FieldDescriptorProto_TYPE_SINT64: + return &litepb.Message_Field_Type_Reflect{Name: "int64"} + case descriptorpb.FieldDescriptorProto_TYPE_UINT64, + descriptorpb.FieldDescriptorProto_TYPE_FIXED64: + return &litepb.Message_Field_Type_Reflect{Name: "uint64"} + case descriptorpb.FieldDescriptorProto_TYPE_INT32, + descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, + descriptorpb.FieldDescriptorProto_TYPE_SINT32: + return &litepb.Message_Field_Type_Reflect{Name: "int32"} + case descriptorpb.FieldDescriptorProto_TYPE_UINT32, + descriptorpb.FieldDescriptorProto_TYPE_FIXED32: + return &litepb.Message_Field_Type_Reflect{Name: "uint32"} + case descriptorpb.FieldDescriptorProto_TYPE_BOOL: + return &litepb.Message_Field_Type_Reflect{Name: "bool"} + case descriptorpb.FieldDescriptorProto_TYPE_STRING: + return &litepb.Message_Field_Type_Reflect{Name: "string"} + case descriptorpb.FieldDescriptorProto_TYPE_GROUP: + stderr.Failf("groups are not supported") + return nil + case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, + descriptorpb.FieldDescriptorProto_TYPE_ENUM: + return a.allTypes[field.GetTypeName()] //.reflect(a.proto.Package.Dependency.Alias) + case descriptorpb.FieldDescriptorProto_TYPE_BYTES: + return &litepb.Message_Field_Type_Reflect{Name: "[]byte"} + default: + stderr.Failf("unknown type %d", field.GetType()) + return nil + } +} + +func (a *generatorFile) fieldZeroValue(field *descriptorpb.FieldDescriptorProto) string { + if field.GetLabel() == descriptorpb.FieldDescriptorProto_LABEL_REPEATED { + return "nil" + } + switch field.GetType() { + case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE, descriptorpb.FieldDescriptorProto_TYPE_FLOAT, + descriptorpb.FieldDescriptorProto_TYPE_INT64, descriptorpb.FieldDescriptorProto_TYPE_UINT64, + descriptorpb.FieldDescriptorProto_TYPE_INT32, descriptorpb.FieldDescriptorProto_TYPE_UINT32, + descriptorpb.FieldDescriptorProto_TYPE_FIXED64, descriptorpb.FieldDescriptorProto_TYPE_FIXED32, + descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, + descriptorpb.FieldDescriptorProto_TYPE_SINT32, descriptorpb.FieldDescriptorProto_TYPE_SINT64: + return "0" + case descriptorpb.FieldDescriptorProto_TYPE_BOOL: + return "false" + case descriptorpb.FieldDescriptorProto_TYPE_STRING: + return `""` + case descriptorpb.FieldDescriptorProto_TYPE_GROUP: + stderr.Failf("groups are not supported") + return "" + case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, descriptorpb.FieldDescriptorProto_TYPE_BYTES: + return "nil" + case descriptorpb.FieldDescriptorProto_TYPE_ENUM: + return "0" + default: + stderr.Failf("unknown type %d", field.GetType()) + return "" + } +} diff --git a/pkg/generator/generator_test.go b/pkg/generator/generator_test.go deleted file mode 100644 index 0568f37..0000000 --- a/pkg/generator/generator_test.go +++ /dev/null @@ -1,51 +0,0 @@ -package generator - -import "testing" - -func BenchmarkReset(b *testing.B) { - type Test struct { - Int1 int32 - Int2 int32 - String1 string - String2 string - Map1 map[string]string - Map2 map[string]string - } - - b.Run("struct-set", func(b *testing.B) { - for i := 0; i < b.N; i++ { - t := &Test{ - Int1: 1, - Int2: 2, - String1: "1", - String2: "2", - Map1: make(map[string]string), - Map2: make(map[string]string), - } - - *t = Test{} - _ = t - } - }) - - b.Run("field-set", func(b *testing.B) { - for i := 0; i < b.N; i++ { - t := &Test{ - Int1: 1, - Int2: 2, - String1: "1", - String2: "2", - Map1: make(map[string]string), - Map2: make(map[string]string), - } - - t.Int1 = 0 - t.Int2 = 0 - t.String1 = "" - t.String2 = "" - t.Map1 = nil - t.Map2 = nil - _ = t - } - }) -} diff --git a/pkg/generator/go_types.go b/pkg/generator/go_types.go deleted file mode 100644 index 03fb52d..0000000 --- a/pkg/generator/go_types.go +++ /dev/null @@ -1,41 +0,0 @@ -package generator - -type GoFile struct { - Package string - Source string - Imports []GoImport - Types []GoType - EnumTypes []GoEnumType -} - -type GoImport struct { - Path string - Alias string -} - -type GoType struct { - Name string - Comments string - Fields []GoTypeField -} - -type GoTypeField struct { - Name string - Comments string - SnakeName string - Type string - ZeroValue string -} - -type GoEnumType struct { - Name string - Comments string - ValuesPrefix string - Values []GoEnumTypeValue -} - -type GoEnumTypeValue struct { - Name string - Comments string - Number int32 -} diff --git a/pkg/generator/template.go b/pkg/generator/template.go index 82c8057..c2b685d 100644 --- a/pkg/generator/template.go +++ b/pkg/generator/template.go @@ -1,30 +1,64 @@ package generator import ( + "bytes" "embed" _ "embed" - "strings" + "fmt" + "io/fs" "text/template" -) - -//go:embed templates/*.tmpl -var goTemplateFiles embed.FS -var goTemplate = template.Must( - template.New(""). - Funcs(goTemplateFunc). - ParseFS(goTemplateFiles, "templates/*.tmpl"), + litepb "github.com/e-tape/litepb/proto" ) -const mainTemplate = "main" +const mainTemplate = "file" -var additionalImports = []string{"fmt"} +type Template struct { + tmpl *template.Template + proto *litepb.File +} + +var ( + //go:embed templates/*.gotmpl + nativeTemplateFiles embed.FS + tmpl = &Template{} +) -var goTemplateFunc = template.FuncMap{ - "lines": func(text string) []string { - if text == "" { - return nil - } - return strings.Split(text, "\n") - }, +func (a *Template) Execute( + tmplFs fs.FS, + proto *litepb.File, +) (string, error) { + // TODO rathil once + tmplFile, err := template.New(""). + Funcs(template.FuncMap{ + "import": addImport, + "arr": arr, + "append": arrAppend, + "kv": kv, + "lines": lines, + "replace": replace, + "is_msg": isMsg, + "is_map": isMap, + "is_generate": isGenerate, + "set": set, + "get": get, + "render": render, + "sort": sort, + "add": add, + "sub": sub, + "mul": mul, + "pack_field_num_bytes": packFieldNumBytes, + "pack_field_num_int": packFieldNumInt, + }). + ParseFS(tmplFs, "templates/*.gotmpl") + if err != nil { + return "", fmt.Errorf("create template, err: %w", err) + } + a.tmpl = tmplFile + buf := bytes.NewBuffer(nil) + a.proto = proto + if err = a.tmpl.ExecuteTemplate(buf, mainTemplate, proto); err != nil { + return "", err + } + return buf.String(), nil } diff --git a/pkg/generator/template_funcs.go b/pkg/generator/template_funcs.go new file mode 100644 index 0000000..5e3abb9 --- /dev/null +++ b/pkg/generator/template_funcs.go @@ -0,0 +1,228 @@ +package generator + +import ( + "bytes" + "cmp" + "regexp" + "slices" + "strings" + + litepb "github.com/e-tape/litepb/proto" +) + +var aliasRegex = regexp.MustCompile("(?mi)[^a-z0-9_]") + +func addImport(path string, alias ...string) string { + if path == "" || path == tmpl.proto.GetPackage().GetDependency().GetPath() { + return "" + } + for _, imp := range tmpl.proto.Imports { + if imp.Path == path { + if imp.Alias != "" { + return imp.Alias + } + parts := strings.Split(imp.Path, "/") + return parts[len(parts)-1] + } + } + var impAlias string + if len(alias) > 0 { + impAlias = alias[0] + } else { + impAlias = aliasRegex.ReplaceAllString(path, "_") + } + if path == impAlias { + impAlias = "" + } + tmpl.proto.Imports = append(tmpl.proto.Imports, &litepb.Dependency{ + Path: path, + Alias: impAlias, + }) + if impAlias != "" { + return impAlias + } + return path +} + +func arr(values ...any) []any { + return values +} + +func arrAppend(arr []any, values ...any) []any { + return append(arr, values...) +} + +func kv(values ...any) map[any]any { + result := make(map[any]any, len(values)/2) + for i := 0; i < len(values); i += 2 { + result[values[i]] = values[i+1] + } + return result +} + +func isMsg(fieldType *litepb.Message_Field_Type) bool { + return fieldType.GetInProto() == litepb.Message_Field_Type_MESSAGE_OR_MAP && fieldType.GetMap() == nil +} + +func isMap(fieldType *litepb.Message_Field_Type) bool { + return fieldType.GetInProto() == litepb.Message_Field_Type_MESSAGE_OR_MAP && fieldType.GetMap() != nil +} + +func isGenerate(generate string) bool { + for _, f := range tmpl.proto.GetGenerates() { + if f.String() == generate { + return true + } + } + return false +} + +func lines(text string) []string { + if text == "" { + return nil + } + return strings.Split(text, "\n") +} + +func replace(input string, values ...string) string { + return strings.NewReplacer(values...).Replace(input) +} + +func set(value any, k any, v any) any { + switch vt := value.(type) { + case map[any]any: + vt[k] = v + case []any: + kt := k.(int) + if len(vt) > kt { + vt[kt] = v + } + } + return "" +} + +func get(value any, k any, defaultValue ...any) any { + switch vt := value.(type) { + case map[any]any: + if v, ok := vt[k]; ok { + return v + } + case []any: + kt := k.(int) + if len(vt) > kt { + return vt[kt] + } + } + if len(defaultValue) > 0 { + return defaultValue[0] + } + return nil +} + +func render(name string, data any) (string, error) { + var result bytes.Buffer + if err := tmpl.tmpl.ExecuteTemplate(&result, name, data); err != nil { + return "", err + } + return result.String(), nil +} + +func sort(items any) any { + switch tItems := items.(type) { + case []string: + slices.SortFunc(tItems, cmp.Compare[string]) + return tItems + case []*litepb.Dependency: + slices.SortFunc(tItems, func(a, b *litepb.Dependency) int { + return cmp.Compare(a.Alias, b.Alias) + }) + return slices.CompactFunc(tItems, func(a, b *litepb.Dependency) bool { + if a.Alias == "" && b.Alias == "" { + return a.Path == b.Path + } + return a.Alias == b.Alias + }) + } + return items +} + +func add(x, y int) int { return x + y } +func sub(x, y int) int { return x - y } +func mul(x, y int) int { return x * y } + +func packFieldNumBytes( + number int32, + inProtoAny any, + packed bool, +) []byte { + var wireType int32 + var inProto litepb.Message_Field_Type_Proto + switch it := inProtoAny.(type) { + case litepb.Message_Field_Type_Proto: + inProto = it + case int: + inProto = litepb.Message_Field_Type_Proto(it) + } + switch litepb.Message_Field_Type_Proto(inProto) { + case litepb.Message_Field_Type_INT32, + litepb.Message_Field_Type_INT64, + litepb.Message_Field_Type_UINT32, + litepb.Message_Field_Type_UINT64, + litepb.Message_Field_Type_SINT32, + litepb.Message_Field_Type_SINT64, + litepb.Message_Field_Type_BOOL: + if !packed { + wireType = 0 + } else { + wireType = 2 + } + case litepb.Message_Field_Type_ENUM: + wireType = 0 + case litepb.Message_Field_Type_FIXED64, + litepb.Message_Field_Type_SFIXED64, + litepb.Message_Field_Type_DOUBLE: + if !packed { + wireType = 1 + } else { + wireType = 2 + } + case litepb.Message_Field_Type_STRING, + litepb.Message_Field_Type_BYTES, + litepb.Message_Field_Type_MESSAGE_OR_MAP: + wireType = 2 + case litepb.Message_Field_Type_FIXED32, + litepb.Message_Field_Type_SFIXED32, + litepb.Message_Field_Type_FLOAT: + if !packed { + wireType = 5 + } else { + wireType = 2 + } + } + + num := number<<3 | wireType + result := make([]byte, 0, 4) + for num >= 1<<7 { + result = append(result, byte(num&127|128)) + num >>= 7 + } + return append(result, byte(num)) +} + +func packFieldNumInt( + number int32, + inProto any, + packed bool, +) any { + data := packFieldNumBytes(number, inProto, packed) + switch len(data) { + case 1: + return data[0] + case 2: + return uint16(data[0]) | uint16(data[1])<<8 + case 3: + return uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16 + default: + return uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16 | uint32(data[3])<<24 + } +} diff --git a/pkg/generator/templates/enums.gotmpl b/pkg/generator/templates/enums.gotmpl new file mode 100644 index 0000000..128dbf8 --- /dev/null +++ b/pkg/generator/templates/enums.gotmpl @@ -0,0 +1,21 @@ +{{- define "enums" -}} + {{ if is_generate "ENUM" -}} + {{- range . -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Enum*/ -}} + {{ range (lines .GetComments) -}} + //{{ . }} + {{- end }} + type {{ template "type_name" kv "msg" . }} int32 + + {{ $enum := . -}} + const ( + {{ range .GetValues -}} + {{ range (lines .Comments) -}} + //{{ . }} + {{ end -}} + {{ $enum.GetValuesPrefix }}_{{ .GetName }} {{ $enum.GetName }} = {{ .GetNumber }} + {{ end -}} + ) + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/enums.tmpl b/pkg/generator/templates/enums.tmpl deleted file mode 100644 index 6e9e755..0000000 --- a/pkg/generator/templates/enums.tmpl +++ /dev/null @@ -1,20 +0,0 @@ -{{ define "enums" }} - -{{ range . -}} -{{- range (lines .Comments) -}}{{/**/}} -//{{ . }} -{{- end }} -type {{ .Name }} int32 - -{{ $enum := . }} -const ( -{{- range .Values -}} - {{- range (lines .Comments) -}}{{/**/}} - //{{ . }} - {{- end }} - {{ $enum.ValuesPrefix }}_{{ .Name }} {{ $enum.Name }} = {{ .Number }} -{{- end }} -) -{{ end }} - -{{ end }} diff --git a/pkg/generator/templates/error_incorrect_of_field_length.gotmpl b/pkg/generator/templates/error_incorrect_of_field_length.gotmpl new file mode 100644 index 0000000..b6d5ad5 --- /dev/null +++ b/pkg/generator/templates/error_incorrect_of_field_length.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_incorrect_of_field_length" -}} + {{- import "fmt" -}}.Errorf("litepb: incorrect of field length for field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_incorrect_of_field_length_kv.gotmpl b/pkg/generator/templates/error_incorrect_of_field_length_kv.gotmpl new file mode 100644 index 0000000..9783d4d --- /dev/null +++ b/pkg/generator/templates/error_incorrect_of_field_length_kv.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_incorrect_of_field_length_kv" -}} + {{- import "fmt" -}}.Errorf("litepb: incorrect of field length for map field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_incorrect_wire_type.gotmpl b/pkg/generator/templates/error_incorrect_wire_type.gotmpl new file mode 100644 index 0000000..8cf5ae4 --- /dev/null +++ b/pkg/generator/templates/error_incorrect_wire_type.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_incorrect_wire_type" -}} + {{- import "fmt" -}}.Errorf("litepb: incorrect wire type [%d] for field {{ .msg.GetName }}.{{ .field.GetName }}", {{ .fieldNum }} & 7) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_incorrect_wire_type_kv.gotmpl b/pkg/generator/templates/error_incorrect_wire_type_kv.gotmpl new file mode 100644 index 0000000..6e21380 --- /dev/null +++ b/pkg/generator/templates/error_incorrect_wire_type_kv.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_incorrect_wire_type_kv" -}} + {{- import "fmt" -}}.Errorf("litepb: incorrect wire type [%d] for {{ .mapName }} map field {{ .fieldName }}", {{ .fieldNum }} & 7) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unexpected_end_of_field_length.gotmpl b/pkg/generator/templates/error_unexpected_end_of_field_length.gotmpl new file mode 100644 index 0000000..0a4aead --- /dev/null +++ b/pkg/generator/templates/error_unexpected_end_of_field_length.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unexpected_end_of_field_length" -}} + {{- import "fmt" -}}.Errorf("litepb: unexpected end of field length for field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unexpected_end_of_field_length_kv.gotmpl b/pkg/generator/templates/error_unexpected_end_of_field_length_kv.gotmpl new file mode 100644 index 0000000..53d886c --- /dev/null +++ b/pkg/generator/templates/error_unexpected_end_of_field_length_kv.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unexpected_end_of_field_length_kv" -}} + {{- import "fmt" -}}.Errorf("litepb: unexpected end of field length for map field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unexpected_end_of_field_number.gotmpl b/pkg/generator/templates/error_unexpected_end_of_field_number.gotmpl new file mode 100644 index 0000000..33e636a --- /dev/null +++ b/pkg/generator/templates/error_unexpected_end_of_field_number.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unexpected_end_of_field_number" -}} + {{- import "fmt" -}}.Errorf("litepb: unexpected end of field number") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unexpected_end_of_field_number_kv.gotmpl b/pkg/generator/templates/error_unexpected_end_of_field_number_kv.gotmpl new file mode 100644 index 0000000..2631764 --- /dev/null +++ b/pkg/generator/templates/error_unexpected_end_of_field_number_kv.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unexpected_end_of_field_number_kv" -}} + {{- import "fmt" -}}.Errorf("litepb: unexpected end of field number for map field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unexpected_end_of_field_value.gotmpl b/pkg/generator/templates/error_unexpected_end_of_field_value.gotmpl new file mode 100644 index 0000000..823475b --- /dev/null +++ b/pkg/generator/templates/error_unexpected_end_of_field_value.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unexpected_end_of_field_value" -}} + {{- import "fmt" -}}.Errorf("litepb: unexpected end of field value for field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unexpected_end_of_field_value_kv.gotmpl b/pkg/generator/templates/error_unexpected_end_of_field_value_kv.gotmpl new file mode 100644 index 0000000..521df1b --- /dev/null +++ b/pkg/generator/templates/error_unexpected_end_of_field_value_kv.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unexpected_end_of_field_value_kv" -}} + {{- import "fmt" -}}.Errorf("litepb: unexpected end of field value for map field {{ . }}") +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/error_unmarshal_custom_type_uuid.gotmpl b/pkg/generator/templates/error_unmarshal_custom_type_uuid.gotmpl new file mode 100644 index 0000000..809b943 --- /dev/null +++ b/pkg/generator/templates/error_unmarshal_custom_type_uuid.gotmpl @@ -0,0 +1,3 @@ +{{- define "error_unmarshal_custom_type_uuid" -}} + {{- import "fmt" -}}.Errorf("litepb: parse field value for uuid field {{ .field }}, err: %w", {{ .err }}) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_set.gotmpl b/pkg/generator/templates/field_set.gotmpl new file mode 100644 index 0000000..febc2f9 --- /dev/null +++ b/pkg/generator/templates/field_set.gotmpl @@ -0,0 +1,17 @@ +{{- define "field_set" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + if a == nil { panic("uninitialized object") } // TODO rathil del??? + {{ $isCustom := render "type_is_custom" .GetType -}} + {{ if and (is_msg .GetType) (.GetType.GetRepeated) (not $isCustom) -}} + {{ template "field_set_list" . }} + {{ else if and (is_map .GetType) (is_msg .GetType.GetMap.GetValue) (not (render "type_is_custom" .GetType.GetMap.GetValue)) -}} + if a.{{ .GetName }} != nil { a.{{ .GetName }}.{{ template "func_name_map_return_to_pool" }}() } + {{ template "field_set_map" . }} + {{ else if and (is_msg .GetType) (not $isCustom) -}} + a.{{ .GetName }}.{{ template "func_name_message_return_to_pool" }}() + a.{{ .GetName }} = {{ template "type_convert_to" .GetType }}(value) + {{ else -}} + a.{{ .GetName }} = {{- if or (.GetType.GetRepeated) (is_map .GetType) }}values{{ else }}value{{ end }} + {{ end -}} + return a +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_set_list.gotmpl b/pkg/generator/templates/field_set_list.gotmpl new file mode 100644 index 0000000..e9614a1 --- /dev/null +++ b/pkg/generator/templates/field_set_list.gotmpl @@ -0,0 +1,10 @@ +{{- define "field_set_list" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{ template "list_return_to_pool_pointer" . }} + a.p{{ .GetName }} = {{- template "field_type_path" .GetType -}} + {{ template "func_name_list_new" .GetType.GetReflect -}}(len(values)) + a.{{ .GetName }} = *a.p{{ .GetName }} + for _, v := range values { + a.{{ .GetName }} = append(a.{{ .GetName }}, {{ template "type_convert_to" .GetType }}(v)) + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_set_map.gotmpl b/pkg/generator/templates/field_set_map.gotmpl new file mode 100644 index 0000000..80f241d --- /dev/null +++ b/pkg/generator/templates/field_set_map.gotmpl @@ -0,0 +1,9 @@ +{{- define "field_set_map" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + a.{{ .GetName }} = {{- template "field_type_path" .GetType -}} + {{ template "func_name_map_new" .GetType.GetMap.GetValue.GetReflect -}} + [{{ template "type_name" kv "type" .GetType.GetMap.GetKey }}](len(values)) + for i, v := range values { + a.{{ .GetName }}[i] = {{ template "type_convert_to" .GetType.GetMap.GetValue }}(v) + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_set_unmarshal_result.gotmpl b/pkg/generator/templates/field_set_unmarshal_result.gotmpl new file mode 100644 index 0000000..a9df7c0 --- /dev/null +++ b/pkg/generator/templates/field_set_unmarshal_result.gotmpl @@ -0,0 +1,24 @@ +{{- define "field_set_unmarshal_result" }} + {{- $c := . -}} + {{- if $c.result -}} + {{- with .field -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{- if .GetType.GetRepeated -}} + {{ if and (is_msg .GetType) (not (render "type_is_custom" .GetType)) -}} + if a.{{ .GetName }} == nil { + a.p{{ .GetName }} = {{ template "field_type_path" .GetType -}} + {{ template "func_name_list_new" .GetType.GetReflect -}}(1) + a.{{ .GetName }} = *a.p{{ .GetName }} + } + {{ end -}} + a.{{ .GetName }} = append(a.{{ .GetName }}, {{ $c.result }}) + {{- else -}} + a.{{ .GetName }} = {{ $c.result }} + {{- end -}} + {{- end -}} + {{- with .oneof -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + a.Set{{ .GetName }}({{ $c.result }}) + {{- end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_tags.gotmpl b/pkg/generator/templates/field_tags.gotmpl new file mode 100644 index 0000000..54d07c5 --- /dev/null +++ b/pkg/generator/templates/field_tags.gotmpl @@ -0,0 +1,13 @@ +{{- define "field_tags" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{- $separator := "" -}} + ` + {{- range $key, $value := .GetTags -}} + {{- $separator -}}{{- $key -}} + {{- $separator = "," -}} + {{- if not (eq $value "") -}} + :"{{- $value -}}" + {{- end -}} + {{- end -}} + ` +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_type_path.gotmpl b/pkg/generator/templates/field_type_path.gotmpl new file mode 100644 index 0000000..c4a48f7 --- /dev/null +++ b/pkg/generator/templates/field_type_path.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_type_path" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{- with import .GetReflect.GetDependency.GetPath -}} + {{- . -}}. + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_bool.gotmpl b/pkg/generator/templates/field_unmarshal_bool.gotmpl new file mode 100644 index 0000000..b8c8c70 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_bool.gotmpl @@ -0,0 +1,5 @@ +{{- define "field_unmarshal_bool" -}} + if len(data) <= index || data[index] > 127 { return {{ .errorUnexpectedEndValue }} } + index++ + {{- set . "result" (render "field_unmarshal_bool_result" .) -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_bool_packed.gotmpl b/pkg/generator/templates/field_unmarshal_bool_packed.gotmpl new file mode 100644 index 0000000..a8f8a8a --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_bool_packed.gotmpl @@ -0,0 +1,19 @@ +{{- define "field_unmarshal_bool_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]{{ .valueTypeName }}, 0, {{ .valueLength }}) + } + for i := 0; i < {{ .valueLength }}; i++ { + if data[index] > 127 { return {{ .errorUnexpectedEndValue }} } + index++ + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, {{ (render "field_unmarshal_bool_result" .) }}) + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_bool_result.gotmpl b/pkg/generator/templates/field_unmarshal_bool_result.gotmpl new file mode 100644 index 0000000..694de4a --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_bool_result.gotmpl @@ -0,0 +1,3 @@ +{{- define "field_unmarshal_bool_result" -}} + data[index-1] == 1 +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_bytes.gotmpl b/pkg/generator/templates/field_unmarshal_bytes.gotmpl new file mode 100644 index 0000000..2c1dd1d --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_bytes.gotmpl @@ -0,0 +1,19 @@ +{{- define "field_unmarshal_bytes" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + index += {{ .valueLength }} + if len(data) < index { return {{ .errorUnexpectedEndValue }} } + {{ if .msg.GetUnsafe -}} + {{ set . "result" (render "field_unmarshal_bytes_result" .valueLength ) -}} + {{ else -}} + dataCopy := make([]byte, {{ .valueLength }}) + copy(dataCopy, data[index-{{ .valueLength }} : index]) + {{ set . "result" "dataCopy" -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_bytes_result.gotmpl b/pkg/generator/templates/field_unmarshal_bytes_result.gotmpl new file mode 100644 index 0000000..8d3c4b1 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_bytes_result.gotmpl @@ -0,0 +1,3 @@ +{{- define "field_unmarshal_bytes_result" -}} + data[index-{{ . }} : index] +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_double.gotmpl b/pkg/generator/templates/field_unmarshal_double.gotmpl new file mode 100644 index 0000000..cc781f8 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_double.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_unmarshal_double" -}} + if len(data) < index + 8 { return {{ .errorUnexpectedEnd }} } + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint64(data[index : index+8]) + index += 8 + {{- set . "result" (render "field_unmarshal_double_result" .valueName) -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_double_packed.gotmpl b/pkg/generator/templates/field_unmarshal_double_packed.gotmpl new file mode 100644 index 0000000..fe72853 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_double_packed.gotmpl @@ -0,0 +1,22 @@ +{{- define "field_unmarshal_double_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if {{ .valueLength }} % 8 != 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]float64, 0, {{ .valueLength }} / 8) + } + for i := 0; i < {{ .valueLength }}; i += 8 { + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, {{ template "field_unmarshal_double_result" (render "field_unmarshal_double_packed_result" "") }}) + index += 8 + } +{{- end -}} +{{- define "field_unmarshal_double_packed_result" -}} + {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint64(data[index : index+8]) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_double_result.gotmpl b/pkg/generator/templates/field_unmarshal_double_result.gotmpl new file mode 100644 index 0000000..21386e4 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_double_result.gotmpl @@ -0,0 +1,3 @@ +{{- define "field_unmarshal_double_result" -}} + {{ import "math" }}.Float64frombits({{ . }}) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_enum.gotmpl b/pkg/generator/templates/field_unmarshal_enum.gotmpl new file mode 100644 index 0000000..e0a9b32 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_enum.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_enum" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" (render "type_name" (kv "type" .type "format" "")) + "rangeItems" (arr 0 7 14 21 28) + -}} + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_fixed32.gotmpl b/pkg/generator/templates/field_unmarshal_fixed32.gotmpl new file mode 100644 index 0000000..5b95009 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_fixed32.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_unmarshal_fixed32" -}} + if len(data) < index + 4 { return {{ .errorUnexpectedEnd }} } + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint32(data[index : index+4]) + index += 4 + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_fixed32_packed.gotmpl b/pkg/generator/templates/field_unmarshal_fixed32_packed.gotmpl new file mode 100644 index 0000000..825eb10 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_fixed32_packed.gotmpl @@ -0,0 +1,19 @@ +{{- define "field_unmarshal_fixed32_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if {{ .valueLength }} % 4 != 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]uint32, 0, {{ .valueLength }} / 4) + } + for i := 0; i < {{ .valueLength }}; i += 4 { + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint32(data[index : index+4])) + index += 4 + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_fixed64.gotmpl b/pkg/generator/templates/field_unmarshal_fixed64.gotmpl new file mode 100644 index 0000000..eb8cc9e --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_fixed64.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_unmarshal_fixed64" -}} + if len(data) < index + 8 { return {{ .errorUnexpectedEnd }} } + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint64(data[index : index+8]) + index += 8 + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_fixed64_packed.gotmpl b/pkg/generator/templates/field_unmarshal_fixed64_packed.gotmpl new file mode 100644 index 0000000..d554462 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_fixed64_packed.gotmpl @@ -0,0 +1,19 @@ +{{- define "field_unmarshal_fixed64_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if {{ .valueLength }} % 8 != 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]uint64, 0, {{ .valueLength }} / 8) + } + for i := 0; i < {{ .valueLength }}; i += 8 { + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint64(data[index : index+8])) + index += 8 + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_float.gotmpl b/pkg/generator/templates/field_unmarshal_float.gotmpl new file mode 100644 index 0000000..47cdc21 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_float.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_unmarshal_float" -}} + if len(data) < index + 4 { return {{ .errorUnexpectedEnd }} } + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint32(data[index : index+4]) + index += 4 + {{- set . "result" (render "field_unmarshal_float_result" .valueName) -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_float_packed.gotmpl b/pkg/generator/templates/field_unmarshal_float_packed.gotmpl new file mode 100644 index 0000000..c43cd7b --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_float_packed.gotmpl @@ -0,0 +1,22 @@ +{{- define "field_unmarshal_float_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if {{ .valueLength }} % 4 != 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]float32, 0, {{ .valueLength }} / 4) + } + for i := 0; i < {{ .valueLength }}; i += 4 { + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, {{ template "field_unmarshal_float_result" (render "field_unmarshal_double_packed_result" "") }}) + index += 4 + } +{{- end -}} +{{- define "field_unmarshal_double_packed_result" -}} + {{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint32(data[index : index+4]) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_float_result.gotmpl b/pkg/generator/templates/field_unmarshal_float_result.gotmpl new file mode 100644 index 0000000..a15e2eb --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_float_result.gotmpl @@ -0,0 +1,3 @@ +{{- define "field_unmarshal_float_result" -}} + {{ import "math" }}.Float32frombits({{ . }}) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_i32.gotmpl b/pkg/generator/templates/field_unmarshal_i32.gotmpl new file mode 100644 index 0000000..31638bd --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_i32.gotmpl @@ -0,0 +1,25 @@ +{{- define "field_unmarshal_i32" -}} + {{- $c := . -}} + {{- with .field -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{ if eq .GetType.GetInProto.String "FIXED32" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_fixed32" $c }} + {{ else -}} + {{ template "field_unmarshal_fixed32_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "SFIXED32" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_sfixed32" $c }} + {{ else -}} + {{ template "field_unmarshal_sfixed32_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "FLOAT" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_float" $c }} + {{ else -}} + {{ template "field_unmarshal_float_packed" $c -}} + {{ end -}} + {{ end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_i64.gotmpl b/pkg/generator/templates/field_unmarshal_i64.gotmpl new file mode 100644 index 0000000..f43e43e --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_i64.gotmpl @@ -0,0 +1,25 @@ +{{- define "field_unmarshal_i64" -}} + {{- $c := . -}} + {{- with .field -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{ if eq .GetType.GetInProto.String "FIXED64" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_fixed64" $c }} + {{ else -}} + {{ template "field_unmarshal_fixed64_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "SFIXED64" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_sfixed64" $c }} + {{ else -}} + {{ template "field_unmarshal_sfixed64_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "DOUBLE" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_double" $c }} + {{ else -}} + {{ template "field_unmarshal_double_packed" $c -}} + {{ end -}} + {{ end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_int.gotmpl b/pkg/generator/templates/field_unmarshal_int.gotmpl new file mode 100644 index 0000000..d5133fd --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_int.gotmpl @@ -0,0 +1,29 @@ +{{- define "field_unmarshal_int" -}} + {{- $c := . -}} + {{ if .valueCreate -}} + var {{ .valueName }} {{ .valueTypeName }} + {{ end -}} + switch { + {{ range $index, $value := .rangeItems -}} + case len(data) > index{{ if gt $index 0 }}+{{ $index }}{{ end }} && data[index{{ if gt $index 0 }}+{{ $index }}{{ end }}] < 128: + {{ $c.valueName }} = {{ range $indexInt, $valueInt := $c.rangeItems -}} + {{- if le $indexInt $index -}} + {{- if gt $indexInt 0 -}} + | + {{- end -}} + {{- $c.valueTypeName }}(data[index + {{- if gt $indexInt 0 -}} + +{{ $indexInt }} + {{- end -}} + ]&127) + {{- if gt $indexInt 0 -}} + <<{{ $valueInt }} + {{- end -}} + {{ end -}} + {{ end }} + index += {{ add $index 1 }} + {{ end -}} + default: + return {{ .errorUnexpectedEnd }} + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_int32.gotmpl b/pkg/generator/templates/field_unmarshal_int32.gotmpl new file mode 100644 index 0000000..85192ef --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_int32.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_int32" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" "int32" + "rangeItems" (arr 0 7 14 21 28) + -}} + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_int32_packed.gotmpl b/pkg/generator/templates/field_unmarshal_int32_packed.gotmpl new file mode 100644 index 0000000..c1fa167 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_int32_packed.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_int32_packed" -}} + {{- set . "valueCreate" true -}} + {{- set . "valueTypeName" "int32" -}} + {{- set . "rangeItems" (arr 0 7 14 21 28) -}} + {{- set . "packedResult" .valueName -}} + {{- template "field_unmarshal_packed" . -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_int64.gotmpl b/pkg/generator/templates/field_unmarshal_int64.gotmpl new file mode 100644 index 0000000..4f623bc --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_int64.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_int64" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" "int64" + "rangeItems" (arr 0 7 14 21 28 35 42 49 56 63) + -}} + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_int64_packed.gotmpl b/pkg/generator/templates/field_unmarshal_int64_packed.gotmpl new file mode 100644 index 0000000..8387cae --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_int64_packed.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_int64_packed" -}} + {{- set . "valueCreate" true -}} + {{- set . "valueTypeName" "int64" -}} + {{- set . "rangeItems" (arr 0 7 14 21 28 35 42 49 56 63) -}} + {{- set . "packedResult" .valueName -}} + {{- template "field_unmarshal_packed" . -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_len.gotmpl b/pkg/generator/templates/field_unmarshal_len.gotmpl new file mode 100644 index 0000000..c027c42 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_len.gotmpl @@ -0,0 +1,17 @@ +{{- define "field_unmarshal_len" -}} + {{- $c := . -}} + {{- if not .packed -}} + {{- with .field -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{- if eq .GetType.GetInProto.String "STRING" -}} + {{ template "field_unmarshal_string" $c }} + {{- else if eq .GetType.GetInProto.String "BYTES" -}} + {{ template "field_unmarshal_bytes" $c }} + {{- else if and (eq .GetType.GetInProto.String "MESSAGE_OR_MAP") (is_map .GetType) -}} + {{ template "field_unmarshal_map" $c }} + {{- else if eq .GetType.GetInProto.String "MESSAGE_OR_MAP" -}} + {{ template "field_unmarshal_message" $c }} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_map.gotmpl b/pkg/generator/templates/field_unmarshal_map.gotmpl new file mode 100644 index 0000000..50a6974 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_map.gotmpl @@ -0,0 +1,73 @@ +{{- define "field_unmarshal_map" -}} + {{- /* for micro acceleration, we can not initiate the valueLength variable, but just skip the message length */ -}} + {{- $c := . -}} + {{ template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if len(data) < index+{{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + + var mapKey {{ template "type_name" kv "type" .type.GetMap.GetKey }} + var mapValue {{ template "type_name" kv "type" .type.GetMap.GetValue }} + mapEnd := index + {{ .valueLength }} + + for index < mapEnd { + {{ template "field_unmarshal_int" kv + "errorUnexpectedEnd" (render "error_unexpected_end_of_field_number_kv" .fieldName) + "valueName" "kvNum" + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21) + }} + switch kvNum { + {{ $paramKey := kv + "msg" .msg + "type" .type.GetMap.GetKey + "valueName" "mapKey" + "valueLength" "mapKeyLength" + "valueCreate" false + "fieldName" $c.fieldName + "errorUnexpectedEndLength" (render "error_unexpected_end_of_field_length_kv" $c.fieldName) + "errorUnexpectedEndValue" (render "error_unexpected_end_of_field_value_kv" $c.fieldName) + "errorUnexpectedEnd" (render "error_unexpected_end_of_field_value_kv" $c.fieldName) + "errorIncorrectLength" (render "error_incorrect_of_field_length_kv" $c.fieldName) + -}} + {{ with (render "field_unmarshal_map_nested" $paramKey) -}} + case {{ pack_field_num_int 1 (get $paramKey "in_proto") false}}: + {{ . }} + {{- end -}} + {{ $paramValue := kv + "msg" .msg + "type" .type.GetMap.GetValue + "valueName" "mapValue" + "valueLength" "mapValueLength" + "valueCreate" false + "fieldName" $c.fieldName + "errorUnexpectedEndLength" (render "error_unexpected_end_of_field_length_kv" $c.fieldName) + "errorUnexpectedEndValue" (render "error_unexpected_end_of_field_value_kv" $c.fieldName) + "errorUnexpectedEnd" (render "error_unexpected_end_of_field_value_kv" $c.fieldName) + "errorIncorrectLength" (render "error_incorrect_of_field_length_kv" $c.fieldName) + -}} + {{ with (render "field_unmarshal_map_nested" $paramValue) -}} + case {{ pack_field_num_int 2 (get $paramValue "in_proto") false}}: + {{ . }} + {{- end -}} + default: + // TODO rathil what to do if the value or key never arrived???? + } + } + if a.{{ .field.GetName }} == nil { + {{ if and (is_msg .type.GetMap.GetValue) (not (render "type_is_custom" .type.GetMap.GetValue)) -}} + a.{{ .field.GetName }} = {{- template "field_type_path" .type -}} + {{ template "func_name_map_new" .type.GetMap.GetValue.GetReflect -}} + [{{ template "type_name" kv "type" .type.GetMap.GetKey }}](1) + {{ else -}} + a.{{ .field.GetName }} = make({{ template "type_name" kv "type" .type }}, 1) + {{ end -}} + } + a.{{ .field.GetName }}[{{ get $paramKey "result" }}] = {{ get $paramValue "result" }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_map_nested.gotmpl b/pkg/generator/templates/field_unmarshal_map_nested.gotmpl new file mode 100644 index 0000000..d6cf577 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_map_nested.gotmpl @@ -0,0 +1,62 @@ +{{- define "field_unmarshal_map_nested" -}} + {{- $c := . -}} + {{ with .type -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{ if eq .GetInProto.String "UINT64" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_uint64" $c }} + {{ else if eq .GetInProto.String "INT64" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_int64" $c }} + {{ else if eq .GetInProto.String "SINT64" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_sint64" $c }} + {{ else if eq .GetInProto.String "UINT32" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_uint32" $c }} + {{ else if eq .GetInProto.String "INT32" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_int32" $c }} + {{ else if eq .GetInProto.String "SINT32" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_sint32" $c }} + {{ else if eq .GetInProto.String "BOOL" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_bool" $c }} + {{ else if eq .GetInProto.String "ENUM" -}} + {{- set $c "in_proto" 0 -}} + {{ template "field_unmarshal_enum" $c }} + {{ else if eq .GetInProto.String "STRING" -}} + {{- set $c "in_proto" 2 -}} + {{ template "field_unmarshal_string" $c -}} + {{ $c.valueName }} = {{ get $c "result" }} + {{ set $c "result" $c.valueName -}} + {{ else if eq .GetInProto.String "BYTES" -}} + {{- set $c "in_proto" 2 -}} + {{ template "field_unmarshal_bytes" $c -}} + {{ $c.valueName }} = {{ get $c "result" }} + {{ set $c "result" $c.valueName -}} + {{ else if and (eq .GetInProto.String "MESSAGE_OR_MAP") (not (is_map .)) -}} + {{- set $c "in_proto" 2 -}} + {{ template "field_unmarshal_message" $c }} + {{ else if eq .GetInProto.String "FIXED64" -}} + {{- set $c "in_proto" 1 -}} + {{ template "field_unmarshal_fixed64" $c }} + {{ else if eq .GetInProto.String "SFIXED64" -}} + {{- set $c "in_proto" 1 -}} + {{ template "field_unmarshal_sfixed64" $c }} + {{ else if eq .GetInProto.String "DOUBLE" -}} + {{- set $c "in_proto" 1 -}} + {{ template "field_unmarshal_double" $c }} + {{ else if eq .GetInProto.String "FIXED32" -}} + {{- set $c "in_proto" 5 -}} + {{ template "field_unmarshal_fixed32" $c }} + {{ else if eq .GetInProto.String "SFIXED32" -}} + {{- set $c "in_proto" 5 -}} + {{ template "field_unmarshal_sfixed32" $c }} + {{ else if eq .GetInProto.String "FLOAT" -}} + {{- set $c "in_proto" 5 -}} + {{ template "field_unmarshal_float" $c }} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_message.gotmpl b/pkg/generator/templates/field_unmarshal_message.gotmpl new file mode 100644 index 0000000..6d0bb9e --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_message.gotmpl @@ -0,0 +1,26 @@ +{{- define "field_unmarshal_message" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if len(data) < index+{{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + {{ with (render "type_custom_unmarshal" (kv "c" . "valueLength" .valueLength)) -}} + {{ . }} + {{ else -}} + {{ if .setInField -}} + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= a.{{ .field.GetName }} + if {{ .valueName }} == nil { + {{ .valueName }} = {{ template "type_new" .type }}() + } + {{ else -}} + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= {{ template "type_new" .type }}() + {{ end -}} + if err := {{ .valueName }}.{{ template "func_name_message_unmarshal" "" }}(data[index : index+{{ .valueLength }}]); err != nil { return err } + index += {{ .valueLength }} + {{ end -}} + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_packed.gotmpl b/pkg/generator/templates/field_unmarshal_packed.gotmpl new file mode 100644 index 0000000..8ffa0cf --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_packed.gotmpl @@ -0,0 +1,25 @@ +{{- define "field_unmarshal_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + endIndex := index + {{ .valueLength }} + if len(data) < endIndex { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + var count int + for i := index; i < endIndex; i++ { + if data[i] < 128 { count++ } + } + if count > 0 { + a.{{ .field.GetName }} = make([]{{ .valueTypeName }}, 0, count) + } + } + for index < endIndex { + {{- template "field_unmarshal_int" . }} + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, {{ .packedResult }}) + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sfixed32.gotmpl b/pkg/generator/templates/field_unmarshal_sfixed32.gotmpl new file mode 100644 index 0000000..68dc478 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sfixed32.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_unmarshal_sfixed32" -}} + if len(data) < index + 4 { return {{ .errorUnexpectedEnd }} } + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= int32({{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint32(data[index : index+4])) + index += 4 + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sfixed32_packed.gotmpl b/pkg/generator/templates/field_unmarshal_sfixed32_packed.gotmpl new file mode 100644 index 0000000..784e710 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sfixed32_packed.gotmpl @@ -0,0 +1,19 @@ +{{- define "field_unmarshal_sfixed32_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if {{ .valueLength }} % 4 != 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]int32, 0, {{ .valueLength }} / 4) + } + for i := 0; i < {{ .valueLength }}; i += 4 { + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, int32({{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint32(data[index : index+4]))) + index += 4 + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sfixed64.gotmpl b/pkg/generator/templates/field_unmarshal_sfixed64.gotmpl new file mode 100644 index 0000000..97387fe --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sfixed64.gotmpl @@ -0,0 +1,6 @@ +{{- define "field_unmarshal_sfixed64" -}} + if len(data) < index + 8 { return {{ .errorUnexpectedEnd }} } + {{ .valueName }} {{ if .valueCreate }}:{{ end }}= int64({{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint64(data[index : index+8])) + index += 8 + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sfixed64_packed.gotmpl b/pkg/generator/templates/field_unmarshal_sfixed64_packed.gotmpl new file mode 100644 index 0000000..381a021 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sfixed64_packed.gotmpl @@ -0,0 +1,19 @@ +{{- define "field_unmarshal_sfixed64_packed" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + if {{ .valueLength }} % 8 != 0 { return {{ .errorIncorrectLength }} } + if len(data) < index + {{ .valueLength }} { return {{ .errorUnexpectedEndValue }} } + if a.{{ .field.GetName }} == nil { + a.{{ .field.GetName }} = make([]int64, 0, {{ .valueLength }} / 8) + } + for i := 0; i < {{ .valueLength }}; i += 8 { + a.{{ .field.GetName }} = append(a.{{ .field.GetName }}, int64({{ import "encoding/binary" "encoding_binary" }}.LittleEndian.Uint64(data[index : index+8]))) + index += 8 + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sint32.gotmpl b/pkg/generator/templates/field_unmarshal_sint32.gotmpl new file mode 100644 index 0000000..61ef6dd --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sint32.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_sint32" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" "int32" + "rangeItems" (arr 0 7 14 21 28) + -}} + {{- set . "result" (render "field_unmarshal_sint32_result" .valueName) -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sint32_packed.gotmpl b/pkg/generator/templates/field_unmarshal_sint32_packed.gotmpl new file mode 100644 index 0000000..dc2e72a --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sint32_packed.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_sint32_packed" -}} + {{- set . "valueCreate" true -}} + {{- set . "valueTypeName" "int32" -}} + {{- set . "rangeItems" (arr 0 7 14 21 28) -}} + {{- set . "packedResult" (render "field_unmarshal_sint32_result" .valueName) -}} + {{- template "field_unmarshal_packed" . -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sint32_result.gotmpl b/pkg/generator/templates/field_unmarshal_sint32_result.gotmpl new file mode 100644 index 0000000..abc55cb --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sint32_result.gotmpl @@ -0,0 +1,3 @@ +{{- define "field_unmarshal_sint32_result" -}} + ({{ . }}>>1) ^ (({{ . }}&1<<31)>>31) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sint64.gotmpl b/pkg/generator/templates/field_unmarshal_sint64.gotmpl new file mode 100644 index 0000000..212893c --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sint64.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_sint64" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" "int64" + "rangeItems" (arr 0 7 14 21 28 35 42 49 56 63) + -}} + {{- set . "result" (render "field_unmarshal_sint64_result" .valueName) -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sint64_packed.gotmpl b/pkg/generator/templates/field_unmarshal_sint64_packed.gotmpl new file mode 100644 index 0000000..20d82a3 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sint64_packed.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_sint64_packed" -}} + {{- set . "valueCreate" true -}} + {{- set . "valueTypeName" "int64" -}} + {{- set . "rangeItems" (arr 0 7 14 21 28 35 42 49 56 63) -}} + {{- set . "packedResult" (render "field_unmarshal_sint64_result" .valueName) -}} + {{- template "field_unmarshal_packed" . -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_sint64_result.gotmpl b/pkg/generator/templates/field_unmarshal_sint64_result.gotmpl new file mode 100644 index 0000000..46a6bba --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_sint64_result.gotmpl @@ -0,0 +1,3 @@ +{{- define "field_unmarshal_sint64_result" -}} + ({{ . }}>>1) ^ (({{ . }}&1<<63)>>63) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_string.gotmpl b/pkg/generator/templates/field_unmarshal_string.gotmpl new file mode 100644 index 0000000..3ee837f --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_string.gotmpl @@ -0,0 +1,13 @@ +{{- define "field_unmarshal_string" -}} + {{- template "field_unmarshal_int" kv + "errorUnexpectedEnd" .errorUnexpectedEndLength + "valueName" .valueLength + "valueCreate" true + "valueTypeName" "int" + "rangeItems" (arr 0 7 14 21 28) + }} + if {{ .valueLength }} < 0 { return {{ .errorIncorrectLength }} } + index += {{ .valueLength }} + if len(data) < index { return {{ .errorUnexpectedEndValue }} } + {{ set . "result" (render "field_unmarshal_string_result" (kv "msg" .msg "valueLength" .valueLength)) -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_string_result.gotmpl b/pkg/generator/templates/field_unmarshal_string_result.gotmpl new file mode 100644 index 0000000..028e1ca --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_string_result.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_string_result" -}} + {{- if .msg.GetUnsafe -}} + {{- import "unsafe" -}}.String(&data[index-{{ .valueLength }}], {{ .valueLength }}) + {{- else -}} + string(data[index-{{ .valueLength }} : index]) + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_uint32.gotmpl b/pkg/generator/templates/field_unmarshal_uint32.gotmpl new file mode 100644 index 0000000..83f70f5 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_uint32.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_uint32" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" "uint32" + "rangeItems" (arr 0 7 14 21 28) + -}} + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_uint32_packed.gotmpl b/pkg/generator/templates/field_unmarshal_uint32_packed.gotmpl new file mode 100644 index 0000000..3a02d7f --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_uint32_packed.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_uint32_packed" -}} + {{- set . "valueCreate" true -}} + {{- set . "valueTypeName" "uint32" -}} + {{- set . "rangeItems" (arr 0 7 14 21 28) -}} + {{- set . "packedResult" .valueName -}} + {{- template "field_unmarshal_packed" . -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_uint64.gotmpl b/pkg/generator/templates/field_unmarshal_uint64.gotmpl new file mode 100644 index 0000000..b5667a0 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_uint64.gotmpl @@ -0,0 +1,11 @@ +{{- define "field_unmarshal_uint64" -}} + {{- template "field_unmarshal_int" kv + "type" .type + "errorUnexpectedEnd" .errorUnexpectedEnd + "valueName" .valueName + "valueCreate" .valueCreate + "valueTypeName" "uint64" + "rangeItems" (arr 0 7 14 21 28 35 42 49 56 63) + -}} + {{- set . "result" .valueName -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_uint64_packed.gotmpl b/pkg/generator/templates/field_unmarshal_uint64_packed.gotmpl new file mode 100644 index 0000000..5ae9440 --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_uint64_packed.gotmpl @@ -0,0 +1,7 @@ +{{- define "field_unmarshal_uint64_packed" -}} + {{- set . "valueCreate" true -}} + {{- set . "valueTypeName" "uint64" -}} + {{- set . "rangeItems" (arr 0 7 14 21 28 35 42 49 56 63) -}} + {{- set . "packedResult" .valueName -}} + {{- template "field_unmarshal_packed" . -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/field_unmarshal_varint.gotmpl b/pkg/generator/templates/field_unmarshal_varint.gotmpl new file mode 100644 index 0000000..7dca36f --- /dev/null +++ b/pkg/generator/templates/field_unmarshal_varint.gotmpl @@ -0,0 +1,51 @@ +{{- define "field_unmarshal_varint" -}} + {{- $c := . -}} + {{- with .field -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + {{ if eq .GetType.GetInProto.String "UINT64" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_uint64" $c }} + {{ else -}} + {{ template "field_unmarshal_uint64_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "INT64" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_int64" $c }} + {{ else -}} + {{ template "field_unmarshal_int64_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "SINT64" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_sint64" $c }} + {{ else -}} + {{ template "field_unmarshal_sint64_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "UINT32" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_uint32" $c }} + {{ else -}} + {{ template "field_unmarshal_uint32_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "INT32" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_int32" $c }} + {{ else -}} + {{ template "field_unmarshal_int32_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "SINT32" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_sint32" $c }} + {{ else -}} + {{ template "field_unmarshal_sint32_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "BOOL" -}} + {{ if not $c.packed -}} + {{ template "field_unmarshal_bool" $c }} + {{ else -}} + {{ template "field_unmarshal_bool_packed" $c -}} + {{ end -}} + {{ else if eq .GetType.GetInProto.String "ENUM" -}} + {{ template "field_unmarshal_enum" $c }} + {{ end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/file.gotmpl b/pkg/generator/templates/file.gotmpl new file mode 100644 index 0000000..8cb7d6b --- /dev/null +++ b/pkg/generator/templates/file.gotmpl @@ -0,0 +1,11 @@ +{{- define "file" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.File*/ -}} + // Code generated by protoc-gen-litepb (https://github.com/e-tape/litepb). DO NOT EDIT. + // source: {{ .GetSource }} + + package {{ .GetPackage.GetName }} + + {{ $source := render "file_entities" . -}} + {{ template "imports" .GetImports | sort }} + {{ $source }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/file_entities.gotmpl b/pkg/generator/templates/file_entities.gotmpl new file mode 100644 index 0000000..acd2fc1 --- /dev/null +++ b/pkg/generator/templates/file_entities.gotmpl @@ -0,0 +1,49 @@ +{{- define "file_entities" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.File*/ -}} + {{ template "enums" .GetEnums -}} + + {{ $types := "" -}} + {{ range .GetMessages -}} + {{ $types = print + $types + (render "message_interface_get" .) + (render "message_interface_set" .) + (render "message_interface" .) + (render "message_struct" .) + (render "message_list" .) + (render "message_map" .) + (render "oneof_types" .) + -}} + {{ end -}} + {{ with $types }} + type ( + {{ . }} + ) + {{ end -}} + {{ range .GetMessages -}} + {{ with print (render "message_pool" .) (render "list_pool" .) (render "map_pool" .) (render "oneof_pools" .) -}} + var ( + {{ . }} + ) + {{ end -}} + + {{ template "message_new" . }} + {{ template "list_new" . }} + {{ template "map_new" . }} + {{ template "message_convert_to" . }} + {{ template "oneof_new" . }} + + {{ template "message_string" . }} + {{ template "message_reset" . }} + {{ template "message_return_to_pool" . }} + {{ template "list_return_to_pool" . }} + {{ template "map_return_to_pool" . }} + {{ template "message_proto_message" . }} + + {{ template "message_methods_get" . }} + {{ template "message_methods_set" . }} + {{ template "message_marshal" . }} + {{ template "message_unmarshal" . }} + {{ template "oneof_methods" . }} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_list_new.gotmpl b/pkg/generator/templates/func_name_list_new.gotmpl new file mode 100644 index 0000000..a32aa4c --- /dev/null +++ b/pkg/generator/templates/func_name_list_new.gotmpl @@ -0,0 +1,4 @@ +{{- define "func_name_list_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + New{{ template "type_name" kv "msg" . "list" true }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_list_return_to_pool.gotmpl b/pkg/generator/templates/func_name_list_return_to_pool.gotmpl new file mode 100644 index 0000000..92b08cb --- /dev/null +++ b/pkg/generator/templates/func_name_list_return_to_pool.gotmpl @@ -0,0 +1 @@ +{{- define "func_name_list_return_to_pool" -}}ReturnToPool{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_map_new.gotmpl b/pkg/generator/templates/func_name_map_new.gotmpl new file mode 100644 index 0000000..9ab7b04 --- /dev/null +++ b/pkg/generator/templates/func_name_map_new.gotmpl @@ -0,0 +1,4 @@ +{{- define "func_name_map_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + New{{ template "type_name" kv "msg" . "map" true }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_map_return_to_pool.gotmpl b/pkg/generator/templates/func_name_map_return_to_pool.gotmpl new file mode 100644 index 0000000..f9536e9 --- /dev/null +++ b/pkg/generator/templates/func_name_map_return_to_pool.gotmpl @@ -0,0 +1 @@ +{{- define "func_name_map_return_to_pool" -}}ReturnToPool{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_message_convert_to.gotmpl b/pkg/generator/templates/func_name_message_convert_to.gotmpl new file mode 100644 index 0000000..6684cb4 --- /dev/null +++ b/pkg/generator/templates/func_name_message_convert_to.gotmpl @@ -0,0 +1,4 @@ +{{- define "func_name_message_convert_to" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + ConvertTo{{ template "type_name" kv "msg" . }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_message_marshal.gotmpl b/pkg/generator/templates/func_name_message_marshal.gotmpl new file mode 100644 index 0000000..d34d896 --- /dev/null +++ b/pkg/generator/templates/func_name_message_marshal.gotmpl @@ -0,0 +1 @@ +{{- define "func_name_message_unmarshal" -}}MarshalProto{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_message_new.gotmpl b/pkg/generator/templates/func_name_message_new.gotmpl new file mode 100644 index 0000000..3d707fc --- /dev/null +++ b/pkg/generator/templates/func_name_message_new.gotmpl @@ -0,0 +1,4 @@ +{{- define "func_name_message_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + New{{ template "type_name" kv "msg" . }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_message_return_to_pool.gotmpl b/pkg/generator/templates/func_name_message_return_to_pool.gotmpl new file mode 100644 index 0000000..b363b0c --- /dev/null +++ b/pkg/generator/templates/func_name_message_return_to_pool.gotmpl @@ -0,0 +1 @@ +{{- define "func_name_message_return_to_pool" -}}ReturnToPool{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_message_unmarshal.gotmpl b/pkg/generator/templates/func_name_message_unmarshal.gotmpl new file mode 100644 index 0000000..de27839 --- /dev/null +++ b/pkg/generator/templates/func_name_message_unmarshal.gotmpl @@ -0,0 +1 @@ +{{- define "func_name_message_unmarshal" -}}UnmarshalProto{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_oneof_new.gotmpl b/pkg/generator/templates/func_name_oneof_new.gotmpl new file mode 100644 index 0000000..ab4901d --- /dev/null +++ b/pkg/generator/templates/func_name_oneof_new.gotmpl @@ -0,0 +1,3 @@ +{{- define "func_name_oneof_new" -}} + New{{ template "oneof_type_name" . }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/func_name_oneof_return_to_pool.gotmpl b/pkg/generator/templates/func_name_oneof_return_to_pool.gotmpl new file mode 100644 index 0000000..dda6814 --- /dev/null +++ b/pkg/generator/templates/func_name_oneof_return_to_pool.gotmpl @@ -0,0 +1 @@ +{{- define "func_name_oneof_return_to_pool" -}}ReturnToPool{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/imports.gotmpl b/pkg/generator/templates/imports.gotmpl new file mode 100644 index 0000000..aed7826 --- /dev/null +++ b/pkg/generator/templates/imports.gotmpl @@ -0,0 +1,9 @@ +{{- define "imports" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Import*/ -}} + + import ( + {{ range . -}} + {{ .GetAlias }} "{{ .GetPath }}" + {{ end -}} + ) +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/imports.tmpl b/pkg/generator/templates/imports.tmpl deleted file mode 100644 index cb451c0..0000000 --- a/pkg/generator/templates/imports.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -{{ define "imports" }} - -import ( - {{- range . -}}{{/**/}} - {{ .Alias }} "{{ .Path }}" - {{- end }} -) - -// Ensure imports always used -var _ = fmt.Errorf - -{{ end }} diff --git a/pkg/generator/templates/list_new.gotmpl b/pkg/generator/templates/list_new.gotmpl new file mode 100644 index 0000000..d8a1731 --- /dev/null +++ b/pkg/generator/templates/list_new.gotmpl @@ -0,0 +1,12 @@ +{{- define "list_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "NEW" -}} + func {{ template "func_name_list_new" . }}(cap int) *{{ template "type_name" kv "msg" . "list" true }} { + {{ if .GetMemPoolList -}} + if value, ok := {{ template "pool_name_list" . }}.Get().(*{{ template "type_name" kv "msg" . "list" true }}); ok { return value } + {{ end -}} + value := make({{ template "type_name" kv "msg" . "list" true }}, 0, cap) + return &value + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/list_pool.gotmpl b/pkg/generator/templates/list_pool.gotmpl new file mode 100644 index 0000000..6189b6c --- /dev/null +++ b/pkg/generator/templates/list_pool.gotmpl @@ -0,0 +1,8 @@ +{{- define "list_pool" -}} + {{ if is_generate "POOL" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if .GetMemPoolList -}} + {{ template "pool_name_list" . }} = &{{ import "sync" }}.Pool{} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/list_return_to_pool.gotmpl b/pkg/generator/templates/list_return_to_pool.gotmpl new file mode 100644 index 0000000..89387c5 --- /dev/null +++ b/pkg/generator/templates/list_return_to_pool.gotmpl @@ -0,0 +1,20 @@ +{{- define "list_return_to_pool" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "RETURN_TO_POOL" -}} + func (a *{{ template "type_name" kv "msg" . "list" true }}){{ template "func_name_list_return_to_pool" }}() { + {{ if or .GetMemPoolMessage .GetMemPoolList -}} + if a == nil { return } + {{ end -}} + {{ if .GetMemPoolMessage -}} + for _, item := range *a { + item.{{ template "func_name_message_return_to_pool" }}() + } + {{ end -}} + {{ if .GetMemPoolList -}} + clear(*a) + *a = (*a)[:0] + {{ template "pool_name_list" . }}.Put(a) + {{ end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/list_return_to_pool_pointer.gotmpl b/pkg/generator/templates/list_return_to_pool_pointer.gotmpl new file mode 100644 index 0000000..d572e7b --- /dev/null +++ b/pkg/generator/templates/list_return_to_pool_pointer.gotmpl @@ -0,0 +1,7 @@ +{{- define "list_return_to_pool_pointer" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field*/ -}} + if a.p{{ .GetName }} != nil { + *a.p{{ .GetName }} = a.{{ .GetName }} + a.p{{ .GetName }}.{{ template "func_name_list_return_to_pool" }}() + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/main.tmpl b/pkg/generator/templates/main.tmpl deleted file mode 100644 index 9be690b..0000000 --- a/pkg/generator/templates/main.tmpl +++ /dev/null @@ -1,14 +0,0 @@ -{{ define "main" }} - -// Code generated by protoc-gen-litepb. DO NOT EDIT. -// source: {{ .Source }} - -package {{ .Package }} - -{{ template "imports" .Imports }} - -{{ template "enums" .EnumTypes }} - -{{ template "types" .Types }} - -{{ end }} diff --git a/pkg/generator/templates/map_new.gotmpl b/pkg/generator/templates/map_new.gotmpl new file mode 100644 index 0000000..6a0f3f5 --- /dev/null +++ b/pkg/generator/templates/map_new.gotmpl @@ -0,0 +1,12 @@ +{{- define "map_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "NEW" -}} + func {{ template "func_name_map_new" . }}[K comparable](cap int) {{ template "type_name" kv "msg" . "map" true }}[K] { + {{ if .GetMemPoolMap -}} + {{ template "map_pool_init" . }} + if value , ok := pool.(*sync.Pool).Get().({{ template "type_name" kv "msg" . "map" true }}[K]); ok { return value } + {{ end -}} + return make({{ template "type_name" kv "msg" . "map" true }}[K], cap) + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/map_pool.gotmpl b/pkg/generator/templates/map_pool.gotmpl new file mode 100644 index 0000000..b14ee52 --- /dev/null +++ b/pkg/generator/templates/map_pool.gotmpl @@ -0,0 +1,8 @@ +{{- define "map_pool" -}} + {{ if is_generate "POOL" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if .GetMemPoolMap -}} + {{ template "pool_name_map" . }} = &{{ import "sync" }}.Map{} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/map_pool_init.gotmpl b/pkg/generator/templates/map_pool_init.gotmpl new file mode 100644 index 0000000..36c4978 --- /dev/null +++ b/pkg/generator/templates/map_pool_init.gotmpl @@ -0,0 +1,8 @@ +{{- define "map_pool_init" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + var key K + pool, loaded := {{ template "pool_name_map" . }}.Load(key) + if !loaded { + pool, _ = {{ template "pool_name_map" . }}.LoadOrStore(key, &sync.Pool{}) + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/map_return_to_pool.gotmpl b/pkg/generator/templates/map_return_to_pool.gotmpl new file mode 100644 index 0000000..40c48de --- /dev/null +++ b/pkg/generator/templates/map_return_to_pool.gotmpl @@ -0,0 +1,20 @@ +{{- define "map_return_to_pool" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "RETURN_TO_POOL" -}} + func (a {{ template "type_name" kv "msg" . "map" true }}[K]){{ template "func_name_map_return_to_pool" }}() { + {{ if or .GetMemPoolMessage .GetMemPoolMap -}} + if a == nil { return } + {{ end -}} + {{ if .GetMemPoolMessage -}} + for _, item := range a { + item.{{ template "func_name_message_return_to_pool" }}() + } + {{ end -}} + {{ if .GetMemPoolMap -}} + {{ template "map_pool_init" . }} + clear(a) + pool.(*sync.Pool).Put(a) + {{ end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_constructor.gotmpl b/pkg/generator/templates/message_constructor.gotmpl new file mode 100644 index 0000000..f2c15fe --- /dev/null +++ b/pkg/generator/templates/message_constructor.gotmpl @@ -0,0 +1,4 @@ +{{- define "message_constructor" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + &{{ template "type_name" kv "msg" . }}{} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_convert_to.gotmpl b/pkg/generator/templates/message_convert_to.gotmpl new file mode 100644 index 0000000..8bf9bd8 --- /dev/null +++ b/pkg/generator/templates/message_convert_to.gotmpl @@ -0,0 +1,32 @@ +{{- define "message_convert_to" -}} + {{ if is_generate "CONVERT_TO" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + func {{ template "func_name_message_convert_to" . }}(value {{ template "type_name" kv "msg" . "i_get" true }}) *{{ template "type_name" kv "msg" . }} { + if a, ok := value.(*{{ template "type_name" kv "msg" . }}); ok { return a } + a := {{ template "func_name_message_new" . }}() + {{ range .GetProperties -}} + {{ with .GetField -}} + {{ $isCustom := render "type_is_custom" .GetType -}} + {{ if and (is_msg .GetType) (.GetType.GetRepeated) (not $isCustom) -}} + { + values := value.Get{{ .GetName }}() + {{ template "field_set_list" . }} + } + {{ else if and (is_map .GetType) (is_msg .GetType.GetMap.GetValue) (not (render "type_is_custom" .GetType.GetMap.GetValue)) -}} + { + values := value.Get{{ .GetName }}() + {{ template "field_set_map" . }} + } + {{ else -}} + a.Set{{ .GetName }}(value.Get{{ .GetName }}()) + {{ end -}} + {{ end -}} + {{ with .GetOneof -}} + a.Set{{ .GetName }}(value.Get{{ .GetName }}()) + {{ end -}} + {{ end -}} + return a + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_interface.gotmpl b/pkg/generator/templates/message_interface.gotmpl new file mode 100644 index 0000000..cd31ec6 --- /dev/null +++ b/pkg/generator/templates/message_interface.gotmpl @@ -0,0 +1,9 @@ +{{- define "message_interface" -}} + {{ if is_generate "INTERFACE" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ template "type_name" kv "msg" . "i" true }} interface { + {{ template "type_name" kv "msg" . "i_get" true }} + {{ template "type_name" kv "msg" . "i_set" true }} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_interface_get.gotmpl b/pkg/generator/templates/message_interface_get.gotmpl new file mode 100644 index 0000000..a08867e --- /dev/null +++ b/pkg/generator/templates/message_interface_get.gotmpl @@ -0,0 +1,19 @@ +{{- define "message_interface_get" -}} + {{ if is_generate "INTERFACE" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ template "type_name" kv "msg" . "i_get" true }} interface { + {{ range .GetProperties -}} + {{ with .GetField -}} + Get{{ .GetName }}() {{ template "type_name" kv "type" .GetType "i" true }} + {{ end -}} + {{ with .GetOneof -}} + Get{{ .GetName }}() {{ template "oneof_type_name" kv "msg" $msg "oneof" . }} + {{ range .GetFields -}} + Get{{ .GetName }}() {{ template "type_name" kv "type" .GetType "i_get" true }} + {{ end -}} + {{ end -}} + {{ end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_interface_set.gotmpl b/pkg/generator/templates/message_interface_set.gotmpl new file mode 100644 index 0000000..4b23a59 --- /dev/null +++ b/pkg/generator/templates/message_interface_set.gotmpl @@ -0,0 +1,22 @@ +{{- define "message_interface_set" -}} + {{ if is_generate "INTERFACE" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ template "type_name" kv "msg" . "i_set" true }} interface { + {{ range .GetProperties -}} + {{ with .GetField -}} + Set{{ .GetName }}({{ template "type_name" kv + "type" .GetType + "i_get" true + }}) {{ template "type_name" kv "msg" $msg "i" true }} + {{ end -}} + {{ with .GetOneof -}} + Set{{ .GetName }}({{ template "oneof_type_name" kv "msg" $msg "oneof" . }}) {{ template "type_name" kv "msg" $msg "i" true }} + {{ range .GetFields -}} + Set{{ .GetName }}({{ template "type_name" kv "type" .GetType "i_get" true }}) {{ template "type_name" kv "msg" $msg "i" true }} + {{ end -}} + {{ end -}} + {{ end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_list.gotmpl b/pkg/generator/templates/message_list.gotmpl new file mode 100644 index 0000000..78a9690 --- /dev/null +++ b/pkg/generator/templates/message_list.gotmpl @@ -0,0 +1,6 @@ +{{- define "message_list" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "LIST" -}} + {{ template "type_name" kv "msg" . "list" true }} []*{{ template "type_name" kv "msg" . }} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_map.gotmpl b/pkg/generator/templates/message_map.gotmpl new file mode 100644 index 0000000..e25baa0 --- /dev/null +++ b/pkg/generator/templates/message_map.gotmpl @@ -0,0 +1,6 @@ +{{- define "message_map" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "MAP" -}} + {{ template "type_name" kv "msg" . "map" true }}[K comparable] map[K]*{{ template "type_name" kv "msg" . }} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_marshal.gotmpl b/pkg/generator/templates/message_marshal.gotmpl new file mode 100644 index 0000000..4fcc2c9 --- /dev/null +++ b/pkg/generator/templates/message_marshal.gotmpl @@ -0,0 +1,8 @@ +{{- define "message_marshal" -}} + {{ if is_generate "MARSHAL" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + func (a *{{ template "type_name" kv "msg" . }})Marshal() ([]byte, error) { + return nil, nil + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_methods_get.gotmpl b/pkg/generator/templates/message_methods_get.gotmpl new file mode 100644 index 0000000..3ea4e48 --- /dev/null +++ b/pkg/generator/templates/message_methods_get.gotmpl @@ -0,0 +1,46 @@ +{{- define "message_methods_get" -}} + {{ if is_generate "GETTER" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ range .GetProperties -}} + {{ with .GetField -}} + func (a *{{ template "type_name" kv "msg" $msg }}) Get{{ .GetName }}() {{ template "type_name" kv + "type" .GetType + "i" true + }} { + {{ if or (render "type_is_custom" .GetType) (render "type_is_custom" .GetType.GetMap.GetValue) -}} + if a == nil { return {{ template "type_custom_zero_value" .GetType }} } + return a.{{ .GetName }} + {{ else -}} + if a == nil { return {{ .GetZeroValue }} } + {{ if or (and (is_map .GetType) (is_msg .GetType.GetMap.GetValue)) (and (is_msg .GetType) (.GetType.GetRepeated)) -}} + result := make({{ template "type_name" kv "type" .GetType "i" true }}, len(a.{{ .GetName }})) + for index, value := range a.{{ .GetName }} { + result[index] = value + } + return result + {{ else -}} + return a.{{ .GetName }} + {{ end -}} + {{ end -}} + } + {{ end -}} + {{ with .GetOneof -}} + {{- $oneof := . -}} + func (a *{{ template "type_name" kv "msg" $msg }}) Get{{ .GetName }}() {{ template "oneof_type_name" kv "msg" $msg "oneof" . }} { + if a == nil { return nil } + return a.{{ .GetName }} + } + {{ range .GetFields -}} + func (a *{{ template "type_name" kv "msg" $msg }}) Get{{ .GetName }}() {{ template "type_name" kv "type" .GetType "i_get" true }} { + if a == nil { return {{ .GetZeroValue }}} + if value, ok := a.{{ $oneof.GetName }}.(*{{ template "oneof_type_name" kv "msg" $msg "field" . }}); ok { + return value.{{ .GetName }} + } + return {{ .GetZeroValue }} + } + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_methods_set.gotmpl b/pkg/generator/templates/message_methods_set.gotmpl new file mode 100644 index 0000000..6747a21 --- /dev/null +++ b/pkg/generator/templates/message_methods_set.gotmpl @@ -0,0 +1,40 @@ +{{- define "message_methods_set" -}} + {{ if is_generate "SETTER" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ range .GetProperties -}} + {{ with .GetField -}} + func (a *{{ template "type_name" kv "msg" $msg }}) Set{{ .GetName }}( + {{- if or (.GetType.GetRepeated) (is_map .GetType) }}values{{ else }}value{{ end }} {{ template "type_name" kv + "type" .GetType + "i_get" true + -}} + ) {{ template "type_name" kv + "msg" $msg + "i" true + }} { + {{ template "field_set" . }} + } + {{ end -}} + {{ with .GetOneof -}} + {{- $oneof := . -}} + func (a *{{ template "type_name" kv "msg" $msg }}) Set{{ .GetName }}(value {{ template "oneof_type_name" kv + "msg" $msg + "oneof" . + }}) {{ template "type_name" kv "msg" $msg "i" true }} { + if a.{{ .GetName }} != nil { a.{{ .GetName }}.{{ template "func_name_oneof_return_to_pool" }}() } + a.{{ .GetName }} = value + return a + } + {{ range .GetFields -}} + func (a *{{ template "type_name" kv "msg" $msg }}) Set{{ .GetName }}(value {{ template "type_name" kv + "type" .GetType + "i_get" true + -}}) {{ template "type_name" kv "msg" $msg "i" true }} { + return a.Set{{ $oneof.GetName }}({{ template "func_name_oneof_new" kv "msg" $msg "field" . }}().Set{{ .GetName }}(value)) + } + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_new.gotmpl b/pkg/generator/templates/message_new.gotmpl new file mode 100644 index 0000000..705f9c6 --- /dev/null +++ b/pkg/generator/templates/message_new.gotmpl @@ -0,0 +1,12 @@ +{{- define "message_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "NEW" -}} + func {{ template "func_name_message_new" . }}() *{{ template "type_name" kv "msg" . }} { + {{- if .GetMemPoolMessage -}} + return {{ template "pool_name_message" . }}.Get().(*{{ template "type_name" kv "msg" . }}) + {{- else -}} + return {{ template "message_constructor" . }} + {{- end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_pool.gotmpl b/pkg/generator/templates/message_pool.gotmpl new file mode 100644 index 0000000..f2f9f94 --- /dev/null +++ b/pkg/generator/templates/message_pool.gotmpl @@ -0,0 +1,8 @@ +{{- define "message_pool" -}} + {{ if is_generate "POOL" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if .GetMemPoolMessage -}} + {{ template "pool_name_message" . }} = &{{ import "sync" }}.Pool{New: func() any { return {{ template "message_constructor" . }} }} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_proto_message.gotmpl b/pkg/generator/templates/message_proto_message.gotmpl new file mode 100644 index 0000000..a5e10e2 --- /dev/null +++ b/pkg/generator/templates/message_proto_message.gotmpl @@ -0,0 +1,6 @@ +{{- define "message_proto_message" -}} + {{ if is_generate "PROTO_MESSAGE" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + func (a *{{ template "type_name" kv "msg" . }}) ProtoMessage() {} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_reset.gotmpl b/pkg/generator/templates/message_reset.gotmpl new file mode 100644 index 0000000..cee2708 --- /dev/null +++ b/pkg/generator/templates/message_reset.gotmpl @@ -0,0 +1,32 @@ +{{- define "message_reset" -}} + {{ if is_generate "RESET" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + func (a *{{ template "type_name" kv "msg" . }}) Reset() { + {{- if gt (len .GetProperties) 0}} + if a == nil { return } + a.reset() + {{- end }} + } + func (a *{{ template "type_name" kv "msg" . }}) reset() { + {{- if gt (len .GetProperties) 0}} + {{ range .GetProperties -}} + {{ with .GetField -}} + {{ if not (render "type_is_custom" .GetType) -}} + {{ if and (.GetType.GetRepeated) (is_msg .GetType) -}} + {{ template "list_return_to_pool_pointer" . }} + {{ else if and (is_map .GetType) (is_msg .GetType.GetMap.GetValue) (not (render "type_is_custom" .GetType.GetMap.GetValue)) -}} + if a.{{ .GetName }} != nil { a.{{ .GetName }}.{{ template "func_name_map_return_to_pool" }}() } + {{ else if is_msg .GetType -}} + if a.{{ .GetName }} != nil { a.{{ .GetName }}.{{ template "func_name_message_return_to_pool" }}() } + {{ end -}} + {{ end -}} + {{ end -}} + {{ with .GetOneof -}} + if a.{{ .GetName }} != nil { a.{{ .GetName }}.{{ template "func_name_oneof_return_to_pool" }}() } + {{ end -}} + {{ end -}} + *a = {{ .GetName }}{} + {{- end }} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_return_to_pool.gotmpl b/pkg/generator/templates/message_return_to_pool.gotmpl new file mode 100644 index 0000000..5585d7d --- /dev/null +++ b/pkg/generator/templates/message_return_to_pool.gotmpl @@ -0,0 +1,14 @@ +{{- define "message_return_to_pool" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "RETURN_TO_POOL" -}} + func (a *{{ template "type_name" kv "msg" . }}){{ template "func_name_message_return_to_pool" }}() { + {{ if gt (len .GetProperties) 0 -}} + if a == nil { return } + a.reset() + {{ if .GetMemPoolMessage -}} + {{ template "pool_name_message" . }}.Put(a) + {{ end -}} + {{ end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_string.gotmpl b/pkg/generator/templates/message_string.gotmpl new file mode 100644 index 0000000..ab5e27a --- /dev/null +++ b/pkg/generator/templates/message_string.gotmpl @@ -0,0 +1,9 @@ +{{- define "message_string" -}} + {{ if is_generate "STRING" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + func (a *{{ template "type_name" kv "msg" . }}) String() string { + if a == nil { return "" } + return {{ import "fmt" -}}.Sprintf("%+v", a){{/* TODO: Implement proper string */}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_struct.gotmpl b/pkg/generator/templates/message_struct.gotmpl new file mode 100644 index 0000000..d33419e --- /dev/null +++ b/pkg/generator/templates/message_struct.gotmpl @@ -0,0 +1,28 @@ +{{- define "message_struct" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{ if is_generate "STRUCT" -}} + {{- $msg := . -}} + {{ range (lines .GetComments) -}} + //{{ . }} + {{ end -}} + {{ template "type_name" kv "msg" . }} struct { + {{- range .GetProperties -}} + {{ with .GetField -}} + {{ range (lines .GetComments) -}} + //{{ . }} + {{ end -}} + {{ .GetName }} {{ template "type_name" kv "type" .GetType }} {{ template "field_tags" . }} + {{ if and (.GetType.Repeated) (is_msg .GetType) (not (render "type_is_custom" .GetType)) -}} + p{{ .GetName }} *{{ template "type_name" kv "type" .GetType "list" true }} `` + {{ end -}} + {{ end -}} + {{ with .GetOneof -}} + {{ range (lines .GetComments) -}} + //{{ . }} + {{ end -}} + {{ .GetName }} {{ template "oneof_type_name" kv "msg" $msg "oneof" . }} {{ template "oneof_tags" . }} + {{ end -}} + {{ end -}} + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/message_unmarshal.gotmpl b/pkg/generator/templates/message_unmarshal.gotmpl new file mode 100644 index 0000000..1379b1f --- /dev/null +++ b/pkg/generator/templates/message_unmarshal.gotmpl @@ -0,0 +1,118 @@ +{{- define "message_unmarshal" -}} + {{ if is_generate "UNMARSHAL" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + func (a *{{ template "type_name" kv "msg" . }}){{ template "func_name_message_unmarshal" }}(data []byte) error { + {{ if gt (len .GetProperties) 0 -}} + {{- /* + { // $item + "number": 0, + "unmarshal": "", + "link": "" + } + */ -}} + {{- $items := arr arr arr arr arr -}} + {{ range .GetProperties -}} + {{ with .GetField -}} + {{- $field := . -}} + {{- $packedList := arr false -}} + {{ if .GetType.GetRepeated -}} + {{- $packedList = append $packedList true -}} + {{ end -}} + {{ range $packedList -}} + {{- $packed := . -}} + {{ range arr "field_unmarshal_varint" "field_unmarshal_len" "field_unmarshal_i64" "field_unmarshal_i32" -}} + {{- $param := kv + "msg" $msg + "field" $field + "type" $field.GetType + "number" $field.GetNumber + "packed" $packed + "setInField" (not $field.GetType.GetRepeated) + "valueName" "value" + "valueLength" "valueLength" + "valueCreate" true + "fieldName" (printf "%s.%s" $msg.GetName $field.GetName) + "errorUnexpectedEndLength" (render "error_unexpected_end_of_field_length" (printf "%s.%s" $msg.GetName $field.GetName)) + "errorUnexpectedEndValue" (render "error_unexpected_end_of_field_value" (printf "%s.%s" $msg.GetName $field.GetName)) + "errorUnexpectedEnd" (render "error_unexpected_end_of_field_value" (printf "%s.%s" $msg.GetName $field.GetName)) + "errorIncorrectLength" (render "error_incorrect_of_field_length" (printf "%s.%s" $msg.GetName $field.GetName)) + -}} + {{ with render . $param -}} + {{- $index := sub (len (pack_field_num_bytes $field.GetNumber $field.GetType.GetInProto $packed)) 1 -}} + {{- $item := (kv + "number" (pack_field_num_int $field.GetNumber $field.GetType.GetInProto $packed) + "unmarshal" . + "link" (render "field_set_unmarshal_result" (kv "field" $field "result" (get $param "result"))) + ) -}} + {{- set $items $index (append (get $items $index) $item) -}} + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} + {{ with .GetOneof -}} + {{ range .GetFields -}} + {{- $field := . -}} + {{ range arr "field_unmarshal_varint" "field_unmarshal_len" "field_unmarshal_i64" "field_unmarshal_i32" -}} + {{- $param := kv + "msg" $msg + "field" $field + "type" $field.GetType + "number" $field.GetNumber + "packed" false + "valueName" "value" + "valueLength" "valueLength" + "valueCreate" true + "fieldName" (printf "%s.%s" $msg.GetName $field.GetName) + "errorUnexpectedEndLength" (render "error_unexpected_end_of_field_length" (printf "%s.%s" $msg.GetName $field.GetName)) + "errorUnexpectedEndValue" (render "error_unexpected_end_of_field_value" (printf "%s.%s" $msg.GetName $field.GetName)) + "errorUnexpectedEnd" (render "error_unexpected_end_of_field_value" (printf "%s.%s" $msg.GetName $field.GetName)) + "errorIncorrectLength" (render "error_incorrect_of_field_length" (printf "%s.%s" $msg.GetName $field.GetName)) + -}} + {{ with render . $param -}} + {{- $index := sub (len (pack_field_num_bytes $field.GetNumber $field.GetType.GetInProto false)) 1 -}} + {{- $item := (kv + "number" (pack_field_num_int $field.GetNumber $field.GetType.GetInProto false) + "unmarshal" . + "link" (render "field_set_unmarshal_result" (kv "oneof" $field "result" (get $param "result"))) + ) -}} + {{- set $items $index (append (get $items $index) $item) -}} + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} + + var index int + for len(data) > index { + switch { + {{ range $index, $value := $items -}} + {{ if $value -}} + case len(data) > index{{ if $index }}+{{ $index }}{{ end }} && data[index{{ if $index }}+{{ $index }}{{ end }}] < 128: + index += {{ add $index 1 }} + switch {{ if eq $index 0 -}} + data[index-1] + {{- else if eq $index 1 -}} + uint16(data[index-2]) | uint16(data[index-1])<<8 + {{- else if eq $index 2 -}} + uint32(data[index-3]) | uint32(data[index-2])<<8 | uint32(data[index-1])<<16 + {{- else if eq $index 3 -}} + uint32(data[index-4]) | uint32(data[index-3])<<8 | uint32(data[index-2])<<16 | uint32(data[index-1])<<24 + {{- end }} { + {{ range $value -}} + case {{ .number }}: + {{ .unmarshal -}} + {{ .link }} + {{ end -}} + } + {{ end -}} + {{ end -}} + default: + return {{ template "error_unexpected_end_of_field_number" }} + } + } + {{ end -}} + return nil + } + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/oneof_methods.gotmpl b/pkg/generator/templates/oneof_methods.gotmpl new file mode 100644 index 0000000..86e0a69 --- /dev/null +++ b/pkg/generator/templates/oneof_methods.gotmpl @@ -0,0 +1,53 @@ +{{- define "oneof_methods" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ range .GetProperties -}} + {{ with .GetOneof -}} + {{- $oneof := . -}} + {{ range .GetFields }} + {{ if is_generate "RETURN_TO_POOL" -}} + func (a *{{ template "oneof_type_name" kv "msg" $msg "field" . }}){{ template "func_name_oneof_return_to_pool" }}(){ + if a == nil { return } // TODO rathil del??? + {{ if is_msg .GetType -}} + if a.{{ .GetName }} != nil { a.{{ .GetName }}.{{ template "func_name_oneof_return_to_pool" }}() } + {{ end -}} + *a = {{ template "oneof_type_name" kv "msg" $msg "field" . }}{} + {{ if $oneof.GetMemPool -}} + {{ template "pool_name_oneof" kv "msg" $msg "oneof" . }}.Put(a) + {{ end -}} + } + {{ end -}} + {{ if is_generate "STRUCT" -}} + func (*{{ template "oneof_type_name" kv "msg" $msg "field" . }})oneof{{ template "oneof_type_name" kv "msg" $msg "field" $oneof }}(){} + {{ end -}} + {{ if is_generate "MARSHAL" -}} + func (a *{{ template "oneof_type_name" kv "msg" $msg "field" . }})marshalTo([]byte) (int, error) { return 0, nil } // TODO rathil marshalTo + {{ end -}} + {{ if is_generate "SIZE" -}} + func (a *{{ template "oneof_type_name" kv "msg" $msg "field" . }})size() int { + if a == nil { return 0 } + if a.{{ .GetName }} == {{ .GetZeroValue }} { return 0 } + return 0 // TODO rathil size + } + {{ end -}} + {{ if is_generate "GETTER" -}} + func (a *{{ template "oneof_type_name" kv "msg" $msg "field" . }}) Get{{ .GetName }}() {{ template "type_name" kv + "type" .GetType + "i_get" true + -}} { + if a == nil { return {{ .GetZeroValue }} } + return a.{{ .GetName }} + } + {{ end -}} + {{ if is_generate "SETTER" -}} + func (a *{{ template "oneof_type_name" kv "msg" $msg "field" . }}) Set{{ .GetName }}(value {{ template "type_name" kv + "type" .GetType + "i_get" true + -}}) {{ template "oneof_type_name" kv "msg" $msg "oneof" $oneof }} { + {{ template "field_set" . }} + } + {{ end -}} + {{ end }} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/oneof_new.gotmpl b/pkg/generator/templates/oneof_new.gotmpl new file mode 100644 index 0000000..e36a044 --- /dev/null +++ b/pkg/generator/templates/oneof_new.gotmpl @@ -0,0 +1,20 @@ +{{- define "oneof_new" -}} + {{ if is_generate "NEW" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ range .GetProperties -}} + {{ with .GetOneof -}} + {{- $oneof := . -}} + {{ range .GetFields -}} + func {{ template "func_name_oneof_new" kv "msg" $msg "field" . }}() *{{ template "oneof_type_name" kv "msg" $msg "field" . }} { + {{ if $oneof.GetMemPool -}} + return {{ template "pool_name_oneof" kv "msg" $msg "oneof" . }}.Get().(*{{ template "oneof_type_name" kv "msg" $msg "field" . }}) + {{ else -}} + return &{{ template "oneof_type_name" kv "msg" $msg "field" . }}{} + {{ end -}} + } + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/oneof_pools.gotmpl b/pkg/generator/templates/oneof_pools.gotmpl new file mode 100644 index 0000000..8e00552 --- /dev/null +++ b/pkg/generator/templates/oneof_pools.gotmpl @@ -0,0 +1,17 @@ +{{- define "oneof_pools" -}} + {{ if is_generate "POOL" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ range .GetProperties -}} + {{ with .GetOneof -}} + {{ if .GetMemPool -}} + {{ range .GetFields -}} + {{ template "pool_name_oneof" kv "msg" $msg "oneof" . }} = &{{ import "sync" -}}.Pool{ + New: func() any { return &{{ template "oneof_type_name" kv "msg" $msg "field" . }}{} }, + } + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/oneof_tags.gotmpl b/pkg/generator/templates/oneof_tags.gotmpl new file mode 100644 index 0000000..8a5ce5b --- /dev/null +++ b/pkg/generator/templates/oneof_tags.gotmpl @@ -0,0 +1,13 @@ +{{- define "oneof_tags" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_OneOf*/ -}} + {{- $separator := "" -}} + ` + {{- range $key, $value := .GetTags -}} + {{- $separator -}}{{- $key -}} + {{- $separator = "," -}} + {{- if not (eq $value "") -}} + :"{{- $value -}}" + {{- end -}} + {{- end -}} + ` +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/oneof_type_name.gotmpl b/pkg/generator/templates/oneof_type_name.gotmpl new file mode 100644 index 0000000..d07a5f4 --- /dev/null +++ b/pkg/generator/templates/oneof_type_name.gotmpl @@ -0,0 +1,7 @@ +{{- define "oneof_type_name" -}} + {{- if .oneof -}} + {{ template "type_name" kv "msg" .msg "i" true }}Oneof{{ .oneof.GetName }} + {{- else if .field -}} + {{ .msg.GetName }}Oneof{{ .field.GetName }} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/oneof_types.gotmpl b/pkg/generator/templates/oneof_types.gotmpl new file mode 100644 index 0000000..e71451e --- /dev/null +++ b/pkg/generator/templates/oneof_types.gotmpl @@ -0,0 +1,26 @@ +{{- define "oneof_types" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- $msg := . -}} + {{ range .GetProperties -}} + {{ with .GetOneof -}} + {{ if is_generate "INTERFACE" -}} + {{ template "oneof_type_name" kv "msg" $msg "oneof" . }} interface { + {{ template "func_name_oneof_return_to_pool" }}() + oneof{{ template "oneof_type_name" kv "msg" $msg "field" . }}() + marshalTo([]byte) (int, error) + size() int + } + {{ end -}} + {{ if is_generate "STRUCT" -}} + {{ range .GetFields -}} + {{ template "oneof_type_name" kv "msg" $msg "field" . }} struct { + {{ range (lines .GetComments) -}} + //{{ . }} + {{ end -}} + {{ .GetName }} {{ template "type_name" kv "type" .GetType }} {{ template "field_tags" . }} + } + {{ end -}} + {{ end -}} + {{ end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/pool_name_list.gotmpl b/pkg/generator/templates/pool_name_list.gotmpl new file mode 100644 index 0000000..87994cb --- /dev/null +++ b/pkg/generator/templates/pool_name_list.gotmpl @@ -0,0 +1,4 @@ +{{- define "pool_name_list" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + poolList{{ template "type_name" kv "msg" . }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/pool_name_map.gotmpl b/pkg/generator/templates/pool_name_map.gotmpl new file mode 100644 index 0000000..0608f8c --- /dev/null +++ b/pkg/generator/templates/pool_name_map.gotmpl @@ -0,0 +1,4 @@ +{{- define "pool_name_map" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + poolMap{{ template "type_name" kv "msg" . }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/pool_name_message.gotmpl b/pkg/generator/templates/pool_name_message.gotmpl new file mode 100644 index 0000000..df35407 --- /dev/null +++ b/pkg/generator/templates/pool_name_message.gotmpl @@ -0,0 +1,4 @@ +{{- define "pool_name_message" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + pool{{ template "type_name" kv "msg" . }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/pool_name_oneof.gotmpl b/pkg/generator/templates/pool_name_oneof.gotmpl new file mode 100644 index 0000000..6b385d9 --- /dev/null +++ b/pkg/generator/templates/pool_name_oneof.gotmpl @@ -0,0 +1,3 @@ +{{- define "pool_name_oneof" -}} + pool{{ .msg.GetName }}Oneof{{ .oneof.GetName }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_convert_to.gotmpl b/pkg/generator/templates/type_convert_to.gotmpl new file mode 100644 index 0000000..d457fd8 --- /dev/null +++ b/pkg/generator/templates/type_convert_to.gotmpl @@ -0,0 +1,4 @@ +{{- define "type_convert_to" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{- template "field_type_path" . }}{{ template "func_name_message_convert_to" .GetReflect }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_custom.gotmpl b/pkg/generator/templates/type_custom.gotmpl new file mode 100644 index 0000000..06186d3 --- /dev/null +++ b/pkg/generator/templates/type_custom.gotmpl @@ -0,0 +1,19 @@ +{{- define "type_custom" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{ if and (eq .GetReflect.GetName "UUID") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- if .GetRepeated -}}[]{{- end -}} + {{- import "github.com/google/uuid" "uuid" -}}.UUID + {{- else if and (eq .GetReflect.GetName "Time") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- if .GetRepeated -}}[]{{- end -}} + {{- import "time" -}}.Time + {{- else if and (eq .GetReflect.GetName "Duration") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- if .GetRepeated -}}[]{{- end -}} + {{- import "time" -}}.Duration + {{- else if and (eq .GetReflect.GetName "BigInt") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- if .GetRepeated -}}[]{{- end -}} + {{- import "big" -}}.Int + {{- else if and (eq .GetReflect.GetName "BigFloat") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- if .GetRepeated -}}[]{{- end -}} + {{- import "big" -}}.Float + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_custom_unmarshal.gotmpl b/pkg/generator/templates/type_custom_unmarshal.gotmpl new file mode 100644 index 0000000..8f5d664 --- /dev/null +++ b/pkg/generator/templates/type_custom_unmarshal.gotmpl @@ -0,0 +1,13 @@ +{{- define "type_custom_unmarshal" -}} + {{- $c := . -}} + {{- with .c.type -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{ if and (eq .GetReflect.GetName "UUID") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{ template "type_custom_unmarshal_uuid" $c -}} + {{ else if and (eq .GetReflect.GetName "Time") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{ else if and (eq .GetReflect.GetName "Duration") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{ else if and (eq .GetReflect.GetName "BigInt") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{ else if and (eq .GetReflect.GetName "BigFloat") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_custom_unmarshal_uuid.gotmpl b/pkg/generator/templates/type_custom_unmarshal_uuid.gotmpl new file mode 100644 index 0000000..f5d3ad6 --- /dev/null +++ b/pkg/generator/templates/type_custom_unmarshal_uuid.gotmpl @@ -0,0 +1,20 @@ +{{- define "type_custom_unmarshal_uuid" -}} + {{ if .c.valueCreate -}} + var {{ .c.valueName }} {{ import "github.com/google/uuid" "uuid" -}}.UUID + {{ end -}} + if data[index] == {{ pack_field_num_int 1 2 false }} && data[index+1] < 128 { + switch data[index+1] { + case 16: + {{ .c.valueName }} = {{- import "github.com/google/uuid" "uuid" -}}.UUID(data[index+2 : index+2+int(data[index+1])]) + default: + var err error + if {{ .c.valueName }}, err = uuid.ParseBytes(data[index+2 : index+2+int(data[index+1])]); err != nil { + return {{ template "error_unmarshal_custom_type_uuid" kv "field" .c.fieldName "err" "err" }} + } + } + index += {{ .valueLength }} + }else{ + index += {{ .valueLength }} + // TODO rathil fallback for skip unknown fields + } +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_custom_zero_value.gotmpl b/pkg/generator/templates/type_custom_zero_value.gotmpl new file mode 100644 index 0000000..6e13a1c --- /dev/null +++ b/pkg/generator/templates/type_custom_zero_value.gotmpl @@ -0,0 +1,22 @@ +{{- define "type_custom_zero_value" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{ if or (.GetRepeated) (.GetMap) -}} + nil + {{ else -}} + {{ if and (eq .GetReflect.GetName "UUID") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- import "github.com/google/uuid" "uuid" -}}.Nil + {{- end -}} + {{ if and (eq .GetReflect.GetName "Time") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + {{- import "time" -}}.Time{} + {{- end -}} + {{ if and (eq .GetReflect.GetName "Duration") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + 0 + {{- end -}} + {{ if and (eq .GetReflect.GetName "BigInt") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + nil + {{- end -}} + {{ if and (eq .GetReflect.GetName "BigFloat") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + nil + {{- end -}} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_is_custom.gotmpl b/pkg/generator/templates/type_is_custom.gotmpl new file mode 100644 index 0000000..3146a92 --- /dev/null +++ b/pkg/generator/templates/type_is_custom.gotmpl @@ -0,0 +1,14 @@ +{{- define "type_is_custom" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{- if and (eq .GetReflect.GetName "UUID") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + true + {{- else if and (eq .GetReflect.GetName "Time") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + true + {{- else if and (eq .GetReflect.GetName "Duration") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + true + {{- else if and (eq .GetReflect.GetName "BigInt") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + true + {{- else if and (eq .GetReflect.GetName "BigFloat") (eq .GetReflect.GetDependency.GetPath "github.com/e-tape/litepb/proto") -}} + true + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_name.gotmpl b/pkg/generator/templates/type_name.gotmpl new file mode 100644 index 0000000..13e58aa --- /dev/null +++ b/pkg/generator/templates/type_name.gotmpl @@ -0,0 +1,72 @@ +{{- define "type_name" -}} + {{- $c := . -}} + {{ with .type -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{- $custom := render "type_custom" . -}} + {{ if not $custom -}} + {{- if is_map . -}} + {{- if and (is_msg .GetMap.GetValue) (not (or ($c.i) ($c.i_get) ($c.i_set))) (not (render "type_is_custom" .GetMap.GetValue)) -}} + Map{{ .GetMap.GetValue.GetReflect.GetName -}} + [{{ template "type_name" kv "type" .GetMap.GetKey }}] + {{- else -}} + map[{{ template "type_name" kv "type" .GetMap.GetKey "i" $c.i "i_get" $c.i_get "no_pointer" $c.no_pointer }}] + {{- template "type_name" kv "type" .GetMap.GetValue "i" $c.i "i_get" $c.i_get "no_pointer" $c.no_pointer }} + {{- end -}} + {{- else if is_msg . -}} + {{- if .GetRepeated -}} + {{- if not $c.list -}} + [] + {{- if not (or ($c.i) ($c.i_get) ($c.no_pointer)) -}} + * + {{- end -}} + {{- end -}} + {{- else if not (or ($c.i) ($c.i_get) ($c.no_pointer)) -}} + * + {{- end -}} + {{- with import .GetReflect.GetDependency.GetPath -}} + {{- . -}}. + {{- end -}} + {{- if or ($c.i) ($c.i_get) -}} + I + {{- end -}} + {{- if and .GetRepeated $c.list -}} + List{{ .GetReflect.GetName }} + {{- else -}} + {{- .GetReflect.GetName -}} + {{- end -}} + {{- if $c.i_get -}} + Get + {{- end -}} + {{- if $c.i_set -}} + Set + {{- end -}} + {{- else -}} + {{- if .GetRepeated -}} + [] + {{- end -}} + {{- with import .GetReflect.GetDependency.GetPath -}} + {{- . -}}. + {{- end -}} + {{- .GetReflect.GetName -}} + {{- end -}} + {{ else -}} + {{- $custom -}} + {{ end -}} + {{ end -}} + {{ with .msg -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message*/ -}} + {{- if $c.i_get -}} + I{{ .GetName }}Get + {{- else if $c.i_set -}} + I{{ .GetName }}Set + {{- else if $c.i -}} + I{{ .GetName }} + {{- else if $c.list -}} + List{{ .GetName }} + {{- else if $c.map -}} + Map{{ .GetName }} + {{- else -}} + {{ .GetName }} + {{- end -}} + {{ end -}} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/type_new.gotmpl b/pkg/generator/templates/type_new.gotmpl new file mode 100644 index 0000000..55c7610 --- /dev/null +++ b/pkg/generator/templates/type_new.gotmpl @@ -0,0 +1,4 @@ +{{- define "type_new" -}} + {{- /*gotype: github.com/e-tape/litepb/proto.Message_Field_Type*/ -}} + {{- template "field_type_path" . }}{{ template "func_name_message_new" .GetReflect }} +{{- end -}} \ No newline at end of file diff --git a/pkg/generator/templates/types.tmpl b/pkg/generator/templates/types.tmpl deleted file mode 100644 index 6630fb8..0000000 --- a/pkg/generator/templates/types.tmpl +++ /dev/null @@ -1,45 +0,0 @@ -{{ define "types" }} - -{{ range . -}} -{{- range (lines .Comments) -}}{{/**/}} -//{{ . }} -{{- end }} -type {{ .Name }} struct { -{{- range .Fields -}}{{/**/}} - {{- range (lines .Comments) -}}{{/**/}} - //{{ . }} - {{- end }} - {{ .Name }} {{ .Type }} `json:"{{ .SnakeName }}"` -{{- end }} -} - -func (m *{{ .Name }}) Reset() { - *m = {{ .Name }}{} -} - -func (m *{{ .Name }}) ProtoMessage() {} - -func (m *{{ .Name }}) String() string { - if m == nil { - return "" - } - return fmt.Sprintf("%+v", m){{/* TODO: Implement proper string */}} -} - -{{ $type := . }} -{{- range .Fields -}}{{/**/}} -func (m *{{ $type.Name }}) Get{{ .Name }}() {{ .Type }} { - if m != nil { - return m.{{ .Name }} - } - return {{ .ZeroValue }} -} - -func (m *{{ $type.Name }}) Set{{ .Name }}(value {{ .Type }}) { - m.{{ .Name }} = value -} -{{ end }} - -{{ end }} - -{{ end }} diff --git a/pkg/generator/types.go b/pkg/generator/types.go new file mode 100644 index 0000000..950a145 --- /dev/null +++ b/pkg/generator/types.go @@ -0,0 +1,31 @@ +package generator + +import ( + "regexp" + + "github.com/e-tape/litepb/config" + litepb "github.com/e-tape/litepb/proto" + "google.golang.org/protobuf/types/descriptorpb" + "google.golang.org/protobuf/types/pluginpb" +) + +// Generator of protobuf bindings +type ( + Generator struct { + cfg config.Config + request *pluginpb.CodeGeneratorRequest + allFiles map[Path]*generatorFile + allTypes map[Package]*litepb.Message_Field_Type_Reflect + mapTypes map[Package]*litepb.Message_Field_Type_Map + aliasRegex *regexp.Regexp + } + Path = string + Package = string + // generatorFile of protobuf bindings for single file + generatorFile struct { + *Generator + proto *litepb.File + messages []*litepb.Message + sourceCodeInfo *descriptorpb.SourceCodeInfo + } +) diff --git a/proto/big.pb.go b/proto/big.pb.go new file mode 100644 index 0000000..6a6ecfe --- /dev/null +++ b/proto/big.pb.go @@ -0,0 +1,209 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/big.proto + +package litepb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Implementation of big.Int transfer +type BigInt struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // big.Int data in bytes + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *BigInt) Reset() { + *x = BigInt{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_big_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BigInt) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BigInt) ProtoMessage() {} + +func (x *BigInt) ProtoReflect() protoreflect.Message { + mi := &file_proto_big_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BigInt.ProtoReflect.Descriptor instead. +func (*BigInt) Descriptor() ([]byte, []int) { + return file_proto_big_proto_rawDescGZIP(), []int{0} +} + +func (x *BigInt) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +// Implementation of big.Float transfer +type BigFloat struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // big.Float data in string + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *BigFloat) Reset() { + *x = BigFloat{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_big_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BigFloat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BigFloat) ProtoMessage() {} + +func (x *BigFloat) ProtoReflect() protoreflect.Message { + mi := &file_proto_big_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BigFloat.ProtoReflect.Descriptor instead. +func (*BigFloat) Descriptor() ([]byte, []int) { + return file_proto_big_proto_rawDescGZIP(), []int{1} +} + +func (x *BigFloat) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +var File_proto_big_proto protoreflect.FileDescriptor + +var file_proto_big_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x22, 0x1e, 0x0a, 0x06, 0x42, 0x69, 0x67, + 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x20, 0x0a, 0x08, 0x42, 0x69, 0x67, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x2d, 0x74, 0x61, 0x70, 0x65, + 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6c, 0x69, + 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_big_proto_rawDescOnce sync.Once + file_proto_big_proto_rawDescData = file_proto_big_proto_rawDesc +) + +func file_proto_big_proto_rawDescGZIP() []byte { + file_proto_big_proto_rawDescOnce.Do(func() { + file_proto_big_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_big_proto_rawDescData) + }) + return file_proto_big_proto_rawDescData +} + +var file_proto_big_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_proto_big_proto_goTypes = []interface{}{ + (*BigInt)(nil), // 0: litepb.BigInt + (*BigFloat)(nil), // 1: litepb.BigFloat +} +var file_proto_big_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_big_proto_init() } +func file_proto_big_proto_init() { + if File_proto_big_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_big_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BigInt); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_big_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BigFloat); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_big_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_big_proto_goTypes, + DependencyIndexes: file_proto_big_proto_depIdxs, + MessageInfos: file_proto_big_proto_msgTypes, + }.Build() + File_proto_big_proto = out.File + file_proto_big_proto_rawDesc = nil + file_proto_big_proto_goTypes = nil + file_proto_big_proto_depIdxs = nil +} diff --git a/proto/big.proto b/proto/big.proto new file mode 100644 index 0000000..38b6528 --- /dev/null +++ b/proto/big.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package litepb; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +// Implementation of big.Int transfer +message BigInt { + // big.Int data in bytes + bytes value = 1; +} + +// Implementation of big.Float transfer +message BigFloat { + // big.Float data in string + string value = 1; +} \ No newline at end of file diff --git a/proto/duration.pb.go b/proto/duration.pb.go new file mode 100644 index 0000000..8f317dd --- /dev/null +++ b/proto/duration.pb.go @@ -0,0 +1,146 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/duration.proto + +package litepb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Implementation of time.Duration transfer +type Duration struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Value of time.Duration + Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Duration) Reset() { + *x = Duration{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_duration_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Duration) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Duration) ProtoMessage() {} + +func (x *Duration) ProtoReflect() protoreflect.Message { + mi := &file_proto_duration_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Duration.ProtoReflect.Descriptor instead. +func (*Duration) Descriptor() ([]byte, []int) { + return file_proto_duration_proto_rawDescGZIP(), []int{0} +} + +func (x *Duration) GetValue() int64 { + if x != nil { + return x.Value + } + return 0 +} + +var File_proto_duration_proto protoreflect.FileDescriptor + +var file_proto_duration_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x22, 0x20, + 0x0a, 0x08, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, + 0x2d, 0x74, 0x61, 0x70, 0x65, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_proto_duration_proto_rawDescOnce sync.Once + file_proto_duration_proto_rawDescData = file_proto_duration_proto_rawDesc +) + +func file_proto_duration_proto_rawDescGZIP() []byte { + file_proto_duration_proto_rawDescOnce.Do(func() { + file_proto_duration_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_duration_proto_rawDescData) + }) + return file_proto_duration_proto_rawDescData +} + +var file_proto_duration_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_proto_duration_proto_goTypes = []interface{}{ + (*Duration)(nil), // 0: litepb.Duration +} +var file_proto_duration_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_duration_proto_init() } +func file_proto_duration_proto_init() { + if File_proto_duration_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_duration_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Duration); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_duration_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_duration_proto_goTypes, + DependencyIndexes: file_proto_duration_proto_depIdxs, + MessageInfos: file_proto_duration_proto_msgTypes, + }.Build() + File_proto_duration_proto = out.File + file_proto_duration_proto_rawDesc = nil + file_proto_duration_proto_goTypes = nil + file_proto_duration_proto_depIdxs = nil +} diff --git a/proto/duration.proto b/proto/duration.proto new file mode 100644 index 0000000..ee46274 --- /dev/null +++ b/proto/duration.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package litepb; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +// Implementation of time.Duration transfer +message Duration { + // Value of time.Duration + int64 value = 1; +} \ No newline at end of file diff --git a/proto/ethereum.pb.go b/proto/ethereum.pb.go new file mode 100644 index 0000000..a926c80 --- /dev/null +++ b/proto/ethereum.pb.go @@ -0,0 +1,223 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/ethereum.proto + +package litepb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Implementation of ethereum common.Address transfer +type Address struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Value of common.Address + Value [][]byte `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"` + Value1 [][]byte `protobuf:"bytes,2,rep,name=value1,proto3" json:"value1,omitempty"` +} + +func (x *Address) Reset() { + *x = Address{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_ethereum_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Address) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Address) ProtoMessage() {} + +func (x *Address) ProtoReflect() protoreflect.Message { + mi := &file_proto_ethereum_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Address.ProtoReflect.Descriptor instead. +func (*Address) Descriptor() ([]byte, []int) { + return file_proto_ethereum_proto_rawDescGZIP(), []int{0} +} + +func (x *Address) GetValue() [][]byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *Address) GetValue1() [][]byte { + if x != nil { + return x.Value1 + } + return nil +} + +// Implementation of ethereum common.Hash transfer +type Hash struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // value of common.Hash + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Hash) Reset() { + *x = Hash{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_ethereum_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Hash) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hash) ProtoMessage() {} + +func (x *Hash) ProtoReflect() protoreflect.Message { + mi := &file_proto_ethereum_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hash.ProtoReflect.Descriptor instead. +func (*Hash) Descriptor() ([]byte, []int) { + return file_proto_ethereum_proto_rawDescGZIP(), []int{1} +} + +func (x *Hash) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +var File_proto_ethereum_proto protoreflect.FileDescriptor + +var file_proto_ethereum_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x1a, 0x13, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x04, 0xf8, + 0xe7, 0x07, 0x14, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x06, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x31, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x42, 0x04, 0xf8, 0xe7, 0x07, 0x14, + 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x3a, 0x06, 0xf8, 0xe7, 0x07, 0xa8, 0xc3, 0x01, + 0x22, 0x22, 0x0a, 0x04, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xf8, 0xe7, 0x07, 0x20, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x65, 0x2d, 0x74, 0x61, 0x70, 0x65, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_ethereum_proto_rawDescOnce sync.Once + file_proto_ethereum_proto_rawDescData = file_proto_ethereum_proto_rawDesc +) + +func file_proto_ethereum_proto_rawDescGZIP() []byte { + file_proto_ethereum_proto_rawDescOnce.Do(func() { + file_proto_ethereum_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_ethereum_proto_rawDescData) + }) + return file_proto_ethereum_proto_rawDescData +} + +var file_proto_ethereum_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_proto_ethereum_proto_goTypes = []interface{}{ + (*Address)(nil), // 0: litepb.Address + (*Hash)(nil), // 1: litepb.Hash +} +var file_proto_ethereum_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_ethereum_proto_init() } +func file_proto_ethereum_proto_init() { + if File_proto_ethereum_proto != nil { + return + } + file_proto_options_proto_init() + if !protoimpl.UnsafeEnabled { + file_proto_ethereum_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Address); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_ethereum_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Hash); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_ethereum_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_ethereum_proto_goTypes, + DependencyIndexes: file_proto_ethereum_proto_depIdxs, + MessageInfos: file_proto_ethereum_proto_msgTypes, + }.Build() + File_proto_ethereum_proto = out.File + file_proto_ethereum_proto_rawDesc = nil + file_proto_ethereum_proto_goTypes = nil + file_proto_ethereum_proto_depIdxs = nil +} diff --git a/proto/ethereum.proto b/proto/ethereum.proto new file mode 100644 index 0000000..ac6f7d9 --- /dev/null +++ b/proto/ethereum.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package litepb; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +import "proto/options.proto"; + +// Implementation of ethereum common.Address transfer +message Address { + option (slice_packed_number) = 25000; + // Value of common.Address + repeated bytes value = 1 [(litepb.array_fixed_size) = 20]; + repeated bytes value1 = 2 [(litepb.array_fixed_size) = 20]; +} + +// Implementation of ethereum common.Hash transfer +message Hash { + // value of common.Hash + bytes value = 1 [(litepb.array_fixed_size) = 32]; +} \ No newline at end of file diff --git a/proto/litepb.yaml b/proto/litepb.yaml new file mode 100644 index 0000000..8d64c5f --- /dev/null +++ b/proto/litepb.yaml @@ -0,0 +1,5 @@ +source_relative: true +mem_pool_message_all: Active +mem_pool_list_all: Active +mem_pool_map_all: Active +mem_pool_oneof_all: Active \ No newline at end of file diff --git a/proto/options.pb.go b/proto/options.pb.go new file mode 100644 index 0000000..a6ad6d0 --- /dev/null +++ b/proto/options.pb.go @@ -0,0 +1,446 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/options.proto + +package litepb + +import ( + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Activity int32 + +const ( + Activity_Default Activity = 0 + Activity_Active Activity = 1 + Activity_Inactive Activity = 2 +) + +// Enum value maps for Activity. +var ( + Activity_name = map[int32]string{ + 0: "Default", + 1: "Active", + 2: "Inactive", + } + Activity_value = map[string]int32{ + "Default": 0, + "Active": 1, + "Inactive": 2, + } +) + +func (x Activity) Enum() *Activity { + p := new(Activity) + *p = x + return p +} + +func (x Activity) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Activity) Descriptor() protoreflect.EnumDescriptor { + return file_proto_options_proto_enumTypes[0].Descriptor() +} + +func (Activity) Type() protoreflect.EnumType { + return &file_proto_options_proto_enumTypes[0] +} + +func (x Activity) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Activity) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Activity(num) + return nil +} + +// Deprecated: Use Activity.Descriptor instead. +func (Activity) EnumDescriptor() ([]byte, []int) { + return file_proto_options_proto_rawDescGZIP(), []int{0} +} + +var file_proto_options_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15998, + Name: "litepb.mem_pool_message_all", + Tag: "varint,15998,opt,name=mem_pool_message_all,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15997, + Name: "litepb.mem_pool_list_all", + Tag: "varint,15997,opt,name=mem_pool_list_all,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15996, + Name: "litepb.mem_pool_map_all", + Tag: "varint,15996,opt,name=mem_pool_map_all,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15995, + Name: "litepb.mem_pool_oneof_all", + Tag: "varint,15995,opt,name=mem_pool_oneof_all,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FileOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15994, + Name: "litepb.unsafe_all", + Tag: "varint,15994,opt,name=unsafe_all,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 15999, + Name: "litepb.slice_packed_number", + Tag: "varint,15999,opt,name=slice_packed_number", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15998, + Name: "litepb.mem_pool_message", + Tag: "varint,15998,opt,name=mem_pool_message,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15997, + Name: "litepb.mem_pool_list", + Tag: "varint,15997,opt,name=mem_pool_list,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15996, + Name: "litepb.mem_pool_map", + Tag: "varint,15996,opt,name=mem_pool_map,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15995, + Name: "litepb.mem_pool_oneof", + Tag: "varint,15995,opt,name=mem_pool_oneof,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.MessageOptions)(nil), + ExtensionType: (*Activity)(nil), + Field: 15994, + Name: "litepb.unsafe", + Tag: "varint,15994,opt,name=unsafe,enum=litepb.Activity", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*int32)(nil), + Field: 15999, + Name: "litepb.array_fixed_size", + Tag: "varint,15999,opt,name=array_fixed_size", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 15998, + Name: "litepb.type", + Tag: "bytes,15998,opt,name=type", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 15997, + Name: "litepb.json_tag", + Tag: "bytes,15997,opt,name=json_tag", + Filename: "proto/options.proto", + }, + { + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 15996, + Name: "litepb.additional_tags", + Tag: "bytes,15996,opt,name=additional_tags", + Filename: "proto/options.proto", + }, +} + +// Extension fields to descriptor.FileOptions. +var ( + // Pool objects activity for all messages in this file + // + // optional litepb.Activity mem_pool_message_all = 15998; + E_MemPoolMessageAll = &file_proto_options_proto_extTypes[0] + // Pool objects activity for all messages list in this file + // + // optional litepb.Activity mem_pool_list_all = 15997; + E_MemPoolListAll = &file_proto_options_proto_extTypes[1] + // Pool objects activity for all messages map in this file + // + // optional litepb.Activity mem_pool_map_all = 15996; + E_MemPoolMapAll = &file_proto_options_proto_extTypes[2] + // Pool objects activity for all messages oneof in this file + // + // optional litepb.Activity mem_pool_oneof_all = 15995; + E_MemPoolOneofAll = &file_proto_options_proto_extTypes[3] + // Processing using unsafe + // + // optional litepb.Activity unsafe_all = 15994; + E_UnsafeAll = &file_proto_options_proto_extTypes[4] +) + +// Extension fields to descriptor.MessageOptions. +var ( + // Field number to be added to the message to transfer the length of all repeating fields. Default: 15999 + // + // optional int32 slice_packed_number = 15999; + E_SlicePackedNumber = &file_proto_options_proto_extTypes[5] + // Pool objects activity for message (has priority over options from FileOptions) + // + // optional litepb.Activity mem_pool_message = 15998; + E_MemPoolMessage = &file_proto_options_proto_extTypes[6] + // Pool objects activity for message list (has priority over options from FileOptions) + // + // optional litepb.Activity mem_pool_list = 15997; + E_MemPoolList = &file_proto_options_proto_extTypes[7] + // Pool objects activity for message map (has priority over options from FileOptions) + // + // optional litepb.Activity mem_pool_map = 15996; + E_MemPoolMap = &file_proto_options_proto_extTypes[8] + // Pool objects activity for message oneof (has priority over options from FileOptions) + // + // optional litepb.Activity mem_pool_oneof = 15995; + E_MemPoolOneof = &file_proto_options_proto_extTypes[9] + // Processing using unsafe + // + // optional litepb.Activity unsafe = 15994; + E_Unsafe = &file_proto_options_proto_extTypes[10] +) + +// Extension fields to descriptor.FieldOptions. +var ( + // Transforming a slice into a fixed-length array + // + // optional int32 array_fixed_size = 15999; + E_ArrayFixedSize = &file_proto_options_proto_extTypes[11] + // Change the declared type in the protobuf to your personal type + // + // optional string type = 15998; + E_Type = &file_proto_options_proto_extTypes[12] + // Field name when marshal to JSON + // + // optional string json_tag = 15997; + E_JsonTag = &file_proto_options_proto_extTypes[13] + // Additional tags + // + // optional string additional_tags = 15996; + E_AdditionalTags = &file_proto_options_proto_extTypes[14] +) + +var File_proto_options_proto protoreflect.FileDescriptor + +var file_proto_options_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x1a, 0x20, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2a, + 0x31, 0x0a, 0x08, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x44, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x10, 0x02, 0x3a, 0x60, 0x0a, 0x14, 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfe, 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, + 0x79, 0x52, 0x11, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x41, 0x6c, 0x6c, 0x3a, 0x5a, 0x0a, 0x11, 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, + 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfd, 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, + 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, + 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, + 0x3a, 0x58, 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x61, 0x70, + 0x5f, 0x61, 0x6c, 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0xfc, 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, + 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6d, 0x65, 0x6d, + 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x41, 0x6c, 0x6c, 0x3a, 0x5c, 0x0a, 0x12, 0x6d, 0x65, + 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x5f, 0x61, 0x6c, 0x6c, + 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfb, + 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, + 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x0f, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, + 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x41, 0x6c, 0x6c, 0x3a, 0x4e, 0x0a, 0x0a, 0x75, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfa, 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, + 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x09, 0x75, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x41, 0x6c, 0x6c, 0x3a, 0x50, 0x0a, 0x13, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xff, 0x7c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x50, 0x61, + 0x63, 0x6b, 0x65, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x5c, 0x0a, 0x10, 0x6d, 0x65, + 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xfe, 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, + 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3a, 0x56, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x5f, + 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfd, 0x7c, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x52, 0x0b, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, 0x4c, 0x69, 0x73, 0x74, + 0x3a, 0x54, 0x0a, 0x0c, 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x61, 0x70, + 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0xfc, 0x7c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, + 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x50, + 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x3a, 0x58, 0x0a, 0x0e, 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, + 0x6f, 0x6c, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfb, 0x7c, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, 0x4f, 0x6e, 0x65, 0x6f, 0x66, + 0x3a, 0x4a, 0x0a, 0x06, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfa, 0x7c, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x52, 0x06, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x3a, 0x48, 0x0a, 0x10, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x5f, 0x66, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xff, 0x7c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x61, 0x72, 0x72, 0x61, 0x79, 0x46, 0x69, 0x78, + 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x3a, 0x32, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfe, 0x7c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x39, 0x0a, 0x08, 0x6a, 0x73, + 0x6f, 0x6e, 0x5f, 0x74, 0x61, 0x67, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfd, 0x7c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6a, 0x73, + 0x6f, 0x6e, 0x54, 0x61, 0x67, 0x3a, 0x47, 0x0a, 0x0f, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfc, 0x7c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x42, 0x27, + 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x2d, 0x74, + 0x61, 0x70, 0x65, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, +} + +var ( + file_proto_options_proto_rawDescOnce sync.Once + file_proto_options_proto_rawDescData = file_proto_options_proto_rawDesc +) + +func file_proto_options_proto_rawDescGZIP() []byte { + file_proto_options_proto_rawDescOnce.Do(func() { + file_proto_options_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_options_proto_rawDescData) + }) + return file_proto_options_proto_rawDescData +} + +var file_proto_options_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_proto_options_proto_goTypes = []interface{}{ + (Activity)(0), // 0: litepb.Activity + (*descriptor.FileOptions)(nil), // 1: google.protobuf.FileOptions + (*descriptor.MessageOptions)(nil), // 2: google.protobuf.MessageOptions + (*descriptor.FieldOptions)(nil), // 3: google.protobuf.FieldOptions +} +var file_proto_options_proto_depIdxs = []int32{ + 1, // 0: litepb.mem_pool_message_all:extendee -> google.protobuf.FileOptions + 1, // 1: litepb.mem_pool_list_all:extendee -> google.protobuf.FileOptions + 1, // 2: litepb.mem_pool_map_all:extendee -> google.protobuf.FileOptions + 1, // 3: litepb.mem_pool_oneof_all:extendee -> google.protobuf.FileOptions + 1, // 4: litepb.unsafe_all:extendee -> google.protobuf.FileOptions + 2, // 5: litepb.slice_packed_number:extendee -> google.protobuf.MessageOptions + 2, // 6: litepb.mem_pool_message:extendee -> google.protobuf.MessageOptions + 2, // 7: litepb.mem_pool_list:extendee -> google.protobuf.MessageOptions + 2, // 8: litepb.mem_pool_map:extendee -> google.protobuf.MessageOptions + 2, // 9: litepb.mem_pool_oneof:extendee -> google.protobuf.MessageOptions + 2, // 10: litepb.unsafe:extendee -> google.protobuf.MessageOptions + 3, // 11: litepb.array_fixed_size:extendee -> google.protobuf.FieldOptions + 3, // 12: litepb.type:extendee -> google.protobuf.FieldOptions + 3, // 13: litepb.json_tag:extendee -> google.protobuf.FieldOptions + 3, // 14: litepb.additional_tags:extendee -> google.protobuf.FieldOptions + 0, // 15: litepb.mem_pool_message_all:type_name -> litepb.Activity + 0, // 16: litepb.mem_pool_list_all:type_name -> litepb.Activity + 0, // 17: litepb.mem_pool_map_all:type_name -> litepb.Activity + 0, // 18: litepb.mem_pool_oneof_all:type_name -> litepb.Activity + 0, // 19: litepb.unsafe_all:type_name -> litepb.Activity + 0, // 20: litepb.mem_pool_message:type_name -> litepb.Activity + 0, // 21: litepb.mem_pool_list:type_name -> litepb.Activity + 0, // 22: litepb.mem_pool_map:type_name -> litepb.Activity + 0, // 23: litepb.mem_pool_oneof:type_name -> litepb.Activity + 0, // 24: litepb.unsafe:type_name -> litepb.Activity + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 15, // [15:25] is the sub-list for extension type_name + 0, // [0:15] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_options_proto_init() } +func file_proto_options_proto_init() { + if File_proto_options_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_options_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 15, + NumServices: 0, + }, + GoTypes: file_proto_options_proto_goTypes, + DependencyIndexes: file_proto_options_proto_depIdxs, + EnumInfos: file_proto_options_proto_enumTypes, + ExtensionInfos: file_proto_options_proto_extTypes, + }.Build() + File_proto_options_proto = out.File + file_proto_options_proto_rawDesc = nil + file_proto_options_proto_goTypes = nil + file_proto_options_proto_depIdxs = nil +} diff --git a/proto/options.proto b/proto/options.proto new file mode 100644 index 0000000..6418230 --- /dev/null +++ b/proto/options.proto @@ -0,0 +1,50 @@ +syntax = "proto2"; + +package litepb; + +import "google/protobuf/descriptor.proto"; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +extend google.protobuf.FileOptions { + // Pool objects activity for all messages in this file + optional Activity mem_pool_message_all = 15998; + // Pool objects activity for all messages list in this file + optional Activity mem_pool_list_all = 15997; + // Pool objects activity for all messages map in this file + optional Activity mem_pool_map_all = 15996; + // Pool objects activity for all messages oneof in this file + optional Activity mem_pool_oneof_all = 15995; + // Processing using unsafe + optional Activity unsafe_all = 15994; +} +extend google.protobuf.MessageOptions { + // Field number to be added to the message to transfer the length of all repeating fields. Default: 15999 + optional int32 slice_packed_number = 15999; + // Pool objects activity for message (has priority over options from FileOptions) + optional Activity mem_pool_message = 15998; + // Pool objects activity for message list (has priority over options from FileOptions) + optional Activity mem_pool_list = 15997; + // Pool objects activity for message map (has priority over options from FileOptions) + optional Activity mem_pool_map = 15996; + // Pool objects activity for message oneof (has priority over options from FileOptions) + optional Activity mem_pool_oneof = 15995; + // Processing using unsafe + optional Activity unsafe = 15994; +} +extend google.protobuf.FieldOptions { + // Transforming a slice into a fixed-length array + optional int32 array_fixed_size = 15999; + // Change the declared type in the protobuf to your personal type + optional string type = 15998; + // Field name when marshal to JSON + optional string json_tag = 15997; + // Additional tags + optional string additional_tags = 15996; +} + +enum Activity { + Default = 0; + Active = 1; + Inactive = 2; +} \ No newline at end of file diff --git a/proto/options_activity_unmarshals.go b/proto/options_activity_unmarshals.go new file mode 100644 index 0000000..356c450 --- /dev/null +++ b/proto/options_activity_unmarshals.go @@ -0,0 +1,46 @@ +package litepb + +import ( + "fmt" + "strings" + + "gopkg.in/yaml.v3" +) + +func (a *Activity) UnmarshalYAML(value *yaml.Node) error { + if v, ok := activityMap[strings.ToLower(value.Value)]; ok { + *a = v + return nil + } + keys := make([]string, 0, len(activityMap)) + for k := range activityMap { + keys = append(keys, k) + } + return fmt.Errorf("unknown Activity value [%s] with type [%s] available: %s", value.Value, value.Tag, strings.Join(keys, ", ")) +} + +func (a *Activity) UnmarshalTOML(value any) error { + vs := fmt.Sprintf("%v", value) + if v, ok := activityMap[strings.ToLower(vs)]; ok { + *a = v + return nil + } + keys := make([]string, 0, len(activityMap)) + for k := range activityMap { + keys = append(keys, k) + } + return fmt.Errorf("unknown Activity value [%v] available: %s", value, strings.Join(keys, ", ")) +} + +var ( + activityMap = map[string]Activity{ + "1": Activity_Active, + "0": Activity_Inactive, + "active": Activity_Active, + "inactive": Activity_Inactive, + "on": Activity_Active, + "off": Activity_Inactive, + "true": Activity_Active, + "false": Activity_Inactive, + } +) diff --git a/proto/plugin.pb.go b/proto/plugin.pb.go new file mode 100644 index 0000000..5a8b878 --- /dev/null +++ b/proto/plugin.pb.go @@ -0,0 +1,1768 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/plugin.proto + +package litepb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type File_Generate int32 + +const ( + File_STRUCT File_Generate = 0 + File_INTERFACE File_Generate = 1 + File_POOL File_Generate = 2 + File_ENUM File_Generate = 3 + File_LIST File_Generate = 4 + File_MAP File_Generate = 5 + File_NEW File_Generate = 100 + File_RETURN_TO_POOL File_Generate = 101 + File_CONVERT_TO File_Generate = 102 + File_PROTO_MESSAGE File_Generate = 103 + File_STRING File_Generate = 104 + File_RESET File_Generate = 105 + File_CLONE File_Generate = 106 + File_GETTER File_Generate = 107 + File_SETTER File_Generate = 108 + File_MARSHAL File_Generate = 109 + File_UNMARSHAL File_Generate = 110 + File_SIZE File_Generate = 111 +) + +// Enum value maps for File_Generate. +var ( + File_Generate_name = map[int32]string{ + 0: "STRUCT", + 1: "INTERFACE", + 2: "POOL", + 3: "ENUM", + 4: "LIST", + 5: "MAP", + 100: "NEW", + 101: "RETURN_TO_POOL", + 102: "CONVERT_TO", + 103: "PROTO_MESSAGE", + 104: "STRING", + 105: "RESET", + 106: "CLONE", + 107: "GETTER", + 108: "SETTER", + 109: "MARSHAL", + 110: "UNMARSHAL", + 111: "SIZE", + } + File_Generate_value = map[string]int32{ + "STRUCT": 0, + "INTERFACE": 1, + "POOL": 2, + "ENUM": 3, + "LIST": 4, + "MAP": 5, + "NEW": 100, + "RETURN_TO_POOL": 101, + "CONVERT_TO": 102, + "PROTO_MESSAGE": 103, + "STRING": 104, + "RESET": 105, + "CLONE": 106, + "GETTER": 107, + "SETTER": 108, + "MARSHAL": 109, + "UNMARSHAL": 110, + "SIZE": 111, + } +) + +func (x File_Generate) Enum() *File_Generate { + p := new(File_Generate) + *p = x + return p +} + +func (x File_Generate) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (File_Generate) Descriptor() protoreflect.EnumDescriptor { + return file_proto_plugin_proto_enumTypes[0].Descriptor() +} + +func (File_Generate) Type() protoreflect.EnumType { + return &file_proto_plugin_proto_enumTypes[0] +} + +func (x File_Generate) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use File_Generate.Descriptor instead. +func (File_Generate) EnumDescriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{3, 0} +} + +type Message_Field_Type_Proto int32 + +const ( + Message_Field_Type_ERROR Message_Field_Type_Proto = 0 + Message_Field_Type_DOUBLE Message_Field_Type_Proto = 1 + Message_Field_Type_FLOAT Message_Field_Type_Proto = 2 + Message_Field_Type_INT64 Message_Field_Type_Proto = 3 + Message_Field_Type_UINT64 Message_Field_Type_Proto = 4 + Message_Field_Type_INT32 Message_Field_Type_Proto = 5 + Message_Field_Type_FIXED64 Message_Field_Type_Proto = 6 + Message_Field_Type_FIXED32 Message_Field_Type_Proto = 7 + Message_Field_Type_BOOL Message_Field_Type_Proto = 8 + Message_Field_Type_STRING Message_Field_Type_Proto = 9 + Message_Field_Type_GROUP Message_Field_Type_Proto = 10 + Message_Field_Type_MESSAGE_OR_MAP Message_Field_Type_Proto = 11 + Message_Field_Type_BYTES Message_Field_Type_Proto = 12 + Message_Field_Type_UINT32 Message_Field_Type_Proto = 13 + Message_Field_Type_ENUM Message_Field_Type_Proto = 14 + Message_Field_Type_SFIXED32 Message_Field_Type_Proto = 15 + Message_Field_Type_SFIXED64 Message_Field_Type_Proto = 16 + Message_Field_Type_SINT32 Message_Field_Type_Proto = 17 + Message_Field_Type_SINT64 Message_Field_Type_Proto = 18 +) + +// Enum value maps for Message_Field_Type_Proto. +var ( + Message_Field_Type_Proto_name = map[int32]string{ + 0: "ERROR", + 1: "DOUBLE", + 2: "FLOAT", + 3: "INT64", + 4: "UINT64", + 5: "INT32", + 6: "FIXED64", + 7: "FIXED32", + 8: "BOOL", + 9: "STRING", + 10: "GROUP", + 11: "MESSAGE_OR_MAP", + 12: "BYTES", + 13: "UINT32", + 14: "ENUM", + 15: "SFIXED32", + 16: "SFIXED64", + 17: "SINT32", + 18: "SINT64", + } + Message_Field_Type_Proto_value = map[string]int32{ + "ERROR": 0, + "DOUBLE": 1, + "FLOAT": 2, + "INT64": 3, + "UINT64": 4, + "INT32": 5, + "FIXED64": 6, + "FIXED32": 7, + "BOOL": 8, + "STRING": 9, + "GROUP": 10, + "MESSAGE_OR_MAP": 11, + "BYTES": 12, + "UINT32": 13, + "ENUM": 14, + "SFIXED32": 15, + "SFIXED64": 16, + "SINT32": 17, + "SINT64": 18, + } +) + +func (x Message_Field_Type_Proto) Enum() *Message_Field_Type_Proto { + p := new(Message_Field_Type_Proto) + *p = x + return p +} + +func (x Message_Field_Type_Proto) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Message_Field_Type_Proto) Descriptor() protoreflect.EnumDescriptor { + return file_proto_plugin_proto_enumTypes[1].Descriptor() +} + +func (Message_Field_Type_Proto) Type() protoreflect.EnumType { + return &file_proto_plugin_proto_enumTypes[1] +} + +func (x Message_Field_Type_Proto) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Message_Field_Type_Proto.Descriptor instead. +func (Message_Field_Type_Proto) EnumDescriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 1, 1, 0} +} + +type Plugin struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Files []*File `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"` + Sources []*Source `protobuf:"bytes,2,rep,name=sources,proto3" json:"sources,omitempty"` + Templates []*Template `protobuf:"bytes,3,rep,name=templates,proto3" json:"templates,omitempty"` +} + +func (x *Plugin) Reset() { + *x = Plugin{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Plugin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Plugin) ProtoMessage() {} + +func (x *Plugin) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Plugin.ProtoReflect.Descriptor instead. +func (*Plugin) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{0} +} + +func (x *Plugin) GetFiles() []*File { + if x != nil { + return x.Files + } + return nil +} + +func (x *Plugin) GetSources() []*Source { + if x != nil { + return x.Sources + } + return nil +} + +func (x *Plugin) GetTemplates() []*Template { + if x != nil { + return x.Templates + } + return nil +} + +type Template struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Content []byte `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *Template) Reset() { + *x = Template{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Template) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Template) ProtoMessage() {} + +func (x *Template) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Template.ProtoReflect.Descriptor instead. +func (*Template) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{1} +} + +func (x *Template) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Template) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +type Source struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Content []byte `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` +} + +func (x *Source) Reset() { + *x = Source{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Source) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Source) ProtoMessage() {} + +func (x *Source) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Source.ProtoReflect.Descriptor instead. +func (*Source) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{2} +} + +func (x *Source) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Source) GetContent() []byte { + if x != nil { + return x.Content + } + return nil +} + +type File struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Package *Package `protobuf:"bytes,1,opt,name=package,proto3" json:"package,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"` + Imports []*Dependency `protobuf:"bytes,4,rep,name=imports,proto3" json:"imports,omitempty"` + Enums []*Enum `protobuf:"bytes,5,rep,name=enums,proto3" json:"enums,omitempty"` + Messages []*Message `protobuf:"bytes,6,rep,name=messages,proto3" json:"messages,omitempty"` + Options []byte `protobuf:"bytes,7,opt,name=options,proto3" json:"options,omitempty"` + Generates []File_Generate `protobuf:"varint,8,rep,packed,name=generates,proto3,enum=litepb.File_Generate" json:"generates,omitempty"` +} + +func (x *File) Reset() { + *x = File{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *File) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*File) ProtoMessage() {} + +func (x *File) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use File.ProtoReflect.Descriptor instead. +func (*File) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{3} +} + +func (x *File) GetPackage() *Package { + if x != nil { + return x.Package + } + return nil +} + +func (x *File) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *File) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *File) GetImports() []*Dependency { + if x != nil { + return x.Imports + } + return nil +} + +func (x *File) GetEnums() []*Enum { + if x != nil { + return x.Enums + } + return nil +} + +func (x *File) GetMessages() []*Message { + if x != nil { + return x.Messages + } + return nil +} + +func (x *File) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +func (x *File) GetGenerates() []File_Generate { + if x != nil { + return x.Generates + } + return nil +} + +type Package struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Dependency *Dependency `protobuf:"bytes,1,opt,name=dependency,proto3" json:"dependency,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *Package) Reset() { + *x = Package{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Package) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Package) ProtoMessage() {} + +func (x *Package) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Package.ProtoReflect.Descriptor instead. +func (*Package) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{4} +} + +func (x *Package) GetDependency() *Dependency { + if x != nil { + return x.Dependency + } + return nil +} + +func (x *Package) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type Dependency struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Alias string `protobuf:"bytes,2,opt,name=alias,proto3" json:"alias,omitempty"` +} + +func (x *Dependency) Reset() { + *x = Dependency{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Dependency) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Dependency) ProtoMessage() {} + +func (x *Dependency) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Dependency.ProtoReflect.Descriptor instead. +func (*Dependency) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{5} +} + +func (x *Dependency) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Dependency) GetAlias() string { + if x != nil { + return x.Alias + } + return "" +} + +type Enum struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Comments string `protobuf:"bytes,2,opt,name=comments,proto3" json:"comments,omitempty"` + ValuesPrefix string `protobuf:"bytes,3,opt,name=values_prefix,json=valuesPrefix,proto3" json:"values_prefix,omitempty"` + Values []*Enum_Value `protobuf:"bytes,4,rep,name=values,proto3" json:"values,omitempty"` + Options []byte `protobuf:"bytes,5,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *Enum) Reset() { + *x = Enum{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Enum) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Enum) ProtoMessage() {} + +func (x *Enum) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Enum.ProtoReflect.Descriptor instead. +func (*Enum) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{6} +} + +func (x *Enum) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Enum) GetComments() string { + if x != nil { + return x.Comments + } + return "" +} + +func (x *Enum) GetValuesPrefix() string { + if x != nil { + return x.ValuesPrefix + } + return "" +} + +func (x *Enum) GetValues() []*Enum_Value { + if x != nil { + return x.Values + } + return nil +} + +func (x *Enum) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +type Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Comments string `protobuf:"bytes,2,opt,name=comments,proto3" json:"comments,omitempty"` + Properties []*Message_Property `protobuf:"bytes,3,rep,name=properties,proto3" json:"properties,omitempty"` + Options []byte `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` + MemPoolMessage bool `protobuf:"varint,5,opt,name=mem_pool_message,json=memPoolMessage,proto3" json:"mem_pool_message,omitempty"` + MemPoolList bool `protobuf:"varint,6,opt,name=mem_pool_list,json=memPoolList,proto3" json:"mem_pool_list,omitempty"` + MemPoolMap bool `protobuf:"varint,7,opt,name=mem_pool_map,json=memPoolMap,proto3" json:"mem_pool_map,omitempty"` + Unsafe bool `protobuf:"varint,8,opt,name=unsafe,proto3" json:"unsafe,omitempty"` +} + +func (x *Message) Reset() { + *x = Message{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7} +} + +func (x *Message) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Message) GetComments() string { + if x != nil { + return x.Comments + } + return "" +} + +func (x *Message) GetProperties() []*Message_Property { + if x != nil { + return x.Properties + } + return nil +} + +func (x *Message) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +func (x *Message) GetMemPoolMessage() bool { + if x != nil { + return x.MemPoolMessage + } + return false +} + +func (x *Message) GetMemPoolList() bool { + if x != nil { + return x.MemPoolList + } + return false +} + +func (x *Message) GetMemPoolMap() bool { + if x != nil { + return x.MemPoolMap + } + return false +} + +func (x *Message) GetUnsafe() bool { + if x != nil { + return x.Unsafe + } + return false +} + +type Enum_Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Number int32 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Comments string `protobuf:"bytes,3,opt,name=comments,proto3" json:"comments,omitempty"` + Options []byte `protobuf:"bytes,4,opt,name=options,proto3" json:"options,omitempty"` +} + +func (x *Enum_Value) Reset() { + *x = Enum_Value{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Enum_Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Enum_Value) ProtoMessage() {} + +func (x *Enum_Value) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Enum_Value.ProtoReflect.Descriptor instead. +func (*Enum_Value) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *Enum_Value) GetNumber() int32 { + if x != nil { + return x.Number + } + return 0 +} + +func (x *Enum_Value) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Enum_Value) GetComments() string { + if x != nil { + return x.Comments + } + return "" +} + +func (x *Enum_Value) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +type Message_Property struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Type: + // *Message_Property_Field + // *Message_Property_Oneof + Type isMessage_Property_Type `protobuf_oneof:"type"` +} + +func (x *Message_Property) Reset() { + *x = Message_Property{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message_Property) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message_Property) ProtoMessage() {} + +func (x *Message_Property) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message_Property.ProtoReflect.Descriptor instead. +func (*Message_Property) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 0} +} + +func (m *Message_Property) GetType() isMessage_Property_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *Message_Property) GetField() *Message_Field { + if x, ok := x.GetType().(*Message_Property_Field); ok { + return x.Field + } + return nil +} + +func (x *Message_Property) GetOneof() *Message_OneOf { + if x, ok := x.GetType().(*Message_Property_Oneof); ok { + return x.Oneof + } + return nil +} + +type isMessage_Property_Type interface { + isMessage_Property_Type() +} + +type Message_Property_Field struct { + Field *Message_Field `protobuf:"bytes,1,opt,name=field,proto3,oneof"` +} + +type Message_Property_Oneof struct { + Oneof *Message_OneOf `protobuf:"bytes,2,opt,name=oneof,proto3,oneof"` +} + +func (*Message_Property_Field) isMessage_Property_Type() {} + +func (*Message_Property_Oneof) isMessage_Property_Type() {} + +type Message_Field struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Number int32 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Comments string `protobuf:"bytes,3,opt,name=comments,proto3" json:"comments,omitempty"` + Type *Message_Field_Type `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` + ZeroValue string `protobuf:"bytes,5,opt,name=zero_value,json=zeroValue,proto3" json:"zero_value,omitempty"` + Options []byte `protobuf:"bytes,6,opt,name=options,proto3" json:"options,omitempty"` + Tags map[string]string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + AppendForRepeated bool `protobuf:"varint,8,opt,name=append_for_repeated,json=appendForRepeated,proto3" json:"append_for_repeated,omitempty"` // TODO ??? +} + +func (x *Message_Field) Reset() { + *x = Message_Field{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message_Field) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message_Field) ProtoMessage() {} + +func (x *Message_Field) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message_Field.ProtoReflect.Descriptor instead. +func (*Message_Field) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 1} +} + +func (x *Message_Field) GetNumber() int32 { + if x != nil { + return x.Number + } + return 0 +} + +func (x *Message_Field) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Message_Field) GetComments() string { + if x != nil { + return x.Comments + } + return "" +} + +func (x *Message_Field) GetType() *Message_Field_Type { + if x != nil { + return x.Type + } + return nil +} + +func (x *Message_Field) GetZeroValue() string { + if x != nil { + return x.ZeroValue + } + return "" +} + +func (x *Message_Field) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +func (x *Message_Field) GetTags() map[string]string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Message_Field) GetAppendForRepeated() bool { + if x != nil { + return x.AppendForRepeated + } + return false +} + +type Message_OneOf struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Comments string `protobuf:"bytes,2,opt,name=comments,proto3" json:"comments,omitempty"` + Options []byte `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` + Fields []*Message_Field `protobuf:"bytes,4,rep,name=fields,proto3" json:"fields,omitempty"` + Tags map[string]string `protobuf:"bytes,5,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + MemPool bool `protobuf:"varint,6,opt,name=mem_pool,json=memPool,proto3" json:"mem_pool,omitempty"` +} + +func (x *Message_OneOf) Reset() { + *x = Message_OneOf{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message_OneOf) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message_OneOf) ProtoMessage() {} + +func (x *Message_OneOf) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message_OneOf.ProtoReflect.Descriptor instead. +func (*Message_OneOf) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 2} +} + +func (x *Message_OneOf) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Message_OneOf) GetComments() string { + if x != nil { + return x.Comments + } + return "" +} + +func (x *Message_OneOf) GetOptions() []byte { + if x != nil { + return x.Options + } + return nil +} + +func (x *Message_OneOf) GetFields() []*Message_Field { + if x != nil { + return x.Fields + } + return nil +} + +func (x *Message_OneOf) GetTags() map[string]string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Message_OneOf) GetMemPool() bool { + if x != nil { + return x.MemPool + } + return false +} + +type Message_Field_Type struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InProto Message_Field_Type_Proto `protobuf:"varint,1,opt,name=in_proto,json=inProto,proto3,enum=litepb.Message_Field_Type_Proto" json:"in_proto,omitempty"` + Reflect *Message_Field_Type_Reflect `protobuf:"bytes,2,opt,name=reflect,proto3" json:"reflect,omitempty"` + Repeated bool `protobuf:"varint,3,opt,name=repeated,proto3" json:"repeated,omitempty"` + Map *Message_Field_Type_Map `protobuf:"bytes,4,opt,name=map,proto3" json:"map,omitempty"` +} + +func (x *Message_Field_Type) Reset() { + *x = Message_Field_Type{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message_Field_Type) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message_Field_Type) ProtoMessage() {} + +func (x *Message_Field_Type) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message_Field_Type.ProtoReflect.Descriptor instead. +func (*Message_Field_Type) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 1, 1} +} + +func (x *Message_Field_Type) GetInProto() Message_Field_Type_Proto { + if x != nil { + return x.InProto + } + return Message_Field_Type_ERROR +} + +func (x *Message_Field_Type) GetReflect() *Message_Field_Type_Reflect { + if x != nil { + return x.Reflect + } + return nil +} + +func (x *Message_Field_Type) GetRepeated() bool { + if x != nil { + return x.Repeated + } + return false +} + +func (x *Message_Field_Type) GetMap() *Message_Field_Type_Map { + if x != nil { + return x.Map + } + return nil +} + +type Message_Field_Type_Reflect struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Dependency *Dependency `protobuf:"bytes,2,opt,name=dependency,proto3" json:"dependency,omitempty"` +} + +func (x *Message_Field_Type_Reflect) Reset() { + *x = Message_Field_Type_Reflect{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message_Field_Type_Reflect) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message_Field_Type_Reflect) ProtoMessage() {} + +func (x *Message_Field_Type_Reflect) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message_Field_Type_Reflect.ProtoReflect.Descriptor instead. +func (*Message_Field_Type_Reflect) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 1, 1, 0} +} + +func (x *Message_Field_Type_Reflect) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Message_Field_Type_Reflect) GetDependency() *Dependency { + if x != nil { + return x.Dependency + } + return nil +} + +type Message_Field_Type_Map struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *Message_Field_Type `protobuf:"bytes,1,opt,name=Key,proto3" json:"Key,omitempty"` + Value *Message_Field_Type `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *Message_Field_Type_Map) Reset() { + *x = Message_Field_Type_Map{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_plugin_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message_Field_Type_Map) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message_Field_Type_Map) ProtoMessage() {} + +func (x *Message_Field_Type_Map) ProtoReflect() protoreflect.Message { + mi := &file_proto_plugin_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message_Field_Type_Map.ProtoReflect.Descriptor instead. +func (*Message_Field_Type_Map) Descriptor() ([]byte, []int) { + return file_proto_plugin_proto_rawDescGZIP(), []int{7, 1, 1, 1} +} + +func (x *Message_Field_Type_Map) GetKey() *Message_Field_Type { + if x != nil { + return x.Key + } + return nil +} + +func (x *Message_Field_Type_Map) GetValue() *Message_Field_Type { + if x != nil { + return x.Value + } + return nil +} + +var File_proto_plugin_proto protoreflect.FileDescriptor + +var file_proto_plugin_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x22, 0x86, 0x01, 0x0a, + 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x22, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x07, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, + 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x07, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, + 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x09, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x22, 0x38, 0x0a, 0x08, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, + 0x36, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x9a, 0x04, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x29, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, + 0x67, 0x65, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, + 0x62, 0x2e, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x07, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, 0x22, 0x0a, 0x05, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x45, 0x6e, + 0x75, 0x6d, 0x52, 0x05, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x08, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, + 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x33, 0x0a, 0x09, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x09, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x00, 0x12, 0x0d, + 0x0a, 0x09, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x46, 0x41, 0x43, 0x45, 0x10, 0x01, 0x12, 0x08, 0x0a, + 0x04, 0x50, 0x4f, 0x4f, 0x4c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x4e, 0x55, 0x4d, 0x10, + 0x03, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x4d, + 0x41, 0x50, 0x10, 0x05, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x45, 0x57, 0x10, 0x64, 0x12, 0x12, 0x0a, + 0x0e, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x54, 0x4f, 0x5f, 0x50, 0x4f, 0x4f, 0x4c, 0x10, + 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x54, 0x5f, 0x54, 0x4f, 0x10, + 0x66, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, + 0x47, 0x45, 0x10, 0x67, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x68, + 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x53, 0x45, 0x54, 0x10, 0x69, 0x12, 0x09, 0x0a, 0x05, 0x43, + 0x4c, 0x4f, 0x4e, 0x45, 0x10, 0x6a, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x45, 0x54, 0x54, 0x45, 0x52, + 0x10, 0x6b, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x45, 0x54, 0x54, 0x45, 0x52, 0x10, 0x6c, 0x12, 0x0b, + 0x0a, 0x07, 0x4d, 0x41, 0x52, 0x53, 0x48, 0x41, 0x4c, 0x10, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x55, + 0x4e, 0x4d, 0x41, 0x52, 0x53, 0x48, 0x41, 0x4c, 0x10, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x49, + 0x5a, 0x45, 0x10, 0x6f, 0x22, 0x51, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, + 0x32, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x44, 0x65, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, + 0x6e, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x36, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x65, 0x6e, + 0x64, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x22, + 0x8c, 0x02, 0x0a, 0x04, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x2a, 0x0a, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x1a, 0x69, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xea, + 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x0a, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, + 0x0a, 0x10, 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, + 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x5f, + 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0c, + 0x6d, 0x65, 0x6d, 0x5f, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x50, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x12, 0x16, + 0x0a, 0x06, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x1a, 0x70, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x48, 0x00, 0x52, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, + 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0xd4, 0x07, 0x0a, 0x05, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, + 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x7a, 0x65, + 0x72, 0x6f, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x7a, 0x65, 0x72, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x46, 0x6f, 0x72, + 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x1a, 0xfb, 0x04, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x69, 0x6e, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x6c, + 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x52, 0x07, + 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x3c, 0x0a, 0x07, 0x72, 0x65, 0x66, 0x6c, 0x65, + 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, + 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e, + 0x54, 0x79, 0x70, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x07, 0x72, 0x65, + 0x66, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x30, 0x0a, 0x03, 0x6d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, + 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x52, 0x03, + 0x6d, 0x61, 0x70, 0x1a, 0x51, 0x0a, 0x07, 0x52, 0x65, 0x66, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x32, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, + 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x1a, 0x65, 0x0a, 0x03, 0x4d, 0x61, 0x70, 0x12, 0x2c, 0x0a, + 0x03, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, + 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x03, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, + 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xef, 0x01, + 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x09, + 0x0a, 0x05, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, + 0x36, 0x34, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, + 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x46, + 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x46, 0x49, 0x58, 0x45, + 0x44, 0x33, 0x32, 0x10, 0x07, 0x12, 0x08, 0x0a, 0x04, 0x42, 0x4f, 0x4f, 0x4c, 0x10, 0x08, 0x12, + 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x09, 0x0a, 0x05, 0x47, + 0x52, 0x4f, 0x55, 0x50, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, + 0x45, 0x5f, 0x4f, 0x52, 0x5f, 0x4d, 0x41, 0x50, 0x10, 0x0b, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x59, + 0x54, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, + 0x0d, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x4e, 0x55, 0x4d, 0x10, 0x0e, 0x12, 0x0c, 0x0a, 0x08, 0x53, + 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x10, 0x0f, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x46, 0x49, + 0x58, 0x45, 0x44, 0x36, 0x34, 0x10, 0x10, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x54, 0x33, + 0x32, 0x10, 0x11, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x12, 0x1a, + 0x89, 0x02, 0x0a, 0x05, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x33, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x70, + 0x6f, 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x50, 0x6f, + 0x6f, 0x6c, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x27, 0x5a, 0x25, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x2d, 0x74, 0x61, 0x70, 0x65, + 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6c, 0x69, + 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_plugin_proto_rawDescOnce sync.Once + file_proto_plugin_proto_rawDescData = file_proto_plugin_proto_rawDesc +) + +func file_proto_plugin_proto_rawDescGZIP() []byte { + file_proto_plugin_proto_rawDescOnce.Do(func() { + file_proto_plugin_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_plugin_proto_rawDescData) + }) + return file_proto_plugin_proto_rawDescData +} + +var file_proto_plugin_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_proto_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_proto_plugin_proto_goTypes = []interface{}{ + (File_Generate)(0), // 0: litepb.File.Generate + (Message_Field_Type_Proto)(0), // 1: litepb.Message.Field.Type.Proto + (*Plugin)(nil), // 2: litepb.Plugin + (*Template)(nil), // 3: litepb.Template + (*Source)(nil), // 4: litepb.Source + (*File)(nil), // 5: litepb.File + (*Package)(nil), // 6: litepb.Package + (*Dependency)(nil), // 7: litepb.Dependency + (*Enum)(nil), // 8: litepb.Enum + (*Message)(nil), // 9: litepb.Message + (*Enum_Value)(nil), // 10: litepb.Enum.Value + (*Message_Property)(nil), // 11: litepb.Message.Property + (*Message_Field)(nil), // 12: litepb.Message.Field + (*Message_OneOf)(nil), // 13: litepb.Message.OneOf + nil, // 14: litepb.Message.Field.TagsEntry + (*Message_Field_Type)(nil), // 15: litepb.Message.Field.Type + (*Message_Field_Type_Reflect)(nil), // 16: litepb.Message.Field.Type.Reflect + (*Message_Field_Type_Map)(nil), // 17: litepb.Message.Field.Type.Map + nil, // 18: litepb.Message.OneOf.TagsEntry +} +var file_proto_plugin_proto_depIdxs = []int32{ + 5, // 0: litepb.Plugin.files:type_name -> litepb.File + 4, // 1: litepb.Plugin.sources:type_name -> litepb.Source + 3, // 2: litepb.Plugin.templates:type_name -> litepb.Template + 6, // 3: litepb.File.package:type_name -> litepb.Package + 7, // 4: litepb.File.imports:type_name -> litepb.Dependency + 8, // 5: litepb.File.enums:type_name -> litepb.Enum + 9, // 6: litepb.File.messages:type_name -> litepb.Message + 0, // 7: litepb.File.generates:type_name -> litepb.File.Generate + 7, // 8: litepb.Package.dependency:type_name -> litepb.Dependency + 10, // 9: litepb.Enum.values:type_name -> litepb.Enum.Value + 11, // 10: litepb.Message.properties:type_name -> litepb.Message.Property + 12, // 11: litepb.Message.Property.field:type_name -> litepb.Message.Field + 13, // 12: litepb.Message.Property.oneof:type_name -> litepb.Message.OneOf + 15, // 13: litepb.Message.Field.type:type_name -> litepb.Message.Field.Type + 14, // 14: litepb.Message.Field.tags:type_name -> litepb.Message.Field.TagsEntry + 12, // 15: litepb.Message.OneOf.fields:type_name -> litepb.Message.Field + 18, // 16: litepb.Message.OneOf.tags:type_name -> litepb.Message.OneOf.TagsEntry + 1, // 17: litepb.Message.Field.Type.in_proto:type_name -> litepb.Message.Field.Type.Proto + 16, // 18: litepb.Message.Field.Type.reflect:type_name -> litepb.Message.Field.Type.Reflect + 17, // 19: litepb.Message.Field.Type.map:type_name -> litepb.Message.Field.Type.Map + 7, // 20: litepb.Message.Field.Type.Reflect.dependency:type_name -> litepb.Dependency + 15, // 21: litepb.Message.Field.Type.Map.Key:type_name -> litepb.Message.Field.Type + 15, // 22: litepb.Message.Field.Type.Map.Value:type_name -> litepb.Message.Field.Type + 23, // [23:23] is the sub-list for method output_type + 23, // [23:23] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name +} + +func init() { file_proto_plugin_proto_init() } +func file_proto_plugin_proto_init() { + if File_proto_plugin_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Plugin); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Template); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Source); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*File); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Package); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Dependency); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Enum); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Enum_Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message_Property); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message_Field); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message_OneOf); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message_Field_Type); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message_Field_Type_Reflect); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_plugin_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message_Field_Type_Map); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_proto_plugin_proto_msgTypes[9].OneofWrappers = []interface{}{ + (*Message_Property_Field)(nil), + (*Message_Property_Oneof)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_plugin_proto_rawDesc, + NumEnums: 2, + NumMessages: 17, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_plugin_proto_goTypes, + DependencyIndexes: file_proto_plugin_proto_depIdxs, + EnumInfos: file_proto_plugin_proto_enumTypes, + MessageInfos: file_proto_plugin_proto_msgTypes, + }.Build() + File_proto_plugin_proto = out.File + file_proto_plugin_proto_rawDesc = nil + file_proto_plugin_proto_goTypes = nil + file_proto_plugin_proto_depIdxs = nil +} diff --git a/proto/plugin.proto b/proto/plugin.proto new file mode 100644 index 0000000..4a49933 --- /dev/null +++ b/proto/plugin.proto @@ -0,0 +1,153 @@ +syntax = "proto3"; + +package litepb; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +message Plugin { + repeated File files = 1; + repeated Source sources = 2; + repeated Template templates = 3; +} + +message Template { + string name = 1; + bytes content = 2; +} + +message Source { + string name = 1; + bytes content = 2; +} + +message File { + Package package = 1; + string name = 2; + string source = 3; + repeated Dependency imports = 4; + repeated Enum enums = 5; + repeated Message messages = 6; + bytes options = 7; + repeated Generate generates = 8; + + enum Generate { + STRUCT = 0; + INTERFACE = 1; + POOL = 2; + ENUM = 3; + LIST = 4; + MAP = 5; + + NEW = 100; + RETURN_TO_POOL = 101; + CONVERT_TO = 102; + PROTO_MESSAGE = 103; + STRING = 104; + RESET = 105; + CLONE = 106; + GETTER = 107; + SETTER = 108; + MARSHAL = 109; + UNMARSHAL = 110; + SIZE = 111; + } +} + +message Package { + Dependency dependency = 1; + string name = 2; +} + +message Dependency { + string path = 1; + string alias = 2; +} + +message Enum { + string name = 1; + string comments = 2; + string values_prefix = 3; + repeated Value values = 4; + bytes options = 5; + + message Value { + int32 number = 1; + string name = 2; + string comments = 3; + bytes options = 4; + } +} + +message Message { + string name = 1; + string comments = 2; + repeated Property properties = 3; + bytes options = 4; + bool mem_pool_message = 5; + bool mem_pool_list = 6; + bool mem_pool_map = 7; + bool unsafe = 8; + + message Property { + oneof type { + Field field = 1; + OneOf oneof = 2; + } + } + + message Field { + int32 number = 1; + string name = 2; + string comments = 3; + Type type = 4; + string zero_value = 5; + bytes options = 6; + map tags = 7; + bool append_for_repeated = 8;// TODO ??? + + message Type { + Proto in_proto = 1; + Reflect reflect = 2; + bool repeated = 3; + Map map = 4; + + enum Proto { + ERROR = 0; + DOUBLE = 1; + FLOAT = 2; + INT64 = 3; + UINT64 = 4; + INT32 = 5; + FIXED64 = 6; + FIXED32 = 7; + BOOL = 8; + STRING = 9; + GROUP = 10; + MESSAGE_OR_MAP = 11; + BYTES = 12; + UINT32 = 13; + ENUM = 14; + SFIXED32 = 15; + SFIXED64 = 16; + SINT32 = 17; + SINT64 = 18; + } + message Reflect { + string name = 1; + Dependency dependency = 2; + } + message Map { + Type Key = 1; + Type Value = 2; + } + } + } + message OneOf { + string name = 1; + string comments = 2; + bytes options = 3; + repeated Field fields = 4; + map tags = 5; + bool mem_pool = 6; + } +} \ No newline at end of file diff --git a/proto/time.pb.go b/proto/time.pb.go new file mode 100644 index 0000000..680fd8f --- /dev/null +++ b/proto/time.pb.go @@ -0,0 +1,157 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/time.proto + +package litepb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Implementation of time.Time transfer. +// You can use the standard type https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto +type Time struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Seconds of time.Time + Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` + // Nanoseconds of time.Time + Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` +} + +func (x *Time) Reset() { + *x = Time{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_time_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Time) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Time) ProtoMessage() {} + +func (x *Time) ProtoReflect() protoreflect.Message { + mi := &file_proto_time_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Time.ProtoReflect.Descriptor instead. +func (*Time) Descriptor() ([]byte, []int) { + return file_proto_time_proto_rawDescGZIP(), []int{0} +} + +func (x *Time) GetSeconds() int64 { + if x != nil { + return x.Seconds + } + return 0 +} + +func (x *Time) GetNanos() int32 { + if x != nil { + return x.Nanos + } + return 0 +} + +var File_proto_time_proto protoreflect.FileDescriptor + +var file_proto_time_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x22, 0x36, 0x0a, 0x04, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x6e, 0x61, 0x6e, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x61, 0x6e, + 0x6f, 0x73, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x65, 0x2d, 0x74, 0x61, 0x70, 0x65, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_proto_time_proto_rawDescOnce sync.Once + file_proto_time_proto_rawDescData = file_proto_time_proto_rawDesc +) + +func file_proto_time_proto_rawDescGZIP() []byte { + file_proto_time_proto_rawDescOnce.Do(func() { + file_proto_time_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_time_proto_rawDescData) + }) + return file_proto_time_proto_rawDescData +} + +var file_proto_time_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_proto_time_proto_goTypes = []interface{}{ + (*Time)(nil), // 0: litepb.Time +} +var file_proto_time_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_time_proto_init() } +func file_proto_time_proto_init() { + if File_proto_time_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_time_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Time); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_time_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_time_proto_goTypes, + DependencyIndexes: file_proto_time_proto_depIdxs, + MessageInfos: file_proto_time_proto_msgTypes, + }.Build() + File_proto_time_proto = out.File + file_proto_time_proto_rawDesc = nil + file_proto_time_proto_goTypes = nil + file_proto_time_proto_depIdxs = nil +} diff --git a/proto/time.proto b/proto/time.proto new file mode 100644 index 0000000..81b5ec6 --- /dev/null +++ b/proto/time.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package litepb; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +// Implementation of time.Time transfer. +// You can use the standard type https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/timestamp.proto +message Time { + // Seconds of time.Time + int64 seconds = 1; + // Nanoseconds of time.Time + int32 nanos = 2; +} \ No newline at end of file diff --git a/proto/uuid.pb.go b/proto/uuid.pb.go new file mode 100644 index 0000000..2df9d90 --- /dev/null +++ b/proto/uuid.pb.go @@ -0,0 +1,148 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.12.1 +// source: proto/uuid.proto + +package litepb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Implementation of uuid.UUID transfer +type UUID struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Value of UUID + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *UUID) Reset() { + *x = UUID{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_uuid_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UUID) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UUID) ProtoMessage() {} + +func (x *UUID) ProtoReflect() protoreflect.Message { + mi := &file_proto_uuid_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UUID.ProtoReflect.Descriptor instead. +func (*UUID) Descriptor() ([]byte, []int) { + return file_proto_uuid_proto_rawDescGZIP(), []int{0} +} + +func (x *UUID) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +var File_proto_uuid_proto protoreflect.FileDescriptor + +var file_proto_uuid_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x75, 0x75, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x1a, 0x13, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0x22, 0x0a, 0x04, 0x55, 0x55, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0xf8, 0xe7, 0x07, 0x10, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x65, 0x2d, 0x74, 0x61, 0x70, 0x65, 0x2f, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6c, 0x69, 0x74, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_uuid_proto_rawDescOnce sync.Once + file_proto_uuid_proto_rawDescData = file_proto_uuid_proto_rawDesc +) + +func file_proto_uuid_proto_rawDescGZIP() []byte { + file_proto_uuid_proto_rawDescOnce.Do(func() { + file_proto_uuid_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_uuid_proto_rawDescData) + }) + return file_proto_uuid_proto_rawDescData +} + +var file_proto_uuid_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_proto_uuid_proto_goTypes = []interface{}{ + (*UUID)(nil), // 0: litepb.UUID +} +var file_proto_uuid_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_proto_uuid_proto_init() } +func file_proto_uuid_proto_init() { + if File_proto_uuid_proto != nil { + return + } + file_proto_options_proto_init() + if !protoimpl.UnsafeEnabled { + file_proto_uuid_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UUID); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_uuid_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_proto_uuid_proto_goTypes, + DependencyIndexes: file_proto_uuid_proto_depIdxs, + MessageInfos: file_proto_uuid_proto_msgTypes, + }.Build() + File_proto_uuid_proto = out.File + file_proto_uuid_proto_rawDesc = nil + file_proto_uuid_proto_goTypes = nil + file_proto_uuid_proto_depIdxs = nil +} diff --git a/proto/uuid.proto b/proto/uuid.proto new file mode 100644 index 0000000..146aa42 --- /dev/null +++ b/proto/uuid.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package litepb; + +option go_package = "github.com/e-tape/litepb/proto;litepb"; + +import "proto/options.proto"; + +// Implementation of uuid.UUID transfer +message UUID { + // Value of UUID + bytes value = 1 [(litepb.array_fixed_size) = 16]; +} \ No newline at end of file diff --git a/qtest/main_test.go b/qtest/main_test.go new file mode 100644 index 0000000..517d875 --- /dev/null +++ b/qtest/main_test.go @@ -0,0 +1,69 @@ +package main + +import ( + "math/big" + "testing" +) + +const count = 10 + +var bigInt, _ = new(big.Int).SetString("565432413251654654654625434542454264546235446254462544625344", 10) +var bigFloat, _ = new(big.Float).SetString("56543241325165465465462543454245426454.6235446254462544625344") + +func BenchmarkSliceDynamic(b *testing.B) { + q := make([]int32, 0, count) + for i := 0; i < b.N; i++ { + q = q[:0] + for j := int32(0); j < count; j++ { + q = append(q, j) + } + } +} + +func BenchmarkSliceFixed(b *testing.B) { + q := make([]int32, count) + for i := 0; i < b.N; i++ { + for j := int32(0); j < count; j++ { + q[j] = j + } + } +} + +func BenchmarkArray(b *testing.B) { + q := [count]int32{} + for i := 0; i < b.N; i++ { + for j := int32(0); j < count; j++ { + q[j] = j + } + } +} + +func BenchmarkBigIntString(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = bigInt.String() + } +} + +func BenchmarkBigIntBytes(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = bigInt.Bytes() + } +} + +func BenchmarkBigIntGob(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = bigInt.GobEncode() + } +} + +func BenchmarkBigFloatString(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = bigFloat.String() + } +} + +func BenchmarkBigFloatGob(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = bigFloat.GobEncode() + } +} diff --git a/test/bench/decode_test.go b/test/bench/decode_test.go new file mode 100644 index 0000000..bf188f9 --- /dev/null +++ b/test/bench/decode_test.go @@ -0,0 +1,263 @@ +package main + +import ( + "bytes" + "testing" + + gogo "bench/proto/gogo/bench" + google "bench/proto/google/bench" + litepbNoPool "bench/proto/litepb_no_pool/bench" + litepbPool "bench/proto/litepb_pool/bench" + litepb2 "github.com/e-tape/litepb/proto" + "github.com/google/uuid" + "google.golang.org/protobuf/proto" +) + +// RUN `make test-compile-for-bench` for init test proto +// go test -bench . -benchmem -benchtime 2s -cpuprofile cpu.prof +// go tool pprof -http :7000 ./cpu.prof + +var _ = litepb2.UUID{} +var decodeData []byte +var decodeModel = &google.Bench{ + Uuid: &litepb2.UUID{ + Value: []byte{18, 52, 86, 120, 21, 117, 69, 117, 101, 117, 135, 83, 19, 84, 21, 64}, + }, + Uint64: 2065657434543, + Uint32: 156547, + String_: "123456", + Smap: map[int32]*google.Bench_InnerForMap{ + 1: { + Uint64: 1, + Uint32: 20, + }, + 2: { + Uint64: 1000, + Uint32: 2000, + }, + 9: { + Uint64: 99, + Uint32: 99, + }, + 14: { + Uint64: 14, + Uint32: 14, + }, + 72: { + Uint64: 72, + Uint32: 72, + }, + 602: { + Uint64: 602, + Uint32: 602, + }, + }, + Iarr: []*google.Bench_InnerForMap{ + { + Uint64: 1001, + Uint32: 1001, + }, + { + Uint64: 2002, + Uint32: 2002, + }, + { + Uint64: 62002, + Uint32: 62002, + }, + }, + Ifm: &google.Bench_InnerForMap{ + Uint64: 64, + Uint32: 32, + }, + Fixed64: 2065657434543, + Fixed32: 156547, + RInt32: []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, +} + +func init() { + d, err := proto.Marshal(decodeModel) + if err != nil { + panic(err) + } + decodeData = d +} + +func BenchmarkSimpleGoogle(b *testing.B) { + for i := 0; i < b.N; i++ { + model := &google.Bench{} + if err := proto.Unmarshal(decodeData, model); err != nil { + panic(err) + } + if !bytes.Equal(decodeModel.GetUuid().GetValue(), model.GetUuid().GetValue()) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + } +} + +func BenchmarkSimpleGogo(b *testing.B) { + for i := 0; i < b.N; i++ { + model := &gogo.Bench{} + if err := model.Unmarshal(decodeData); err != nil { + panic(err) + } + if !bytes.Equal(decodeModel.GetUuid().GetValue(), model.GetUuid().GetValue()) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + } +} + +func BenchmarkSimpleLitePb(b *testing.B) { + for i := 0; i < b.N; i++ { + model := litepbPool.NewBench() + if err := model.UnmarshalProto(decodeData); err != nil { + panic(err) + } + if !(bytes.Equal(decodeModel.GetUuid().GetValue(), model.Uuid[:]) || model.Uuid == uuid.Nil) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + model.ReturnToPool() + } +} + +func BenchmarkSimpleLitePbNoPool(b *testing.B) { + for i := 0; i < b.N; i++ { + model := litepbNoPool.NewBench() + if err := model.UnmarshalProto(decodeData); err != nil { + panic(err) + } + if !(bytes.Equal(decodeModel.GetUuid().GetValue(), model.Uuid[:]) || model.Uuid == uuid.Nil) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + model.ReturnToPool() + } +} + +func BenchmarkParallelGoogle(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := &google.Bench{} + if err := proto.Unmarshal(decodeData, model); err != nil { + panic(err) + } + if !bytes.Equal(decodeModel.GetUuid().GetValue(), model.GetUuid().GetValue()) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + } + }) +} + +func BenchmarkParallelGogo(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := &gogo.Bench{} + if err := model.Unmarshal(decodeData); err != nil { + panic(err) + } + if !bytes.Equal(decodeModel.GetUuid().GetValue(), model.GetUuid().GetValue()) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + } + }) +} + +func BenchmarkParallelLitePb(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := litepbPool.NewBench() + if err := model.UnmarshalProto(decodeData); err != nil { + panic(err) + } + if !(bytes.Equal(decodeModel.GetUuid().GetValue(), model.Uuid[:]) || model.Uuid == uuid.Nil) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + model.ReturnToPool() + } + }) +} + +func BenchmarkParallelLitePbNoPool(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := litepbNoPool.NewBench() + if err := model.UnmarshalProto(decodeData); err != nil { + panic(err) + } + if !(bytes.Equal(decodeModel.GetUuid().GetValue(), model.Uuid[:]) || model.Uuid == uuid.Nil) || + decodeModel.Uint32 != model.Uint32 || + decodeModel.Uint64 != model.Uint64 || + decodeModel.String_ != model.String_ || + len(decodeModel.Smap) != len(model.Smap) || + len(decodeModel.Iarr) != len(model.Iarr) || + decodeModel.GetIfm().GetUint32() != model.GetIfm().GetUint32() || + decodeModel.GetIfm().GetUint64() != model.GetIfm().GetUint64() || + len(decodeModel.RInt32) != len(model.RInt32) || + decodeModel.Fixed32 != model.Fixed32 { + panic(`eq`) + } + } + }) +} diff --git a/test/bench/go.mod b/test/bench/go.mod new file mode 100644 index 0000000..d2d7487 --- /dev/null +++ b/test/bench/go.mod @@ -0,0 +1,15 @@ +module bench + +go 1.22.4 + +require ( + github.com/e-tape/litepb v0.0.0-20240628203019-4987e239966f + github.com/gogo/protobuf v1.3.2 + github.com/google/uuid v1.6.0 + google.golang.org/protobuf v1.34.2 +) + +require ( + github.com/golang/protobuf v1.5.4 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/test/bench/go.sum b/test/bench/go.sum new file mode 100644 index 0000000..e8c5260 --- /dev/null +++ b/test/bench/go.sum @@ -0,0 +1,46 @@ +github.com/e-tape/litepb v0.0.0-20240628203019-4987e239966f h1:MwhB3eo6yWaeTvAvq17iSqAFobSrzWuCoGgTEk7nF94= +github.com/e-tape/litepb v0.0.0-20240628203019-4987e239966f/go.mod h1:gAGJ9RFS2hMOz2CNESF4YOw3luUhsoSFX94yE8SWhCo= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +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/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/test/bench/marge/marge_test.go b/test/bench/marge/marge_test.go new file mode 100644 index 0000000..aed3d74 --- /dev/null +++ b/test/bench/marge/marge_test.go @@ -0,0 +1,103 @@ +package main + +import ( + "slices" + "testing" + + gogo "bench/proto/gogo/bench" + google "bench/proto/google/bench" + litepbNoPool "bench/proto/litepb_no_pool/bench" + "google.golang.org/protobuf/proto" +) + +func TestMarge(t *testing.T) { + d1, err := proto.Marshal(&google.Bench{Ifm: &google.Bench_InnerForMap{Uint64: 1}}) + if err != nil { + panic(err) + } + d2, err := proto.Marshal(&google.Bench{Ifm: &google.Bench_InnerForMap{Uint32: 2}}) + if err != nil { + panic(err) + } + { + model := &google.Bench{} + if err = proto.Unmarshal(d1, model); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 1 && model.GetIfm().GetUint32() != 0 { + panic("eq") + } + } + { + model := &google.Bench{} + if err = proto.Unmarshal(d2, model); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 0 && model.GetIfm().GetUint32() != 2 { + panic("eq") + } + } + { + model := &google.Bench{} + if err = proto.Unmarshal(slices.Concat(d2, d1), model); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 1 && model.GetIfm().GetUint32() != 2 { + panic("eq") + } + } + { + model := &gogo.Bench{} + if err = model.Unmarshal(d1); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 1 && model.GetIfm().GetUint32() != 0 { + panic("eq") + } + } + { + model := &gogo.Bench{} + if err = model.Unmarshal(d2); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 0 && model.GetIfm().GetUint32() != 2 { + panic("eq") + } + } + { + model := &gogo.Bench{} + if err = model.Unmarshal(slices.Concat(d2, d1)); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 1 && model.GetIfm().GetUint32() != 2 { + panic("eq") + } + } + { + model := &litepbNoPool.Bench{} + if err = model.UnmarshalProto(d1); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 1 && model.GetIfm().GetUint32() != 0 { + panic("eq") + } + } + { + model := &litepbNoPool.Bench{} + if err = model.UnmarshalProto(d2); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 0 && model.GetIfm().GetUint32() != 2 { + panic("eq") + } + } + { + model := &litepbNoPool.Bench{} + if err = model.UnmarshalProto(slices.Concat(d2, d1)); err != nil { + panic(err) + } + if model.GetIfm().GetUint64() != 1 && model.GetIfm().GetUint32() != 2 { + panic("eq") + } + } +} diff --git a/test/bench/struct_or_setter/decode_test.go b/test/bench/struct_or_setter/decode_test.go new file mode 100644 index 0000000..869da52 --- /dev/null +++ b/test/bench/struct_or_setter/decode_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "testing" + + gogo "bench/proto/gogo/bench" + litepbNoPool "bench/proto/litepb_no_pool/bench" + litepbPool "bench/proto/litepb_pool/bench" +) + +func BenchmarkParallelGogoField(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := &gogo.Bench{} + model.Iarr = []*gogo.Bench_InnerForMap{ + {}, + {}, + {}, + } + } + }) +} + +func BenchmarkParallelField(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := &litepbNoPool.Bench{} + model.Iarr = []*litepbNoPool.Bench_InnerForMap{ + {}, + {}, + {}, + } + } + }) +} + +func BenchmarkParallelSetter(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + model := litepbPool.NewBench() + model.SetIarr([]litepbPool.IBench_InnerForMapGet{ + litepbPool.NewBench_InnerForMap().SetUint32(2).SetUint64(5).SetUint64(654), + litepbPool.NewBench_InnerForMap().SetUint64(6), + litepbPool.NewBench_InnerForMap(), + }) + model.ReturnToPool() + } + }) +} diff --git a/test/encode_test.go b/test/encode_test.go new file mode 100644 index 0000000..026237d --- /dev/null +++ b/test/encode_test.go @@ -0,0 +1,319 @@ +package main + +import ( + "fmt" + "testing" + + "google.golang.org/protobuf/proto" + "test/generated/google" +) + +var data []byte + +func init() { + r := &google.R1{ + U1: 203, + U2: 15, + } + d, err := proto.Marshal(r) + if err != nil { + panic(err) + } + data = d +} + +func BenchmarkSelf(b *testing.B) { + r := &google.R1{} + for i := 0; i < b.N; i++ { + var index int32 + { + next, _, _ := decodeIndex(data[index:]) + index += next + } + { + next, value := decodeUin64(data[index:]) + r.U1 = value + index += next + } + { + next, _, _ := decodeIndex(data[index:]) + index += next + } + { + next, value := decodeUin32(data[index:]) + r.U2 = value + index += next + } + } +} + +func BenchmarkProto(b *testing.B) { + r := &google.R1{} + for i := 0; i < b.N; i++ { + _ = proto.Unmarshal(data, r) + } +} + +func Test(*testing.T) { + r := &google.R1{ + U1: 203, + U2: 15, + } + data, err := proto.Marshal(r) + if err != nil { + panic(err) + } + fmt.Printf("%b\n", data) + fmt.Printf("%d\n", data) + + r2 := &google.R1{} + var index int32 + { + next, number, wType := decodeIndex(data[index:]) + //_, _ = number, wType + fmt.Println(index, number, wType) + index += next + } + { + next, value := decodeUin64(data[index:]) + fmt.Println(index, value) + r2.U1 = value + index += next + } + { + next, number, wType := decodeIndex(data[index:]) + //_, _ = number, wType + fmt.Println(index, number, wType) + index += next + } + { + next, value := decodeUin32(data[index:]) + r2.U2 = value + fmt.Println(index, value) + index += next + } + fmt.Println(r2) +} + +// 127 - 0b01111111 +// 128 - 0b10000000 + +func decodeIndex(data []byte) (index_ int32, fieldNum_ int32, wireType_ int32) { + l := len(data) + var fieldNum int32 + if l > 0 { + index_++ + fieldNum |= int32(data[0] & 127) + if data[0] < 128 { + goto end + } + } + if l > 1 { + index_++ + fieldNum |= int32(data[1]&127) << 7 + if data[1] < 128 { + goto end + } + } + if l > 2 { + index_++ + fieldNum |= int32(data[2]&127) << 14 + if data[2] < 128 { + goto end + } + } + if l > 3 { + index_++ + fieldNum |= int32(data[3]&127) << 21 + if data[3] < 128 { + goto end + } + } + panic(`ErrIntOverflowProto`) +end: + return index_, fieldNum >> 3, fieldNum & 0x7 +} +func decodeUin32(data []byte) (index_ int32, result_ uint32) { + l := len(data) + if l > 0 { + index_++ + result_ |= uint32(data[0] & 127) + if data[0] < 128 { + goto end + } + } + if l > 1 { + index_++ + result_ |= uint32(data[1]&127) << 7 + if data[1] < 128 { + goto end + } + } + if l > 2 { + index_++ + result_ |= uint32(data[2]&127) << 14 + if data[2] < 128 { + goto end + } + } + if l > 3 { + index_++ + result_ |= uint32(data[3]&127) << 21 + if data[3] < 128 { + goto end + } + } + panic(`ErrIntOverflowProto`) +end: + return index_, result_ +} +func decodeUin64(data []byte) (index_ int32, result_ uint64) { + l := len(data) + if l > 0 { + index_++ + result_ |= uint64(data[0] & 127) + if data[0] < 128 { + goto end + } + } + if l > 1 { + index_++ + result_ |= uint64(data[1]&127) << 7 + if data[1] < 128 { + goto end + } + } + if l > 2 { + index_++ + result_ |= uint64(data[2]&127) << 14 + if data[2] < 128 { + goto end + } + } + if l > 3 { + index_++ + result_ |= uint64(data[3]&127) << 21 + if data[3] < 128 { + goto end + } + } + if l > 4 { + index_++ + result_ |= uint64(data[4]&127) << 28 + if data[4] < 128 { + goto end + } + } + if l > 5 { + index_++ + result_ |= uint64(data[5]&127) << 35 + if data[5] < 128 { + goto end + } + } + if l > 6 { + index_++ + result_ |= uint64(data[6]&127) << 42 + if data[6] < 128 { + goto end + } + } + if l > 7 { + index_++ + result_ |= uint64(data[7]&127) << 49 + if data[7] < 128 { + goto end + } + } + if l > 8 { + index_++ + result_ |= uint64(data[8]&127) << 56 + if data[8] < 128 { + goto end + } + } + if l > 9 { + index_++ + result_ |= uint64(data[9]&127) << 63 + if data[9] < 128 { + goto end + } + } + panic(`ErrIntOverflowProto`) +end: + return index_, result_ +} + +//func benchIfGoto(bm bench) func(*testing.B) { +// return func(bt *testing.B) { +// for i := 0; i < bt.N; i++ { +// l := len(bm.inData) +// var i64 int64 +// if l > 0 { +// i64 |= int64(bm.inData[0] & 0b01111111) +// if bm.inData[0] < 0b10000000 { +// goto end +// } +// } +// if l > 1 { +// i64 |= int64(bm.inData[1]&0b01111111) << 7 +// if bm.inData[1] < 0b10000000 { +// goto end +// } +// } +// if l > 2 { +// i64 |= int64(bm.inData[2]&0b01111111) << 14 +// if bm.inData[2] < 0b10000000 { +// goto end +// } +// } +// if l > 3 { +// i64 |= int64(bm.inData[3]&0b01111111) << 21 +// if bm.inData[3] < 0b10000000 { +// goto end +// } +// } +// if l > 4 { +// i64 |= int64(bm.inData[4]&0b01111111) << 28 +// if bm.inData[4] < 0b10000000 { +// goto end +// } +// } +// if l > 5 { +// i64 |= int64(bm.inData[5]&0b01111111) << 35 +// if bm.inData[5] < 0b10000000 { +// goto end +// } +// } +// if l > 6 { +// i64 |= int64(bm.inData[6]&0b01111111) << 42 +// if bm.inData[6] < 0b10000000 { +// goto end +// } +// } +// if l > 7 { +// i64 |= int64(bm.inData[7]&0b01111111) << 49 +// if bm.inData[7] < 0b10000000 { +// goto end +// } +// } +// if l > 8 { +// i64 |= int64(bm.inData[8]&0b01111111) << 56 +// if bm.inData[8] < 0b10000000 { +// goto end +// } +// } +// if l > 9 { +// i64 |= int64(bm.inData[9]&0b01111111) << 63 +// if bm.inData[9] < 0b10000000 { +// goto end +// } +// } +// panic(`ErrIntOverflowProto`) +// end: +// if i64 != bm.inI64 { +// panic(`mismatch`) +// } +// } +// } +//} diff --git a/test/go.mod b/test/go.mod new file mode 100644 index 0000000..1bcc69c --- /dev/null +++ b/test/go.mod @@ -0,0 +1,12 @@ +module test + +go 1.22.4 + +replace github.com/e-tape/litepb => ../ + +require ( + github.com/google/uuid v1.6.0 + google.golang.org/protobuf v1.34.2 +) + +require golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect diff --git a/test/go.sum b/test/go.sum new file mode 100644 index 0000000..9b4c6a9 --- /dev/null +++ b/test/go.sum @@ -0,0 +1,8 @@ +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/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/test/per2_test.go b/test/per2_test.go new file mode 100644 index 0000000..283c805 --- /dev/null +++ b/test/per2_test.go @@ -0,0 +1,103 @@ +package main + +import ( + "math/bits" + "strconv" + "testing" +) + +var mathBits = []uint64{ + 1, 10, 100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000, 100_000_000, 1_000_000_000, 10_000_000_000, 100_000_000_000, 1_000_000_000_000, +} + +func BenchmarkMathBits(b *testing.B) { + bLen := 0 + for _, bm := range mathBits { + b.Run(strconv.FormatUint(bm, 10), func(b *testing.B) { + for i := 0; i < b.N; i++ { + bLen = (bits.Len64(bm+uint64(i)|1) + 6) / 7 + } + }) + } + _ = bLen +} + +func BenchmarkMathBitsIf(b *testing.B) { + bLen := 0 + for _, bm := range mathBits { + b.Run(strconv.FormatUint(bm, 10), func(b *testing.B) { + for i := 0; i < b.N; i++ { + bLen = mathBitsIf(bm + uint64(i)) + } + }) + } + _ = bLen +} + +func mathBitsIf(value uint64) int { + if value <= 127 { + return 1 + } + if value <= 16383 { + return 2 + } + if value <= 2097151 { + return 3 + } + if value <= 268435455 { + return 4 + } + if value <= 34359738367 { + return 5 + } + if value <= 4398046511103 { + return 6 + } + if value <= 562949953421311 { + return 7 + } + if value <= 72057594037927935 { + return 8 + } + if value <= 9223372036854775807 { + return 9 + } + return 10 +} + +func BenchmarkMathBitsCase(b *testing.B) { + bLen := 0 + for _, bm := range mathBits { + b.Run(strconv.FormatUint(bm, 10), func(b *testing.B) { + for i := 0; i < b.N; i++ { + bLen = mathBitsCase(bm + uint64(i)) + } + }) + } + _ = bLen +} + +func mathBitsCase(value uint64) int { + switch { + case value <= 127: + return 1 + case value <= 16383: + return 2 + case value <= 2097151: + return 3 + case value <= 268435455: + return 4 + case value <= 34359738367: + return 5 + case value <= 4398046511103: + return 6 + case value <= 562949953421311: + return 7 + case value <= 72057594037927935: + return 8 + case value <= 9223372036854775807: + return 9 + default: + return 10 + } +} diff --git a/test/per_test.go b/test/per_test.go new file mode 100644 index 0000000..74072c5 --- /dev/null +++ b/test/per_test.go @@ -0,0 +1,249 @@ +package main + +import ( + "fmt" + "sync" + "testing" +) + +type Qu struct { + Int int + err error +} + +func (a *Qu) SetInt(value int) *Qu { + if a == nil { + a = &Qu{} + } + a.Int = value + return a +} + +func (a *Qu) ppp() { + *a = Qu{} +} + +func TestPointer(t *testing.T) { + var q *Qu + q.SetInt(55).SetInt(6547) + fmt.Println(q) + q = &Qu{Int: 555} + fmt.Printf("%p\n", q) + q.ppp() + fmt.Printf("%p\n", q) + q.ppp() + fmt.Printf("%p\n", q) +} + +type Q struct { + f1 int + f2 string + f3 float32 + f4 []int32 + f5 map[int]int + f6 int64 + f7 *Q + f8 bool + f9 []byte + f0 uint32 +} +type IQ interface { + get_f1() int + get_f2() string + get_f3() float32 + get_f4() []int32 + get_f5() map[int]int + get_f6() int64 + get_f7() *Q + get_f8() bool + get_f9() []byte + get_f0() uint32 +} + +func (a *Q) get_f1() int { + if a == nil { + return 0 + } + return a.f1 +} +func (a *Q) get_f2() string { + if a == nil { + return "" + } + return a.f2 +} +func (a *Q) get_f3() float32 { + if a == nil { + return 0 + } + return a.f3 +} +func (a *Q) get_f4() []int32 { + if a == nil { + return nil + } + return a.f4 +} +func (a *Q) get_f5() map[int]int { + if a == nil { + return nil + } + return a.f5 +} +func (a *Q) get_f6() int64 { + if a == nil { + return 0 + } + return a.f6 +} +func (a *Q) get_f7() *Q { + if a == nil { + return nil + } + return a.f7 +} +func (a *Q) get_f8() bool { + if a == nil { + return false + } + return a.f8 +} +func (a *Q) get_f9() []byte { + if a == nil { + return nil + } + return a.f9 +} +func (a *Q) get_f0() uint32 { + if a == nil { + return 0 + } + return a.f0 +} + +func BenchmarkField(b *testing.B) { + q := Q{ + f1: 10, + f2: "10", + f3: 10, + f4: []int32{10}, + f5: map[int]int{10: 10}, + f6: 10, + f7: &Q{}, + f8: false, + f9: []byte{10}, + f0: 10, + } + w := &Q{} + for i := 0; i < b.N; i++ { + w.f1 = q.f1 + w.f2 = q.f2 + w.f3 = q.f3 + w.f4 = q.f4 + w.f5 = q.f5 + w.f6 = q.f6 + w.f7 = q.f7 + w.f8 = q.f8 + w.f9 = q.f9 + w.f0 = q.f0 + } +} + +func BenchmarkInterface(b *testing.B) { + q := Q{ + f1: 10, + f2: "10", + f3: 10, + f4: []int32{10}, + f5: map[int]int{10: 10}, + f6: 10, + f7: &Q{}, + f8: false, + f9: []byte{10}, + f0: 10, + } + w := &Q{} + for i := 0; i < b.N; i++ { + w.f1 = q.get_f1() + w.f2 = q.get_f2() + w.f3 = q.get_f3() + w.f4 = q.get_f4() + w.f5 = q.get_f5() + w.f6 = q.get_f6() + w.f7 = q.get_f7() + w.f8 = q.get_f8() + w.f9 = q.get_f9() + w.f0 = q.get_f0() + } +} + +type EmptyStruct struct{} + +func (a *EmptyStruct) U() int { + return 10 +} + +func BenchmarkEmptyStructPool(b *testing.B) { + pool := sync.Pool{ + New: func() any { return &EmptyStruct{} }, + } + for i := 0; i < b.N; i++ { + q := pool.Get().(*EmptyStruct) + collect(q) + pool.Put(q) + } +} +func BenchmarkEmptyStruct(b *testing.B) { + for i := 0; i < b.N; i++ { + q := &EmptyStruct{} + collect(q) + } +} +func BenchmarkEmptyStructConst(b *testing.B) { + e := &EmptyStruct{} + for i := 0; i < b.N; i++ { + collect(e) + } +} + +var lastEmptyStruct *EmptyStruct + +func collect(e *EmptyStruct) { + lastEmptyStruct = e +} + +type R struct{} + +func (a *R) Reset() {} + +func BenchmarkReset(b *testing.B) { + r := &R{} + for i := 0; i < b.N; i++ { + r.Reset() + } +} +func BenchmarkResetNil(b *testing.B) { + var r *R = nil + for i := 0; i < b.N; i++ { + r.Reset() + } +} + +type Ii interface { + Q() +} +type Q0 struct { + i Ii +} +type Q1 struct{} +type Q2 struct{} + +func (a *Q1) Q() {} +func (a *Q2) Q() {} + +func TestCastType(t *testing.T) { + q := &Q0{} + if q.i != nil { + q.i.Q() + } +} diff --git a/test/proto/bench/bench.proto b/test/proto/bench/bench.proto new file mode 100644 index 0000000..d6d35a7 --- /dev/null +++ b/test/proto/bench/bench.proto @@ -0,0 +1,72 @@ +syntax = "proto3"; + +package bench; + +option go_package = "/bench"; + +//import "vendor/validate/validate.proto"; +//import "proto/options.proto"; +import "proto/uuid.proto"; + +message Bench { + litepb.UUID uuid = 10100; + repeated litepb.UUID r_uuid = 10101; + map m_uuid = 10102; + + uint64 request_id = 1; + uint64 uint64 = 4; + uint32 uint32 = 200; + int64 int64 = 201; + int32 int32 = 202; + sint64 sint64 = 203; + sint32 sint32 = 204; + repeated sint64 r_sint64 = 205; + repeated sint32 r_sint32 = 206; + string string = 207; + repeated string r_string = 208; + map map = 209; + map smap = 210; + repeated InnerForMap iarr = 211; + InnerForMap ifm = 220; + + bytes bytes = 229; + + repeated int32 r_int32 = 250; + + repeated fixed32 r_fixed32 = 299; + fixed32 fixed32 = 300; + sfixed32 sfixed32 = 301; + float float = 303; + + fixed64 fixed64 = 400; + sfixed64 sfixed64 = 401; + double double = 403; + + oneof __age { + uint32 age1 = 500; + Empty no_age = 501; + } + + oneof ordering { + uint32 o1 = 160; +// int64 o2 = 8; +// int64 o3 = 14; +// int64 o4 = 15; +// int64 o5 = 16; + } + + int64 o2 = 8; + int64 o3 = 14; + int64 o4 = 15; + int64 o5 = 16; + + message Empty{} + message InnerForMap { + uint64 uint64 = 1;// [(validate.rules).uint64.gte = 1]; + uint32 uint32 = 2;// [(validate.rules).uint32.gte = 1]; + } + message NoPool { + // option (litepb.mem_pool) = Inactive; + string string = 1; + } +} \ No newline at end of file diff --git a/test/proto/bench/bench_additional.proto b/test/proto/bench/bench_additional.proto new file mode 100644 index 0000000..caa56c0 --- /dev/null +++ b/test/proto/bench/bench_additional.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package bench; + +option go_package = "/bench"; + +import "proto/options.proto"; + +message NoPool { + option (litepb.mem_pool_message) = Inactive; + string string = 1; +} \ No newline at end of file diff --git a/test/proto/bench/litepb.toml b/test/proto/bench/litepb.toml new file mode 100644 index 0000000..8100e83 --- /dev/null +++ b/test/proto/bench/litepb.toml @@ -0,0 +1,5 @@ +source_relative = false +mem_pool_message_all = "TRUE" +mem_pool_list_all = true +mem_pool_map_all = "on" +mem_pool_oneof_all = "aCtive" \ No newline at end of file diff --git a/test/proto/bench/litepb.yaml b/test/proto/bench/litepb.yaml new file mode 100644 index 0000000..a434d68 --- /dev/null +++ b/test/proto/bench/litepb.yaml @@ -0,0 +1,5 @@ +source_relative: false +#mem_pool_message_all: TRUE +#mem_pool_list_all: True +#mem_pool_map_all: on +#mem_pool_oneof_all: aCtive \ No newline at end of file diff --git a/test/proto/bench/vendor/validate/validate.proto b/test/proto/bench/vendor/validate/validate.proto new file mode 100644 index 0000000..5aa9653 --- /dev/null +++ b/test/proto/bench/vendor/validate/validate.proto @@ -0,0 +1,862 @@ +syntax = "proto2"; +package validate; + +option go_package = "github.com/envoyproxy/protoc-gen-validate/validate"; +option java_package = "io.envoyproxy.pgv.validate"; + +import "google/protobuf/descriptor.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +// Validation rules applied at the message level +extend google.protobuf.MessageOptions { + // Disabled nullifies any validation rules for this message, including any + // message fields associated with it that do support validation. + optional bool disabled = 1071; + // Ignore skips generation of validation methods for this message. + optional bool ignored = 1072; +} + +// Validation rules applied at the oneof level +extend google.protobuf.OneofOptions { + // Required ensures that exactly one the field options in a oneof is set; + // validation fails if no fields in the oneof are set. + optional bool required = 1071; +} + +// Validation rules applied at the field level +extend google.protobuf.FieldOptions { + // Rules specify the validations to be performed on this field. By default, + // no validation is performed against a field. + optional FieldRules rules = 1071; +} + +// FieldRules encapsulates the rules for each type of field. Depending on the +// field, the correct set should be used to ensure proper validations. +message FieldRules { + optional MessageRules message = 17; + oneof type { + // Scalar Field Types + FloatRules float = 1; + DoubleRules double = 2; + Int32Rules int32 = 3; + Int64Rules int64 = 4; + UInt32Rules uint32 = 5; + UInt64Rules uint64 = 6; + SInt32Rules sint32 = 7; + SInt64Rules sint64 = 8; + Fixed32Rules fixed32 = 9; + Fixed64Rules fixed64 = 10; + SFixed32Rules sfixed32 = 11; + SFixed64Rules sfixed64 = 12; + BoolRules bool = 13; + StringRules string = 14; + BytesRules bytes = 15; + + // Complex Field Types + EnumRules enum = 16; + RepeatedRules repeated = 18; + MapRules map = 19; + + // Well-Known Field Types + AnyRules any = 20; + DurationRules duration = 21; + TimestampRules timestamp = 22; + } +} + +// FloatRules describes the constraints applied to `float` values +message FloatRules { + // Const specifies that this field must be exactly the specified value + optional float const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional float lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional float lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional float gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional float gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated float in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated float not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// DoubleRules describes the constraints applied to `double` values +message DoubleRules { + // Const specifies that this field must be exactly the specified value + optional double const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional double lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional double lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional double gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional double gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated double in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated double not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Int32Rules describes the constraints applied to `int32` values +message Int32Rules { + // Const specifies that this field must be exactly the specified value + optional int32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional int32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional int32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional int32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional int32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated int32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Int64Rules describes the constraints applied to `int64` values +message Int64Rules { + // Const specifies that this field must be exactly the specified value + optional int64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional int64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional int64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional int64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional int64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated int64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// UInt32Rules describes the constraints applied to `uint32` values +message UInt32Rules { + // Const specifies that this field must be exactly the specified value + optional uint32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional uint32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional uint32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional uint32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional uint32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated uint32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated uint32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// UInt64Rules describes the constraints applied to `uint64` values +message UInt64Rules { + // Const specifies that this field must be exactly the specified value + optional uint64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional uint64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional uint64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional uint64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional uint64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated uint64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated uint64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SInt32Rules describes the constraints applied to `sint32` values +message SInt32Rules { + // Const specifies that this field must be exactly the specified value + optional sint32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sint32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sint32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sint32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sint32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sint32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sint32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SInt64Rules describes the constraints applied to `sint64` values +message SInt64Rules { + // Const specifies that this field must be exactly the specified value + optional sint64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sint64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sint64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sint64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sint64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sint64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sint64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Fixed32Rules describes the constraints applied to `fixed32` values +message Fixed32Rules { + // Const specifies that this field must be exactly the specified value + optional fixed32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional fixed32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional fixed32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional fixed32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional fixed32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated fixed32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated fixed32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Fixed64Rules describes the constraints applied to `fixed64` values +message Fixed64Rules { + // Const specifies that this field must be exactly the specified value + optional fixed64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional fixed64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional fixed64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional fixed64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional fixed64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated fixed64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated fixed64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SFixed32Rules describes the constraints applied to `sfixed32` values +message SFixed32Rules { + // Const specifies that this field must be exactly the specified value + optional sfixed32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sfixed32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sfixed32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sfixed32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sfixed32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sfixed32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sfixed32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SFixed64Rules describes the constraints applied to `sfixed64` values +message SFixed64Rules { + // Const specifies that this field must be exactly the specified value + optional sfixed64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sfixed64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sfixed64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sfixed64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sfixed64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sfixed64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sfixed64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// BoolRules describes the constraints applied to `bool` values +message BoolRules { + // Const specifies that this field must be exactly the specified value + optional bool const = 1; +} + +// StringRules describe the constraints applied to `string` values +message StringRules { + // Const specifies that this field must be exactly the specified value + optional string const = 1; + + // Len specifies that this field must be the specified number of + // characters (Unicode code points). Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 len = 19; + + // MinLen specifies that this field must be the specified number of + // characters (Unicode code points) at a minimum. Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 min_len = 2; + + // MaxLen specifies that this field must be the specified number of + // characters (Unicode code points) at a maximum. Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 max_len = 3; + + // LenBytes specifies that this field must be the specified number of bytes + optional uint64 len_bytes = 20; + + // MinBytes specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 min_bytes = 4; + + // MaxBytes specifies that this field must be the specified number of bytes + // at a maximum + optional uint64 max_bytes = 5; + + // Pattern specifies that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + optional string pattern = 6; + + // Prefix specifies that this field must have the specified substring at + // the beginning of the string. + optional string prefix = 7; + + // Suffix specifies that this field must have the specified substring at + // the end of the string. + optional string suffix = 8; + + // Contains specifies that this field must have the specified substring + // anywhere in the string. + optional string contains = 9; + + // NotContains specifies that this field cannot have the specified substring + // anywhere in the string. + optional string not_contains = 23; + + // In specifies that this field must be equal to one of the specified + // values + repeated string in = 10; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated string not_in = 11; + + // WellKnown rules provide advanced constraints against common string + // patterns + oneof well_known { + // Email specifies that the field must be a valid email address as + // defined by RFC 5322 + bool email = 12; + + // Hostname specifies that the field must be a valid hostname as + // defined by RFC 1034. This constraint does not support + // internationalized domain names (IDNs). + bool hostname = 13; + + // Ip specifies that the field must be a valid IP (v4 or v6) address. + // Valid IPv6 addresses should not include surrounding square brackets. + bool ip = 14; + + // Ipv4 specifies that the field must be a valid IPv4 address. + bool ipv4 = 15; + + // Ipv6 specifies that the field must be a valid IPv6 address. Valid + // IPv6 addresses should not include surrounding square brackets. + bool ipv6 = 16; + + // Uri specifies that the field must be a valid, absolute URI as defined + // by RFC 3986 + bool uri = 17; + + // UriRef specifies that the field must be a valid URI as defined by RFC + // 3986 and may be relative or absolute. + bool uri_ref = 18; + + // Address specifies that the field must be either a valid hostname as + // defined by RFC 1034 (which does not support internationalized domain + // names or IDNs), or it can be a valid IP (v4 or v6). + bool address = 21; + + // Uuid specifies that the field must be a valid UUID as defined by + // RFC 4122 + bool uuid = 22; + + // WellKnownRegex specifies a common well known pattern defined as a regex. + KnownRegex well_known_regex = 24; + } + + // This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable + // strict header validation. + // By default, this is true, and HTTP header validations are RFC-compliant. + // Setting to false will enable a looser validations that only disallows + // \r\n\0 characters, which can be used to bypass header matching rules. + optional bool strict = 25 [default = true]; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 26; +} + +// WellKnownRegex contain some well-known patterns. +enum KnownRegex { + UNKNOWN = 0; + + // HTTP header name as defined by RFC 7230. + HTTP_HEADER_NAME = 1; + + // HTTP header value as defined by RFC 7230. + HTTP_HEADER_VALUE = 2; +} + +// BytesRules describe the constraints applied to `bytes` values +message BytesRules { + // Const specifies that this field must be exactly the specified value + optional bytes const = 1; + + // Len specifies that this field must be the specified number of bytes + optional uint64 len = 13; + + // MinLen specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 min_len = 2; + + // MaxLen specifies that this field must be the specified number of bytes + // at a maximum + optional uint64 max_len = 3; + + // Pattern specifies that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + optional string pattern = 4; + + // Prefix specifies that this field must have the specified bytes at the + // beginning of the string. + optional bytes prefix = 5; + + // Suffix specifies that this field must have the specified bytes at the + // end of the string. + optional bytes suffix = 6; + + // Contains specifies that this field must have the specified bytes + // anywhere in the string. + optional bytes contains = 7; + + // In specifies that this field must be equal to one of the specified + // values + repeated bytes in = 8; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated bytes not_in = 9; + + // WellKnown rules provide advanced constraints against common byte + // patterns + oneof well_known { + // Ip specifies that the field must be a valid IP (v4 or v6) address in + // byte format + bool ip = 10; + + // Ipv4 specifies that the field must be a valid IPv4 address in byte + // format + bool ipv4 = 11; + + // Ipv6 specifies that the field must be a valid IPv6 address in byte + // format + bool ipv6 = 12; + } + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 14; +} + +// EnumRules describe the constraints applied to enum values +message EnumRules { + // Const specifies that this field must be exactly the specified value + optional int32 const = 1; + + // DefinedOnly specifies that this field must be only one of the defined + // values for this enum, failing on any undefined value. + optional bool defined_only = 2; + + // In specifies that this field must be equal to one of the specified + // values + repeated int32 in = 3; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int32 not_in = 4; +} + +// MessageRules describe the constraints applied to embedded message values. +// For message-type fields, validation is performed recursively. +message MessageRules { + // Skip specifies that the validation rules of this field should not be + // evaluated + optional bool skip = 1; + + // Required specifies that this field must be set + optional bool required = 2; +} + +// RepeatedRules describe the constraints applied to `repeated` values +message RepeatedRules { + // MinItems specifies that this field must have the specified number of + // items at a minimum + optional uint64 min_items = 1; + + // MaxItems specifies that this field must have the specified number of + // items at a maximum + optional uint64 max_items = 2; + + // Unique specifies that all elements in this field must be unique. This + // constraint is only applicable to scalar and enum types (messages are not + // supported). + optional bool unique = 3; + + // Items specifies the constraints to be applied to each item in the field. + // Repeated message fields will still execute validation against each item + // unless skip is specified here. + optional FieldRules items = 4; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 5; +} + +// MapRules describe the constraints applied to `map` values +message MapRules { + // MinPairs specifies that this field must have the specified number of + // KVs at a minimum + optional uint64 min_pairs = 1; + + // MaxPairs specifies that this field must have the specified number of + // KVs at a maximum + optional uint64 max_pairs = 2; + + // NoSparse specifies values in this field cannot be unset. This only + // applies to map's with message value types. + optional bool no_sparse = 3; + + // Keys specifies the constraints to be applied to each key in the field. + optional FieldRules keys = 4; + + // Values specifies the constraints to be applied to the value of each key + // in the field. Message values will still have their validations evaluated + // unless skip is specified here. + optional FieldRules values = 5; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 6; +} + +// AnyRules describe constraints applied exclusively to the +// `google.protobuf.Any` well-known type +message AnyRules { + // Required specifies that this field must be set + optional bool required = 1; + + // In specifies that this field's `type_url` must be equal to one of the + // specified values. + repeated string in = 2; + + // NotIn specifies that this field's `type_url` must not be equal to any of + // the specified values. + repeated string not_in = 3; +} + +// DurationRules describe the constraints applied exclusively to the +// `google.protobuf.Duration` well-known type +message DurationRules { + // Required specifies that this field must be set + optional bool required = 1; + + // Const specifies that this field must be exactly the specified value + optional google.protobuf.Duration const = 2; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional google.protobuf.Duration lt = 3; + + // Lt specifies that this field must be less than the specified value, + // inclusive + optional google.protobuf.Duration lte = 4; + + // Gt specifies that this field must be greater than the specified value, + // exclusive + optional google.protobuf.Duration gt = 5; + + // Gte specifies that this field must be greater than the specified value, + // inclusive + optional google.protobuf.Duration gte = 6; + + // In specifies that this field must be equal to one of the specified + // values + repeated google.protobuf.Duration in = 7; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated google.protobuf.Duration not_in = 8; +} + +// TimestampRules describe the constraints applied exclusively to the +// `google.protobuf.Timestamp` well-known type +message TimestampRules { + // Required specifies that this field must be set + optional bool required = 1; + + // Const specifies that this field must be exactly the specified value + optional google.protobuf.Timestamp const = 2; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional google.protobuf.Timestamp lt = 3; + + // Lte specifies that this field must be less than the specified value, + // inclusive + optional google.protobuf.Timestamp lte = 4; + + // Gt specifies that this field must be greater than the specified value, + // exclusive + optional google.protobuf.Timestamp gt = 5; + + // Gte specifies that this field must be greater than the specified value, + // inclusive + optional google.protobuf.Timestamp gte = 6; + + // LtNow specifies that this must be less than the current time. LtNow + // can only be used with the Within rule. + optional bool lt_now = 7; + + // GtNow specifies that this must be greater than the current time. GtNow + // can only be used with the Within rule. + optional bool gt_now = 8; + + // Within specifies that this field must be within this duration of the + // current time. This constraint can be used alone or with the LtNow and + // GtNow rules. + optional google.protobuf.Duration within = 9; +} diff --git a/test/proto/common/c1.proto b/test/proto/common/c1.proto index e48e584..6b0e8a3 100644 --- a/test/proto/common/c1.proto +++ b/test/proto/common/c1.proto @@ -2,6 +2,6 @@ syntax = "proto3"; package common; -option go_package = "generated/test/common"; +option go_package = "test/generated/test/common"; message C1{} diff --git a/test/proto/common/c2.proto b/test/proto/common/c2.proto index 1414e01..41e6a71 100644 --- a/test/proto/common/c2.proto +++ b/test/proto/common/c2.proto @@ -2,6 +2,9 @@ syntax = "proto3"; package common; -option go_package = "generated/test/inside/common"; +option go_package = "test/generated/test/inside/common"; -message C2{} +message C2{ + int32 i1 = 1; + int32 i2 = 2; +} diff --git a/test/proto/dir/dir/test.proto b/test/proto/dir/dir/test.proto index 598189e..3dd5c05 100644 --- a/test/proto/dir/dir/test.proto +++ b/test/proto/dir/dir/test.proto @@ -2,6 +2,6 @@ syntax = "proto3"; package dir.dir; -option go_package = "generated/test/dir/dir"; +option go_package = "test/generated/test/dir/dir"; message Baz3 {} diff --git a/test/proto/dir/test.proto b/test/proto/dir/test.proto index a050091..b2723b8 100644 --- a/test/proto/dir/test.proto +++ b/test/proto/dir/test.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package dir; -option go_package = "generated/test/dir;dir_package"; +option go_package = "test/generated/test/dir;dir_package"; message Baz {} diff --git a/test/proto/dir1/test_dir.proto b/test/proto/dir1/test_dir.proto new file mode 100644 index 0000000..38c8df8 --- /dev/null +++ b/test/proto/dir1/test_dir.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +package dir1; + +option go_package = "test/generated/test/dir;dir_package"; + +message Dir1 { + string name = 1; +} \ No newline at end of file diff --git a/test/proto/dir2/test_dir.proto b/test/proto/dir2/test_dir.proto new file mode 100644 index 0000000..66e4bad --- /dev/null +++ b/test/proto/dir2/test_dir.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; + +package dir; + +option go_package = "test/generated/test/dir2;dir_package"; + +message Dir2 {} \ No newline at end of file diff --git a/test/proto/struct/struct.proto b/test/proto/struct/struct.proto new file mode 100644 index 0000000..c6cc55a --- /dev/null +++ b/test/proto/struct/struct.proto @@ -0,0 +1,64 @@ +syntax = "proto3"; + +package bench; + +option go_package = "/bench"; + +message Bench { + uint64 request_id = 1; + uint64 uint64 = 4; + uint32 uint32 = 200; + int64 int64 = 201; + int32 int32 = 202; + sint64 sint64 = 203; + sint32 sint32 = 204; + repeated sint64 r_sint64 = 205; + repeated sint32 r_sint32 = 206; + string string = 207; + repeated string r_string = 208; + map map = 209; + map smap = 210; + + repeated fixed32 r_fixed32 = 299; + fixed32 fixed32 = 300; + sfixed32 sfixed32 = 301; + float float = 303; + + fixed64 fixed64 = 400; + sfixed64 sfixed64 = 401; + double double = 403; + + oneof __age { + uint32 age1 = 500; + Empty no_age = 501; + } + oneof __page { + fixed32 page1 = 600; + _Empty no_page = 601; + } + oneof _page { + fixed32 page2 = 610; + __Empty no_page2 = 611; + } + oneof ___page { + fixed32 page3 = 620; + __Empty no_page3 = 621; + } + oneof _____page { + fixed32 page4 = 630; + __Empty no_page4 = 631; + } + int32 _age = 1000; + // int32 X_age = 1001; + int32 X_page = 1002; + string ProtoMessage = 999; + + message Empty{} + message _Empty{} + message __Empty{} + message XEmpty{} + message InnerForMap { + uint64 uint64 = 1; + uint32 uint32 = 2; + } +} \ No newline at end of file diff --git a/test/proto/test.proto b/test/proto/test.proto index 72b8856..18136d6 100644 --- a/test/proto/test.proto +++ b/test/proto/test.proto @@ -2,11 +2,13 @@ syntax = "proto3"; package test; -option go_package = "generated/test"; +option go_package = "test/generated/test"; import "test2.proto"; import "test3.proto"; import "dir/test.proto"; +import "dir1/test_dir.proto"; +import "dir2/test_dir.proto"; import "dir/dir/test.proto"; import "common/c1.proto"; @@ -19,6 +21,10 @@ enum Direction { WEST = 3; } +message R1 { + uint64 u64 = 1; +} + // Test message message Test { // ID @@ -26,19 +32,65 @@ message Test { // Name string name = 2; - test2.Ok ok2 = 3; + test.Ok ok2 = 3; test3.Ok ok3 = 4; test3.Ok.Status status = 5; - map kv = 6; + map kv = 6; + map kv_int = 7; - dir.Baz baz = 7; - dir.dir.Baz3 baz3 = 8; + dir.Baz baz = 8; + dir.dir.Baz3 baz3 = 9; + dir1.Dir1 dir1 = 10; + dir.Dir2 dir2 = 11; - common.C1 c1 = 9; - common.C2 c2 = 10; + common.C1 c1 = 12; + common.C2 c2 = 13; + // option (field_number_slice_len) = 20; + oneof oo_u { + int32 oo_i = 20;// [(type) = "int64", (num) = 9]; + string s = 21; + MsgForQOneof field_msg = 22; + } + test3.Error error = 30; + MsgForQOneof for_oneof = 31; + test.MsgForQOneof for_oneof_global = 32; + + repeated dir1.Dir1 r_dir1 = 39; + repeated uint64 r_uint64 = 40; + repeated uint32 r_uint32 = 41; + repeated int32 r_int32 = 42; + repeated int64 r_int64 = 43; + int64 int64 = 44; + int32 int32 = 45; + uint64 uint64 = 46; + uint32 uint32 = 47; + sint32 sint32 = 48; + sint64 sint64 = 49; + repeated sint32 r_sint32 = 50; + repeated sint64 r_sint64 = 51; + repeated bool r_bool = 52; + bool bool = 53; + Direction direction_enum = 54; + repeated Direction r_direction_enum = 55; + + fixed32 fixed32 = 300; + sfixed32 sfixed32 = 301; + float float = 303; + + fixed64 fixed64 = 400; + sfixed64 sfixed64 = 401; + double double = 403; + + + // ForOneof - msg for oneof + message MsgForQOneof { + int32 __int = 1; + int32 ___int2 = 2; + int32 ____int3 = 4; + } // Inner message TEST message Inner { // Inner text @@ -47,6 +99,15 @@ message Test { test3.Error error = 3; } } +// ForOneof - msg for oneof +message MsgForQOneof { + int32 __int = 1; +} + + +message PreFoo { + bool first = 1; +} // Foo message message Foo { @@ -58,8 +119,9 @@ message Foo { repeated Bar bars = 2; // The bar Bar bar = 3; + PreFoo pre_foo = 4; - Status status = 4; + Status status = 5; // Status of FOO enum Status { @@ -72,7 +134,7 @@ message Foo { // Inner message message Inner { // Inner text - string text = 2; + string text = 1; } } @@ -81,4 +143,5 @@ message Bar { bool done = 2; // Numbers repeated int32 numbers = 3; + repeated Foo.Inner foo_inner_field = 4; } diff --git a/test/proto/test2.proto b/test/proto/test2.proto index e2f7cb3..48210e1 100644 --- a/test/proto/test2.proto +++ b/test/proto/test2.proto @@ -1,13 +1,15 @@ syntax = "proto3"; -package test2; +package test; -option go_package = "generated/test"; +option go_package = "test/generated/test"; import "dir/test.proto"; +import "dir1/test_dir.proto"; message Ok {} message Pss { dir.Baz baz = 1; + dir1.Dir1 dir1 = 2; } diff --git a/test/proto/test3.proto b/test/proto/test3.proto index e59dd54..55d7acf 100644 --- a/test/proto/test3.proto +++ b/test/proto/test3.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package test3; -option go_package = "generated/test3"; +option go_package = "test/generated/test3"; // The OK message Ok { diff --git a/test/proto/test4.proto b/test/proto/test4.proto new file mode 100644 index 0000000..450bf48 --- /dev/null +++ b/test/proto/test4.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package ANOTHER.nAmE.test4; + +option go_package = "test/generated/test"; + +// T4 comments +// - list1 +// - list2 +message T4 { + // status comments + // - status1 + // - status2 + int32 status = 1; +} \ No newline at end of file diff --git a/test/t10/q_test.go b/test/t10/q_test.go new file mode 100644 index 0000000..947461b --- /dev/null +++ b/test/t10/q_test.go @@ -0,0 +1,108 @@ +package t10 + +import ( + "sync" + "testing" +) + +func TestQ(t *testing.T) { + m := &sync.Map{} + getData[uint](m) + getData[int](m) + getData[uint32](m) + getData[int32](m) + getData[float32](m) + getData[float64](m) + getData[string](m) + getData[byte](m) + getData[[3]byte](m) + getData[[4]byte](m) +} + +func getData[K comparable](m *sync.Map) { + var key K + _, loaded := m.LoadOrStore(key, key) + if loaded { + panic("loaded") + } +} + +var mapV1 sync.Map +var mapV2 sync.Map + +type Q struct { + Int int + Int1 int + Int2 int + Int3 int + Int4 int + Int5 int + Int6 int + Int7 int +} + +func BenchmarkMap(b *testing.B) { + for i := 0; i < b.N; i++ { + poolRaw, _ := mapV1.LoadOrStore(i%5, &sync.Pool{New: func() any { return make(map[int]*Q) }}) + pool := poolRaw.(*sync.Pool) + qm := pool.Get().(map[int]*Q) + for j := 0; j < 300; j++ { + qm[j%3] = &Q{ + Int: i, + Int2: j, + Int7: i, + } + } + clear(qm) + pool.Put(qm) + } +} + +func BenchmarkMapV2(b *testing.B) { + for i := 0; i < b.N; i++ { + poolRaw, ok := mapV2.Load(i % 5) + if !ok { + poolRaw, _ = mapV2.LoadOrStore(i%5, &sync.Pool{}) + } + pool := poolRaw.(*sync.Pool) + qm, ok := pool.Get().(map[int]*Q) + if !ok { + qm = make(map[int]*Q, 100) + } + for j := 0; j < 300; j++ { + qm[j%3] = &Q{ + Int: i, + Int2: j, + Int7: i, + } + } + clear(qm) + pool.Put(qm) + } +} + +func BenchmarkMake(b *testing.B) { + for i := 0; i < b.N; i++ { + qm := make(map[int]*Q) + for j := 0; j < 300; j++ { + qm[j%3] = &Q{ + Int: i, + Int2: j, + Int7: i, + } + } + } +} + +func BenchmarkMakeCap(b *testing.B) { + for i := 0; i < b.N; i++ { + qm := make(map[int]*Q, 100) + for j := 0; j < 300; j++ { + qm[j%3] = &Q{ + Int: i, + Int2: j, + Int7: i, + } + } + } +} diff --git a/test/t12/q_test.go b/test/t12/q_test.go new file mode 100644 index 0000000..20b3587 --- /dev/null +++ b/test/t12/q_test.go @@ -0,0 +1,137 @@ +package t12 + +import ( + "fmt" + "sync" + "testing" +) + +func TestQ(t *testing.T) { + pool := sync.Pool{} + q := make([]int, 2, 10) + fmt.Println(len(q), cap(q)) + pool.Put(q) + q = pool.Get().([]int) + fmt.Println(len(q), cap(q)) +} + +func BenchmarkQ(b *testing.B) { + //countGet := 0 + //countNot := 0 + for i := 0; i < b.N; i++ { + pool := sync.Pool{} + q := make([]int, 2, 10) + pool.Put(q) + if _, ok := pool.Get().([]int); ok { + //countGet++ + //} else { + // countNot++ + } + } + //fmt.Println("count get", countGet, "count not", countNot) +} + +func BenchmarkParallelSliceNew(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + q := make(ListQ, 0, 20) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + } + }) +} + +func BenchmarkParallelSlice(b *testing.B) { + var pool = &Pool[*Q]{&sync.Pool{}} + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + q := pool.Get(20) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + q = append(q, nil) + pool.Put(q) + } + }) +} + +func BenchmarkParallelSlicePointer(b *testing.B) { + var pool = &PoolPointer[*Q]{&sync.Pool{}} + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + q := pool.Get(20) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + *q = append(*q, nil) + pool.Put(q) + } + }) +} + +type PoolPointer[T any] struct { + *sync.Pool +} +type Pool[T any] struct { + *sync.Pool +} +type Q struct { + Int int +} +type ListQ []*Q + +func (a *PoolPointer[T]) Get(cap int) *[]T { + if q, ok := a.Pool.Get().(*[]T); ok { + return q + } + q := make([]T, 0, cap) + return &q +} + +func (a *PoolPointer[T]) Put(q *[]T) { + clear(*q) + *q = (*q)[:0] + a.Pool.Put(q) +} + +func (a *Pool[T]) Get(cap int) []T { + if q, ok := a.Pool.Get().(*[]T); ok { + return *q + } + return make([]T, 0, cap) +} + +func (a *Pool[T]) Put(q []T) { + clear(q) + q = q[:0] + a.Pool.Put(&q) +} diff --git a/test/t13/q_test.go b/test/t13/q_test.go new file mode 100644 index 0000000..33141c7 --- /dev/null +++ b/test/t13/q_test.go @@ -0,0 +1,85 @@ +package t13 + +import ( + "fmt" + "sync" + "testing" +) + +type Q struct { + Int int +} +type ListQ []*Q + +func Benchmark1(b *testing.B) { + for i := 0; i < b.N; i++ { + list := get() + list = append(list, nil) + put(list) + } +} + +func Benchmark2(b *testing.B) { + for i := 0; i < b.N; i++ { + list := *getP() + list = append(list, nil) + putP(&list) + } +} + +func Benchmark3(b *testing.B) { + for i := 0; i < b.N; i++ { + list := getP() + *list = append(*list, nil) + putP(list) + } +} + +func Benchmark4(b *testing.B) { + for i := 0; i < b.N; i++ { + pt := getP() + list := *pt + list = append(list, nil) + *pt = list + putP(pt) + } +} + +var pool = sync.Pool{New: func() any { return make(ListQ, 0) }} + +func get() ListQ { + return pool.Get().(ListQ) +} +func put(list ListQ) { + list = list[:0] + pool.Put(list) +} + +var poolP = sync.Pool{New: func() any { list := make(ListQ, 0); return &list }} + +func getP() *ListQ { + return poolP.Get().(*ListQ) +} +func putP(list *ListQ) { + *list = (*list)[:0] + poolP.Put(list) +} + +type U struct { + Int int +} + +func Test22(t *testing.T) { + q := make([]*U, 0) + q = append(q, nil, &U{1}, &U{2}, nil) + fmt.Println(q) + q = q[:0] + fmt.Println(q) + q = q[:3] + fmt.Println(q) + clear(q) + q = q[:0] + fmt.Println(q) + q = q[:3] + fmt.Println(q) +} diff --git a/test/t14/q_test.go b/test/t14/q_test.go new file mode 100644 index 0000000..4b49a0f --- /dev/null +++ b/test/t14/q_test.go @@ -0,0 +1,250 @@ +package t14 + +import ( + "math/big" + "sync" + "testing" + + "github.com/google/uuid" +) + +var gUuid uuid.UUID +var bb = []byte{0, 0, 18, 52, 86, 120, 21, 117, 69, 117, 101, 117, 135, 83, 19, 84, 5, 69, 0, 0} +var originUuid = uuid.Must(uuid.FromBytes(bb[2:18])) + +func BenchmarkUuidParseString(b *testing.B) { + for i := 0; i < b.N; i++ { + u := uuid.MustParse("12345678-1575-4575-6575-875313540545") + gUuid = u + } +} +func BenchmarkUuidFromBytes(b *testing.B) { + for i := 0; i < b.N; i++ { + u, err := uuid.FromBytes(bb[2:18]) + if err != nil { + panic(err) + } + if u != originUuid { + panic("eq") + } + gUuid = u + } +} +func BenchmarkUuidRefBytes(b *testing.B) { + for i := 0; i < b.N; i++ { + u := uuid.UUID(bb[2:18]) + if u != originUuid { + panic("eq") + } + gUuid = u + } +} + +var uuidPool = &sync.Pool{New: func() any { return new(uuid.UUID) }} + +func BenchmarkUuidFromBytesPool(b *testing.B) { + for i := 0; i < b.N; i++ { + u := uuidPool.Get().(*uuid.UUID) + err := u.UnmarshalBinary(bb[2:18]) + if err != nil { + panic(err) + } + if *u != originUuid { + panic("eq") + } + clear((*u)[:]) + uuidPool.Put(u) + //gUuid = *u + } +} + +func BenchmarkUuidEq(b *testing.B) { + for i := 0; i < b.N; i++ { + u, err := uuid.FromBytes(bb[2:18]) + if err != nil { + panic(err) + } + if u == [16]byte{} { + panic(1) + } + if u != originUuid { + panic("eq") + } + } +} + +var gBig *big.Int + +var bigPool = &sync.Pool{ + New: func() interface{} { + return new(big.Int) + }, +} + +type QBig struct { + Value *big.Int +} + +func initQBigPool(x uint64) QBig { + u := bigPool.Get().(*big.Int) + return QBig{ + Value: u.SetUint64(x), + } +} + +func initQBigNew(x uint64) QBig { + return QBig{ + Value: big.NewInt(int64(x)), + } +} + +func BenchmarkBigIntPool(b *testing.B) { + for i := 0; i < b.N; i++ { + u := initQBigPool(1234567890) + //u := bigPool.Get().(*big.Int) + //u.SetInt64(1234567890) + u.Value.SetUint64(0) + uuidPool.Put(u.Value) + gBig = u.Value + } +} + +func BenchmarkBigIntNew(b *testing.B) { + for i := 0; i < b.N; i++ { + u := initQBigNew(1234567890) + u.Value.SetUint64(0) + _ = u + gBig = u.Value + } +} + +var parseBb = []byte{0, 1, 2, 3, 0, 2, 2, 2, 10, 0, 4, 4, 4, 0} + +func BenchmarkParseLoop(b *testing.B) { + for i := 0; i < b.N; i++ { + index := 0 + var key, val, pb byte + var item *byte + for len(parseBb) > index { + pb = parseBb[index] + index++ + switch pb { + case 0: + item = nil + case 1: + if item == nil { + item = &key + } else { + *item += pb + } + case 2: + if item == nil { + item = &val + } else { + *item += pb + } + default: + if item != nil { + *item += pb + } + } + } + if key != 5 { + panic("key") + } + if val != 14 { + panic("val") + } + } +} +func BenchmarkParseLoopConst(b *testing.B) { + for i := 0; i < b.N; i++ { + index := 0 + var key, val, set, pb byte + var item *byte + for set != 2 { + if len(parseBb) <= index { + break + } + pb = parseBb[index] + index++ + switch pb { + case 0: + if item != nil { + set++ + } + item = nil + case 1: + if item == nil { + item = &key + } else { + *item += pb + } + case 2: + if item == nil { + item = &val + } else { + *item += pb + } + default: + if item != nil { + *item += pb + } + } + } + if key != 5 { + panic("key") + } + if val != 14 { + panic("val") + } + } +} + +func BenchmarkParseGoto(b *testing.B) { + for i := 0; i < b.N; i++ { + index := 0 + var key, val, set, pb byte + var item *byte + loop: + if len(parseBb) <= index || set == 2 { + goto check + } + pb = parseBb[index] + index++ + switch pb { + case 0: + if item != nil { + set++ + } + item = nil + goto loop + case 1: + if item == nil { + item = &key + } else { + *item += pb + } + goto loop + case 2: + if item == nil { + item = &val + } else { + *item += pb + } + goto loop + default: + if item != nil { + *item += pb + } + goto loop + } + check: + if key != 5 { + panic("key") + } + if val != 14 { + panic("val") + } + } +} diff --git a/test/t15/.gitignore b/test/t15/.gitignore new file mode 100644 index 0000000..e84fc0d --- /dev/null +++ b/test/t15/.gitignore @@ -0,0 +1,2 @@ +!generate_test.go +* \ No newline at end of file diff --git a/test/t15/generate_test.go b/test/t15/generate_test.go new file mode 100644 index 0000000..86188b0 --- /dev/null +++ b/test/t15/generate_test.go @@ -0,0 +1,329 @@ +package t15 + +import ( + "fmt" + "go/format" + "os" + "strings" + "testing" +) + +var ( + fieldNum = [][]int{ + {1, 15}, + //{30, 50}, + {120, 150}, + {300, 320}, + {1150, 1200}, + {1950, 2000}, + {59950, 60000}, + //{24999990, 25000000}, + {25000000, 25000000}, + } + countWireType = 2 +) + +func getFieldNum(fieldNumber int, wireType int) []byte { + fieldNumber <<= 3 + fieldNumber |= wireType + var result []byte + for fieldNumber >= 1<<7 { + result = append(result, byte(fieldNumber&127|128)) + fieldNumber >>= 7 + } + result = append(result, byte(fieldNumber)) + return result +} + +func TestGenerateData(t *testing.T) { + data := `package t15 + +import ( + "slices" +) + +var data = slices.Concat( + {ITEM} +) +` + for _, r := range fieldNum { + for i := r[0]; i <= r[1]; i++ { + for j := 1; j < countWireType+1; j++ { + val := getFieldNum(i, j) + + var valInt any + switch len(val) { + case 1: + valInt = val[0] + case 2: + valInt = uint16(val[0]) | uint16(val[1])<<8 + case 3: + valInt = uint32(val[0]) | uint32(val[1])<<8 | uint32(val[2])<<16 + case 4: + valInt = uint32(val[0]) | uint32(val[1])<<8 | uint32(val[2])<<16 | uint32(val[3])<<24 + } + data = strings.Replace( + data, + "{ITEM}", + fmt.Sprintf( + `getFieldNum(%d, %d), // %d - %d + {ITEM}`, i, j, valInt, val, + ), + 1, + ) + } + } + } + data = strings.Replace(data, "{ITEM}", "", 1) + if err := os.WriteFile(`q_data_test.go`, []byte(data), 0666); err != nil { + panic(err) + } +} + +func TestGenerateDecode(t *testing.T) { + bench := `package t15 + +import ( + "testing" +) + +func BenchmarkDecode(b *testing.B) { + for i := 0; i < b.N; i++ { + var c int + var index int + for len(data) > index { + fieldNum := int32(data[index] & 127) + if data[index] < 128 { + goto end + } + index++ + if len(data) > index { + fieldNum |= int32(data[index]&127) << 7 + if data[index] < 128 { + goto end + } + } + index++ + if len(data) > index { + fieldNum |= int32(data[index]&127) << 14 + if data[index] < 128 { + goto end + } + } + index++ + if len(data) > index { + fieldNum |= int32(data[index]&127) << 21 + if data[index] < 128 { + goto end + } + } + panic("litepb: unexpected end of field number") + end: + index++ + switch fieldNum >> 3 { + {FIELD_NUMBER} + default: + panic("litepb: unknown field number") + } + } + } +} +` + for _, r := range fieldNum { + for i := r[0]; i <= r[1]; i++ { + bench = strings.Replace( + bench, + "{FIELD_NUMBER}", + fmt.Sprintf( + `case %d: + switch fieldNum & 7 { + {WIRE_TYPE} + default: + panic("litepb: incorrect wire type") + } + {FIELD_NUMBER}`, i, + ), + 1, + ) + for j := 1; j < countWireType+1; j++ { + bench = strings.Replace( + bench, + "{WIRE_TYPE}", + fmt.Sprintf( + `case %d: + c++ + {WIRE_TYPE}`, j, + ), + 1, + ) + } + bench = strings.Replace(bench, "{WIRE_TYPE}", "", 1) + } + } + bench = strings.Replace(bench, "{FIELD_NUMBER}", "", 1) + source, _ := format.Source([]byte(bench)) + if err := os.WriteFile(`q_decode_test.go`, source, 0666); err != nil { + panic(err) + } +} + +func TestGenerateDecodeIf(t *testing.T) { + bench := `package t15 + +import ( + "testing" +) + +func BenchmarkDecodeIf(b *testing.B) { + for i := 0; i < b.N; i++ { + var c int + var index int + for len(data) > index { + fieldNum := int32(data[index] & 127) + if data[index] > 127 { + index++ + if len(data) > index { + fieldNum |= int32(data[index]&127) << 7 + if data[index] > 127 { + index++ + if len(data) > index { + fieldNum |= int32(data[index]&127) << 14 + if data[index] > 127 { + index++ + if len(data) > index { + fieldNum |= int32(data[index]&127) << 21 + if data[index] > 127 { + panic("litepb: unexpected end of field number") + } + } + } + } + } + } + } + index++ + switch fieldNum >> 3 { + {FIELD_NUMBER} + default: + panic("litepb: unknown field number") + } + } + } +} +` + for _, r := range fieldNum { + for i := r[0]; i <= r[1]; i++ { + bench = strings.Replace( + bench, + "{FIELD_NUMBER}", + fmt.Sprintf( + `case %d: + switch fieldNum & 7 { + {WIRE_TYPE} + default: + panic("litepb: incorrect wire type") + } + {FIELD_NUMBER}`, i, + ), + 1, + ) + for j := 1; j < countWireType+1; j++ { + bench = strings.Replace( + bench, + "{WIRE_TYPE}", + fmt.Sprintf( + `case %d: + c++ + {WIRE_TYPE}`, j, + ), + 1, + ) + } + bench = strings.Replace(bench, "{WIRE_TYPE}", "", 1) + } + } + bench = strings.Replace(bench, "{FIELD_NUMBER}", "", 1) + source, _ := format.Source([]byte(bench)) + if err := os.WriteFile(`q_decode_if_test.go`, source, 0666); err != nil { + panic(err) + } +} + +func TestGenerateDecodeStatic(t *testing.T) { + bench := `package t15 + +import ( + "testing" +) + +func BenchmarkDecodeStatic(b *testing.B) { + for i := 0; i < b.N; i++ { + var c int + var index int + for len(data) > index {{SWITCH} + panic("litepb: unknown field number or incorrect wire type") + } + } +} +` + caseList := make([]string, 4) + for _, r := range fieldNum { + for i := r[0]; i <= r[1]; i++ { + for j := 1; j < countWireType+1; j++ { + item := getFieldNum(i, j) + var itemText []string + for _, itemOne := range item { + itemText = append(itemText, fmt.Sprintf("%d", itemOne)) + } + var val any + switch len(item) { + case 1: + val = item[0] + case 2: + val = uint16(item[0]) | uint16(item[1])<<8 + case 3: + val = uint32(item[0]) | uint32(item[1])<<8 | uint32(item[2])<<16 + case 4: + val = uint32(item[0]) | uint32(item[1])<<8 | uint32(item[2])<<16 | uint32(item[3])<<24 + } + caseList[len(item)-1] += fmt.Sprintf( + ` + case %d: // %[3]d,%[4]d + c++`, + val, + len(item), + i, j, + ) + } + } + } + switchCode := "" + for i := 0; i < len(caseList); i++ { + if caseList[i] == "" { + continue + } + var val string + switch i { + case 0: + val = "data[index]" + case 1: + val = "uint16(data[index]) | uint16(data[index+1])<<8" + case 2: + val = "uint32(data[index]) | uint32(data[index+1])<<8 | uint32(data[index+2])<<16" + case 3: + val = "uint32(data[index]) | uint32(data[index+1])<<8 | uint32(data[index+2])<<16 | uint32(data[index+3])<<24" + } + switchCode += fmt.Sprintf(` + if len(data) > index+%d && data[index+%[1]d] < 128 { + switch %s {%s + } + index += %d + continue + }`, i, val, caseList[i], i+1, + ) + } + bench = strings.Replace(bench, "{SWITCH}", switchCode, 1) + if err := os.WriteFile(`q_decode_static_test.go`, []byte(bench), 0666); err != nil { + panic(err) + } +} diff --git a/test/t16/c_test.go b/test/t16/c_test.go new file mode 100644 index 0000000..c3bb78c --- /dev/null +++ b/test/t16/c_test.go @@ -0,0 +1,17 @@ +package main + +import ( + "testing" + "unsafe" +) + +func BenchmarkCast1(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = data[:5] + } +} +func BenchmarkCast2(b *testing.B) { + for i := 0; i < b.N; i++ { + _ = *(*Bytes)(unsafe.Pointer(&data[0])) + } +} diff --git a/test/t16/q.go b/test/t16/q.go new file mode 100644 index 0000000..fe35949 --- /dev/null +++ b/test/t16/q.go @@ -0,0 +1,458 @@ +package main + +import ( + "crypto/rand" + "fmt" + "time" + "unsafe" +) + +var ( + buf = make([]byte, 2) + bufAfter = make([]byte, 2) +) + +func main() { + var r time.Time + var d time.Duration + + { + // then we can call rand.Read. + _, _ = rand.Read(buf) + _, _ = rand.Read(bufAfter) + fmt.Println("buf") + fmt.Println(buf) + fmt.Println((*Bytes)(unsafe.Pointer(&buf[0]))) + fmt.Println((*[5]byte)(unsafe.Pointer(&buf[0]))) + fmt.Println("bufAfter") + fmt.Println(bufAfter) + fmt.Println((*Bytes)(unsafe.Pointer(&bufAfter[0]))) + fmt.Println((*[5]byte)(unsafe.Pointer(&bufAfter[0]))) + fmt.Println("buf inc") + r := uintptr(unsafe.Pointer(&buf[0])) + r++ + fmt.Println((*Bytes)(unsafe.Pointer(r))) + fmt.Println((*[5]byte)(unsafe.Pointer(r))) + return + } + + _ = data[11:] + + r = time.Now() + u2 := (*Bytes)(unsafe.Pointer(&data[11])) + d = time.Since(r) + fmt.Println(d) + + r = time.Now() + u1 := data[11:] + d = time.Since(r) + fmt.Println(d) + + fmt.Println(u1[0], u1[1], u1[2], u1[3]) + fmt.Println(u2.B1, u2.B2, u2.B3, u2.B4) + fmt.Println(data, len(data)) +} + +var data = []byte{ + 3, + 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, +} + +type Bytes struct { + B1 byte + B2 byte + B3 byte + B4 byte + B5 byte +} +type Q struct { + Var1 int + Var2 int +} + +func (a *Q) DecodeCurrent(data []byte, ind int) { + var index int + for len(data) > index { + switch ind { + case 0: + var value int + if len(data) > index { + value |= int(data[index] & 127) + if data[index] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 7 + if data[index] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 14 + if data[index] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 21 + if data[index] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 28 + if data[index] < 128 { + goto end1 + } + } + panic("---") + end1: + index++ + a.Var1 = value + case 1: + var value int + if len(data) > index { + value |= int(data[index] & 127) + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 7 + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 14 + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 21 + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 28 + if data[index] < 128 { + goto end2 + } + } + panic("---") + end2: + index++ + a.Var2 = value + } + } +} + +func (a *Q) DecodeCurrentModify(data []byte, ind int) { + var index int + for len(data) > index { + switch ind { + case 0, 1: + var value int + if len(data) > index { + value |= int(data[index] & 127) + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 7 + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 14 + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 21 + if data[index] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(data[index]&127) << 28 + if data[index] < 128 { + goto end2 + } + } + panic("---") + end2: + index++ + switch ind { + case 0: + a.Var1 = value + case 1: + a.Var2 = value + } + } + } +} + +func (a *Q) DecodeModify(data []byte, ind int) { + var index int + for len(data) > index { + switch ind { + case 0, 1: + var value int + switch { + case len(data) > index && data[index] < 128: + value = int(data[index] & 127) + index += 1 + case len(data) > index+1 && data[index+1] < 128: + value = int(data[index]&127) | int(data[index+1]&127)<<7 + index += 2 + case len(data) > index+2 && data[index+2] < 128: + value = int(data[index]&127) | int(data[index+1]&127)<<7 | int(data[index+2]&127)<<14 + index += 3 + case len(data) > index+3 && data[index+3] < 128: + value = int(data[index]&127) | int(data[index+1]&127)<<7 | int(data[index+2]&127)<<14 | int(data[index+3]&127)<<21 + index += 4 + case len(data) > index+4 && data[index+4] < 128: + value = int(data[index]&127) | int(data[index+1]&127)<<7 | int(data[index+2]&127)<<14 | int(data[index+3]&127)<<21 | int(data[index+4]&127)<<28 + index += 5 + } + switch ind { + case 0: + a.Var1 = value + case 1: + a.Var2 = value + } + } + } +} + +func (a *Q) DecodeModify21(data []byte, ind int) { + var index int + for len(data) > index { + switch ind { + case 0, 1: + var value int + bd := *(*Bytes)(unsafe.Pointer(&data[index])) + switch { + case len(data) > index && bd.B1 < 128: + value = int(bd.B1 & 127) + index += 1 + case len(data) > index+1 && bd.B2 < 128: + value = int(bd.B1&127) | int(bd.B2&127)<<7 + index += 2 + case len(data) > index+2 && bd.B3 < 128: + value = int(bd.B1&127) | int(bd.B2&127)<<7 | int(bd.B3&127)<<14 + index += 3 + case len(data) > index+3 && bd.B4 < 128: + value = int(bd.B1&127) | int(bd.B2&127)<<7 | int(bd.B3&127)<<14 | int(bd.B4&127)<<21 + index += 4 + case len(data) > index+4 && bd.B5 < 128: + value = int(bd.B1&127) | int(bd.B2&127)<<7 | int(bd.B3&127)<<14 | int(bd.B4&127)<<21 | int(bd.B5&127)<<28 + index += 5 + } + switch ind { + case 0: + a.Var1 = value + case 1: + a.Var2 = value + } + } + } +} +func (a *Q) DecodeModify2(data []byte, ind int) { + var index int + for len(data) > index { + bd := (*Bytes)(unsafe.Pointer(&data[index])) + switch ind { + case 0: + var value int + if len(data) > index { + value |= int(bd.B1 & 127) + if bd.B1 < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd.B2&127) << 7 + if bd.B2 < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd.B3&127) << 14 + if bd.B3 < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd.B4&127) << 21 + if bd.B4 < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd.B5&127) << 28 + if bd.B5 < 128 { + goto end1 + } + } + panic("---") + end1: + index++ + a.Var1 = value + case 1: + var value int + if len(data) > index { + value |= int(bd.B1 & 127) + if bd.B1 < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd.B2&127) << 7 + if bd.B2 < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd.B3&127) << 14 + if bd.B3 < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd.B4&127) << 21 + if bd.B4 < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd.B5&127) << 28 + if bd.B5 < 128 { + goto end2 + } + } + panic("---") + end2: + index++ + a.Var2 = value + } + } +} +func (a *Q) DecodeModify3(data []byte, ind int) { + var index int + for len(data) > index { + bd := (*[5]byte)(unsafe.Pointer(&data[index])) + switch ind { + case 0: + var value int + if len(data) > index { + value |= int(bd[0] & 127) + if bd[0] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd[1]&127) << 7 + if bd[1] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd[2]&127) << 14 + if bd[2] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd[3]&127) << 21 + if bd[3] < 128 { + goto end1 + } + } + index++ + if len(data) > index { + value |= int(bd[4]&127) << 28 + if bd[4] < 128 { + goto end1 + } + } + panic("---") + end1: + index++ + a.Var1 = value + case 1: + var value int + if len(data) > index { + value |= int(bd[0] & 127) + if bd[0] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd[1]&127) << 7 + if bd[1] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd[2]&127) << 14 + if bd[2] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd[3]&127) << 21 + if bd[3] < 128 { + goto end2 + } + } + index++ + if len(data) > index { + value |= int(bd[4]&127) << 28 + if bd[4] < 128 { + goto end2 + } + } + panic("---") + end2: + index++ + a.Var2 = value + } + } +} diff --git a/test/t16/q_test.go b/test/t16/q_test.go new file mode 100644 index 0000000..b473bc0 --- /dev/null +++ b/test/t16/q_test.go @@ -0,0 +1,134 @@ +package main + +import ( + "testing" +) + +func BenchmarkSwitch(b *testing.B) { + q := make(map[int]int) + for i := 0; i < b.N; i++ { + u := i % 30 + switch u { + case 3: + q[1]++ + case 4: + q[1]++ + case 22: + q[1]++ + case 17: + q[1]++ + case 8: + q[2]++ + case 10: + q[2]++ + case 1: + q[3]++ + case 5: + q[3]++ + case 18: + q[3]++ + default: + q[5]++ + } + } +} + +func BenchmarkSwitch2(b *testing.B) { + q := make(map[int]int) + for i := 0; i < b.N; i++ { + u := i % 30 + switch u { + case 3, 4, 22, 17: + switch u { + case 3: + q[1]++ + case 4: + q[1]++ + case 22: + q[1]++ + case 17: + q[1]++ + } + case 8, 10: + switch u { + case 8: + q[2]++ + case 10: + q[2]++ + } + case 1, 5: + switch u { + case 1: + q[3]++ + case 5: + q[3]++ + } + case 18: + q[3]++ + default: + q[5]++ + } + } +} + +func BenchmarkDecodeCurrent(b *testing.B) { + q := &Q{} + for i := 0; i < b.N; i++ { + q.DecodeCurrent(data, i%2) + } +} + +func BenchmarkDecodeCurrentModify(b *testing.B) { + q := &Q{} + for i := 0; i < b.N; i++ { + q.DecodeCurrentModify(data, i%2) + } +} + +func BenchmarkDecodeModify(b *testing.B) { + q := &Q{} + for i := 0; i < b.N; i++ { + q.DecodeModify(data, i%2) + if i%2 == 0 { + if q.Var1 != 8640662552 { + panic("eq") + } + } else { + if q.Var2 != 8640662552 { + panic("eq") + } + } + } +} + +func BenchmarkDecodeModify2(b *testing.B) { + q := &Q{} + for i := 0; i < b.N; i++ { + q.DecodeModify2(data, i%2) + if i%2 == 0 { + if q.Var1 != 8640662552 { + panic("eq") + } + } else { + if q.Var2 != 8640662552 { + panic("eq") + } + } + } +} + +func BenchmarkDecodeModify3(b *testing.B) { + q := &Q{} + for i := 0; i < b.N; i++ { + q.DecodeModify3(data, i%2) + if i%2 == 0 { + if q.Var1 != 8640662552 { + panic("eq") + } + } else { + if q.Var2 != 8640662552 { + panic("eq") + } + } + } +} diff --git a/test/t16/r/main.go b/test/t16/r/main.go new file mode 100644 index 0000000..3f2c134 --- /dev/null +++ b/test/t16/r/main.go @@ -0,0 +1,169 @@ +package main + +/* +go build -gcflags -S main.go 2> asm.txt +go build -gcflags "-d=ssa/check_bce/debug=1" main.go +*/ + +var data = []byte{ + 3, + 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, +} + +func main() { + //q := &Q{} + //r := time.Now() + //q.DecodeModify2(data, 1) + //fmt.Println(time.Since(r)) +} + +type Q struct { + Var1 int + Var164 int64 + Var2 int +} + +//func (a *Q) DecodeModify2(data []byte, ind int) byte { +// _ = data[ind] +// if len(data) > ind+10 { +// return data[ind] +// } +// return 0 +//} +// +//func (a *Q) Decode(data []byte, ind int) { +// for index := 0; index < len(data); index++ { +// switch ind { +// case 0: +// var value int +// if len(data) > index { +// value |= int(data[index] & 127) +// if data[index] < 128 { +// goto end1 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 7 +// if data[index] < 128 { +// goto end1 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 14 +// if data[index] < 128 { +// goto end1 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 21 +// if data[index] < 128 { +// goto end1 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 28 +// if data[index] < 128 { +// goto end1 +// } +// } +// panic("---") +// end1: +// index++ +// a.Var1 = value +// case 1: +// var value int +// if len(data) > index { +// value |= int(data[index] & 127) +// if data[index] < 128 { +// goto end2 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 7 +// if data[index] < 128 { +// goto end2 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 14 +// if data[index] < 128 { +// goto end2 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 21 +// if data[index] < 128 { +// goto end2 +// } +// } +// index++ +// if len(data) > index { +// value |= int(data[index]&127) << 28 +// if data[index] < 128 { +// goto end2 +// } +// } +// panic("---") +// end2: +// index++ +// a.Var2 = value +// } +// } +//} + +func (a *Q) Decode2(data []byte, ind int) { + for index := 0; index < len(data); index++ { + switch { + //case len(data) > index && data[index] < 128: + // a.Var164 = int64(data[index] & 127) + // index += 1 + //case len(data) > index+1 && data[index+1] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 + // index += 2 + //case len(data) > index+2 && data[index+2] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 + // index += 3 + //case len(data) > index+3 && data[index+3] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 + // index += 4 + //case len(data) > index+4 && data[index+4] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 | int64(data[index+4]&127)<<28 + // index += 5 + //case len(data) > index+5 && data[index+5] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 | int64(data[index+4]&127)<<28 | int64(data[index+5]&127)<<35 + // index += 6 + //case len(data) > index+6 && data[index+6] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 | int64(data[index+4]&127)<<28 | int64(data[index+5]&127)<<35 | int64(data[index+6]&127)<<42 + // index += 7 + //case len(data) > index+7 && data[index+7] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 | int64(data[index+4]&127)<<28 | int64(data[index+5]&127)<<35 | int64(data[index+6]&127)<<42 | int64(data[index+7]&127)<<49 + // index += 8 + case len(data) > index+8 && data[index+8] < 128: + q := ([9]byte)(data[index : index+8]) + //a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 | int64(data[index+4]&127)<<28 | int64(data[index+5]&127)<<35 | int64(data[index+6]&127)<<42 | int64(data[index+7]&127)<<49 | int64(data[index+8]&127)<<56 + a.Var164 = int64(q[0]&127) | + int64(q[1]&127)<<7 | + int64(q[2]&127)<<14 | + int64(q[3]&127)<<21 | + int64(q[4]&127)<<28 | + int64(q[5]&127)<<35 | + int64(q[6]&127)<<42 | + int64(q[7]&127)<<49 | + int64(q[8]&127)<<56 + index += 9 + //case len(data) > index+9 && data[index+9] < 128: + // a.Var164 = int64(data[index]&127) | int64(data[index+1]&127)<<7 | int64(data[index+2]&127)<<14 | int64(data[index+3]&127)<<21 | int64(data[index+4]&127)<<28 | int64(data[index+5]&127)<<35 | int64(data[index+6]&127)<<42 | int64(data[index+7]&127)<<49 | int64(data[index+8]&127)<<56 | int64(data[index+9]&127)<<63 + // index += 10 + } + } +} diff --git a/test/t17/data.go b/test/t17/data.go new file mode 100644 index 0000000..48eabd9 --- /dev/null +++ b/test/t17/data.go @@ -0,0 +1,16 @@ +package t17 + +var data = []byte{ + 3, + 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, + 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 1<<7 | 3<<3, 2 << 4, +} +var dataValue = []uint64{ + 3, + 4120, + 527384, + 67505176, + 8640662552, +} diff --git a/test/t17/for.go b/test/t17/for.go new file mode 100644 index 0000000..69169fa --- /dev/null +++ b/test/t17/for.go @@ -0,0 +1,28 @@ +package t17 + +func For() { + var index int + var value uint64 + var current int + for len(data) > index { + value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + panic("shift") + } + if index >= len(data) { + panic("eof") + } + b := data[index] + index++ + value |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + if value != dataValue[current] { + panic("eq") + } + current++ + } +} diff --git a/test/t17/goto.go b/test/t17/goto.go new file mode 100644 index 0000000..235fe18 --- /dev/null +++ b/test/t17/goto.go @@ -0,0 +1,48 @@ +package t17 + +func Goto() { + var index int + var value uint64 + var current int + for len(data) > index { + value = uint64(data[index] & 127) + if data[index] < 128 { + goto end + } + index++ + if len(data) > index { + value |= uint64(data[index]&127) << 7 + if data[index] < 128 { + goto end + } + } + index++ + if len(data) > index { + value |= uint64(data[index]&127) << 14 + if data[index] < 128 { + goto end + } + } + index++ + if len(data) > index { + value |= uint64(data[index]&127) << 21 + if data[index] < 128 { + goto end + } + } + index++ + if len(data) > index { + value |= uint64(data[index]&127) << 28 + if data[index] < 128 { + goto end + } + } + panic("eof") + end: + index++ + if value != dataValue[current] { + panic("eq") + } + current++ + } +} diff --git a/test/t17/goto_modify.go b/test/t17/goto_modify.go new file mode 100644 index 0000000..0a9faa4 --- /dev/null +++ b/test/t17/goto_modify.go @@ -0,0 +1,64 @@ +package t17 + +import ( + "unsafe" +) + +type Bytes struct { + B0 byte + B1 byte + B2 byte + B3 byte + B4 byte +} + +func GotoModify() { + var index int + var value uint64 + var current int + //arrPointer := uintptr(unsafe.Pointer(&data[0])) + for len(data) > index { + //arr := (*[5]byte)(unsafe.Pointer(arrPointer + uintptr(index))) + //arr := (*[5]byte)(unsafe.Pointer(&data[index])) + b := (*Bytes)(unsafe.Pointer(&data[index])) + value = uint64(b.B0 & 127) + if b.B0 < 128 { + goto end + } + index++ + if len(data) > index { + value |= uint64(b.B1&127) << 7 + if b.B1 < 128 { + goto end + } + } + index++ + if len(data) > index { + value |= uint64(b.B2&127) << 14 + if b.B2 < 128 { + goto end + } + } + index++ + if len(data) > index { + value |= uint64(b.B3&127) << 21 + if b.B3 < 128 { + goto end + } + } + index++ + if len(data) > index { + value |= uint64(b.B4&127) << 28 + if b.B4 < 128 { + goto end + } + } + panic("eof") + end: + index++ + if value != dataValue[current] { + panic("eq") + } + current++ + } +} diff --git a/test/t17/q_test.go b/test/t17/q_test.go new file mode 100644 index 0000000..2714226 --- /dev/null +++ b/test/t17/q_test.go @@ -0,0 +1,21 @@ +package t17 + +import "testing" + +func BenchmarkFor(b *testing.B) { + for i := 0; i < b.N; i++ { + For() + } +} + +func BenchmarkGoto(b *testing.B) { + for i := 0; i < b.N; i++ { + Goto() + } +} + +func BenchmarkGotoModify(b *testing.B) { + for i := 0; i < b.N; i++ { + GotoModify() + } +} diff --git a/test/t2/m_test.go b/test/t2/m_test.go new file mode 100644 index 0000000..1f78ebf --- /dev/null +++ b/test/t2/m_test.go @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "testing" + "unsafe" +) + +func BenchmarkL(b *testing.B) { + u := 7 + for i := 0; i < b.N; i++ { + _ = (u) << 3 + } +} + +func BenchmarkF(b *testing.B) { + u := 7 + for i := 0; i < b.N; i++ { + _ = (u & i) << 3 + } +} + +func BenchmarkIf(b *testing.B) { + u := 7 + c := 0 + for i := 0; i < b.N; i++ { + if u == i { + continue + } else if u == i+1 { + continue + } + c++ + } +} + +func BenchmarkSwitch(b *testing.B) { + u := 7 + c := 0 + for i := 0; i < b.N; i++ { + switch u { + case i: + continue + case i + 1: + continue + default: + c++ + } + } +} + +type Q struct { + Data uint64 +} + +func (a *Q) direct(b *testing.B) { + for i := 0; i < b.N; i++ { + a.Data++ + } +} +func (a *Q) local(b *testing.B) { + data := uint64(0) + for i := 0; i < b.N; i++ { + data++ + } + a.Data = data +} + +func BenchmarkDirect(b *testing.B) { + (&Q{}).direct(b) +} + +func BenchmarkLocal(b *testing.B) { + (&Q{}).local(b) +} + +var strData = []byte("Моё текст на русском языке 23 вот так") +var strLen = len(strData) - 3 +var strString = string(strData[4:strLen]) + +func TestString(t *testing.T) { + fmt.Println(strData) + fmt.Println(string(strData)) + fmt.Println(unsafe.String(&strData[0], len(strData)-4)) +} + +func BenchmarkString(b *testing.B) { + for i := 0; i < b.N; i++ { + if strString != string(strData[4:strLen]) { + panic("eq") + } + } +} + +var q string + +func BenchmarkUnsafeString(b *testing.B) { + for i := 0; i < b.N; i++ { + q = unsafe.String(&strData[4], strLen-4) + if strString != q { + panic("eq") + } + } +} diff --git a/test/t3/s_test.go b/test/t3/s_test.go new file mode 100644 index 0000000..179fba0 --- /dev/null +++ b/test/t3/s_test.go @@ -0,0 +1,56 @@ +package zerocast + +import ( + "strings" + "testing" + "unsafe" +) + +const size = 2000 + +var s = strings.Repeat("текст", size) +var bb = []byte(strings.Repeat("текст", size)) +var s1 string +var bb1 []byte +var s1Init = string(bb) + +//func BenchmarkStringToBytesStandard(b *testing.B) { +// for i := 0; i < b.N; i++ { +// bb1 = []byte(s) +// } +//} + +func BenchmarkBytesToStringStandard(b *testing.B) { + for i := 0; i < b.N; i++ { + s1 = string(bb) + } + if string(bb) != s1Init { + panic("eq") + } +} + +//func BenchmarkStringToBytes(b *testing.B) { +// for i := 0; i < b.N; i++ { +// bb1 = StringToBytes(s) +// } +//} + +func BenchmarkBytesToString(b *testing.B) { + for i := 0; i < b.N; i++ { + //s1 = unsafe.String(&bb[10], len(bb)-10) + s1 = BytesToString(bb) + //if unsafe.String(&bb[10], len(bb)-10) != s1Init { + } + if s1 != s1Init { + panic("eq") + } +} + +// func StringToBytes(s string) []byte { +// p := unsafe.StringData(s) +// b := unsafe.Slice(p, len(s)) +// return b +// } +func BytesToString(b []byte) string { + return unsafe.String(&b[0], len(b)) +} diff --git a/test/t4/q_test.go b/test/t4/q_test.go new file mode 100644 index 0000000..682aef3 --- /dev/null +++ b/test/t4/q_test.go @@ -0,0 +1,61 @@ +package t4 + +import "testing" + +var found int64 + +func BenchmarkIf1(b *testing.B) { + for i := 0; i < b.N; i++ { + if i%3 == 0 { + found++ + } + } +} +func BenchmarkSwitch1(b *testing.B) { + for i := 0; i < b.N; i++ { + switch i % 3 { + case 0: + found++ + } + } +} + +func BenchmarkIf2(b *testing.B) { + for i := 0; i < b.N; i++ { + if i%3 == 0 { + found++ + } else if i%3 == 1 { + found++ + } + } +} + +func BenchmarkSwitch2(b *testing.B) { + for i := 0; i < b.N; i++ { + switch i % 3 { + case 0: + found++ + case 1: + found++ + } + } +} + +var q int + +func BenchmarkD(b *testing.B) { + var v int + for i := 0; i < b.N; i++ { + v += i + } + v = v >> 3 + q = v +} + +func BenchmarkL(b *testing.B) { + var v int + for i := 0; i < b.N; i++ { + v += i + } + q = v >> 3 +} diff --git a/test/t5/q_test.go b/test/t5/q_test.go new file mode 100644 index 0000000..7398a41 --- /dev/null +++ b/test/t5/q_test.go @@ -0,0 +1,26 @@ +package t5 + +import ( + "bytes" + "testing" +) + +const size = 200 + +var bb = bytes.Repeat([]byte{1, 2, 3, 4, 5}, size) + +func BenchmarkCap(b *testing.B) { + for i := 0; i < b.N; i++ { + r(bb[20:200:200]) + } +} + +func BenchmarkLen(b *testing.B) { + for i := 0; i < b.N; i++ { + r(bb[20:200]) + } +} + +func r(data []byte) { + _ = len(data) +} diff --git a/test/t6/q_test.go b/test/t6/q_test.go new file mode 100644 index 0000000..e419f0c --- /dev/null +++ b/test/t6/q_test.go @@ -0,0 +1,34 @@ +package t6 + +import "testing" + +func BenchmarkFor(b *testing.B) { + var q1, q2 int + for i := 0; i < b.N; i++ { + for j := 0; j < 2; j++ { + switch j { + case 0: + q1++ + case 1: + q2++ + } + } + } +} + +func BenchmarkGoto(b *testing.B) { + var q1, q2 int + for i := 0; i < b.N; i++ { + j := 0 + l: + j++ + switch j { + case 1: + q1++ + goto l + case 2: + q2++ + goto l + } + } +} diff --git a/test/t7/q_test.go b/test/t7/q_test.go new file mode 100644 index 0000000..bc1cc41 --- /dev/null +++ b/test/t7/q_test.go @@ -0,0 +1,55 @@ +package t7 + +import ( + "encoding/binary" + "testing" +) + +var q = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} +var index = 6 +var r uint64 + +func BenchmarkNative(b *testing.B) { + for i := 0; i < b.N; i++ { + if len(q) > index+7 { + r = binary.LittleEndian.Uint64(q[index:]) + } + } +} +func BenchmarkNativeLen(b *testing.B) { + for i := 0; i < b.N; i++ { + if len(q) > index+7 { + r = binary.LittleEndian.Uint64(q[index : index+8]) + } + } +} + +func BenchmarkSlice(b *testing.B) { + for i := 0; i < b.N; i++ { + if len(q) > index+7 { + bb := q[index:] + r = uint64(bb[0]) | uint64(bb[1])<<8 | uint64(bb[2])<<16 | uint64(bb[3])<<24 | + uint64(bb[4])<<32 | uint64(bb[5])<<40 | uint64(bb[6])<<48 | uint64(bb[7])<<56 + } + } +} + +func BenchmarkSliceLen(b *testing.B) { + for i := 0; i < b.N; i++ { + if len(q) > index+7 { + bb := q[index : index+8] + r = uint64(bb[0]) | uint64(bb[1])<<8 | uint64(bb[2])<<16 | uint64(bb[3])<<24 | + uint64(bb[4])<<32 | uint64(bb[5])<<40 | uint64(bb[6])<<48 | uint64(bb[7])<<56 + } + } +} + +func BenchmarkIndex(b *testing.B) { + for i := 0; i < b.N; i++ { + if len(q) > index+7 { + _ = q[index+7] + r = uint64(q[index]) | uint64(q[index+1])<<8 | uint64(q[index+2])<<16 | uint64(q[index+3])<<24 | + uint64(q[index+4])<<32 | uint64(q[index+5])<<40 | uint64(q[index+6])<<48 | uint64(q[index+7])<<56 + } + } +} diff --git a/test/t8/q_test.go b/test/t8/q_test.go new file mode 100644 index 0000000..6890091 --- /dev/null +++ b/test/t8/q_test.go @@ -0,0 +1,40 @@ +package t8 + +import "testing" + +type Q struct { + Arr []int +} + +var q = &Q{ + Arr: make([]int, 0), +} +var count int + +func BenchmarkFree(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, el := range q.Arr { + count += el + } + } +} + +func BenchmarkIf(b *testing.B) { + for i := 0; i < b.N; i++ { + if len(q.Arr) > 0 { + for _, el := range q.Arr { + count += el + } + } + } +} + +func BenchmarkEmpty(b *testing.B) { + for i := 0; i < b.N; i++ { + if q != nil && len(q.Arr) > 0 { + for _, el := range q.Arr { + count += el + } + } + } +} diff --git a/test/t9/q_test.go b/test/t9/q_test.go new file mode 100644 index 0000000..359dc26 --- /dev/null +++ b/test/t9/q_test.go @@ -0,0 +1,30 @@ +package t9 + +import "testing" + +type Q struct { + int32 int32 + int64 int64 +} + +var qList = []*Q{ + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, +} + +func BenchmarkMap(b *testing.B) { + for i := 0; i < b.N; i++ { + q := make(map[int]*Q) + for j := 0; j < 100; j++ { + q[j%10] = qList[j%10] + } + } +} + +func BenchmarkMapCap(b *testing.B) { + for i := 0; i < b.N; i++ { + q := make(map[int]*Q, 20) + for j := 0; j < 100; j++ { + q[j%10] = qList[j%10] + } + } +} diff --git a/test/t_pool/q_test.go b/test/t_pool/q_test.go new file mode 100644 index 0000000..cce8feb --- /dev/null +++ b/test/t_pool/q_test.go @@ -0,0 +1,204 @@ +package t_pool + +import ( + "sync" + "sync/atomic" + "testing" +) + +type Q struct { + Int int + Int32 int32 + Int64 int64 + RInt64 []int64 +} + +var globalSyncPool = &sync.Pool{ + New: func() any { return &Q{} }, +} + +type ChPool struct { + ch chan *Q +} + +func (a *ChPool) Get() *Q { + select { + case obj := <-a.ch: + return obj + default: + return &Q{} + } +} + +func (a *ChPool) Put(item *Q) { + select { + case a.ch <- item: + default: + } +} + +const chPoolCount = 100 + +var chPool = &ChPool{ + ch: make(chan *Q, chPoolCount), +} + +func init() { + for i := 0; i < chPoolCount; i++ { + chPool.Put(&Q{}) + } +} + +const ringPoolCount = 100 + +type RingPool struct { + buffer [ringPoolCount]*Q + readIndex uint64 + writeIndex uint64 + size uint64 +} + +func (a *RingPool) Put(item *Q) bool { + for { + r := atomic.LoadUint64(&a.readIndex) + w := atomic.LoadUint64(&a.writeIndex) + if (w+1)%a.size == r%a.size { + return false + } + if atomic.CompareAndSwapUint64(&a.writeIndex, w, w+1) { + a.buffer[w%a.size] = item + return true + } + } +} + +func (a *RingPool) Get() *Q { + for { + r := atomic.LoadUint64(&a.readIndex) + w := atomic.LoadUint64(&a.writeIndex) + if r == w { + return &Q{} + } + if atomic.CompareAndSwapUint64(&a.readIndex, r, r+1) { + return a.buffer[r%a.size] + } + } +} + +var ringPool = &RingPool{ + size: ringPoolCount, +} + +var threadPools sync.Map + +func getLocalMapPool() *sync.Pool { + pool, ok := threadPools.Load(getThreadId()) + if !ok { + pool, _ = threadPools.LoadOrStore(getThreadId(), &sync.Pool{ + New: func() any { + return &Q{} + }, + }) + } + return pool.(*sync.Pool) +} + +///////////// + +func BenchmarkSimpleGlobalSyncPool(b *testing.B) { + for i := 0; i < b.N; i++ { + q := globalSyncPool.Get().(*Q) + q.Int = i + globalSyncPool.Put(q) + } +} + +func BenchmarkSimpleLocalSyncPool(b *testing.B) { + localSyncPool := &sync.Pool{ + New: func() any { return &Q{} }, + } + for i := 0; i < b.N; i++ { + q := localSyncPool.Get().(*Q) + q.Int = i + localSyncPool.Put(q) + } +} + +func BenchmarkSimpleChanPool(b *testing.B) { + for i := 0; i < b.N; i++ { + q := chPool.Get() + q.Int = i + chPool.Put(q) + } +} + +func BenchmarkSimpleRingPool(b *testing.B) { + for i := 0; i < b.N; i++ { + q := ringPool.Get() + q.Int = i + ringPool.Put(q) + } +} + +func BenchmarkSimpleLocalMapPool(b *testing.B) { + for i := 0; i < b.N; i++ { + pool := getLocalMapPool() + obj := pool.Get().(*Q) + obj.Int = i + pool.Put(obj) + } +} + +func BenchmarkAsyncGlobalSyncPool(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + q := globalSyncPool.Get().(*Q) + q.Int = 5 + globalSyncPool.Put(q) + } + }) +} + +func BenchmarkAsyncLocalSyncPool(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + localSyncPool := &sync.Pool{ + New: func() any { return &Q{} }, + } + for pb.Next() { + q := localSyncPool.Get().(*Q) + q.Int = 5 + localSyncPool.Put(q) + } + }) +} + +func BenchmarkAsyncChanPool(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + q := chPool.Get() + q.Int = 5 + chPool.Put(q) + } + }) +} + +func BenchmarkAsyncRingPool(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + q := ringPool.Get() + q.Int = 5 + ringPool.Put(q) + } + }) +} + +func BenchmarkAsyncLocalMapPool(b *testing.B) { + b.RunParallel(func(pb *testing.PB) { + pool := getLocalMapPool() + for pb.Next() { + obj := pool.Get().(*Q) + obj.Int = 5 + pool.Put(obj) + } + }) +} diff --git a/test/t_pool/thread_id.go b/test/t_pool/thread_id.go new file mode 100644 index 0000000..3dc92b9 --- /dev/null +++ b/test/t_pool/thread_id.go @@ -0,0 +1,10 @@ +package t_pool + +/* +#include +*/ +import "C" + +func getThreadId() uint64 { + return uint64(C.pthread_self()) +}