From a8a417199b43ac2e24bb79bc77d34a3d1b82366f Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Fri, 28 Oct 2022 00:33:02 +0500 Subject: [PATCH 01/10] in/not_in show enum values instead of numbers --- templates/goshared/in.go | 4 ++-- templates/goshared/register.go | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/templates/goshared/in.go b/templates/goshared/in.go index b6fdfa4c9..f2df50248 100644 --- a/templates/goshared/in.go +++ b/templates/goshared/in.go @@ -3,13 +3,13 @@ package goshared const inTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[{{ accessor . }}]; !ok { - err := {{ err . "value must be in list " $r.In }} + err := {{ err . "value must be in list " (list $f $r.In) }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[{{ accessor . }}]; ok { - err := {{ err . "value must not be in list " $r.NotIn }} + err := {{ err . "value must not be in list " (list $f $r.NotIn) }} if !all { return err } errors = append(errors, err) } diff --git a/templates/goshared/register.go b/templates/goshared/register.go index d94f236d7..88d0728ea 100644 --- a/templates/goshared/register.go +++ b/templates/goshared/register.go @@ -50,6 +50,7 @@ func Register(tpl *template.Template, params pgs.Parameters) { "externalEnums": fns.externalEnums, "enumName": fns.enumName, "enumPackages": fns.enumPackages, + "list": fns.list, }) template.Must(tpl.New("msg").Parse(msgTpl)) @@ -377,3 +378,17 @@ func (fns goSharedFuncs) enumPackages(enums []pgs.Enum) map[pgs.Name]NormalizedE func (fns goSharedFuncs) snakeCase(name string) string { return strcase.ToSnake(name) } + +func (fns goSharedFuncs) list(f pgs.Field, list []int32) string { + stringList := make([]string, 0, len(list)) + if enum := f.Type().Enum(); enum != nil { + for _, n := range list { + stringList = append(stringList, enum.Values()[n].Name().String()) + } + } else { + for _, n := range list { + stringList = append(stringList, fmt.Sprint(n)) + } + } + return "[" + strings.Join(stringList, " ") + "]" +} From 9d9572a3a3a1565fc7d4aa668bd11131ef336bfb Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Fri, 28 Oct 2022 14:23:08 +0500 Subject: [PATCH 02/10] move function to shared and C++ support --- templates/cc/duration.go | 4 ++-- templates/cc/in.go | 4 ++-- templates/goshared/bytes.go | 4 ++-- templates/goshared/duration.go | 4 ++-- templates/goshared/in.go | 4 ++-- templates/goshared/register.go | 15 --------------- templates/shared/functions.go | 3 ++- templates/shared/in_list.go | 23 +++++++++++++++++++++++ 8 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 templates/shared/in_list.go diff --git a/templates/cc/duration.go b/templates/cc/duration.go index 16f086f00..e40cd1e2a 100644 --- a/templates/cc/duration.go +++ b/templates/cc/duration.go @@ -77,10 +77,10 @@ const durationTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if ({{ lookup $f "InLookup" }}.find(dur) == {{ lookup $f "InLookup" }}.end()) - {{ err . "value must be in list " $r.In }} + {{ err . "value must be in list " (inList $f $r.In) }} {{ else if $r.NotIn }} if ({{ lookup $f "NotInLookup" }}.find(dur) != {{ lookup $f "NotInLookup" }}.end()) - {{ err . "value must not be in list " $r.NotIn }} + {{ err . "value must not be in list " (inList $f $r.NotIn) }} {{ end }} } } diff --git a/templates/cc/in.go b/templates/cc/in.go index c9b8f7525..47e6dfde6 100644 --- a/templates/cc/in.go +++ b/templates/cc/in.go @@ -3,11 +3,11 @@ package cc const inTpl = `{{ $f := .Field -}}{{ $r := .Rules -}} {{- if $r.In }} if ({{ lookup $f "InLookup" }}.find(static_cast({{ accessor . }})) == {{ lookup $f "InLookup" }}.end()) { - {{ err . "value must be in list " $r.In }} + {{ err . "value must be in list " (inList $f $r.In) }} } {{- else if $r.NotIn }} if ({{ lookup $f "NotInLookup" }}.find(static_cast({{ accessor . }})) != {{ lookup $f "NotInLookup" }}.end()) { - {{ err . "value must not be in list " $r.NotIn }} + {{ err . "value must not be in list " (inList $f $r.NotIn) }} } {{- end }} ` diff --git a/templates/goshared/bytes.go b/templates/goshared/bytes.go index e9caa66a2..c86f5593d 100644 --- a/templates/goshared/bytes.go +++ b/templates/goshared/bytes.go @@ -69,13 +69,13 @@ const bytesTpl = ` {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[string({{ accessor . }})]; !ok { - err := {{ err . "value must be in list " $r.In }} + err := {{ err . "value must be in list " (inList $f $r.In) }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[string({{ accessor . }})]; ok { - err := {{ err . "value must not be in list " $r.NotIn }} + err := {{ err . "value must not be in list " (inList $f $r.NotIn) }} if !all { return err } errors = append(errors, err) } diff --git a/templates/goshared/duration.go b/templates/goshared/duration.go index c039ab564..287dbb300 100644 --- a/templates/goshared/duration.go +++ b/templates/goshared/duration.go @@ -104,13 +104,13 @@ const durationcmpTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[dur]; !ok { - err := {{ err . "value must be in list " $r.In }} + err := {{ err . "value must be in list " (inList $f $r.In) }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[dur]; ok { - err := {{ err . "value must not be in list " $r.NotIn }} + err := {{ err . "value must not be in list " (inList $f $r.NotIn) }} if !all { return err } errors = append(errors, err) } diff --git a/templates/goshared/in.go b/templates/goshared/in.go index f2df50248..ef1d3d1f1 100644 --- a/templates/goshared/in.go +++ b/templates/goshared/in.go @@ -3,13 +3,13 @@ package goshared const inTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[{{ accessor . }}]; !ok { - err := {{ err . "value must be in list " (list $f $r.In) }} + err := {{ err . "value must be in list " (inList $f $r.In) }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[{{ accessor . }}]; ok { - err := {{ err . "value must not be in list " (list $f $r.NotIn) }} + err := {{ err . "value must not be in list " (inList $f $r.NotIn) }} if !all { return err } errors = append(errors, err) } diff --git a/templates/goshared/register.go b/templates/goshared/register.go index 88d0728ea..d94f236d7 100644 --- a/templates/goshared/register.go +++ b/templates/goshared/register.go @@ -50,7 +50,6 @@ func Register(tpl *template.Template, params pgs.Parameters) { "externalEnums": fns.externalEnums, "enumName": fns.enumName, "enumPackages": fns.enumPackages, - "list": fns.list, }) template.Must(tpl.New("msg").Parse(msgTpl)) @@ -378,17 +377,3 @@ func (fns goSharedFuncs) enumPackages(enums []pgs.Enum) map[pgs.Name]NormalizedE func (fns goSharedFuncs) snakeCase(name string) string { return strcase.ToSnake(name) } - -func (fns goSharedFuncs) list(f pgs.Field, list []int32) string { - stringList := make([]string, 0, len(list)) - if enum := f.Type().Enum(); enum != nil { - for _, n := range list { - stringList = append(stringList, enum.Values()[n].Name().String()) - } - } else { - for _, n := range list { - stringList = append(stringList, fmt.Sprint(n)) - } - } - return "[" + strings.Join(stringList, " ") + "]" -} diff --git a/templates/shared/functions.go b/templates/shared/functions.go index 2bf111a45..7aaa55d35 100644 --- a/templates/shared/functions.go +++ b/templates/shared/functions.go @@ -3,7 +3,7 @@ package shared import ( "text/template" - "github.com/lyft/protoc-gen-star" + pgs "github.com/lyft/protoc-gen-star" ) func RegisterFunctions(tpl *template.Template, params pgs.Parameters) { @@ -16,5 +16,6 @@ func RegisterFunctions(tpl *template.Template, params pgs.Parameters) { "has": Has, "needs": Needs, "fileneeds": FileNeeds, + "inList": inList, }) } diff --git a/templates/shared/in_list.go b/templates/shared/in_list.go new file mode 100644 index 000000000..7e3c1d53a --- /dev/null +++ b/templates/shared/in_list.go @@ -0,0 +1,23 @@ +package shared + +import ( + "fmt" + "strings" + + pgs "github.com/lyft/protoc-gen-star" +) + +// inList - returns list between box brackets, if type is ENUM, instead of numbers enum values are used +func inList(f pgs.Field, list []int32) string { + stringList := make([]string, 0, len(list)) + if enum := f.Type().Enum(); enum != nil { + for _, n := range list { + stringList = append(stringList, enum.Values()[n].Name().String()) + } + } else { + for _, n := range list { + stringList = append(stringList, fmt.Sprint(n)) + } + } + return "[" + strings.Join(stringList, " ") + "]" +} From d2dc5db08b686a41494c591aad9324a2c47155eb Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Tue, 1 Nov 2022 14:12:13 +0500 Subject: [PATCH 03/10] remove unwanted inLists --- templates/cc/duration.go | 4 ++-- templates/goshared/bytes.go | 4 ++-- templates/goshared/duration.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/cc/duration.go b/templates/cc/duration.go index e40cd1e2a..16f086f00 100644 --- a/templates/cc/duration.go +++ b/templates/cc/duration.go @@ -77,10 +77,10 @@ const durationTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if ({{ lookup $f "InLookup" }}.find(dur) == {{ lookup $f "InLookup" }}.end()) - {{ err . "value must be in list " (inList $f $r.In) }} + {{ err . "value must be in list " $r.In }} {{ else if $r.NotIn }} if ({{ lookup $f "NotInLookup" }}.find(dur) != {{ lookup $f "NotInLookup" }}.end()) - {{ err . "value must not be in list " (inList $f $r.NotIn) }} + {{ err . "value must not be in list " $r.NotIn }} {{ end }} } } diff --git a/templates/goshared/bytes.go b/templates/goshared/bytes.go index c86f5593d..e9caa66a2 100644 --- a/templates/goshared/bytes.go +++ b/templates/goshared/bytes.go @@ -69,13 +69,13 @@ const bytesTpl = ` {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[string({{ accessor . }})]; !ok { - err := {{ err . "value must be in list " (inList $f $r.In) }} + err := {{ err . "value must be in list " $r.In }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[string({{ accessor . }})]; ok { - err := {{ err . "value must not be in list " (inList $f $r.NotIn) }} + err := {{ err . "value must not be in list " $r.NotIn }} if !all { return err } errors = append(errors, err) } diff --git a/templates/goshared/duration.go b/templates/goshared/duration.go index 287dbb300..c039ab564 100644 --- a/templates/goshared/duration.go +++ b/templates/goshared/duration.go @@ -104,13 +104,13 @@ const durationcmpTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[dur]; !ok { - err := {{ err . "value must be in list " (inList $f $r.In) }} + err := {{ err . "value must be in list " $r.In }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[dur]; ok { - err := {{ err . "value must not be in list " (inList $f $r.NotIn) }} + err := {{ err . "value must not be in list " $r.NotIn }} if !all { return err } errors = append(errors, err) } From 6159273e0c2757d23668d256df337500a67464f8 Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Tue, 1 Nov 2022 14:36:52 +0500 Subject: [PATCH 04/10] add isEnum --- templates/cc/in.go | 12 ++++++++++-- templates/goshared/in.go | 12 ++++++++++-- templates/shared/BUILD.bazel | 1 + templates/shared/{in_list.go => enums.go} | 8 ++++++-- templates/shared/functions.go | 3 ++- 5 files changed, 29 insertions(+), 7 deletions(-) rename templates/shared/{in_list.go => enums.go} (71%) diff --git a/templates/cc/in.go b/templates/cc/in.go index 47e6dfde6..de67d69a6 100644 --- a/templates/cc/in.go +++ b/templates/cc/in.go @@ -3,11 +3,19 @@ package cc const inTpl = `{{ $f := .Field -}}{{ $r := .Rules -}} {{- if $r.In }} if ({{ lookup $f "InLookup" }}.find(static_cast({{ accessor . }})) == {{ lookup $f "InLookup" }}.end()) { - {{ err . "value must be in list " (inList $f $r.In) }} + {{- if isEnum $f }} + {{ err . "value must be in list " (enumList $f $r.In) }} + {{- else }} + {{ err . "value must be in list " $r.In }} + {{- end }} } {{- else if $r.NotIn }} if ({{ lookup $f "NotInLookup" }}.find(static_cast({{ accessor . }})) != {{ lookup $f "NotInLookup" }}.end()) { - {{ err . "value must not be in list " (inList $f $r.NotIn) }} + {{- if isEnum $f }} + {{ err . "value must not be in list " (enumList $f $r.NotIn) }} + {{- else }} + {{ err . "value must not be in list " $r.NotIn }} + {{- end }} } {{- end }} ` diff --git a/templates/goshared/in.go b/templates/goshared/in.go index ef1d3d1f1..347f26b7a 100644 --- a/templates/goshared/in.go +++ b/templates/goshared/in.go @@ -3,13 +3,21 @@ package goshared const inTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[{{ accessor . }}]; !ok { - err := {{ err . "value must be in list " (inList $f $r.In) }} + {{- if isEnum $f }} + err := {{ err . "value must be in list " (enumList $f $r.In) }} + {{- else }} + err := {{ err . "value must be in list " $r.In }} + {{- end }} if !all { return err } errors = append(errors, err) } {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[{{ accessor . }}]; ok { - err := {{ err . "value must not be in list " (inList $f $r.NotIn) }} + {{- if isEnum $f }} + err := {{ err . "value must not be in list " (enumList $f $r.NotIn) }} + {{- else }} + err := {{ err . "value must not be in list " $r.NotIn }} + {{- end }} if !all { return err } errors = append(errors, err) } diff --git a/templates/shared/BUILD.bazel b/templates/shared/BUILD.bazel index 2137345d7..0f9f5f151 100644 --- a/templates/shared/BUILD.bazel +++ b/templates/shared/BUILD.bazel @@ -8,6 +8,7 @@ go_library( "functions.go", "reflection.go", "well_known.go", + "enums.go" ], importpath = "github.com/envoyproxy/protoc-gen-validate/templates/shared", visibility = ["//visibility:public"], diff --git a/templates/shared/in_list.go b/templates/shared/enums.go similarity index 71% rename from templates/shared/in_list.go rename to templates/shared/enums.go index 7e3c1d53a..7d89b38ae 100644 --- a/templates/shared/in_list.go +++ b/templates/shared/enums.go @@ -7,8 +7,12 @@ import ( pgs "github.com/lyft/protoc-gen-star" ) -// inList - returns list between box brackets, if type is ENUM, instead of numbers enum values are used -func inList(f pgs.Field, list []int32) string { +func isEnum(f pgs.Field) bool { + return f.Type().IsEnum() +} + +// enumList - if type is ENUM, enum values are returned +func enumList(f pgs.Field, list []int32) string { stringList := make([]string, 0, len(list)) if enum := f.Type().Enum(); enum != nil { for _, n := range list { diff --git a/templates/shared/functions.go b/templates/shared/functions.go index 7aaa55d35..24f27187e 100644 --- a/templates/shared/functions.go +++ b/templates/shared/functions.go @@ -16,6 +16,7 @@ func RegisterFunctions(tpl *template.Template, params pgs.Parameters) { "has": Has, "needs": Needs, "fileneeds": FileNeeds, - "inList": inList, + "isEnum": isEnum, + "enumList": enumList, }) } From 5fb9e995f76e004335c7437387c402c873e5d374 Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Tue, 1 Nov 2022 14:51:57 +0500 Subject: [PATCH 05/10] remove extra tabs --- templates/cc/in.go | 8 ++++---- templates/goshared/in.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/templates/cc/in.go b/templates/cc/in.go index de67d69a6..57cf21f75 100644 --- a/templates/cc/in.go +++ b/templates/cc/in.go @@ -4,17 +4,17 @@ const inTpl = `{{ $f := .Field -}}{{ $r := .Rules -}} {{- if $r.In }} if ({{ lookup $f "InLookup" }}.find(static_cast({{ accessor . }})) == {{ lookup $f "InLookup" }}.end()) { {{- if isEnum $f }} - {{ err . "value must be in list " (enumList $f $r.In) }} + {{ err . "value must be in list " (enumList $f $r.In) }} {{- else }} - {{ err . "value must be in list " $r.In }} + {{ err . "value must be in list " $r.In }} {{- end }} } {{- else if $r.NotIn }} if ({{ lookup $f "NotInLookup" }}.find(static_cast({{ accessor . }})) != {{ lookup $f "NotInLookup" }}.end()) { {{- if isEnum $f }} - {{ err . "value must not be in list " (enumList $f $r.NotIn) }} + {{ err . "value must not be in list " (enumList $f $r.NotIn) }} {{- else }} - {{ err . "value must not be in list " $r.NotIn }} + {{ err . "value must not be in list " $r.NotIn }} {{- end }} } {{- end }} diff --git a/templates/goshared/in.go b/templates/goshared/in.go index 347f26b7a..c2fc2e3bb 100644 --- a/templates/goshared/in.go +++ b/templates/goshared/in.go @@ -4,9 +4,9 @@ const inTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.In }} if _, ok := {{ lookup $f "InLookup" }}[{{ accessor . }}]; !ok { {{- if isEnum $f }} - err := {{ err . "value must be in list " (enumList $f $r.In) }} + err := {{ err . "value must be in list " (enumList $f $r.In) }} {{- else }} - err := {{ err . "value must be in list " $r.In }} + err := {{ err . "value must be in list " $r.In }} {{- end }} if !all { return err } errors = append(errors, err) @@ -14,9 +14,9 @@ const inTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ else if $r.NotIn }} if _, ok := {{ lookup $f "NotInLookup" }}[{{ accessor . }}]; ok { {{- if isEnum $f }} - err := {{ err . "value must not be in list " (enumList $f $r.NotIn) }} + err := {{ err . "value must not be in list " (enumList $f $r.NotIn) }} {{- else }} - err := {{ err . "value must not be in list " $r.NotIn }} + err := {{ err . "value must not be in list " $r.NotIn }} {{- end }} if !all { return err } errors = append(errors, err) From 7672a1490c67122fb20b7dde39715eba52ec886c Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Wed, 2 Nov 2022 11:44:27 +0500 Subject: [PATCH 06/10] const support --- templates/cc/const.go | 6 +++++- templates/goshared/const.go | 6 +++++- templates/shared/enums.go | 8 ++++++++ templates/shared/functions.go | 1 + 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/templates/cc/const.go b/templates/cc/const.go index 2d6af9ed7..27c8e2839 100644 --- a/templates/cc/const.go +++ b/templates/cc/const.go @@ -1,9 +1,13 @@ package cc -const constTpl = `{{ $r := .Rules }} +const constTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.Const }} if ({{ accessor . }} != {{ lit $r.GetConst }}) { + {{- if isEnum $f }} + {{ err . "value must equal " (enumVal $f $r.GetConst) }} + {{- else }} {{ err . "value must equal " (lit $r.GetConst) }} + {{- end }} } {{ end }} ` diff --git a/templates/goshared/const.go b/templates/goshared/const.go index 18bf64665..118172e4a 100644 --- a/templates/goshared/const.go +++ b/templates/goshared/const.go @@ -1,9 +1,13 @@ package goshared -const constTpl = `{{ $r := .Rules }} +const constTpl = `{{ $f := .Field }}{{ $r := .Rules }} {{ if $r.Const }} if {{ accessor . }} != {{ lit $r.GetConst }} { + {{- if isEnum $f }} + err := {{ err . "value must equal " (enumVal $f $r.GetConst) }} + {{- else }} err := {{ err . "value must equal " $r.GetConst }} + {{- end }} if !all { return err } errors = append(errors, err) } diff --git a/templates/shared/enums.go b/templates/shared/enums.go index 7d89b38ae..83209787a 100644 --- a/templates/shared/enums.go +++ b/templates/shared/enums.go @@ -25,3 +25,11 @@ func enumList(f pgs.Field, list []int32) string { } return "[" + strings.Join(stringList, " ") + "]" } + +// enumVal - if type is ENUM, enum value is returned +func enumVal(f pgs.Field, val int32) string { + if enum := f.Type().Enum(); enum != nil { + return enum.Values()[val].Name().String() + } + return fmt.Sprint(val) +} diff --git a/templates/shared/functions.go b/templates/shared/functions.go index 24f27187e..3e5c26e20 100644 --- a/templates/shared/functions.go +++ b/templates/shared/functions.go @@ -18,5 +18,6 @@ func RegisterFunctions(tpl *template.Template, params pgs.Parameters) { "fileneeds": FileNeeds, "isEnum": isEnum, "enumList": enumList, + "enumVal": enumVal, }) } From 5c1bebdcd5fe07cb8096d48099dfbab06b9ec737 Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Tue, 8 Nov 2022 19:54:52 +0500 Subject: [PATCH 07/10] update rule_comarison.md --- rule_comparison.md | 1 + 1 file changed, 1 insertion(+) diff --git a/rule_comparison.md b/rule_comparison.md index 05b65b4f9..a9c023336 100644 --- a/rule_comparison.md +++ b/rule_comparison.md @@ -55,6 +55,7 @@ | const |✅|✅|✅|✅|✅| | defined_only |✅|✅|✅|✅|✅| | in/not_in |✅|✅|✅|✅|✅| +| in/not_in/const
enum value in error |✅|✅|✅|✅|❌| ## Messages | Constraint Rule | Go | GoGo | C++ | Java | Python | From 2869e43655342d49f69072d81b8c7763969fda52 Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Tue, 27 Dec 2022 15:08:40 +0500 Subject: [PATCH 08/10] enum val check fix --- templates/shared/enums.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/templates/shared/enums.go b/templates/shared/enums.go index 83209787a..5c9a7d1a4 100644 --- a/templates/shared/enums.go +++ b/templates/shared/enums.go @@ -11,12 +11,24 @@ func isEnum(f pgs.Field) bool { return f.Type().IsEnum() } +func enumNamesMap(values []pgs.EnumValue) (m map[int32]string) { + m = make(map[int32]string) + for _, v := range values { + // TODO: Allow aliases? + if _, exists := m[v.Value()]; !exists { + m[v.Value()] = v.Name().String() + } + } + return m +} + // enumList - if type is ENUM, enum values are returned func enumList(f pgs.Field, list []int32) string { stringList := make([]string, 0, len(list)) if enum := f.Type().Enum(); enum != nil { + names := enumNamesMap(enum.Values()) for _, n := range list { - stringList = append(stringList, enum.Values()[n].Name().String()) + stringList = append(stringList, names[n]) } } else { for _, n := range list { @@ -29,7 +41,7 @@ func enumList(f pgs.Field, list []int32) string { // enumVal - if type is ENUM, enum value is returned func enumVal(f pgs.Field, val int32) string { if enum := f.Type().Enum(); enum != nil { - return enum.Values()[val].Name().String() + return enumNamesMap(enum.Values())[val] } return fmt.Sprint(val) } From 2b94dc10d0f3d57aeeea52cae973eee8c21c711b Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Tue, 27 Dec 2022 21:14:15 +0500 Subject: [PATCH 09/10] python support --- python/protoc_gen_validate/validator.py | 46 +++++++++++++++++++++---- rule_comparison.md | 1 - 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/python/protoc_gen_validate/validator.py b/python/protoc_gen_validate/validator.py index a6874ab72..0137331df 100644 --- a/python/protoc_gen_validate/validator.py +++ b/python/protoc_gen_validate/validator.py @@ -308,9 +308,6 @@ def const_template(option_value, name): {%- elif str(o.bool) and o.bool['const'] != "" -%} if {{ name }} != {{ o.bool['const'] }}: raise ValidationFailed(\"{{ name }} not equal to {{ o.bool['const'] }}\") - {%- elif str(o.enum) and o.enum['const'] -%} - if {{ name }} != {{ o.enum['const'] }}: - raise ValidationFailed(\"{{ name }} not equal to {{ o.enum['const'] }}\") {%- elif str(o.bytes) and o.bytes.HasField('const') -%} {% if sys.version_info[0] >= 3 %} if {{ name }} != {{ o.bytes['const'] }}: @@ -828,17 +825,52 @@ def enum_values(field): return [x.number for x in field.enum_type.values] +def enum_name(field, number): + for x in field.enum_type.values: + if x.number == number: + return x.name + return "" + + +def enum_names(field, numbers): + m = {x.number: x.name for x in field.enum_type.values} + return "[" + "".join([m[n] for n in numbers]) + "]" + + +def enum_const_template(value, name, field): + const_tmpl = """{%- if str(value) and value['const'] -%} + if {{ name }} != {{ value['const'] }}: + raise ValidationFailed(\"{{ name }} not equal to {{ enum_name(field, value['const']) }}\") + {%- endif -%} + """ + return Template(const_tmpl).render(value=value, name=name, field=field, enum_name=enum_name, str=str) + + +def enum_in_template(value, name, field): + in_tmpl = """ + {%- if value['in'] %} + if {{ name }} not in {{ value['in'] }}: + raise ValidationFailed(\"{{ name }} not in {{ enum_names(field, value['in']) }}\") + {%- endif -%} + {%- if value['not_in'] %} + if {{ name }} in {{ value['not_in'] }}: + raise ValidationFailed(\"{{ name }} in {{ enum_names(field, value['not_in']) }}\") + {%- endif -%} + """ + return Template(in_tmpl).render(value=value, name=name, field=field, enum_names=enum_names) + + def enum_template(option_value, name, field): enum_tmpl = """ - {{ const_template(option_value, name) -}} - {{ in_template(option_value.enum, name) -}} + {{ enum_const_template(option_value.enum, name, field) -}} + {{ enum_in_template(option_value.enum, name, field) -}} {% if option_value.enum['defined_only'] %} if {{ name }} not in {{ enum_values(field) }}: raise ValidationFailed(\"{{ name }} is not defined\") {% endif %} """ - return Template(enum_tmpl).render(option_value=option_value, name=name, const_template=const_template, - in_template=in_template, field=field, enum_values=enum_values) + return Template(enum_tmpl).render(option_value=option_value, name=name, enum_const_template=enum_const_template, + enum_in_template=enum_in_template, field=field, enum_values=enum_values) def any_template(option_value, name, repeated=False): diff --git a/rule_comparison.md b/rule_comparison.md index a9c023336..05b65b4f9 100644 --- a/rule_comparison.md +++ b/rule_comparison.md @@ -55,7 +55,6 @@ | const |✅|✅|✅|✅|✅| | defined_only |✅|✅|✅|✅|✅| | in/not_in |✅|✅|✅|✅|✅| -| in/not_in/const
enum value in error |✅|✅|✅|✅|❌| ## Messages | Constraint Rule | Go | GoGo | C++ | Java | Python | From 3761a60bbb57fb79a5a18c4830aa346186df2329 Mon Sep 17 00:00:00 2001 From: Elbek Khoshimjonov Date: Wed, 4 Jan 2023 12:04:12 +0500 Subject: [PATCH 10/10] remove TODO:alias --- templates/shared/enums.go | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/shared/enums.go b/templates/shared/enums.go index 5c9a7d1a4..cdc7e64b7 100644 --- a/templates/shared/enums.go +++ b/templates/shared/enums.go @@ -14,7 +14,6 @@ func isEnum(f pgs.Field) bool { func enumNamesMap(values []pgs.EnumValue) (m map[int32]string) { m = make(map[int32]string) for _, v := range values { - // TODO: Allow aliases? if _, exists := m[v.Value()]; !exists { m[v.Value()] = v.Name().String() }