diff --git a/Makefile b/Makefile index afa59a1..74d8a10 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,4 @@ -.PHONY: generate -generate: - protoc \ - -I. \ - --go_out=paths=source_relative:. \ - s12/protobuf/proto/*.proto s12/flags/permissions/*.proto - ARCH := $(shell uname -p) ifeq ($(ARCH), arm) SYS_ROOT = /opt/homebrew/ @@ -25,47 +18,15 @@ protobuf/protoc-gen-cruxclient/api_generator.o \ protobuf/protoc-gen-cruxclient/mock_service_generator.o $(CXX) $^ $(LDFLAGS) -o $@ -.PHONY: install-govalidator -install-govalidator: - go install ./protobuf/protoc-gen-govalidator - .PHONY: install-logger go install github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-logger -.PHONY: install-s12perm -install-s12perm: generate - go install ./protobuf/protoc-gen-s12perm - .PHONY: install-cruxclient install-cruxclient: protoc-gen-cruxclient install protoc-gen-cruxclient $(SYS_ROOT)/bin/protoc-gen-cruxclient .PHONY: install -install: install-govalidator install-logger - -.PHONY: govalidator -govalidator: install-govalidator - protoc \ - -I./protobuf/protoc-gen-govalidator/example \ - -I$(GOPATH)/src \ - -I. \ - --go_out=paths=source_relative:protobuf/protoc-gen-govalidator/example \ - --govalidator_out=paths=source_relative:protobuf/protoc-gen-govalidator/example \ - protobuf/protoc-gen-govalidator/example/*.proto - -.PHONY: govalidator-test -govalidator-test: - go test github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/example - -.PHONY: govalidator-valtest -govalidator-valtest: install-govalidator - protoc \ - -I./protobuf/protoc-gen-govalidator/valtest \ - -I$(GOPATH)/src \ - -I. \ - --go_out=paths=source_relative:protobuf/protoc-gen-govalidator/valtest \ - --govalidator_out=paths=source_relative:protobuf/protoc-gen-govalidator/valtest \ - protobuf/protoc-gen-govalidator/valtest/*.proto +install: install-logger PLAYGROUND=./protobuf/protoc-gen-govalidator/playground PLAYGROUND_GEN=$(PLAYGROUND)/gen @@ -82,32 +43,6 @@ endif --debug_out="${PLAYGROUND}:${PLAYGROUND}" \ $(PLAYGROUND)/*.proto -.PHONY: govalidator-valtest1 -playground-generated-code: install-govalidator # Generates code from protobuf files - protoc \ - -I$(PLAYGROUND) \ - -I$(GOPATH)/src \ - -I. \ - --go_out=paths=source_relative:$(PLAYGROUND_GEN) \ - --govalidator_out=paths=source_relative:$(PLAYGROUND_GEN) \ - $(PLAYGROUND)/*.proto - -.PHONY: govalidator-valtest-test -govalidator-valtest-test: - go test github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/valtest - -.PHONY: s12perm -s12perm: install-s12perm - protoc \ - -I./protobuf/protoc-gen-s12perm/example \ - -I$(GOPATH)/src \ - -I. \ - --s12perm_out=paths=source_relative:protobuf/protoc-gen-s12perm/example \ - protobuf/protoc-gen-s12perm/example/*proto - -.PHONY: s12perm-test -s12perm-test: s12perm - cd protobuf/protoc-gen-s12perm/example && go test .PHONY: logger logger: install-logger @@ -143,4 +78,4 @@ gogrpcmock: install-gogrpcmock .PHONY: example -example: govalidator logger +example: logger diff --git a/go.mod b/go.mod index 23949e0..46c600b 100644 --- a/go.mod +++ b/go.mod @@ -5,20 +5,13 @@ go 1.18 require ( github.com/gofrs/uuid v3.3.0+incompatible github.com/gogo/protobuf v1.3.1 - github.com/golang/protobuf v1.5.4 github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 - github.com/stretchr/testify v1.7.0 - google.golang.org/protobuf v1.34.2 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.7.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) -require ( - github.com/corpix/uarand v0.1.1 // indirect - golang.org/x/text v0.18.0 -) +require github.com/corpix/uarand v0.1.1 // indirect diff --git a/go.sum b/go.sum index 0b7c993..291d653 100644 --- a/go.sum +++ b/go.sum @@ -11,10 +11,6 @@ github.com/gofrs/uuid v3.3.0+incompatible h1:8K4tyRfvU1CYPgJsveYFQMhpFd/wXNM7iK6 github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428 h1:Mo9W14pwbO9VfRe+ygqZ8dFbPpoIK1HFrG/zjTuQ+nc= github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -27,12 +23,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -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.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/protobuf/protoc-gen-govalidator/README.md b/protobuf/protoc-gen-govalidator/README.md deleted file mode 100644 index d8a74b3..0000000 --- a/protobuf/protoc-gen-govalidator/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# Protocol buffer validators compiler - -A `protoc` plugin that generates `Validate() error` functions on Go proto `struct`s based on field options inside `.proto` files. The validation functions are code-generated and thus don't suffer on performance from tag-based reflection on deeply-nested messages. - -  - -## Usage - -``` -$ go get github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator -$ protoc -I. --gogo_out=:. --govalidator_out=. example.proto -``` -  - -## Development - -Use these commands at the root folder of this repository for testing: -```bash -cd s12-proto - -# regenerate examples and run tests -make govalidator -make govalidator-test - -# regenerate valtest and run tests -make govalidator-valtest -make govalidator-valtest-test -``` -  - -## Playground - -The validator plugin is invoked by the protobuf compiler tool directly to generate the respective validator code. -As a result, it makes it very hard to attach the plugin to a debugger and inspect the code during that process. - -A sample code has been provided that allows you to attach and step through the plugin during the code generation process. -The basic premise of the playground approach is -- generate the `CodeGeneratorRequest` object of the proto files (via makefile) -- run the validator plugin on the request object (via the .go code) -- the resulting files are printed to `stdout` - -The `CodeGeneratorRequest` object is what is consumed by the protobuf compiler as well. -The code in `playground_main.go` is a standard go file with a main function. - -There are a couple of Makefile targets that help us to achieve this -- `make playground-req-object`: generate the request object from the `playground.proto` -- `make playground-generated-code`: generate the eventual code in the respective `validator_regex.pb.go` and `validator.pb.go` - -At minimum, you are required to run the `playground-req-object` target before you run the code in `playground_main.go` - -You can modify the `playground.proto` to add in a new type of message or use existing validators to see how the plugin works in action. - -## Protobuf Validators -There are a number of common fields for which validators have been developed. For detailed documentation and usage, visit the following link to a private SafetyCulture confluence page - https://safetyculture.atlassian.net/l/cp/wC1Xz6np. - -If new validators are added, please be sure to document them including their usage and options. - -Link to the last public version of the readme which had the complete documentation to date - https://github.com/SafetyCulture/s12-proto/blob/f8d868b8135e3f2438bfaca234e27b2f305c59d9/protobuf/protoc-gen-govalidator/README.md - -  - -## Legacy Validator Fields - -__Deprecated: do not define the following validators for new fields. Use one of the newer validation options above.__ - -- validator.uuid -- validator.int_gt -- validator.int_lt -- validator.int_gte -- validator.int_lte -- validator.length_lte -- validator.length_gte -- validator.legacy_id -- validator.trim_len_check diff --git a/protobuf/protoc-gen-govalidator/example/example.pb.go b/protobuf/protoc-gen-govalidator/example/example.pb.go deleted file mode 100644 index 4534c88..0000000 --- a/protobuf/protoc-gen-govalidator/example/example.pb.go +++ /dev/null @@ -1,1049 +0,0 @@ -// Copyright (c) 2018 SafetyCulture Pty Ltd. All Rights Reserved. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.2 -// source: example.proto - -package example - -import ( - _ "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - 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 MyMessageWithEnum_MyEnum int32 - -const ( - // Default is unspecified. - MyMessageWithEnum_MY_ENUM_UNSPECIFIED MyMessageWithEnum_MyEnum = 0 - // First valid value. - MyMessageWithEnum_MY_ENUM_FIRST MyMessageWithEnum_MyEnum = 1 -) - -// Enum value maps for MyMessageWithEnum_MyEnum. -var ( - MyMessageWithEnum_MyEnum_name = map[int32]string{ - 0: "MY_ENUM_UNSPECIFIED", - 1: "MY_ENUM_FIRST", - } - MyMessageWithEnum_MyEnum_value = map[string]int32{ - "MY_ENUM_UNSPECIFIED": 0, - "MY_ENUM_FIRST": 1, - } -) - -func (x MyMessageWithEnum_MyEnum) Enum() *MyMessageWithEnum_MyEnum { - p := new(MyMessageWithEnum_MyEnum) - *p = x - return p -} - -func (x MyMessageWithEnum_MyEnum) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (MyMessageWithEnum_MyEnum) Descriptor() protoreflect.EnumDescriptor { - return file_example_proto_enumTypes[0].Descriptor() -} - -func (MyMessageWithEnum_MyEnum) Type() protoreflect.EnumType { - return &file_example_proto_enumTypes[0] -} - -func (x MyMessageWithEnum_MyEnum) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use MyMessageWithEnum_MyEnum.Descriptor instead. -func (MyMessageWithEnum_MyEnum) EnumDescriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{4, 0} -} - -type ExampleMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // returns an error if the string cannot be parsed as a UUID - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // bytes can also be parsed as UUID with support for gogo - UserId []byte `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - // should be a valid email address - Email string `protobuf:"bytes,3,opt,name=email,proto3" json:"email,omitempty"` - // integers can be greater than a value - Age int32 `protobuf:"varint,4,opt,name=age,proto3" json:"age,omitempty"` - // integers can be less than a value - Speed int64 `protobuf:"varint,5,opt,name=speed,proto3" json:"speed,omitempty"` - // integers greater/less than or equal, the can also be combined - Score int32 `protobuf:"varint,6,opt,name=score,proto3" json:"score,omitempty"` - // validation is created for all messages - Inner *InnerMessage `protobuf:"bytes,7,opt,name=inner,proto3" json:"inner,omitempty"` - // can validate each repeated item too - Ids [][]byte `protobuf:"bytes,8,rep,name=ids,proto3" json:"ids,omitempty"` - // only validate if non-zero value - MediaId string `protobuf:"bytes,9,opt,name=media_id,json=mediaId,proto3" json:"media_id,omitempty"` - // validate the max length of a string - Description string `protobuf:"bytes,10,opt,name=description,proto3" json:"description,omitempty"` - // validate the min length - Password string `protobuf:"bytes,11,opt,name=password,proto3" json:"password,omitempty"` - // You don't need to validate everything - NoValidation string `protobuf:"bytes,12,opt,name=no_validation,json=noValidation,proto3" json:"no_validation,omitempty"` - // Types that are assignable to ContactOneof: - // - // *ExampleMessage_Fax - // *ExampleMessage_Phone - ContactOneof isExampleMessage_ContactOneof `protobuf_oneof:"contact_oneof"` - // Required inner message - MsgRequired *InnerMessage `protobuf:"bytes,15,opt,name=msg_required,json=msgRequired,proto3" json:"msg_required,omitempty"` - // returns an error if the string cannot be parsed as a legacy id - LegacyId string `protobuf:"bytes,16,opt,name=legacy_id,json=legacyId,proto3" json:"legacy_id,omitempty"` - // InnerMessage can contain a legacy id too - InnerLegacyId *InnerMessageWithLegacyId `protobuf:"bytes,17,opt,name=inner_legacy_id,json=innerLegacyId,proto3" json:"inner_legacy_id,omitempty"` - // Trim leading and trailing whitespaces (as defined by Unicode) before doing length check - Name string `protobuf:"bytes,18,opt,name=name,proto3" json:"name,omitempty"` - NestedMessage *ExampleMessage_NestedMessage `protobuf:"bytes,19,opt,name=nested_message,json=nestedMessage,proto3" json:"nested_message,omitempty"` - NotSupported map[string]string `protobuf:"bytes,100,rep,name=not_supported,json=notSupported,proto3" json:"not_supported,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // strings can validate against a regular expression - Url string `protobuf:"bytes,21,opt,name=url,proto3" json:"url,omitempty"` - ContactsWithLengthConstraint []*ExampleMessage_Contact `protobuf:"bytes,22,rep,name=contacts_with_length_constraint,json=contactsWithLengthConstraint,proto3" json:"contacts_with_length_constraint,omitempty"` - ContactsWithNoLengthConstraint []*ExampleMessage_Contact `protobuf:"bytes,23,rep,name=contacts_with_no_length_constraint,json=contactsWithNoLengthConstraint,proto3" json:"contacts_with_no_length_constraint,omitempty"` - ScheduledFor *timestamppb.Timestamp `protobuf:"bytes,24,opt,name=scheduled_for,json=scheduledFor,proto3" json:"scheduled_for,omitempty"` - Timezone string `protobuf:"bytes,25,opt,name=timezone,proto3" json:"timezone,omitempty"` - TimezoneOptional string `protobuf:"bytes,26,opt,name=timezone_optional,json=timezoneOptional,proto3" json:"timezone_optional,omitempty"` - StringOptional *string `protobuf:"bytes,27,opt,name=string_optional,json=stringOptional,proto3,oneof" json:"string_optional,omitempty"` -} - -func (x *ExampleMessage) Reset() { - *x = ExampleMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExampleMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExampleMessage) ProtoMessage() {} - -func (x *ExampleMessage) ProtoReflect() protoreflect.Message { - mi := &file_example_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 ExampleMessage.ProtoReflect.Descriptor instead. -func (*ExampleMessage) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0} -} - -func (x *ExampleMessage) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -func (x *ExampleMessage) GetUserId() []byte { - if x != nil { - return x.UserId - } - return nil -} - -func (x *ExampleMessage) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *ExampleMessage) GetAge() int32 { - if x != nil { - return x.Age - } - return 0 -} - -func (x *ExampleMessage) GetSpeed() int64 { - if x != nil { - return x.Speed - } - return 0 -} - -func (x *ExampleMessage) GetScore() int32 { - if x != nil { - return x.Score - } - return 0 -} - -func (x *ExampleMessage) GetInner() *InnerMessage { - if x != nil { - return x.Inner - } - return nil -} - -func (x *ExampleMessage) GetIds() [][]byte { - if x != nil { - return x.Ids - } - return nil -} - -func (x *ExampleMessage) GetMediaId() string { - if x != nil { - return x.MediaId - } - return "" -} - -func (x *ExampleMessage) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *ExampleMessage) GetPassword() string { - if x != nil { - return x.Password - } - return "" -} - -func (x *ExampleMessage) GetNoValidation() string { - if x != nil { - return x.NoValidation - } - return "" -} - -func (m *ExampleMessage) GetContactOneof() isExampleMessage_ContactOneof { - if m != nil { - return m.ContactOneof - } - return nil -} - -func (x *ExampleMessage) GetFax() string { - if x, ok := x.GetContactOneof().(*ExampleMessage_Fax); ok { - return x.Fax - } - return "" -} - -func (x *ExampleMessage) GetPhone() string { - if x, ok := x.GetContactOneof().(*ExampleMessage_Phone); ok { - return x.Phone - } - return "" -} - -func (x *ExampleMessage) GetMsgRequired() *InnerMessage { - if x != nil { - return x.MsgRequired - } - return nil -} - -func (x *ExampleMessage) GetLegacyId() string { - if x != nil { - return x.LegacyId - } - return "" -} - -func (x *ExampleMessage) GetInnerLegacyId() *InnerMessageWithLegacyId { - if x != nil { - return x.InnerLegacyId - } - return nil -} - -func (x *ExampleMessage) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *ExampleMessage) GetNestedMessage() *ExampleMessage_NestedMessage { - if x != nil { - return x.NestedMessage - } - return nil -} - -func (x *ExampleMessage) GetNotSupported() map[string]string { - if x != nil { - return x.NotSupported - } - return nil -} - -func (x *ExampleMessage) GetUrl() string { - if x != nil { - return x.Url - } - return "" -} - -func (x *ExampleMessage) GetContactsWithLengthConstraint() []*ExampleMessage_Contact { - if x != nil { - return x.ContactsWithLengthConstraint - } - return nil -} - -func (x *ExampleMessage) GetContactsWithNoLengthConstraint() []*ExampleMessage_Contact { - if x != nil { - return x.ContactsWithNoLengthConstraint - } - return nil -} - -func (x *ExampleMessage) GetScheduledFor() *timestamppb.Timestamp { - if x != nil { - return x.ScheduledFor - } - return nil -} - -func (x *ExampleMessage) GetTimezone() string { - if x != nil { - return x.Timezone - } - return "" -} - -func (x *ExampleMessage) GetTimezoneOptional() string { - if x != nil { - return x.TimezoneOptional - } - return "" -} - -func (x *ExampleMessage) GetStringOptional() string { - if x != nil && x.StringOptional != nil { - return *x.StringOptional - } - return "" -} - -type isExampleMessage_ContactOneof interface { - isExampleMessage_ContactOneof() -} - -type ExampleMessage_Fax struct { - Fax string `protobuf:"bytes,13,opt,name=fax,proto3,oneof"` -} - -type ExampleMessage_Phone struct { - Phone string `protobuf:"bytes,14,opt,name=phone,proto3,oneof"` -} - -func (*ExampleMessage_Fax) isExampleMessage_ContactOneof() {} - -func (*ExampleMessage_Phone) isExampleMessage_ContactOneof() {} - -type OuterMessageUsingNestedMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - SomeMessage *ExampleMessage_NestedMessage `protobuf:"bytes,1,opt,name=some_message,json=someMessage,proto3" json:"some_message,omitempty"` -} - -func (x *OuterMessageUsingNestedMessage) Reset() { - *x = OuterMessageUsingNestedMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *OuterMessageUsingNestedMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*OuterMessageUsingNestedMessage) ProtoMessage() {} - -func (x *OuterMessageUsingNestedMessage) ProtoReflect() protoreflect.Message { - mi := &file_example_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 OuterMessageUsingNestedMessage.ProtoReflect.Descriptor instead. -func (*OuterMessageUsingNestedMessage) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{1} -} - -func (x *OuterMessageUsingNestedMessage) GetSomeMessage() *ExampleMessage_NestedMessage { - if x != nil { - return x.SomeMessage - } - return nil -} - -type InnerMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *InnerMessage) Reset() { - *x = InnerMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InnerMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InnerMessage) ProtoMessage() {} - -func (x *InnerMessage) ProtoReflect() protoreflect.Message { - mi := &file_example_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 InnerMessage.ProtoReflect.Descriptor instead. -func (*InnerMessage) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{2} -} - -func (x *InnerMessage) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type InnerMessageWithLegacyId struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *InnerMessageWithLegacyId) Reset() { - *x = InnerMessageWithLegacyId{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InnerMessageWithLegacyId) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InnerMessageWithLegacyId) ProtoMessage() {} - -func (x *InnerMessageWithLegacyId) ProtoReflect() protoreflect.Message { - mi := &file_example_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 InnerMessageWithLegacyId.ProtoReflect.Descriptor instead. -func (*InnerMessageWithLegacyId) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{3} -} - -func (x *InnerMessageWithLegacyId) GetId() string { - if x != nil { - return x.Id - } - return "" -} - -type MyMessageWithEnum struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Enum MyMessageWithEnum_MyEnum `protobuf:"varint,1,opt,name=enum,proto3,enum=example.MyMessageWithEnum_MyEnum" json:"enum,omitempty"` -} - -func (x *MyMessageWithEnum) Reset() { - *x = MyMessageWithEnum{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MyMessageWithEnum) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MyMessageWithEnum) ProtoMessage() {} - -func (x *MyMessageWithEnum) ProtoReflect() protoreflect.Message { - mi := &file_example_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 MyMessageWithEnum.ProtoReflect.Descriptor instead. -func (*MyMessageWithEnum) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{4} -} - -func (x *MyMessageWithEnum) GetEnum() MyMessageWithEnum_MyEnum { - if x != nil { - return x.Enum - } - return MyMessageWithEnum_MY_ENUM_UNSPECIFIED -} - -type ExampleMessage_NestedMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Val string `protobuf:"bytes,1,opt,name=val,proto3" json:"val,omitempty"` - NestedEmail string `protobuf:"bytes,2,opt,name=nested_email,json=nestedEmail,proto3" json:"nested_email,omitempty"` - MemberEmails []string `protobuf:"bytes,3,rep,name=member_emails,json=memberEmails,proto3" json:"member_emails,omitempty"` -} - -func (x *ExampleMessage_NestedMessage) Reset() { - *x = ExampleMessage_NestedMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExampleMessage_NestedMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExampleMessage_NestedMessage) ProtoMessage() {} - -func (x *ExampleMessage_NestedMessage) ProtoReflect() protoreflect.Message { - mi := &file_example_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 ExampleMessage_NestedMessage.ProtoReflect.Descriptor instead. -func (*ExampleMessage_NestedMessage) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *ExampleMessage_NestedMessage) GetVal() string { - if x != nil { - return x.Val - } - return "" -} - -func (x *ExampleMessage_NestedMessage) GetNestedEmail() string { - if x != nil { - return x.NestedEmail - } - return "" -} - -func (x *ExampleMessage_NestedMessage) GetMemberEmails() []string { - if x != nil { - return x.MemberEmails - } - return nil -} - -type ExampleMessage_Contact struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone,omitempty"` - Email string `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"` -} - -func (x *ExampleMessage_Contact) Reset() { - *x = ExampleMessage_Contact{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExampleMessage_Contact) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExampleMessage_Contact) ProtoMessage() {} - -func (x *ExampleMessage_Contact) ProtoReflect() protoreflect.Message { - mi := &file_example_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 ExampleMessage_Contact.ProtoReflect.Descriptor instead. -func (*ExampleMessage_Contact) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0, 2} -} - -func (x *ExampleMessage_Contact) GetPhone() string { - if x != nil { - return x.Phone - } - return "" -} - -func (x *ExampleMessage_Contact) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -type ExampleMessage_NestedMessage_InnerNestedMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - InnerVal string `protobuf:"bytes,1,opt,name=inner_val,json=innerVal,proto3" json:"inner_val,omitempty"` -} - -func (x *ExampleMessage_NestedMessage_InnerNestedMessage) Reset() { - *x = ExampleMessage_NestedMessage_InnerNestedMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_example_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExampleMessage_NestedMessage_InnerNestedMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExampleMessage_NestedMessage_InnerNestedMessage) ProtoMessage() {} - -func (x *ExampleMessage_NestedMessage_InnerNestedMessage) ProtoReflect() protoreflect.Message { - mi := &file_example_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 ExampleMessage_NestedMessage_InnerNestedMessage.ProtoReflect.Descriptor instead. -func (*ExampleMessage_NestedMessage_InnerNestedMessage) Descriptor() ([]byte, []int) { - return file_example_proto_rawDescGZIP(), []int{0, 0, 0} -} - -func (x *ExampleMessage_NestedMessage_InnerNestedMessage) GetInnerVal() string { - if x != nil { - return x.InnerVal - } - return "" -} - -var File_example_proto protoreflect.FileDescriptor - -var file_example_proto_rawDesc = []byte{ - 0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x73, 0x31, 0x32, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa8, 0x0e, - 0x0a, 0x0e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x14, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0x80, 0xeb, - 0x1f, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x04, 0x80, 0xeb, 0x1f, 0x01, 0x52, 0x06, 0x75, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xf2, 0xeb, 0x1f, 0x02, 0x08, 0x01, 0x52, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, - 0x42, 0x04, 0x90, 0xeb, 0x1f, 0x00, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x05, 0x73, - 0x70, 0x65, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x42, 0x04, 0x98, 0xeb, 0x1f, 0x6e, - 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x42, 0x08, 0xa0, 0xeb, 0x1f, 0x00, 0xa8, 0xeb, 0x1f, 0x64, - 0x52, 0x05, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x05, 0x69, - 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0c, 0x42, 0x04, 0x80, 0xeb, 0x1f, 0x01, 0x52, 0x03, 0x69, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x08, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, - 0x80, 0xeb, 0x1f, 0x01, 0xc0, 0xeb, 0x1f, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x49, - 0x64, 0x12, 0x27, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x05, 0xb8, 0xeb, 0x1f, 0xd0, 0x0f, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x08, 0x70, 0x61, - 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xb0, 0xeb, - 0x1f, 0x08, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x23, 0x0a, 0x0d, - 0x6e, 0x6f, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x6f, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x12, 0x0a, 0x03, 0x66, 0x61, 0x78, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, - 0x52, 0x03, 0x66, 0x61, 0x78, 0x12, 0x1c, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xb0, 0xeb, 0x1f, 0x0b, 0x48, 0x00, 0x52, 0x05, 0x70, 0x68, - 0x6f, 0x6e, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x6d, 0x73, 0x67, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x42, 0x04, 0xc8, 0xeb, 0x1f, 0x01, 0x52, 0x0b, 0x6d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x09, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x69, 0x64, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xd0, 0xeb, 0x1f, 0x01, 0x52, 0x08, 0x6c, 0x65, - 0x67, 0x61, 0x63, 0x79, 0x49, 0x64, 0x12, 0x49, 0x0a, 0x0f, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, - 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, - 0x49, 0x64, 0x52, 0x0d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x49, - 0x64, 0x12, 0x20, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x0c, 0xb0, 0xeb, 0x1f, 0x06, 0xb8, 0xeb, 0x1f, 0x0a, 0xd8, 0xeb, 0x1f, 0x01, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x4c, 0x0a, 0x0e, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x65, 0x78, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x0d, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x6e, 0x6f, 0x74, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x18, 0x64, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x12, 0x3c, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, - 0x8a, 0xeb, 0x1f, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x5c, 0x2f, 0x5c, 0x2f, 0x77, 0x77, - 0x77, 0x5c, 0x2e, 0x73, 0x61, 0x66, 0x65, 0x74, 0x79, 0x63, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, - 0x5c, 0x2e, 0x28, 0x69, 0x6f, 0x7c, 0x63, 0x6f, 0x6d, 0x29, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, - 0x70, 0x0a, 0x1f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x5f, 0x77, 0x69, 0x74, 0x68, - 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, - 0x6e, 0x74, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x42, 0x08, 0xe0, 0xeb, 0x1f, 0x00, 0xe8, - 0xeb, 0x1f, 0x0a, 0x52, 0x1c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x57, 0x69, 0x74, - 0x68, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, - 0x74, 0x12, 0x6b, 0x0a, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x5f, 0x77, 0x69, - 0x74, 0x68, 0x5f, 0x6e, 0x6f, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, - 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x1e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x4e, 0x6f, 0x4c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x45, - 0x0a, 0x0d, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x18, - 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x42, 0x04, 0xc0, 0xeb, 0x1f, 0x01, 0x52, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x64, 0x46, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, - 0x65, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xa2, 0xec, 0x1f, 0x00, 0x52, 0x08, 0x74, - 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x33, 0x0a, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x7a, - 0x6f, 0x6e, 0x65, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, 0x1a, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x06, 0xa2, 0xec, 0x1f, 0x02, 0x08, 0x01, 0x52, 0x10, 0x74, 0x69, 0x6d, 0x65, - 0x7a, 0x6f, 0x6e, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x12, 0x32, 0x0a, 0x0f, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x18, - 0x1b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xfa, 0xeb, 0x1f, 0x00, 0x48, 0x01, 0x52, 0x0e, 0x73, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x88, 0x01, 0x01, - 0x1a, 0xda, 0x02, 0x0a, 0x0d, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x0c, 0xb0, 0xeb, 0x1f, 0x01, 0xb8, 0xeb, 0x1f, 0x28, 0xd8, 0xeb, 0x1f, 0x01, 0x52, 0x03, 0x76, - 0x61, 0x6c, 0x12, 0x31, 0x0a, 0x0c, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0x8a, 0xeb, 0x1f, 0x0a, 0x2e, 0x2b, - 0x5c, 0x40, 0x2e, 0x2b, 0x5c, 0x2e, 0x2e, 0x2b, 0x52, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0xb4, 0x01, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x8e, 0x01, - 0x8a, 0xeb, 0x1f, 0x81, 0x01, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x21, 0x23, 0x24, 0x26, - 0x27, 0x2a, 0x2b, 0x2f, 0x3d, 0x3f, 0x5e, 0x5f, 0x7b, 0x7c, 0x7d, 0x7e, 0x2d, 0x5d, 0x2b, 0x28, - 0x3f, 0x3a, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x21, 0x23, 0x24, 0x26, 0x27, - 0x2a, 0x2b, 0x2f, 0x3d, 0x3f, 0x5e, 0x5f, 0x7b, 0x7c, 0x7d, 0x7e, 0x2d, 0x5d, 0x2b, 0x29, 0x2a, - 0x40, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, - 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, - 0x5d, 0x29, 0x3f, 0x5c, 0x2e, 0x29, 0x2b, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x28, - 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, - 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0xe0, 0xeb, 0x1f, 0x02, 0xe8, 0xeb, 0x1f, 0x05, 0x52, 0x0c, - 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x1a, 0x3f, 0x0a, 0x12, - 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x29, 0x0a, 0x09, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0c, 0xb0, 0xeb, 0x1f, 0x01, 0xb8, 0xeb, 0x1f, 0x28, 0xd8, - 0xeb, 0x1f, 0x01, 0x52, 0x08, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x1a, 0x3f, 0x0a, - 0x11, 0x4e, 0x6f, 0x74, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 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, 0x43, - 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x1a, 0x0a, 0x05, 0x70, 0x68, 0x6f, - 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x04, 0xc0, 0xeb, 0x1f, 0x01, 0x52, 0x05, - 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xf2, 0xeb, 0x1f, 0x02, 0x08, 0x01, 0x52, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x5f, 0x6f, - 0x6e, 0x65, 0x6f, 0x66, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x22, 0x6a, 0x0a, 0x1e, 0x4f, 0x75, 0x74, 0x65, - 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x48, 0x0a, 0x0c, 0x73, 0x6f, - 0x6d, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x73, 0x6f, 0x6d, 0x65, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x24, 0x0a, 0x0c, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x04, 0x80, 0xeb, 0x1f, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x30, 0x0a, 0x18, 0x49, 0x6e, - 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x65, - 0x67, 0x61, 0x63, 0x79, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x04, 0xd0, 0xeb, 0x1f, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x86, 0x01, 0x0a, - 0x11, 0x4d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, 0x45, 0x6e, - 0x75, 0x6d, 0x12, 0x3b, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x21, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x4d, 0x79, 0x4d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, 0x45, 0x6e, 0x75, 0x6d, 0x2e, 0x4d, 0x79, 0x45, - 0x6e, 0x75, 0x6d, 0x42, 0x04, 0x90, 0xec, 0x1f, 0x01, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x22, - 0x34, 0x0a, 0x06, 0x4d, 0x79, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x59, 0x5f, - 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x59, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x49, - 0x52, 0x53, 0x54, 0x10, 0x01, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x61, 0x66, 0x65, 0x74, 0x79, 0x43, 0x75, 0x6c, 0x74, 0x75, 0x72, - 0x65, 0x2f, 0x73, 0x31, 0x32, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, - 0x67, 0x6f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x65, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_example_proto_rawDescOnce sync.Once - file_example_proto_rawDescData = file_example_proto_rawDesc -) - -func file_example_proto_rawDescGZIP() []byte { - file_example_proto_rawDescOnce.Do(func() { - file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData) - }) - return file_example_proto_rawDescData -} - -var file_example_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 9) -var file_example_proto_goTypes = []any{ - (MyMessageWithEnum_MyEnum)(0), // 0: example.MyMessageWithEnum.MyEnum - (*ExampleMessage)(nil), // 1: example.ExampleMessage - (*OuterMessageUsingNestedMessage)(nil), // 2: example.OuterMessageUsingNestedMessage - (*InnerMessage)(nil), // 3: example.InnerMessage - (*InnerMessageWithLegacyId)(nil), // 4: example.InnerMessageWithLegacyId - (*MyMessageWithEnum)(nil), // 5: example.MyMessageWithEnum - (*ExampleMessage_NestedMessage)(nil), // 6: example.ExampleMessage.NestedMessage - nil, // 7: example.ExampleMessage.NotSupportedEntry - (*ExampleMessage_Contact)(nil), // 8: example.ExampleMessage.Contact - (*ExampleMessage_NestedMessage_InnerNestedMessage)(nil), // 9: example.ExampleMessage.NestedMessage.InnerNestedMessage - (*timestamppb.Timestamp)(nil), // 10: google.protobuf.Timestamp -} -var file_example_proto_depIdxs = []int32{ - 3, // 0: example.ExampleMessage.inner:type_name -> example.InnerMessage - 3, // 1: example.ExampleMessage.msg_required:type_name -> example.InnerMessage - 4, // 2: example.ExampleMessage.inner_legacy_id:type_name -> example.InnerMessageWithLegacyId - 6, // 3: example.ExampleMessage.nested_message:type_name -> example.ExampleMessage.NestedMessage - 7, // 4: example.ExampleMessage.not_supported:type_name -> example.ExampleMessage.NotSupportedEntry - 8, // 5: example.ExampleMessage.contacts_with_length_constraint:type_name -> example.ExampleMessage.Contact - 8, // 6: example.ExampleMessage.contacts_with_no_length_constraint:type_name -> example.ExampleMessage.Contact - 10, // 7: example.ExampleMessage.scheduled_for:type_name -> google.protobuf.Timestamp - 6, // 8: example.OuterMessageUsingNestedMessage.some_message:type_name -> example.ExampleMessage.NestedMessage - 0, // 9: example.MyMessageWithEnum.enum:type_name -> example.MyMessageWithEnum.MyEnum - 10, // [10:10] is the sub-list for method output_type - 10, // [10:10] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name -} - -func init() { file_example_proto_init() } -func file_example_proto_init() { - if File_example_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_example_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*ExampleMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*OuterMessageUsingNestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*InnerMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*InnerMessageWithLegacyId); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*MyMessageWithEnum); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*ExampleMessage_NestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*ExampleMessage_Contact); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_example_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*ExampleMessage_NestedMessage_InnerNestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_example_proto_msgTypes[0].OneofWrappers = []any{ - (*ExampleMessage_Fax)(nil), - (*ExampleMessage_Phone)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_example_proto_rawDesc, - NumEnums: 1, - NumMessages: 9, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_example_proto_goTypes, - DependencyIndexes: file_example_proto_depIdxs, - EnumInfos: file_example_proto_enumTypes, - MessageInfos: file_example_proto_msgTypes, - }.Build() - File_example_proto = out.File - file_example_proto_rawDesc = nil - file_example_proto_goTypes = nil - file_example_proto_depIdxs = nil -} diff --git a/protobuf/protoc-gen-govalidator/example/example.proto b/protobuf/protoc-gen-govalidator/example/example.proto deleted file mode 100644 index 1ac3464..0000000 --- a/protobuf/protoc-gen-govalidator/example/example.proto +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2018 SafetyCulture Pty Ltd. All Rights Reserved. - -syntax = "proto3"; -package example; - -import "google/protobuf/timestamp.proto"; -import "s12/protobuf/proto/validator.proto"; - -option go_package = "github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/example"; - -message ExampleMessage { - // returns an error if the string cannot be parsed as a UUID - string id = 1 [(validator.uuid) = true]; - // bytes can also be parsed as UUID with support for gogo - bytes user_id = 2 [(validator.uuid) = true]; - // should be a valid email address - string email = 3 [(validator.email) = { optional: true }]; - // integers can be greater than a value - int32 age = 4 [(validator.int_gt) = 0]; - // integers can be less than a value - int64 speed = 5 [(validator.int_lt) = 110]; - // integers greater/less than or equal, the can also be combined - int32 score = 6 [(validator.int_gte) = 0, (validator.int_lte) = 100]; - // validation is created for all messages - InnerMessage inner = 7; - // can validate each repeated item too - repeated bytes ids = 8 [(validator.uuid) = true]; - // only validate if non-zero value - string media_id = 9 [(validator.uuid) = true, (validator.optional) = true]; - // validate the max length of a string - string description = 10 [(validator.length_lte) = 2000]; - // validate the min length - string password = 11 [(validator.length_gte) = 8]; - // You don't need to validate everything - string no_validation = 12; - - oneof contact_oneof { - string fax = 13; - string phone = 14 [(validator.length_gte) = 11]; - } - - // Required inner message - InnerMessage msg_required = 15 [(validator.msg_required) = true]; - - // returns an error if the string cannot be parsed as a legacy id - string legacy_id = 16 [(validator.legacy_id) = true]; - - // InnerMessage can contain a legacy id too - InnerMessageWithLegacyId inner_legacy_id = 17; - - // Trim leading and trailing whitespaces (as defined by Unicode) before doing length check - string name = 18 [(validator.length_gte) = 6, (validator.length_lte) = 10, (validator.trim_len_check) = true]; - - message NestedMessage { - string val = 1 [ - (validator.length_gte) = 1, - (validator.length_lte) = 40, - (validator.trim_len_check) = true - ]; - - message InnerNestedMessage { - string inner_val = 1 [ - (validator.length_gte) = 1, - (validator.length_lte) = 40, - (validator.trim_len_check) = true - ]; - } - - string nested_email = 2 [(validator.regex) = ".+\\@.+\\..+"]; - - repeated string member_emails = 3 [ - (validator.regex) = - "[a-z0-9!#$&'*+/=?^_{|}~-]+(?:\\.[a-z0-9!#$&'*+/=?^_{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", - (validator.repeated_len_gte) = 2, - (validator.repeated_len_lte) = 5 - ]; - } - - NestedMessage nested_message = 19; - - map not_supported = 100; - - // strings can validate against a regular expression - string url = 21 [(validator.regex) = "https:\\/\\/www\\.safetyculture\\.(io|com)"]; - - message Contact { - string phone = 1 [ (validator.optional) = true ]; - string email = 2 [(validator.email) = { optional: true }]; - } - repeated Contact contacts_with_length_constraint = 22 [ - (validator.repeated_len_gte) = 0, - (validator.repeated_len_lte) = 10 - ]; - repeated Contact contacts_with_no_length_constraint = 23; - - google.protobuf.Timestamp scheduled_for = 24 [ - (validator.optional) = true - ]; - - string timezone = 25 [ - (validator.timezone) = {} - ]; - - string timezone_optional = 26 [ - (validator.timezone) = { - optional: true - } - ]; - - optional string string_optional = 27 [(validator.string) = {}]; -} - -message OuterMessageUsingNestedMessage { - ExampleMessage.NestedMessage some_message = 1; -} - -message InnerMessage { - string id = 1 [(validator.uuid) = true]; -} - -message InnerMessageWithLegacyId { - string id = 1 [(validator.legacy_id) = true]; -} - -message MyMessageWithEnum { - MyEnum enum = 1 [(validator.enum_required) = true]; - - enum MyEnum { - // Default is unspecified. - MY_ENUM_UNSPECIFIED = 0; - // First valid value. - MY_ENUM_FIRST = 1; - } -} diff --git a/protobuf/protoc-gen-govalidator/example/example.validator.pb.go b/protobuf/protoc-gen-govalidator/example/example.validator.pb.go deleted file mode 100644 index d7b1625..0000000 --- a/protobuf/protoc-gen-govalidator/example/example.validator.pb.go +++ /dev/null @@ -1,273 +0,0 @@ -// Code generated by protoc-gen-govalidator. DO NOT EDIT. -// versions: -// protoc-gen-govalidator v2.7.0 -// protoc v5.28.2 -// source: example.proto - -package example - -import ( - fmt "fmt" - proto "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" - transform "golang.org/x/text/transform" - norm "golang.org/x/text/unicode/norm" - regexp "regexp" - strings "strings" - time "time" - utf8 "unicode/utf8" -) - -const _regex_val_ExampleMessage_Url = `https:\/\/www\.safetyculture\.(io|com)` - -var _regex_ExampleMessage_Url = regexp.MustCompile(_regex_val_ExampleMessage_Url) - -const _regex_val_ExampleMessage_NestedMessage_NestedEmail = `.+\@.+\..+` - -var _regex_ExampleMessage_NestedMessage_NestedEmail = regexp.MustCompile(_regex_val_ExampleMessage_NestedMessage_NestedEmail) - -const _regex_val_ExampleMessage_NestedMessage_MemberEmails = `[a-z0-9!#$&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$&'*+/=?^_{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?` - -var _regex_ExampleMessage_NestedMessage_MemberEmails = regexp.MustCompile(_regex_val_ExampleMessage_NestedMessage_MemberEmails) - -func (m *ExampleMessage) Validate() error { - if !proto.IsUUID(m.Id) { - return fmt.Errorf(`id: value must be parsable as a UUID`) - } - if len(m.UserId) != proto.UUIDSize { - return fmt.Errorf(`user_id: value must be exactly 16 bytes long to be a valid UUID`) - } - if m.Email != "" { - if !proto.IsValidEmail(m.Email, false) { - return fmt.Errorf(`email: value must be parsable as an email address`) - } - } - if !(m.Age > 0) { - return fmt.Errorf(`age: value must be greater than 0`) - } - if !(m.Speed < 110) { - return fmt.Errorf(`speed: value must be less than 110`) - } - if !(m.Score >= 0) { - return fmt.Errorf(`score: value must be greater than or equal to 0`) - } - if !(m.Score <= 100) { - return fmt.Errorf(`score: value must be less than or equal to 100`) - } - if m.Inner != nil { - if v, ok := interface{}(m.Inner).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("inner", err) - } - } - } - for _, item := range m.Ids { - if len(item) != proto.UUIDSize { - return fmt.Errorf(`ids: value must be exactly 16 bytes long to be a valid UUID`) - } - } - if m.MediaId != "" { - if !proto.IsUUID(m.MediaId) { - return fmt.Errorf(`media_id: value must be parsable as a UUID`) - } - } - if !(len(m.Description) <= 2000) { - return fmt.Errorf(`description: value must have length less than or equal to 2000`) - } - if !(len(m.Password) >= 8) { - return fmt.Errorf(`password: value must have length greater than or equal to 8`) - } - if x, ok := m.ContactOneof.(*ExampleMessage_Phone); ok { - if !(len(x.Phone) >= 11) { - return fmt.Errorf(`phone: value must have length greater than or equal to 11`) - } - } - if m.MsgRequired == nil { - return fmt.Errorf("field msg_required is required") - } - if m.MsgRequired != nil { - if v, ok := interface{}(m.MsgRequired).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("msg_required", err) - } - } - } - if !proto.IsLegacyID(m.LegacyId, false) { - return fmt.Errorf(`legacy_id: value must be parsable as a UUID or a legacy ID`) - } - if m.InnerLegacyId != nil { - if v, ok := interface{}(m.InnerLegacyId).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("inner_legacy_id", err) - } - } - } - _trim_ExampleMessage_Name := strings.TrimSpace(m.Name) - _ = _trim_ExampleMessage_Name - if !(len(_trim_ExampleMessage_Name) >= 6) { - return fmt.Errorf(`name: value must have length greater than or equal to 6`) - } - if !(len(_trim_ExampleMessage_Name) <= 10) { - return fmt.Errorf(`name: value must have length less than or equal to 10`) - } - if m.NestedMessage != nil { - if v, ok := interface{}(m.NestedMessage).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("nested_message", err) - } - } - } - // Validation of proto3 map<> fields is unsupported. - if !_regex_ExampleMessage_Url.MatchString(m.Url) { - return fmt.Errorf(`url: value must be a string conforming to predefined pattern`) - } - if !(len(m.ContactsWithLengthConstraint) >= 0) { - return fmt.Errorf(`contacts_with_length_constraint: length must be greater than or equal to 0`) - } - if !(len(m.ContactsWithLengthConstraint) <= 10) { - return fmt.Errorf(`contacts_with_length_constraint: length must be lesser than or equal to 10`) - } - if len(m.ContactsWithLengthConstraint) > 0 { - for _, item := range m.ContactsWithLengthConstraint { - if item != nil { - if v, ok := interface{}(item).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("contacts_with_length_constraint", err) - } - } - } - } - } - if len(m.ContactsWithNoLengthConstraint) > 0 { - for _, item := range m.ContactsWithNoLengthConstraint { - if item != nil { - if v, ok := interface{}(item).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("contacts_with_no_length_constraint", err) - } - } - } - } - } - if m.ScheduledFor != nil { - if v, ok := interface{}(m.ScheduledFor).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("scheduled_for", err) - } - } - } - if m.Timezone == "" { - return fmt.Errorf("field timezone is required") - } - if tz, err := time.LoadLocation(m.Timezone); err != nil || tz == nil { - return fmt.Errorf(`timezone: value must be a valid IANA TZ database value`) - } - if m.TimezoneOptional != "" { - if tz, err := time.LoadLocation(m.TimezoneOptional); err != nil || tz == nil { - return fmt.Errorf(`timezone_optional: value must be a valid IANA TZ database value`) - } - } - if m.StringOptional != nil { - if !norm.NFC.IsNormalString(*m.StringOptional) && norm.NFD.IsNormalString(*m.StringOptional) { - // normalise NFD to NFC string - var normErr error - *m.StringOptional, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), *m.StringOptional) - if normErr != nil { - return fmt.Errorf(`string_optional: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(*m.StringOptional, utf8.RuneError) { - return fmt.Errorf(`string_optional: value must must have valid encoding`) - } else if !utf8.ValidString(*m.StringOptional) { - return fmt.Errorf(`string_optional: value must must be a valid UTF-8-encoded string`) - } - var _len_ExampleMessage_StringOptional = len(*m.StringOptional) - if !(_len_ExampleMessage_StringOptional >= 1 && _len_ExampleMessage_StringOptional <= 130) { - return fmt.Errorf(`string_optional: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(*m.StringOptional) { - return fmt.Errorf(`string_optional: value must only have valid characters`) - } - } - return nil -} - -func (m *ExampleMessage_NestedMessage) Validate() error { - _trim_ExampleMessage_NestedMessage_Val := strings.TrimSpace(m.Val) - _ = _trim_ExampleMessage_NestedMessage_Val - if !(len(_trim_ExampleMessage_NestedMessage_Val) >= 1) { - return fmt.Errorf(`val: value must have length greater than or equal to 1`) - } - if !(len(_trim_ExampleMessage_NestedMessage_Val) <= 40) { - return fmt.Errorf(`val: value must have length less than or equal to 40`) - } - if !_regex_ExampleMessage_NestedMessage_NestedEmail.MatchString(m.NestedEmail) { - return fmt.Errorf(`nested_email: value must be a string conforming to predefined pattern`) - } - if !(len(m.MemberEmails) >= 2) { - return fmt.Errorf(`member_emails: length must be greater than or equal to 2`) - } - if !(len(m.MemberEmails) <= 5) { - return fmt.Errorf(`member_emails: length must be lesser than or equal to 5`) - } - for _, item := range m.MemberEmails { - if !_regex_ExampleMessage_NestedMessage_MemberEmails.MatchString(item) { - return fmt.Errorf(`member_emails: value must be a string conforming to predefined pattern`) - } - } - return nil -} - -func (m *ExampleMessage_NestedMessage_InnerNestedMessage) Validate() error { - _trim_ExampleMessage_NestedMessage_InnerNestedMessage_InnerVal := strings.TrimSpace(m.InnerVal) - _ = _trim_ExampleMessage_NestedMessage_InnerNestedMessage_InnerVal - if !(len(_trim_ExampleMessage_NestedMessage_InnerNestedMessage_InnerVal) >= 1) { - return fmt.Errorf(`inner_val: value must have length greater than or equal to 1`) - } - if !(len(_trim_ExampleMessage_NestedMessage_InnerNestedMessage_InnerVal) <= 40) { - return fmt.Errorf(`inner_val: value must have length less than or equal to 40`) - } - return nil -} - -func (m *ExampleMessage_Contact) Validate() error { - if m.Phone != "" { - } - if m.Email != "" { - if !proto.IsValidEmail(m.Email, false) { - return fmt.Errorf(`email: value must be parsable as an email address`) - } - } - return nil -} - -func (m *OuterMessageUsingNestedMessage) Validate() error { - if m.SomeMessage != nil { - if v, ok := interface{}(m.SomeMessage).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("some_message", err) - } - } - } - return nil -} - -func (m *InnerMessage) Validate() error { - if !proto.IsUUID(m.Id) { - return fmt.Errorf(`id: value must be parsable as a UUID`) - } - return nil -} - -func (m *InnerMessageWithLegacyId) Validate() error { - if !proto.IsLegacyID(m.Id, false) { - return fmt.Errorf(`id: value must be parsable as a UUID or a legacy ID`) - } - return nil -} - -func (m *MyMessageWithEnum) Validate() error { - if int(m.Enum) == 0 { - return fmt.Errorf("field enum must be specified and a non-zero value") - } - return nil -} diff --git a/protobuf/protoc-gen-govalidator/example/example.validator_regex.pb.go b/protobuf/protoc-gen-govalidator/example/example.validator_regex.pb.go deleted file mode 100644 index 7fcd10b..0000000 --- a/protobuf/protoc-gen-govalidator/example/example.validator_regex.pb.go +++ /dev/null @@ -1,17 +0,0 @@ -// Code generated by protoc-gen-govalidator. DO NOT EDIT. -// versions: -// protoc-gen-govalidator v2.7.0 -// protoc v5.28.2 -// source: example.proto - -package example - -import ( - _ "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" - regexp "regexp" -) - -// Pattern for ExampleMessage_StringOptional -const _regex_val_d4db71516b8749dc594e5bf604c6a110 = `^[\pL\pN\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{2013}]+$` - -var _regex_d4db71516b8749dc594e5bf604c6a110 = regexp.MustCompile(_regex_val_d4db71516b8749dc594e5bf604c6a110) diff --git a/protobuf/protoc-gen-govalidator/example/example_test.go b/protobuf/protoc-gen-govalidator/example/example_test.go deleted file mode 100644 index cc0d5ff..0000000 --- a/protobuf/protoc-gen-govalidator/example/example_test.go +++ /dev/null @@ -1,1206 +0,0 @@ -package example - -import ( - "strings" - "testing" - - proto "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" -) - -func TestValidationRules(t *testing.T) { - - const ( - id string = "92b6c2f9-abd8-48bc-a2c9-bf70e969751a" - legacyId string = "56341C6E-35A7-4C97-9C5E-7AC79673EAB2" - legacyLongIdFail string = "00EAE67E-2160-4C2E-BEB1-E5558A2696A7-9-00000190327E0675" // length = 49 (without dashes) - legacyLongId1 string = "00EAE67E-2160-4C2E-BEB1-E5558A2696A7-90-00000190327E0675" // length = 50 (without dashes) - legacyLongId2 string = "005F2E38-8426-48AF-94DE-5FEA3A396EEA-891-00000153F68896DC" // length = 51 (without dashes) - legacyLongId3 string = "007B516E-53F1-4AA0-ABAF-8C78342A2C82-2388-00000221F1C2BD1E" // length = 52 (without dashes) - legacyLongId4 string = "00709A17-151F-4CFC-B412-F080343ED84D-11977-000010227B4C60A9" // length = 53 (without dashes) - email string = "email@example.com" - password string = "12345678" - name string = "safety" - url string = "https://www.safetyculture.io" - ) - var ( - byteID []byte = []byte{53, 30, 208, 165, 196, 219, 75, 61, 142, 60, 101, 84, 229, 43, 61, 108} - emptyStr string = "" - optionalStr string = "optional" - ) - - sb := strings.Builder{} - for i := 0; i < 2001; i++ { - sb.WriteRune('a') - } - - tests := [...]struct { - name string - input proto.Validator - shouldError bool - }{ - { - "ValidMessage", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "UUIDWithoutDashes", - &ExampleMessage{ - Id: strings.Replace(id, "-", "", -1), - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "EmptyUUID", - &ExampleMessage{ - Id: "", - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidUUID", - &ExampleMessage{ - Id: "notauuid", - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidUUID", - &ExampleMessage{ - Id: id + "a", - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidUUID", - &ExampleMessage{ - Id: "92b6c2f9-abd8-48bc-a2c9-bf70e969751h", - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "EmptyByteUUID", - &ExampleMessage{ - Id: id, - UserId: []byte{}, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidByteUUID", - &ExampleMessage{ - Id: id, - UserId: []byte{53}, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidByteUUID", - &ExampleMessage{ - Id: id, - UserId: append(byteID, 67), - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "EmptyRegex", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: "", - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidRegex", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: "https://www.safetyculture.net", - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidGreaterThan", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 0, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidLessThan", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Speed: 10, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "ValidLessThan", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Speed: -10, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidLessThan", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Speed: 120, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidGreaterThanEquals", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Score: 1, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidGreaterThanEquals", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Score: -1, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidLessThanEquals", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Score: 100, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "ValidLessThanEquals", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Score: 99, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidLessThanEquals", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Score: 111, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidRepeated", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Ids: [][]byte{byteID}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "ValidRepeated", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Ids: [][]byte{byteID, byteID}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidRepeated", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Ids: [][]byte{[]byte{}}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidRepeated", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Ids: [][]byte{[]byte{121}}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidRepeated", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Ids: [][]byte{byteID, []byte{121}}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidOptional", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - MediaId: "", - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidOptional", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - MediaId: "notauuid", - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidMaxLength", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Description: "", - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "ValidMaxLength", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Description: "Some text here", - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidMaxLength", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Description: sb.String(), - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidMinLength", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: "", - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidMinLength", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: "1234567", - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidInnerMsg", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Inner: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidInnerMsg", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Inner: &InnerMessage{}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidInnerMsg", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - Inner: &InnerMessage{Id: "notauuid"}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "RequiredMessage", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "LegacyId", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "UUIDAsLegacyID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: id, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: id}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "LegacyIDWithoutDashes", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: strings.Replace(legacyId, "-", "", -1), - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "EmptyLegacyID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: "", - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidLegacyID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: "totally-invalid", - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "InvalidLegacyID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId + "1", - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "LegacyIDWithInvalidInnerLegacyID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId + "a"}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "LegacyLongIDWithLength50", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongIdFail, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "LegacyLongIDWithLength50", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, - { - "LegacyLongIDWithLength51", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId2, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, - { - "LegacyLongIDWithLength52", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId3, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, - { - "LegacyLongIDWithLength53", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId4, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, - { - "LegacyLongIDWithLength54", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId4 + "1", - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, - { - "LegacyLongIDWithoutDashes", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: strings.Replace(legacyLongId1, "-", "", -1), - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "InvalidLegacyLongID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1 + "1", - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "LegacyLongIDWithInvalidInnerLegacyLongID", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1 + "a"}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "MixOfLegacyIDAndLegacyLongID-1", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyLongId1}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "MixOfLegacyIDAndLegacyLongID-2", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: name, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "OnlyWhitespaceInputOnName", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: " \n\t\r ", - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "LessThanMininumEffectiveLengthOnName", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: " \t\t12345 ", // min is 6 - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "EffectiveLengthInRangeOnName", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: " \t\t1234567890\t\t\t\r ", // min is 6, max 10 - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "RepeatedSizeInRange", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: name, - NestedMessage: &ExampleMessage_NestedMessage{ - Val: "inner val", - NestedEmail: email, - MemberEmails: []string{ - email, - email, - }, - }, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, { - "RepeatedSizeLessThanMinimum", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: name, - NestedMessage: &ExampleMessage_NestedMessage{ - Val: "inner val", - NestedEmail: email, - MemberEmails: []string{ - email, - }, - }, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, - { - "RepeatedSizeExceedsMaximum", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyLongId1, - Name: name, - NestedMessage: &ExampleMessage_NestedMessage{ - Val: "inner val", - NestedEmail: email, - MemberEmails: []string{ - email, - email, - email, - email, - email, - email, - }, - }, - Url: url, - Timezone: "Australia/Sydney", - }, - true, - }, { - "ValidEmailAddress", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, - { - "InvalidEmailAddress-1", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: "test.invalid.test.com", - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - }, - true, - }, - { - "InvalidEmailAddress-2", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: "a@b", - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - }, - true, - }, - { - "ValidTimezone", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - }, - false, - }, - { - "InvalidTimezone", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/BonnieDoon", - }, - true, - }, - { - "ValidTimezoneOptional", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - TimezoneOptional: "Australia/Sydney", - }, - false, - }, - { - "InvalidTimezoneOptional", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - TimezoneOptional: "Australia/BonnieDoon", - }, - true, - }, - { - "ValidNilOptionalField", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - StringOptional: nil, - }, - false, - }, - { - "InvalidEmptyOptionalField", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - StringOptional: &emptyStr, - }, - true, - }, - { - "ValidNonEmptyOptionalField", - &ExampleMessage{ - Id: id, - UserId: byteID, - Email: email, - Age: 18, - Password: password, - MsgRequired: &InnerMessage{Id: id}, - LegacyId: legacyId, - Name: name, - Url: url, - Timezone: "Australia/Sydney", - StringOptional: &optionalStr, - }, - false, - }, - { - "enum_required is failed", - &MyMessageWithEnum{}, - true, - }, - { - "enum_required is passed", - &MyMessageWithEnum{ - Enum: MyMessageWithEnum_MY_ENUM_FIRST, - }, - false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - t.Parallel() - err := test.input.Validate() - if test.shouldError && err == nil { - t.Error("expected error, but nil") - } - if !test.shouldError && err != nil { - t.Errorf("unexpected error: %v", err) - } - }) - } - -} diff --git a/protobuf/protoc-gen-govalidator/main.go b/protobuf/protoc-gen-govalidator/main.go deleted file mode 100644 index 772b9ca..0000000 --- a/protobuf/protoc-gen-govalidator/main.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2020 SafetyCulture Pty Ltd. All Rights Reserved. - -package main - -import ( - "flag" - - "google.golang.org/protobuf/compiler/protogen" - - "github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/plugin" -) - -func main() { - var flags flag.FlagSet - opts := &protogen.Options{ - ParamFunc: flags.Set, - } - - opts.Run(func(p *protogen.Plugin) error { - for _, f := range p.Files { - if f.Generate { - plugin.GenerateFile(p, f) - } - } - return nil - }) -} diff --git a/protobuf/protoc-gen-govalidator/playground/gen/.empty-placeholder-directory b/protobuf/protoc-gen-govalidator/playground/gen/.empty-placeholder-directory deleted file mode 100644 index 03dc260..0000000 --- a/protobuf/protoc-gen-govalidator/playground/gen/.empty-placeholder-directory +++ /dev/null @@ -1 +0,0 @@ -The code generated by the plugin (via the makefile target) is placed in this directory. diff --git a/protobuf/protoc-gen-govalidator/playground/playground.proto b/protobuf/protoc-gen-govalidator/playground/playground.proto deleted file mode 100644 index 12178ae..0000000 --- a/protobuf/protoc-gen-govalidator/playground/playground.proto +++ /dev/null @@ -1,11 +0,0 @@ -syntax = "proto3"; -package playground; - -import "google/protobuf/wrappers.proto"; -import "s12/protobuf/proto/validator.proto"; - -option go_package = "github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/playground"; - -message Message { - google.protobuf.StringValue string_value_id = 1 [(validator.id) = { s12id: true }]; -} diff --git a/protobuf/protoc-gen-govalidator/playground/playground_main.go b/protobuf/protoc-gen-govalidator/playground/playground_main.go deleted file mode 100644 index 1a10642..0000000 --- a/protobuf/protoc-gen-govalidator/playground/playground_main.go +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "fmt" - "github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/plugin" - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/types/pluginpb" - "log" - "os" -) - -func main() { - // the file name is hard coded to match the output from the makefile target `playground-req-object` - req, err := os.ReadFile("./code_generator_request.pb.bin") - if err != nil { - log.Fatal(err) - } - - cgReq := pluginpb.CodeGeneratorRequest{} - if err = proto.Unmarshal(req, &cgReq); err != nil { - panic(fmt.Errorf("proto.Unmarshal(): %w", err)) - } - - opts := protogen.Options{} - protoPlugins, err := opts.New(&cgReq) - if err != nil { - panic(fmt.Errorf("protogen.Options.New(): %w", err)) - } - - for _, f := range protoPlugins.Files { - if !f.Generate { - continue - } - - plugin.GenerateFile(protoPlugins, f) - resp := protoPlugins.Response() - - for _, f := range resp.File { - os.Stdout.WriteString(">>>>>>>>>>>>>>> " + *f.Name + "\n") - _, err := os.Stdout.WriteString(*f.Content) - if err != nil { - log.Fatal(err) - } - os.Stdout.WriteString("<<<<<<<<<<<<<<< " + *f.Name + "\n") - os.Stdout.WriteString("\n") - os.Stdout.WriteString("\n") - } - } -} diff --git a/protobuf/protoc-gen-govalidator/plugin/plugin.go b/protobuf/protoc-gen-govalidator/plugin/plugin.go deleted file mode 100644 index 0c7dcaa..0000000 --- a/protobuf/protoc-gen-govalidator/plugin/plugin.go +++ /dev/null @@ -1,1180 +0,0 @@ -// Copyright (c) 2020 SafetyCulture Pty Ltd. All Rights Reserved. - -package plugin - -import ( - "crypto/md5" - "encoding/hex" - "fmt" - "os" - "strconv" - "strings" - - "google.golang.org/protobuf/compiler/protogen" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/descriptorpb" - "google.golang.org/protobuf/types/pluginpb" - - validator "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" -) - -// Standard library dependencies. -const ( - fmtPackage = protogen.GoImportPath("fmt") - timePackage = protogen.GoImportPath("time") - mathPackage = protogen.GoImportPath("math") - regexpPackage = protogen.GoImportPath("regexp") - stringsPackage = protogen.GoImportPath("strings") - utfPackage = protogen.GoImportPath("unicode/utf8") - normPackage = protogen.GoImportPath("golang.org/x/text/unicode/norm") - transformPackage = protogen.GoImportPath("golang.org/x/text/transform") -) - -// Other library dependencies. -const ( - s12protoPackage = protogen.GoImportPath("github.com/SafetyCulture/s12-proto/s12/protobuf/proto") -) - -// Some global vars for regex generations -var regexGeneratedFile *protogen.GeneratedFile -var regexHashLib = make(map[string]struct{}) - -// Validator plugin version -var validatorVersion = "v2.7.1" - -// Write a preamble in the auto generated files -func genGeneratedHeader(gen *protogen.Plugin, g *protogen.GeneratedFile, f *protogen.File) { - g.P("// Code generated by protoc-gen-govalidator. DO NOT EDIT.") - g.P("// versions:") - protocVersion := "(unknown)" - if v := gen.Request.GetCompilerVersion(); v != nil { - protocVersion = fmt.Sprintf("v%v.%v.%v", v.GetMajor(), v.GetMinor(), v.GetPatch()) - if s := v.GetSuffix(); s != "" { - protocVersion += "-" + s - } - } - g.P("// \tprotoc-gen-govalidator ", validatorVersion) - g.P("// \tprotoc ", protocVersion) - - if f.Proto.GetOptions().GetDeprecated() { - g.P("// ", f.Desc.Path(), " is a deprecated file.") - } else { - g.P("// source: ", f.Desc.Path()) - } - g.P() -} - -// GenerateFile generates the validator.pb.go file -func GenerateFile(p *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile { - p.SupportedFeatures |= uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) - - filename := file.GeneratedFilenamePrefix + ".validator.pb.go" - g := p.NewGeneratedFile(filename, file.GoImportPath) - - // Add preamble and version for validator.pb.go - genGeneratedHeader(p, g, file) - - g.P() - g.P("package ", file.GoPackageName) - g.P() - - // Generate a blank import statement if not used by any validation functions, - // as we still want to register the protobuf validation types for the Reflection API. - g.Import(s12protoPackage) - - // Also prepare a separate file for regex patterns - // Writing these to a separate file otherwise the generation logic would be confusing - // and require two iterations for each message field (one to generate the regex, one for the rest) - regexFilename := file.GeneratedFilenamePrefix + ".validator_regex.pb.go" - regexGeneratedFile = p.NewGeneratedFile(regexFilename, file.GoImportPath) - - // Add preamble and version for validator_regex.pb.go - genGeneratedHeader(p, regexGeneratedFile, file) - regexGeneratedFile.P() - regexGeneratedFile.P("package ", file.GoPackageName) - regexGeneratedFile.P() - regexGeneratedFile.Import(s12protoPackage) - - genStringGenerics() - for _, msg := range file.Messages { - if opts, ok := msg.Desc.Options().(*descriptorpb.MessageOptions); !ok || opts.GetMapEntry() { - continue - } - genLegacyRegexVars(g, msg) - genValidateFunc(g, msg) - g.P() - } - - return g -} - -func addRegexVar(fieldName, regexId string) string { - - r, e := getPreparedRegex(regexId) - if e != nil { - // Should not continue as we don't have a regex pattern - panic("Error generating regex for " + regexId + "/" + fieldName + ": " + fmt.Sprint(e)) - } - - // Generate a unique hash based on regex pattern so we can reuse patterns - hash := md5.New() - hash.Write([]byte(r)) - name := hex.EncodeToString(hash.Sum(nil)) - - // Check if this is a duplicate regex pattern in which case we can reuse the regex - if _, found := regexHashLib[name]; found { - regexGeneratedFile.P("// " + fieldName + " is using regex " + name) - return name - } - - regexGeneratedFile.P("// Pattern for " + fieldName) - regexGeneratedFile.P("const ", "_regex_val_", name, " = `", r, "`") - regexGeneratedFile.P("var ", "_regex_", name, " = ", regexpPackage.Ident("MustCompile"), "(_regex_val_", name, ")") - - // Keep track of this regex to avoid duplicates - if _, found := regexHashLib[name]; !found { - regexHashLib[name] = struct{}{} - } - return name -} - -// Generic preparations/initialisations for the string validator -func genStringGenerics() { - - // Prepare the regex pattern to allow replaced chars - prepareStringReplacerRegex(stringUnsafeReplacerMap, "replacer_unsafe_allowed") - prepareStringReplacerRegex(stringSymbolReplacerMap, "replacer_symbol_allowed") - - // Prepare the default `unsafe_string` pattern by adding tokens from `string` - stringReDefaultUnsafe = append(stringReDefaultSafe, stringReDefaultUnsafe...) -} - -// Generator for legacy regex validator -func genLegacyRegexVars(g *protogen.GeneratedFile, msg *protogen.Message) { - for _, field := range msg.Fields { - if regex := getRegexValue(field); regex != "" { - g.P("const ", "_regex_val_", field.GoIdent, " = `", regex, "`") - g.P("var ", "_regex_", field.GoIdent, " = ", regexpPackage.Ident("MustCompile"), "(_regex_val_", field.GoIdent, ")") - } - } - for _, innerMsg := range msg.Messages { - genLegacyRegexVars(g, innerMsg) - } -} - -func genValidateFunc(g *protogen.GeneratedFile, msg *protogen.Message) { - g.P("func (m *", msg.GoIdent.GoName, `) Validate() error {`) - for _, f := range msg.Fields { - hasExt := hasValidationExtensions(f) - if !hasExt && f.Message == nil { - continue - } - - varName := "m." + f.GoName - hasRepeatedExt := hasExt && f.Desc.Cardinality() == protoreflect.Repeated - isMessageField := f.Desc.Kind() == protoreflect.MessageKind - - // shouldLoopOverField decides whether to generate the for loop or not: - // - don't generate the for loop for an array of msg because it will be handled differently - // - only generate the for loop if there are validations for each element - shouldLoopOverField := hasRepeatedExt && !isMessageField && hasNonRepeatedValidationExtensions(f) - - if hasRepeatedExt { - if v := getIntExtention(f, validator.E_RepeatedLenGte); v >= 0 { - g.P("if !(len(", varName, ") >= ", v, ") {") - errStr := fmt.Sprintf(`be greater than or equal to %d`, v) - genLenErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - if v := getIntExtention(f, validator.E_RepeatedLenLte); v >= 0 { - g.P("if !(len(", varName, ") <= ", v, ") {") - errStr := fmt.Sprintf(`be lesser than or equal to %d`, v) - genLenErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - } - - if shouldLoopOverField { - g.P("for _, item := range ", varName, "{") - varName = "item" - } - - if f.Desc.IsMap() { - g.P(`// Validation of proto3 map<> fields is unsupported.`) - continue - } - - // exclude synthetic oneof fields, e.g. fields with the optional keyword - if f.Oneof != nil && !f.Oneof.Desc.IsSynthetic() { - g.P("if x, ok := m.", f.Oneof.GoName, ".(*", g.QualifiedGoIdent(f.GoIdent), "); ok {") - varName = "x." + f.GoName - } - - if f.Desc.HasOptionalKeyword() { - g.P("if ", varName, " != nil {") - varName = "*" + varName - } - - switch f.Desc.Kind() { - case protoreflect.StringKind: - // Run both legacy and newer validation logic as both options can be combined at this time - // Should exclusively use newer validation logic (validator.string/unsafe_string) for newly added fields - // For existing fields, should be fairly easy to update the rules to the new validator - genLegacyStringValidator(g, f, varName) - genStringValidator(g, f, varName) - genIdValidator(g, f, varName) - genEmailValidator(g, f, varName) - genURLValidator(g, f, varName) - genTimezoneValidator(g, f, varName) - genSimpleStringValidator(g, f, varName) - case protoreflect.BytesKind: - // IdValidator not supported for bytes at this point - genBytesValidator(g, f, varName) - case protoreflect.Int32Kind, protoreflect.Int64Kind, - protoreflect.Uint32Kind, protoreflect.Uint64Kind, - protoreflect.Sint32Kind, protoreflect.Sint64Kind: - genIntValidator(g, f, varName) // legacy validator - genNumberValidator(g, f, varName) // new validator - case protoreflect.MessageKind: - genMsgValidator(g, f, varName) - case protoreflect.EnumKind: - genEnumValidator(g, f, varName) - case protoreflect.DoubleKind, protoreflect.FloatKind: - genNumberValidator(g, f, varName) - } - - if f.Desc.HasOptionalKeyword() { - g.P("}") - } - - if f.Oneof != nil && !f.Oneof.Desc.IsSynthetic() { - g.P("}") - } - - if shouldLoopOverField { - g.P(`}`) - } - } - - g.P(`return nil`) - g.P(`}`) - - for _, innerMsg := range msg.Messages { - if innerMsg.Desc.IsMapEntry() { - // Do not generate validation func for map entry type - continue - } - g.P() - genValidateFunc(g, innerMsg) - } -} - -func genLegacyStringValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - optional := getBoolExtension(f, validator.E_Optional) - - if optional { - g.P("if ", varName, " != \"\" {") - } - - if regex := getRegexValue(f); regex != "" { - g.P("if !_regex_", f.GoIdent, ".MatchString(", varName, ") {") - // Let's not expose the regex pattern and find a better way to reflect what was wrong with the data - // Might want to replace with a more helpful message - errStr := "be a string conforming to predefined pattern" - genErrorStringWithParams(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - // Legacy UUIDv4 validator - if getBoolExtension(f, validator.E_Uuid) { - g.P("if !", s12protoPackage.Ident("IsUUID"), "(", varName, ") {") - errStr := "be parsable as a UUID" - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - if getBoolExtension(f, validator.E_LegacyId) { - g.P("if !", s12protoPackage.Ident("IsLegacyID"), "(", varName, ", false) {") - errStr := "be parsable as a UUID or a legacy ID" - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - genLenValidator(g, f, varName) - - if optional { - g.P("}") - } -} - -func genSimpleStringValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - rules := getSimpleStringExtension(f, validator.E_SimpleString) - if rules == nil { - return - } - - // "optional" can be provided via the legacy directive or set as option on the `string`/`unsafe_string` validator - // To allow deprecation of the 'old' directive later, we duplicate the logic here - if rules.GetOptional() { - g.P("if ", varName, " != \"\" {") - } - - if rules.GetMinLen() >= 1 || rules.GetMaxLen() >= 1 { - g.P("var length = ", utfPackage.Ident("RuneCountInString"), "(", varName, ")") - g.P("if (length > ", rules.GetMaxLen(), " || length < ", rules.GetMinLen(), ") {") - errStr := fmt.Sprintf(`have a length between %d and %d`, rules.GetMinLen(), rules.GetMaxLen()) - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errStr) - } - g.P("}") - } - - // Optional value: close the if statement - if rules.GetOptional() { - g.P("}") - } -} - -func genStringValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - // `string` and `unsafe_string` share most of the underlying validation logic - stringType := validator.E_String - rules := getStringExtension(f, stringType) - if rules == nil { - stringType = validator.E_UnsafeString - rules = getStringExtension(f, stringType) - } - if rules == nil { - // not E_String or E_UnsafeString - return - } - - // Prepare to allow list regex - allowListReId := "re_" + f.GoIdent.GoName - if stringType == validator.E_String { - prepareRegex(allowListReId, stringReDefaultSafe...) - } else { - prepareRegex(allowListReId, stringReDefaultUnsafe...) - } - - // "optional" can be provided via the legacy directive or set as option on the `string`/`unsafe_string` validator - // To allow deprecation of the 'old' directive later, we duplicate the logic here - if rules.GetOptional() { - g.P("if ", varName, " != \"\" {") - } - - // ### STEP 1: decode - // TODO PA: Check if we can confirm that data has been decoded, things like %20 might indicate otherwise - - // ### STEP 2: normalise and canonicalise - // Normalisation for file paths/URLs should not happen here but in URL validator - - // ##### 2A. Normalise Unicode NFD strings to NFC - // Convert to unicode NFC if not already in that format - // e.g. NFD string man\u0303ana should be normalised to ma\u00F1ana (n + \u0303 = \u00F1) - // TODO PA: Check if we need support for NFKC/NFKD - // TODO PA: Do we want to have support for U+202E RIGHT-TO-LEFT OVERRIDE by default for all strings? - g.P("if !", normPackage.Ident("NFC.IsNormalString"), "(", varName, ") && ", normPackage.Ident("NFD.IsNormalString"), "(", varName, ") {") - g.P("// normalise NFD to NFC string") - g.P("var normErr error") - g.P(varName, ", _, normErr = ", transformPackage.Ident("String"), "(", transformPackage.Ident("Chain"), "(", normPackage.Ident("NFD"), ",", normPackage.Ident("NFC"), ")", ",", varName, ")") - g.P("if normErr != nil {") - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), `must be normalisable to NFC`, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), `must be normalisable to NFC`) - } - g.P("}") - g.P("}") - - // ##### 2B. Check for encoding issues - if rules.GetValidateEncoding() { - // U+FFFD in character indicates that the encoding was likely incorrect, resulting in � U+FFFD (RuneError) - // Test string: $\xa35 for Pepp\xe9 which is encoded as latin1 - g.P("if ", stringsPackage.Ident("ContainsRune"), "(", varName, ", ", utfPackage.Ident("RuneError"), ") {") - errStr := `must have valid encoding` - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errStr) - } - - // Also validate using utf8.ValidString: reports whether string consists entirely of valid UTF-8-encoded runes - g.P("} else if !", utfPackage.Ident("ValidString"), "(", varName, ") {") - errStr = `must be a valid UTF-8-encoded string` - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errStr) - } - g.P("}") - } else { - // Allow RuneError as valid character if we do not check for invalid encoding otherwise the string might be denied - // U+FFFD is in Symbol_So category which must be allowed in case validateInvalidEncoding is disabled (to detect issues) - prepareRegex(allowListReId, `\x{FFFD}`) - } - - // If the text contains a full URL anywhere in it, reject it. This should help us control spam. - if rules.GetRejectUrl() { - g.P("if ", s12protoPackage.Ident("RejectURLMatcher"), ".MatchString(", varName, ") {") - genErrorStringWithParams(g, varName, string(f.Desc.Name()), "not contain a URL") - g.P("}") - } - - // ### STEP 3: sanitise - // #### 3A-1. 'Break' partial URLs by introducing a space after each dot between characters. - // Note this will PERMANENTLY mutate the message field data. Further iterations will ignore these '. ' patterns, - // we only care about patterns like 'a.b' - if rules.GetBreakPartialUrl() { - g.P(varName, " = ", s12protoPackage.Ident("BreakURLMatcher"), ".ReplaceAllString(", varName, ", \". $1\")") - } - - // ##### 3A-2. sanitise whitespace (trim option) - // Note this will PERMANENTLY mutate the message field data, this trim is not for length check only but for sanitisation - // WARNING: Any leading/trailing whitespace will be permanently removed (this is intended here) - if rules.GetTrim() { - g.P(varName, " = ", stringsPackage.Ident("TrimSpace"), "(", varName, ")") - } - - // ##### 3B. replace restricted characters with a safe alternative - // WARNING: this could corrupt data, eg. hyperlinks in a description box so disabled by default - // Ensure to test the alternative characters in all output (database, email, pdf, csv, web UI, mobile UI) - if rules.GetReplaceUnsafe() { - // If allow option is defined, only chars from allow list will be allowed - // Otherwise, all chars in the replace map are accepted - // If none of the allow chars are in the unsafe map, there is no work to be done here - // throw a warning that the option is not required in that case - if rules.GetAllow() != "" { - - for _, runeValue := range rules.GetAllow() { - unicodeValue := fmt.Sprintf("%U", runeValue) - unicodeValue = strings.Replace(unicodeValue, "U+", "", 1) - if _, isUnsafe := stringUnsafeReplacerMap[`\u`+unicodeValue]; isUnsafe { - // need to replace this one, replace case by case instead of using the replacer - replacedUnicodeValue := stringUnsafeReplacerMap[`\u`+unicodeValue] - g.P(varName, " = ", stringsPackage.Ident("ReplaceAll"), "(", varName, `, "\u`, unicodeValue, `", "`, replacedUnicodeValue, `")`) - - // and add it to the regex - prepareRegex(allowListReId, `\x{`+strings.Replace(replacedUnicodeValue, `\u`, ``, 1)+`}`) - } - } - } else { - // Add the possible replaced characters to the allow list as they are not all allowed by default - mergeRegex(allowListReId, "replacer_unsafe_allowed") - // Replace the unsafe values - g.P(varName, " = ", s12protoPackage.Ident("UnsafeCharReplacer"), ".Replace(", varName, ")") - } - } - - // ##### 3C. strip carriage return characters \r in multiline strings (leave \n) - if rules.GetMultiline() { - // Generates: varName = strings.ReplaceAll(varName, "\r", "") - g.P(varName, " = ", stringsPackage.Ident("ReplaceAll"), "(", varName, ", \"\\r\", \"\")") - } - - // ##### 3D. replace rare symbols with a more common alternative - if rules.GetReplaceOther() { - // Add the possible replaced characters to the allow list as they might not be allowed by default - mergeRegex(allowListReId, "replacer_symbol_allowed") - // Replace the values - if rules.GetMultiline() { - // Should not replace \n as the normal symbol replacer does otherwise multiline breaks - g.P(varName, " = ", s12protoPackage.Ident("SymbolCharReplacerMultiline"), ".Replace(", varName, ")") - } else { - g.P(varName, " = ", s12protoPackage.Ident("SymbolCharReplacer"), ".Replace(", varName, ")") - - } - } - - // ##### 3E. Sanitise (remove) Private Use Area Codepoints in the Basic Multilingual Plane - // Note that we do not check for PUA in planes 15 and 16 currently - if rules.GetSanitisePua() { - g.P(varName, "= ", s12protoPackage.Ident("RegexPua"), ".ReplaceAllString(", varName, ", \"\")") - } - - // ### STEP 4: validate - // ##### 4A. validate length - // Length could be checked as part of the regex in next step but currently implemented - // as a separate step before testing against the regex. This might be more efficient - // for large strings/invalid data as we reject it early. It also allows for regex reuse. - - // Always have a min and max length: either default vals or set in the field option - // This ensures that we no longer accept any length string (safe by default) - minLen := stringLenMinDefault - maxLen := stringLenMaxDefault - - // Check if friendly format length defined ("x:y"), overrides the above - if fLen := rules.GetLen(); fLen != "" { - // Check for a single value or min:max notation - fLenChunks := strings.SplitN(fLen, ":", 3) - fMinLen, fMaxLen := -1, -1 // set -1 as default to distinguish between 0 and unset - switch len(fLenChunks) { - case 2: - // min:max notation deffiend, e.g. len: "2:20" - // Try casting from string to int - fMinLen, _ = strconv.Atoi(fLenChunks[0]) - fMaxLen, _ = strconv.Atoi(fLenChunks[1]) - if fMinLen == 0 { - // Use default min length (not unlimited) for missing min value, e.g. :X - fMinLen = int(minLen) - } - if fMaxLen == 0 { - // Use default min length (not unlimited) for missing max value, e.g. X: - fMaxLen = int(maxLen) - } - if fMaxLen <= fMinLen || fMinLen < 0 || fMaxLen < 0 { - // Invalid syntax; don't just skip validation but break the compilation so this can be fixed in the definition - panic("unparsable string validator value for len in field " + f.GoIdent.GoName + ": expected 0=x>=y " + fLen) - } - case 1: - // Fixed length defined, e.g. len: "8" - min and max length are equal in this case - fMinLen, _ = strconv.Atoi(fLenChunks[0]) - fMaxLen = fMinLen - default: - // Invalid definition, more than two -, e.g. -5 or 5-10-12 or -5-5 or something we don't understand - // This should be fixed so break the compilation - panic("unparsable string validator value for len in field " + f.GoIdent.GoName + ": expected x-y or x, found " + fLen) - } - - if fMinLen > 0 { - minLen = uint32(fMinLen) - } - if fMaxLen > 0 { - maxLen = uint32(fMaxLen) - } - } - - // Now both minLen and maxLen are set - // First make sure this satisfies our predefined absolute min/max values for `string` and `unsafe_string` - validMin := stringLenMinSafe - validMax := stringLenMaxSafe - if stringType == validator.E_UnsafeString { - validMin = stringLenMinUnsafe - validMax = stringLenMaxUnsafe - } - if minLen < validMin || maxLen > validMax { - // Could just warn and ignore this instead of breaking initially until we are confident that we have appropriate safe guard values - panic("invalid string validator value for len in field " + f.GoIdent.GoName + ": expected " + fmt.Sprint(validMin) + "<=x<=" + fmt.Sprint(validMax) + ", found " + fmt.Sprint(minLen) + "-" + fmt.Sprint(maxLen)) - } - - // Determine which length check method to use: bytes or runes - // Byte length check is default [using len()], unless rune length option is enabled - lenVar := "_len_" + f.GoIdent.GoName - if rules.GetRunes() { - // Use utf8.RuneCountInString method, requires import of utf8 package - g.P("var "+lenVar+" = ", utfPackage.Ident("RuneCountInString"), "(", varName, ")") - } else { - g.P("var "+lenVar+" = len(", varName, ")") - } - - // Write the len check logic to the validator - errStr := "" - if minLen == maxLen { - // Could use the same if statement as for min+max checks but this is a bit cleaner - g.P("if !("+lenVar+" == ", minLen, ") {") - errStr = fmt.Sprintf(`have length %d`, minLen) - } else { - g.P("if !("+lenVar+" >= ", minLen, " && "+lenVar+" <= ", maxLen, ") {") - errStr = fmt.Sprintf(`have a length between %d and %d`, minLen, maxLen) - } - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errStr) - } - g.P("}") - - // ##### 4B. prepare whitelist/regex - // Check if allow option is set: these will be allowed in addition to the default whitelist - if rules.GetAllow() != "" { - // Note that this does inentionally not support a regex pattern or entire categories like \pX - // All characters in the string are considered as LITERAL value - - // Convert chars to \x{dddd} notation - for _, runeValue := range rules.GetAllow() { - unicodeValue := fmt.Sprintf("%U", runeValue) - unicodeValue = strings.Replace(unicodeValue, "U+", "", 1) - if stringType == validator.E_String { - if _, isUnsafe := stringUnsafeReplacerMap[`\u`+unicodeValue]; isUnsafe { - // Chars in stringUnsafeReplacerMap can not be used in `string` allow option when `replace_unsafe` is not enabled - if !rules.GetReplaceUnsafe() { - panic("invalid allow character in field " + f.GoIdent.GoName + ": " + string(runeValue) + ", enable replace_unsafe option or use validator.unsafe_string instead") - } - // else: this char was replaced with a safe equivalent so we do not need to add the unsafe one to the allow regex - continue - } - // Chars in charDenyList can not be used in allow option as they are potentially dangerous - if _, isRestricted := charDenyList[`\u`+unicodeValue]; isRestricted { - panic("invalid allow character in field " + f.GoIdent.GoName + ": U+" + string(unicodeValue) + ", this character is potentially dangerous (check charDenyList)") - } - } - prepareRegex(allowListReId, `\x{`+unicodeValue+`}`) - } - } - - // Check for multiline option which allows linebreaks - if rules.GetMultiline() { - // Add predefined linebreak chars (currently just \n) - // \r was stripped in step 2B - prepareRegex(allowListReId, stringReLineBreaks...) - } - - // Add symbols if defined - symbols := rules.GetSymbols() - if len(symbols) > 0 { - // Add the corresponding regex pattern to the allow list - for i := range symbols { - symbol := symbols[i] - if stringType == validator.E_String && !rules.GetReplaceUnsafe() { - // Check and error on restricted symbol classes - if _, ok := restrictedSafeStringSymbols[symbol]; ok { - panic("invalid symbol class in field " + f.GoIdent.GoName + ": " + symbol.String() + ", enable replace_unsafe option or use unsafe_string instead.") - } - } - if symbolRe, ok := stringSymbolMap[symbol]; ok { - prepareRegex(allowListReId, symbolRe...) - continue - } - // Ignore this as it would not weaken the validation. - // Warn as it likely indicates something that requires follow up - fmt.Fprintf(os.Stderr, "WARN: Symbol "+fmt.Sprint(symbol)+" not in stringSymbolMap (not implemented)\n") - } - } - - // ##### 4C. validate string against the whitelist/regex - regexName := addRegexVar(f.GoIdent.GoName, allowListReId) - g.P("if !_regex_", regexName, ".MatchString(", varName, ") {") - // Might want to improve the error message: make it more helpful so the end-user can fix it if applicable - errStr = "only have valid characters" - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorStringWithParams(g, varName, string(f.Desc.Name()), errStr) - } - g.P("}") - - // Optional value: close the if statement - if rules.GetOptional() { - g.P("}") - } -} - -func genIdValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - - // ID validator with support for legacy ids and UUIDv4 - // Might want to move the shared validation logic such as optional to a separate method - rules := getIdExtension(f, validator.E_Id) - if rules == nil { - return - } - - if rules.GetOptional() { - g.P("if ", varName, " != \"\" {") - } - - var errMsg string - - switch rules.GetVersion() { - case "v4": - // Try to validate the value for valid UUIDv4 - g.P("if !", s12protoPackage.Ident("IsUUIDv4"), "(", varName, ") {") - errMsg = "be parsable as UUIDv4" - case "any": - // Try to validate the value for valid UUID (any version) - g.P("if !", s12protoPackage.Ident("IsUUID"), "(", varName, ") {") - errMsg = "be parsable as UUID" - default: - // Unsupported version; do not generate the validators without having an implementation for this version - panic("unsupported UUID version in field " + f.GoIdent.GoName + ", got: " + rules.GetVersion()) - } - - // Check what ID formats are accepted in addition to UUID - // Validation passes if the provided value passes at least one of the validators - // UUID format is always accepted where LegacyId and S12 Id can be enabled as an option - - // Invalid UUID: check other formats or error if no other options enabled - g.P("isValidId := false") - - // Check for valid legacy id if option enabled - if rules.GetLegacy() { - errMsg += " or legacy ID" - g.P("if ", s12protoPackage.Ident("IsLegacyID"), "(", varName, ", ", rules.GetLowercaseOnly(), ") {") - g.P("isValidId = true") - g.P("}") - } - - // If still no valid id found, also check for S12 Id if option enabled - if rules.GetS12Id() { - errMsg += " or S12 ID" - g.P("if !isValidId && ", s12protoPackage.Ident("IsS12ID"), "(", varName, ", ", rules.GetLowercaseOnly(), ") {") - g.P("isValidId = true") - g.P("}") - } - - // Finally, we have a special case for prefixed, long legacy format Ids which requires both s12 and legacy option - if rules.GetLegacy() && rules.GetS12Id() { - g.P("if !isValidId && ", s12protoPackage.Ident("IsLongPrefixedLegacyID"), "(", varName, ") {") - g.P("isValidId = true") - g.P("}") - } - - // Check if any of the validations passed - g.P("if !isValidId {") - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errMsg, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errMsg) - } - - g.P("}") - g.P("}") - - if rules.GetOptional() { - g.P("}") - } -} - -func genEmailValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - - rules := getEmailExtension(f, validator.E_Email) - if rules == nil { - return - } - - if rules.GetOptional() { - g.P("if ", varName, " != \"\" {") - } - - checkDomain := false // rules.GetCheckDomain() == true - - // Validate the value for valid email using govalidator validation package - g.P("if !", s12protoPackage.Ident("IsValidEmail"), "(", varName, ", ", checkDomain, ") {") - errStr := "be parsable as an email address" - if checkDomain { - errStr = "be a valid email address" - } - // Should not return/log email address as this is PII (genErrorString will no longer reflect values) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - - if rules.GetOptional() { - g.P("}") - } -} - -func genURLValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - - rules := getURLExtension(f, validator.E_Url) - if rules == nil { - return - } - - if rules.GetOptional() { - g.P("if ", varName, " != \"\" {") - } - - // Check defined schemes - schemes := rules.GetSchemes() - if len(schemes) == 0 { - schemes = append(schemes, "https") - } - - if rules.GetAllowHttp() { - schemes = append(schemes, "http") - } - - // Validate the url using the helper method - g.P(`_schemes_`+f.GoIdent.GoName+` := []string{"`, strings.Join(schemes, `", "`), `"}`) - g.P("if _, err := ", s12protoPackage.Ident("IsValidURL"), "(", varName, ", _schemes_"+f.GoIdent.GoName+", ", rules.GetAllowFragment(), "); err != nil {") - genErrorStringWithParams(g, varName, string(f.Desc.Name()), "be parsable as a URL: %v", "err") - g.P("}") - - if rules.GetOptional() { - g.P("}") - } -} - -func genTimezoneValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - rules := getTimezoneExtension(f, validator.E_Timezone) - if rules == nil { - return - } - - if rules.GetOptional() { - g.P("if ", varName, " != \"\" {") - } else { - g.P("if ", varName, " == \"\" {") - g.P("return ", fmtPackage.Ident("Errorf"), "(\"field ", f.Desc.Name(), " is required\")") - g.P("}") - } - - g.P("if tz, err := ", timePackage.Ident("LoadLocation"), "(", varName, "); err != nil || tz == nil {") - errStr := "be a valid IANA TZ database value" - genErrorStringWithParams(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - - if rules.GetOptional() { - g.P("}") - } -} - -func genLenValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - if getBoolExtension(f, validator.E_TrimLenCheck) { - g.P("_trim_", f.GoIdent, " := ", stringsPackage.Ident("TrimSpace"), "(", varName, ")") - varName = "_trim_" + f.GoIdent.GoName - g.P("_ = ", varName) - } - - if v := getIntExtention(f, validator.E_LengthGte); v >= 0 { - g.P("if !(len(", varName, ") >= ", v, ") {") - errStr := fmt.Sprintf(`have length greater than or equal to %d`, v) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - if v := getIntExtention(f, validator.E_LengthLte); v >= 0 { - g.P("if !(len(", varName, ") <= ", v, ") {") - errStr := fmt.Sprintf(`have length less than or equal to %d`, v) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } -} - -func genBytesValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - optional := getBoolExtension(f, validator.E_Optional) - - if optional { - g.P("if ", varName, " != nil && len(", varName, ") > 0 {") - } - - if getBoolExtension(f, validator.E_Uuid) { - g.P("if len(", varName, ") != ", s12protoPackage.Ident("UUIDSize"), " {") - errStr := "be exactly 16 bytes long to be a valid UUID" - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - genLenValidator(g, f, varName) - - if optional { - g.P("}") - } -} - -func genIntValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - optional := getBoolExtension(f, validator.E_Optional) - - if optional { - g.P("if ", varName, " != 0 {") - } - - if v := getIntExtention(f, validator.E_IntGt); v >= 0 { - g.P("if !(", varName, " > ", v, ") {") - errStr := fmt.Sprintf(`be greater than %d`, v) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - if v := getIntExtention(f, validator.E_IntGte); v >= 0 { - g.P("if !(", varName, " >= ", v, ") {") - errStr := fmt.Sprintf(`be greater than or equal to %d`, v) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - if v := getIntExtention(f, validator.E_IntLt); v >= 0 { - g.P("if !(", varName, " < ", v, ") {") - errStr := fmt.Sprintf(`be less than %d`, v) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - if v := getIntExtention(f, validator.E_IntLte); v >= 0 { - g.P("if !(", varName, " <= ", v, ") {") - errStr := fmt.Sprintf(`be less than or equal to %d`, v) - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - if optional { - g.P("}") - } -} - -func genMsgValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - if getBoolExtension(f, validator.E_MsgRequired) { - g.P("if ", varName, " == nil {") - g.P("return ", fmtPackage.Ident("Errorf"), "(\"field ", f.Desc.Name(), " is required\")") - g.P("}") - } - - // For repeated messages, we need to run the validator on each message instead of this field - repeated := f.Desc.Cardinality() == protoreflect.Repeated - if repeated { - // Please leave the len check in place here as I have identified edge cases where it is required (will add test case for it later) - g.P("if len(", varName, ") > 0 {") - g.P("for _, item := range ", varName, "{") - varName = "item" - } - - g.P("if ", varName, " != nil {") - g.P("if v, ok := interface{}(", varName, ").(", s12protoPackage.Ident("Validator"), "); ok {") - g.P("if err := v.Validate(); err != nil {") - g.P("return ", s12protoPackage.Ident("FieldError"), "(\"", f.Desc.Name(), "\", err)") - g.P("}") - g.P("}") - g.P("}") - - if repeated { - g.P("}") // for - g.P("}") // if len - } -} - -func genEnumValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - if !getBoolExtension(f, validator.E_EnumRequired) { - return - } - - g.P("if int(", varName, ") == 0 {") - g.P("return ", fmtPackage.Ident("Errorf"), "(\"field ", f.Desc.Name(), " must be specified and a non-zero value\")") - g.P("}") -} - -func printErrorString(g *protogen.GeneratedFile, varName, fieldName, specificErr string, maxLen int) { - // Do not reflect untrusted value in error, certainly not for sensitive fields like password or PII like email - g.P(fmtPackage.Ident("Printf"), `("[log-only] %s: value must be %s: Base64Encoded input: %s\n", `, `"`, fieldName, `", "`, specificErr, `" `, ", ", - s12protoPackage.Ident("Base64Encode("), - s12protoPackage.Ident("FirstCharactersFromString("), - fmtPackage.Ident("Sprintf"), "(\"%v\", ", varName, "), ", maxLen, ")))") -} - -func genErrorString(g *protogen.GeneratedFile, varName, fieldName, specificErr string) { - // Do not reflect untrusted value in error, certainly not for sensitive fields like password or PII like email - g.P(`return `, fmtPackage.Ident("Errorf"), "(`", fieldName, `: value must `, specificErr, "`)") -} - -func genErrorStringWithParams(g *protogen.GeneratedFile, varName, fieldName, specificErr string, errParams ...string) { - // Might want to improve the error message: make it more helpful so the end-user can fix it if applicable - g.P(`return `, fmtPackage.Ident("Errorf"), "(`", fieldName, `: value must `, specificErr, "`, ", strings.Join(errParams, ", "), `)`) -} - -func genLenErrorString(g *protogen.GeneratedFile, varName, fieldName, specificErr string) { - g.P(`return `, fmtPackage.Ident("Errorf"), "(`", fieldName, `: length must `, specificErr, "`)") -} - -var validNonRepeatedExts = []protoreflect.ExtensionType{ - validator.E_Regex, - validator.E_Uuid, - validator.E_IntGt, - validator.E_IntLt, - validator.E_IntGte, - validator.E_IntLte, - validator.E_LengthGte, - validator.E_LengthLte, - validator.E_Optional, - validator.E_MsgRequired, - validator.E_LegacyId, - validator.E_TrimLenCheck, - validator.E_Email, - validator.E_Id, - validator.E_String, - validator.E_UnsafeString, - validator.E_EnumRequired, - validator.E_Url, - validator.E_Timezone, - validator.E_Number, - validator.E_SimpleString, -} - -var validRepeatedExts = []protoreflect.ExtensionType{ - validator.E_RepeatedLenGte, - validator.E_RepeatedLenLte, -} - -var validExts = append(validNonRepeatedExts, validRepeatedExts...) - -func hasValidationExtensions(f *protogen.Field) bool { - if opts := f.Desc.Options(); opts != nil { - for _, ext := range validExts { - if proto.HasExtension(opts, ext) { - return true - } - } - } - return false -} - -func hasNonRepeatedValidationExtensions(f *protogen.Field) bool { - if opts := f.Desc.Options(); opts != nil { - for _, ext := range validNonRepeatedExts { - if proto.HasExtension(opts, ext) { - return true - } - } - } - - return false -} - -func getRegexValue(f *protogen.Field) string { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, validator.E_Regex) - if v, ok := ext.(string); ok { - return v - } - } - return "" -} - -func getSimpleStringExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.SimpleStringRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.SimpleStringRules); ok { - return v - } - } - return nil -} - -func getStringExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.StringRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.StringRules); ok { - return v - } - } - return nil -} - -func getIdExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.IdRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.IdRules); ok { - return v - } - } - return nil -} - -func getEmailExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.EmailRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.EmailRules); ok { - return v - } - } - return nil -} - -func getURLExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.URLRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.URLRules); ok { - return v - } - } - return nil -} - -func getTimezoneExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.TimezoneRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.TimezoneRules); ok { - return v - } - } - return nil -} - -func getBoolExtension(f *protogen.Field, xt protoreflect.ExtensionType) bool { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(bool); ok { - return v - } - } - return false -} - -func getIntExtention(f *protogen.Field, xt protoreflect.ExtensionType) int64 { - if opts := f.Desc.Options(); opts != nil { - if !proto.HasExtension(opts, xt) { - return -1 - } - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(int64); ok { - return v - } - } - return -1 -} - -func genNumberValidator(g *protogen.GeneratedFile, f *protogen.Field, varName string) { - rules := getNumberExtension(f, validator.E_Number) - - if rules.GetOptional() { - g.P("if ", varName, " != 0 {") - } - - if !rules.GetAllowNan() { - if f.Desc.Kind() != protoreflect.DoubleKind && f.Desc.Kind() != protoreflect.FloatKind { - panic("cannot use allow_nan option for integers, only supported for float/double") - } - g.P("// This statement checks for NaN value without using Math package") - g.P("if ", varName, " != ", varName, " {") - errStr := "not be NaN" - genErrorString(g, varName, string(f.Desc.Name()), errStr) - g.P("}") - } - - if rules.GetRange() != "" { - if !strings.Contains(rules.GetRange(), ":") { - // Range must contain : to be used - panic("unparsable range for number validator") - } - - var rangeVals = strings.Split(rules.GetRange(), ":") - if len(rangeVals) < 1 || len(rangeVals) > 2 { - panic("unparsable range for number validator") - } - - if rangeVals[0] != "" { - g.P("// Range check lower bounds") - g.P("if ", varName, " < ", rangeVals[0], " {") - errStr := fmt.Sprintf("be greater than or equal to %v", rangeVals[0]) - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errStr) - } - g.P("}") - } - - if rangeVals[1] != "" { - g.P("// Range check upper bounds") - g.P("if ", varName, " > ", rangeVals[1], " {") - errStr := fmt.Sprintf("be less than or equal to %v", rangeVals[1]) - if rules.GetLogOnly() { - printErrorString(g, varName, string(f.Desc.Name()), errStr, 50) - } else { - genErrorString(g, varName, string(f.Desc.Name()), errStr) - } - g.P("}") - } - } - - if rules.GetOptional() { - g.P("}") - } -} - -func getNumberExtension(f *protogen.Field, xt protoreflect.ExtensionType) *validator.NumberRules { - if opts := f.Desc.Options(); opts != nil { - ext := proto.GetExtension(opts, xt) - if v, ok := ext.(*validator.NumberRules); ok { - return v - } - } - return nil -} diff --git a/protobuf/protoc-gen-govalidator/plugin/validation_definitions.go b/protobuf/protoc-gen-govalidator/plugin/validation_definitions.go deleted file mode 100644 index f8515dd..0000000 --- a/protobuf/protoc-gen-govalidator/plugin/validation_definitions.go +++ /dev/null @@ -1,263 +0,0 @@ -package plugin - -import ( - "fmt" - "sort" - "strings" - - validator "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" -) - -// Any changes made in this file will require Security Engineering consultation/review - -// String consts -const ( - stringLenMinSafe = uint32(1) - stringLenMinUnsafe = uint32(1) // <1 not allowed, use optional instead of empty strings - stringLenMaxSafe = uint32(1000) - stringLenMaxUnsafe = uint32(30000) - stringLenMinDefault = uint32(1) - stringLenMaxDefault = uint32(130) -) - -// Default allowed regex tokens for validator.string (safe_string) -var stringReDefaultSafe = []string{ - `\pL`, // Letter (Unicode Category) - any kind of letter from any language - `\pN`, // Number (Unicode Category) - any kind of numeric character in any script - `\x{0020}`, // Space Unicode Category: Space Separator (Zs) - `\x{0028}`, // ( Left Parenthesis Unicode Category: Open Punctuation (Ps) - `\x{0029}`, // ) Right Parenthesis Unicode Category: Close Punctuation (Pe) - `\x{002C}`, // , Comma Unicode Category: Other Punctuation (Po) - `\x{002E}`, // . Full Stop Unicode Category: Other Punctuation (Po) - `\x{003A}`, // : Colon Unicode Category: Other Punctuation (Po) - `\x{003F}`, // ? Question Mark Unicode Category: Other Punctuation (Po) - `\x{0040}`, // @ Commercial At Unicode Category: Other Punctuation (Po) - `\x{005B}`, // [ Left Square Bracket Unicode Category: Open Punctuation (Ps) - `\x{005D}`, // ] Right Square Bracket Unicode Category: Close Punctuation (Pe) - `\x{005F}`, // _ Low Line Unicode Category: Connector Punctuation (Pc) - `\x{00BF}`, // ¿ Inverted Question Mark Unicode Category: Other Punctuation (Po) - `\x{2013}`, // – En Dash Unicode Category: Dash Punctuation (Pd) -} - -// Default allowed regex tokens for validator.unsafe_string -// Can be further extended by adding symbol categories in the validation field option -// Notice that by default < and > are not included as they are not often used -var stringReDefaultUnsafe = []string{ - // Anything from stringReDefaultSafe, plus: - `\x{0021}`, // ! Exclamation Mark Other Punctuation (Po) - `\x{0022}`, // " Quotation Mark Other Punctuation (Po) - `\x{0023}`, // # Number Sign Other Punctuation (Po) - `\x{0025}`, // % Percent Sign Other Punctuation (Po) - `\x{0026}`, // & Ampersand Other Punctuation (Po) - `\x{0027}`, // ' Apostrophe Other Punctuation (Po) - `\x{002A}`, // * Asterisk Other Punctuation (Po) - `\x{002D}`, // - Hyphen-Minus Dash Punctuation (Pd) - `\x{002F}`, // / Solidus Other Punctuation (Po) - `\x{005C}`, // \ Reverse Solidus Other Punctuation (Po) -} - -var stringReLineBreaks = []string{ - `\x{000A}`, // (EOL, LF, NL, \n) Control (Cc) - // \x{000D} (CR, \r) is stripped by default for multiline strings -} - -// Library that holds all regex patterns in format map[regex_id]map[pattern_token] -var regexLib = make(map[string]map[string]bool) - -// replace_unsafe option -// The following alternative characters are all in the COMMON script but might not be available in all fonts -// None of these characters are allowed in safe_string unless replace_unsafe option is enabled -// Use string literals otherwise the visual unicode symbol will be used in the replacer string which can fail for certain chars -var stringUnsafeReplacerMap = map[string]string{ - `\u0021`: `\uFF01`, // ! : ! EXCLAMATION MARK to FULLWIDTH EXCLAMATION MARK - `\u0022`: `\u201D`, // " : ” QUOTATION MARK to RIGHT DOUBLE QUOTATION MARK (alternative: “ \u0093) - `\u0023`: `\u0020`, // TODO # : ? NUMBER SIGN to TODO (not found an appropriate alternative, using space for now) - `\u0025`: `\u2052`, // % : ⁒ PERCENT SIGN to COMMERCIAL MINUS SIGN - `\u0026`: `\u0020`, // TODO & : ? AMPERSAND to TODO (not found an appropriate alternative, using space for now) - `\u0027`: `\u2019`, // ' : ’ APOSTROPHE to RIGHT SINGLE QUOTATION MARK - `\u002A`: `\u2217`, // * : ∗ ASTERISK to ASTERISK OPERATOR - `\u002B`: `\uFF0B`, // + : + PLUS SIGN to FULLWIDTH PLUS SIGN (alternative ➕ U+2795) - `\u002D`: `\u2212`, // - : − HYPHEN-MINUS to MINUS SIGN (alternative ‐ U+2010) - `\u002F`: `\u2215`, // / : ∕ SOLIDUS to DIVISION SLASH (alternative / U+FF0F) - `\u003B`: `\u037E`, // ; : ; SEMICOLON to GREEK QUESTION MARK - `\u003C`: `\u02C2`, // < : ˂ LESS-THAN SIGN to MODIFIER LETTER LEFT ARROWHEAD (similar to >, alternative: U+1438) - `\u003D`: `\u2E40`, // = : ⹀ EQUALS SIGN to DOUBLE HYPHEN (alternative ゠U+30A0 or ꓿ U+A4FF) - `\u003E`: `\u02C3`, // > : ˃ GREATER-THAN SIGN to MODIFIER LETTER RIGHT ARROWHEAD (alternative in other script: U+16F3F) - `\u005C`: `\uFF3C`, // \ : \ REVERSE SOLIDUS to FULLWIDTH REVERSE SOLIDUS (alternative ⧵ U+29F5) - `\u0060`: `\u2019`, // ` : ’ GRAVE ACCENT to RIGHT SINGLE QUOTATION MARK - `\u00B4`: `\u2019`, // ` : ’ ACUTE ACCENT to RIGHT SINGLE QUOTATION MARK - `\u007C`: `\uFFE8`, // | : │ VERTICAL LINE to HALFWIDTH FORMS LIGHT VERTICAL - `\u3164`: `\u0020`, // ㅤ : HANGUL FILLER to normal space (HANGUL FILLER is in Letter, other so accepted by default) - // NOTE: when updating, also need to update UnsafeCharReplacer in validator_helpers.go (TODO PA: improve this) -} - -// Unicode cats not allowed in safe_string without replace_unsafe option -var restrictedSafeStringSymbols = map[validator.SymbolCategory]struct{}{ - validator.SymbolCategory_PUNCTUATION: {}, - validator.SymbolCategory_MODIFIER: {}, -} - -// Translates the SymbolCategory to the matching Unicode regex pattern -var stringSymbolMap = map[validator.SymbolCategory][]string{ - validator.SymbolCategory_CURRENCY: { - `\pSc`, // Currency symbols like $ £ € - https://www.fileformat.info/info/unicode/category/Sc/list.htm - }, - validator.SymbolCategory_PUNCTUATION: { - // UNSAFE: contains several unsafe symbols like < | ` ! - // Can be used with string when replace unsafe option is enabled - `\pSm`, // Math symbols like + < | - https://www.fileformat.info/info/unicode/category/Sm/list.htm - `\pPo`, // Punctuation, other category symbols like ! # % ? - https://www.fileformat.info/info/unicode/category/Po/list.htm - }, - validator.SymbolCategory_MODIFIER: { - // UNSAFE: Contains some unsafe symbols like \x{0060} GRAVE ACCENT - // Can be used with string when replace unsafe option is enabled - `\pSk`, // Modifier symbols like ^ ˥ 🏻 - }, - validator.SymbolCategory_OTHER: { - `\pSo`, // Symbol Other including symbols like © ♬ 🐳 😗 - https://www.fileformat.info/info/unicode/category/So/list.htm - `\x{200D}`, // ZERO WIDTH JOINER which is used to combine some emoticons like 👨‍💻 (👨+💻) - }, - validator.SymbolCategory_MARK: {`\pM`}, // Mark and combining symbols (all sub cats Spacing Combining, Enclosing, Nonspacing) - validator.SymbolCategory_COMMON: { - // Do not add unsafe symbols to this category! - `\x{007E}`, // ~ TILDE - `\x{104B}`, // ။ MYANMAR SIGN SECTION - `\x{2018}`, // ‘ LEFT SINGLE QUOTATION MARK - `\x{2019}`, // ’ RIGHT SINGLE QUOTATION MARK - `\x{2022}`, // • BULLET - `\x{201C}`, // “ LEFT DOUBLE QUOTATION MARK - `\x{201D}`, // ” RIGHT DOUBLE QUOTATION MARK - }, -} - -// replace_other option -// Translate rare symbols to a more common alternative or space to sanitise the data -// Most of these occur in less than 0.02% of our data -var stringSymbolReplacerMap = map[string]string{ - // Separator, Space (Zs) to normal space - https://www.fileformat.info/info/unicode/category/Zs/list.htm - `\u00A0`: `\u0020`, // NO-BREAK SPACE - `\u1680`: `\u0020`, // OGHAM SPACE MARK - `\u2000`: `\u0020`, // EN QUAD - `\u2001`: `\u0020`, // EM QUAD - `\u2002`: `\u0020`, // EN SPACE - `\u2003`: `\u0020`, // EM SPACE - `\u2004`: `\u0020`, // THREE-PER-EM SPACE - `\u2005`: `\u0020`, // FOUR-PER-EM SPACE - `\u2006`: `\u0020`, // SIX-PER-EM SPACE - `\u2007`: `\u0020`, // FIGURE SPACE - `\u2008`: `\u0020`, // PUNCTUATION SPACE - `\u2009`: `\u0020`, // THIN SPACE - `\u200A`: `\u0020`, // HAIR SPACE - `\u202F`: `\u0020`, // NARROW NO-BREAK SPACE - `\u205F`: `\u0020`, // MEDIUM MATHEMATICAL SPACE - `\u3000`: `\u0020`, // IDEOGRAPHIC SPACE - // Other, format (Control) - `\u200C`: ``, // ZERO WIDTH NON-JOINER to (strip) - `\u200D`: ``, // ZERO WIDTH JOINER to (strip) - // TODO: `\u200E`: ``, // LEFT-TO-RIGHT MARK - we do not actively support LTR or RTR atm, likely resulting in UI issues - // TODO: `\u200F`: ``, // RIGHT-TO-LEFT MARK - needs further work, currently we will reject this input, uncomment this to strip - `\uFEFF`: ``, // ZERO WIDTH NO-BREAK SPACE - // Punctuation - `\u2014`: `\u2013`, // EM DASH to EN dash - `\u2018`: `\u2019`, // LEFT SINGLE QUOTATION MARK to right (allowed by default) - `\u3002`: `\u002E`, // IDEOGRAPHIC FULL STOP to normal full stop - `\uFF0C`: `\u002C`, // FULLWIDTH COMMA to normal comma (from [Po]) - `\uFF1A`: `\u003A`, // FULLWIDTH COLON to normal colon - // Control chars to normal space (other control chars, especially the ones listed in charDenyList should still be denied) - `\u0009`: `\u0020`, // \t HORIZONTAL TAB - `\u000A`: `\u0020`, // \n LINE FEED (will not be replaced with multiline option enabled) - `\u000D`: `\u0020`, // \r CARRIAGE RETURN - // NOTE: when updating, also need to update SymbolCharReplacer and SymbolCharReplacerMultiline in validator_helpers.go (TODO PA: improve this) -} - -// Prepare the string replacer arguments based on provided map contents -func prepareStringReplacerRegex(replacerMap map[string]string, regexId string) []string { - stringReplacerArguments := []string{} - for _, safe := range replacerMap { - // Add to whitelist regex so that the replaced characters are allowed in the validation pattern - r := strings.Replace(safe, `\u`, `\x{`, 1) + "}" - prepareRegex(regexId, r) - } - return stringReplacerArguments -} - -// Prepare a regex by adding one or multiple tokens to the pattern -func prepareRegex(regexId string, patternTokens ...string) { - for _, patternToken := range patternTokens { - if _, ok := regexLib[regexId]; !ok { - regexLib[regexId] = make(map[string]bool) - } - regexLib[regexId][patternToken] = true - } -} - -// Add tokens from a prepared regex to another one -// This is used to add safe_string pattern to unsafe_string pattern -func mergeRegex(toRegexId, fromRegexId string) { - for k, v := range regexLib[fromRegexId] { - regexLib[toRegexId][k] = v - } -} - -// Return the regex pattern based on tokens added via prepareRegex -func getPreparedRegex(regexId string) (string, error) { - - if _, ok := regexLib[regexId]; !ok { - // regexId not initialised via prepareRegex - // might indicate typo, return a pattern that will always fail validation - // should not continue in the validator though, so just in case errors are not handled - return "^\b$", fmt.Errorf("invalid regexId %s - initialise the regex with prepareRegex first", regexId) - } - // Sort the tokens so that we can consistent results - tokens := make([]string, 0, len(regexLib[regexId])) - for k := range regexLib[regexId] { - tokens = append(tokens, k) - } - sort.Strings(tokens) - return `^[` + strings.Join(tokens, "") + `]+$`, nil -} - -// Deny list of characters not allowed in both safe_string and/or unsafe_string -// Normally, none of these characters are allowed by our default lists as they are potentially dangerous -// This deny list is a safeguard to avoid that these characters are added to the 'allow' validator option -// Use string literals as we do not need the actual character -var charDenyList = map[string]struct{}{ - // For safe_string, this is in addition to stringUnsafeReplacerMap and restrictedSafeStringSymbols - // ASCII Control Characters (0-31 and 127): - `\u0000`: {}, // Null byte - `\u0001`: {}, // Start of Heading - `\u0002`: {}, // Start of Text - `\u0003`: {}, // End of Text - `\u0004`: {}, // End of Transmission - `\u0005`: {}, // Enquiry - `\u0006`: {}, // Acknowledge - `\u0007`: {}, // Bell - `\u0008`: {}, // \b Backspace - `\u000B`: {}, // \v Vertical Tab - `\u000C`: {}, // \f Form Feed - `\u000E`: {}, // Shift Out - `\u000F`: {}, // Shift In - `\u0010`: {}, // Data Link Escape - `\u0011`: {}, // Device Control 1 (XON) - `\u0012`: {}, // Device Control 2 - `\u0013`: {}, // Device Control 3 (XOFF) - `\u0014`: {}, // Device Control 4 - `\u0015`: {}, // Negative Acknowledge - `\u0016`: {}, // Synchronous Idle - `\u0017`: {}, // End of Transmission Block - `\u0018`: {}, // Cancel - `\u0019`: {}, // End of Medium - `\u001A`: {}, // Substitute - `\u001B`: {}, // \e Escape - `\u001C`: {}, // File Separator - `\u001D`: {}, // Group Separator - `\u001E`: {}, // Record Separator - `\u001F`: {}, // Unit Separator - `\u007F`: {}, // Delete - // ANSI Characters (128-159), ISO-8859-1 treats these as control characters: - `\u0081`: {}, // Not used - `\u008D`: {}, // Not used - `\u008F`: {}, // Not used - `\u0090`: {}, // Not used - `\u009D`: {}, // Not used -} diff --git a/protobuf/protoc-gen-govalidator/valtest/geo.pb.go b/protobuf/protoc-gen-govalidator/valtest/geo.pb.go deleted file mode 100644 index 88c3a5b..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/geo.pb.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) 2021 SafetyCulture Pty Ltd. All Rights Reserved. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.2 -// source: geo.proto - -package valtest - -import ( - _ "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" - 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 GeoValidationMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Latitude float64 `protobuf:"fixed64,6,opt,name=latitude,proto3" json:"latitude,omitempty"` - Longitude float64 `protobuf:"fixed64,7,opt,name=longitude,proto3" json:"longitude,omitempty"` - Accuracy int32 `protobuf:"varint,9,opt,name=accuracy,proto3" json:"accuracy,omitempty"` -} - -func (x *GeoValidationMessage) Reset() { - *x = GeoValidationMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_geo_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GeoValidationMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GeoValidationMessage) ProtoMessage() {} - -func (x *GeoValidationMessage) ProtoReflect() protoreflect.Message { - mi := &file_geo_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 GeoValidationMessage.ProtoReflect.Descriptor instead. -func (*GeoValidationMessage) Descriptor() ([]byte, []int) { - return file_geo_proto_rawDescGZIP(), []int{0} -} - -func (x *GeoValidationMessage) GetLatitude() float64 { - if x != nil { - return x.Latitude - } - return 0 -} - -func (x *GeoValidationMessage) GetLongitude() float64 { - if x != nil { - return x.Longitude - } - return 0 -} - -func (x *GeoValidationMessage) GetAccuracy() int32 { - if x != nil { - return x.Accuracy - } - return 0 -} - -var File_geo_proto protoreflect.FileDescriptor - -var file_geo_proto_rawDesc = []byte{ - 0x0a, 0x09, 0x67, 0x65, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x76, 0x61, 0x6c, - 0x74, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x73, 0x31, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa3, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x6f, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x01, 0x42, 0x0e, 0xaa, 0xec, 0x1f, 0x0a, 0x08, 0x01, 0x1a, 0x06, 0x2d, 0x39, 0x30, - 0x3a, 0x39, 0x30, 0x52, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x30, 0x0a, - 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, - 0x42, 0x12, 0xaa, 0xec, 0x1f, 0x0e, 0x08, 0x01, 0x1a, 0x08, 0x2d, 0x31, 0x38, 0x30, 0x3a, 0x31, - 0x38, 0x30, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, - 0x2d, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x05, 0x42, 0x11, 0xaa, 0xec, 0x1f, 0x0d, 0x08, 0x01, 0x1a, 0x07, 0x30, 0x3a, 0x31, 0x30, 0x30, - 0x30, 0x30, 0x28, 0x01, 0x52, 0x08, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x42, 0x4c, - 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x53, 0x61, 0x66, - 0x65, 0x74, 0x79, 0x43, 0x75, 0x6c, 0x74, 0x75, 0x72, 0x65, 0x2f, 0x73, 0x31, 0x32, 0x2d, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x76, 0x61, 0x6c, 0x69, 0x64, - 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_geo_proto_rawDescOnce sync.Once - file_geo_proto_rawDescData = file_geo_proto_rawDesc -) - -func file_geo_proto_rawDescGZIP() []byte { - file_geo_proto_rawDescOnce.Do(func() { - file_geo_proto_rawDescData = protoimpl.X.CompressGZIP(file_geo_proto_rawDescData) - }) - return file_geo_proto_rawDescData -} - -var file_geo_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_geo_proto_goTypes = []any{ - (*GeoValidationMessage)(nil), // 0: valtest.GeoValidationMessage -} -var file_geo_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_geo_proto_init() } -func file_geo_proto_init() { - if File_geo_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_geo_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*GeoValidationMessage); 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_geo_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_geo_proto_goTypes, - DependencyIndexes: file_geo_proto_depIdxs, - MessageInfos: file_geo_proto_msgTypes, - }.Build() - File_geo_proto = out.File - file_geo_proto_rawDesc = nil - file_geo_proto_goTypes = nil - file_geo_proto_depIdxs = nil -} diff --git a/protobuf/protoc-gen-govalidator/valtest/geo.proto b/protobuf/protoc-gen-govalidator/valtest/geo.proto deleted file mode 100644 index 264a234..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/geo.proto +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2021 SafetyCulture Pty Ltd. All Rights Reserved. - -syntax = "proto3"; -package valtest; - -import "s12/protobuf/proto/validator.proto"; - -option go_package = "github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/valtest"; - -message GeoValidationMessage { - double latitude = 6 [(validator.number) = { optional: true, range: "-90:90" }]; - double longitude = 7 [(validator.number) = { optional: true, log_only: true, range: "-180:180"}]; - int32 accuracy = 9 [(validator.number) = { optional: true, log_only: true, range: "0:10000"}]; -} diff --git a/protobuf/protoc-gen-govalidator/valtest/geo.validator.pb.go b/protobuf/protoc-gen-govalidator/valtest/geo.validator.pb.go deleted file mode 100644 index 44be39b..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/geo.validator.pb.go +++ /dev/null @@ -1,46 +0,0 @@ -// Code generated by protoc-gen-govalidator. DO NOT EDIT. -// versions: -// protoc-gen-govalidator v2.7.0 -// protoc v5.28.2 -// source: geo.proto - -package valtest - -import ( - fmt "fmt" - proto "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" -) - -func (m *GeoValidationMessage) Validate() error { - if m.Latitude != 0 { - // Range check lower bounds - if m.Latitude < -90 { - return fmt.Errorf(`latitude: value must be greater than or equal to -90`) - } - // Range check upper bounds - if m.Latitude > 90 { - return fmt.Errorf(`latitude: value must be less than or equal to 90`) - } - } - if m.Longitude != 0 { - // Range check lower bounds - if m.Longitude < -180 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "longitude", "be greater than or equal to -180", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Longitude), 50))) - } - // Range check upper bounds - if m.Longitude > 180 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "longitude", "be less than or equal to 180", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Longitude), 50))) - } - } - if m.Accuracy != 0 { - // Range check lower bounds - if m.Accuracy < 0 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "accuracy", "be greater than or equal to 0", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Accuracy), 50))) - } - // Range check upper bounds - if m.Accuracy > 10000 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "accuracy", "be less than or equal to 10000", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Accuracy), 50))) - } - } - return nil -} diff --git a/protobuf/protoc-gen-govalidator/valtest/geo.validator_regex.pb.go b/protobuf/protoc-gen-govalidator/valtest/geo.validator_regex.pb.go deleted file mode 100644 index d45e465..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/geo.validator_regex.pb.go +++ /dev/null @@ -1,11 +0,0 @@ -// Code generated by protoc-gen-govalidator. DO NOT EDIT. -// versions: -// protoc-gen-govalidator v2.7.0 -// protoc v5.28.2 -// source: geo.proto - -package valtest - -import ( - _ "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" -) diff --git a/protobuf/protoc-gen-govalidator/valtest/invalid_safe_strings.txt b/protobuf/protoc-gen-govalidator/valtest/invalid_safe_strings.txt deleted file mode 100644 index b0054de..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/invalid_safe_strings.txt +++ /dev/null @@ -1,10 +0,0 @@ - (HTMLi) -ព្រះ​ពុទ្ឋឃោសាចារ‌្យ​ជួន​ណាត (Khmer script) -সুকুমার রায় (Bengali script) -माधुरी दीक्षित (Devanagari script) -ธงไชย แม็คอินไตย์ (Thai script) -མགོན་པོ་རྡོ་རྗེ། (Tibetran script) -சிவாஜி கனேசன் (Tibetran script) -Audit - M&R Process (中文版)(Han script) -> (HTMLi) -#"> valtest.InnerMessageWithLegacyId - 6, // 1: valtest.ValTestMessage.msg_required:type_name -> valtest.InnerMessage - 21, // 2: valtest.ValTestMessage.nested_message:type_name -> valtest.ValTestMessage.NestedMessage - 22, // 3: valtest.ValTestMessage.not_supported:type_name -> valtest.ValTestMessage.NotSupportedEntry - 23, // 4: valtest.ValTestMessage.contacts_with_length_constraint:type_name -> valtest.ValTestMessage.Contact - 23, // 5: valtest.ValTestMessage.contacts_without_length_constraint:type_name -> valtest.ValTestMessage.Contact - 8, // 6: valtest.ValTestMessage.inner_s12_id:type_name -> valtest.InnerMessageWithS12Id - 21, // 7: valtest.OuterMessageUsingNestedMessage.some_message:type_name -> valtest.ValTestMessage.NestedMessage - 9, // 8: valtest.NestedLevel2Message.org_nested:type_name -> valtest.NestedLevel3Message - 10, // 9: valtest.NestedLevel1Message.org_nested:type_name -> valtest.NestedLevel2Message - 11, // 10: valtest.MyReqMessage.org_nested:type_name -> valtest.NestedLevel1Message - 13, // 11: valtest.ScimUser.emails:type_name -> valtest.ScimEmail - 0, // 12: valtest.MyMessageWithEnum.enum:type_name -> valtest.MyMessageWithEnum.MyEnum - 0, // 13: valtest.MyMessageWithEnum.enums:type_name -> valtest.MyMessageWithEnum.MyEnum - 1, // 14: valtest.MyMessageWithRepeatedEnum.enums:type_name -> valtest.MyMessageWithRepeatedEnum.MyEnum - 25, // 15: valtest.MyOneOfMsg.my_first_field:type_name -> valtest.MyOneOfMsg.FirstType - 26, // 16: valtest.MyOneOfMsg.my_second_field:type_name -> valtest.MyOneOfMsg.SecondType - 27, // 17: valtest.NumberMessage.nested_number:type_name -> valtest.NumberMessage.NestedNumber - 18, // [18:18] is the sub-list for method output_type - 18, // [18:18] is the sub-list for method input_type - 18, // [18:18] is the sub-list for extension type_name - 18, // [18:18] is the sub-list for extension extendee - 0, // [0:18] is the sub-list for field type_name -} - -func init() { file_valtest_proto_init() } -func file_valtest_proto_init() { - if File_valtest_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_valtest_proto_msgTypes[0].Exporter = func(v any, i int) any { - switch v := v.(*ValTestMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[1].Exporter = func(v any, i int) any { - switch v := v.(*LogOnlyValidationMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[2].Exporter = func(v any, i int) any { - switch v := v.(*LowercaseValidationMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[3].Exporter = func(v any, i int) any { - switch v := v.(*OuterMessageUsingNestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[4].Exporter = func(v any, i int) any { - switch v := v.(*InnerMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[5].Exporter = func(v any, i int) any { - switch v := v.(*InnerMessageWithLegacyId); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[6].Exporter = func(v any, i int) any { - switch v := v.(*InnerMessageWithS12Id); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[7].Exporter = func(v any, i int) any { - switch v := v.(*NestedLevel3Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[8].Exporter = func(v any, i int) any { - switch v := v.(*NestedLevel2Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[9].Exporter = func(v any, i int) any { - switch v := v.(*NestedLevel1Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[10].Exporter = func(v any, i int) any { - switch v := v.(*MyReqMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[11].Exporter = func(v any, i int) any { - switch v := v.(*ScimEmail); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[12].Exporter = func(v any, i int) any { - switch v := v.(*ScimUser); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[13].Exporter = func(v any, i int) any { - switch v := v.(*MyMessageWithEnum); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[14].Exporter = func(v any, i int) any { - switch v := v.(*MyMessageWithRepeatedEnum); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[15].Exporter = func(v any, i int) any { - switch v := v.(*MyMessageWithRepeatedField); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[16].Exporter = func(v any, i int) any { - switch v := v.(*MyOneOfMsg); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[17].Exporter = func(v any, i int) any { - switch v := v.(*NumberMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[18].Exporter = func(v any, i int) any { - switch v := v.(*NonUrlMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[19].Exporter = func(v any, i int) any { - switch v := v.(*ValTestMessage_NestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[21].Exporter = func(v any, i int) any { - switch v := v.(*ValTestMessage_Contact); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[22].Exporter = func(v any, i int) any { - switch v := v.(*ValTestMessage_NestedMessage_InnerNestedMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[23].Exporter = func(v any, i int) any { - switch v := v.(*MyOneOfMsg_FirstType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[24].Exporter = func(v any, i int) any { - switch v := v.(*MyOneOfMsg_SecondType); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_valtest_proto_msgTypes[25].Exporter = func(v any, i int) any { - switch v := v.(*NumberMessage_NestedNumber); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_valtest_proto_msgTypes[0].OneofWrappers = []any{ - (*ValTestMessage_Fax)(nil), - (*ValTestMessage_Phone)(nil), - } - file_valtest_proto_msgTypes[16].OneofWrappers = []any{ - (*MyOneOfMsg_MyFirstField)(nil), - (*MyOneOfMsg_MySecondField)(nil), - (*MyOneOfMsg_MyThirdField)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_valtest_proto_rawDesc, - NumEnums: 2, - NumMessages: 26, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_valtest_proto_goTypes, - DependencyIndexes: file_valtest_proto_depIdxs, - EnumInfos: file_valtest_proto_enumTypes, - MessageInfos: file_valtest_proto_msgTypes, - }.Build() - File_valtest_proto = out.File - file_valtest_proto_rawDesc = nil - file_valtest_proto_goTypes = nil - file_valtest_proto_depIdxs = nil -} diff --git a/protobuf/protoc-gen-govalidator/valtest/valtest.proto b/protobuf/protoc-gen-govalidator/valtest/valtest.proto deleted file mode 100644 index f614802..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/valtest.proto +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright (c) 2021 SafetyCulture Pty Ltd. All Rights Reserved. - -syntax = "proto3"; -package valtest; - -import "s12/protobuf/proto/validator.proto"; - -option go_package = "github.com/SafetyCulture/s12-proto/protobuf/protoc-gen-govalidator/valtest"; - -message ValTestMessage { - // returns an error if the string cannot be parsed as a UUIDv4 - string id = 1 [(validator.id) = {}]; - // we do not support bytes currently for id - // bytes user_id = 2 [(validator.id) = {}]; - // can validate each repeated item too - repeated string ids = 3 [(validator.id) = {}]; - // only validate if non-zero value - string media_id = 4 [(validator.id) = { optional: true }]; - // returns an error if the string cannot be parsed as a legacy id - string legacy_id = 5 [(validator.id) = { legacy: true }]; - // InnerMessage can contain a legacy id too - InnerMessageWithLegacyId inner_legacy_id = 6; - // returns an error if the string cannot be parsed as a UUID - string uuid = 7 [(validator.id) = { version : "any" }]; - - // email validation - string email = 11 [(validator.email) = {}]; - // optional email address - string opt_email = 12 [(validator.email) = { optional: true }]; - // email address with domain validation - //string existing_email = 13 [(validator.email) = { check_domain: true }]; - - // validate the max length of a string - string description = 21 [(validator.string) = { len: ":750" }]; - // validate the min length (max length defaults to current default string len (130)) - string password = 22 [(validator.unsafe_string) = { len: "8:", allow: "~$^+`{}=|;<>" }]; - // validate min and max length - string title = 23 [(validator.string) = { len: "3:50" }]; - // validate fixed length - string fixed_string = 24 [(validator.string) = { len: "4" }]; - // validate length in runes instead of bytes - string rune_string = 25 [(validator.string) = { len: "4", runes: true, symbols: [OTHER] }]; - // replace unsafe chars - string replace_string = 26 [(validator.string) = { replace_unsafe: true }]; - string not_replace_string = 27 [(validator.string) = { /*replace_unsafe: false* (default shoulud be off)*/ }]; - // allow additional characters including # as part of the restricted chars list (should be replaced by replace_unsafe) - string allow_string = 28 [(validator.string) = { allow: "~#", replace_unsafe: true }]; - // allow symbol category - string symbol_string = 29 [(validator.string) = { symbols: [CURRENCY] }]; - // allow multiple symbol categories - string symbols_string = 30 [(validator.string) = { symbols: [OTHER, MARK] }]; - // allow newlines - string newline_string = 31 [(validator.string) = { multiline: true }]; - // disable encoding validation - string invalid_encoding_string = 32 [(validator.string) = { validate_encoding: false }]; - // optional string - string opt_string = 33 [(validator.string) = { optional: true }]; - // trimmed string - string trim_string = 34 [(validator.string) = { trim: true }]; - // all options - string all_string = 35 [(validator.string) = { - optional: false, - trim: false, - len: "6-20", - runes: false, - replace_unsafe: true, - replace_other: true, - sanitise_pua: false, - allow: ">", - symbols: [COMMON,CURRENCY,MARK,PUNCTUATION,MODIFIER,OTHER], - multiline: false, - validate_encoding: false - }]; - // custom tests for names - string name = 36 [(validator.string) = { replace_unsafe: true, allow: "'-", optional: true, len: ":50" }]; - string sc_title = 37 [(validator.string) = { replace_unsafe: true, optional: true, len: ":500" }]; - // this is an example of a definition that will allow many characters but still will replace unsafe chars - // normally, definitions like this should be avoided as it is unlikely that it will match your data requirements - // however, as a starting point, with these settings it is very unlikely that user input is rejected unless it is malformed - string sc_permissive = 38 [(validator.string) = { - len: ":1000", - replace_unsafe: true, - replace_other: true, - sanitise_pua: true, - optional: true, - symbols: [COMMON,CURRENCY,MARK,PUNCTUATION,MODIFIER,OTHER], - }]; - string not_sanitise_pua = 39 [(validator.string) = { sanitise_pua: false, optional: true }]; - string sanitise_pua = 40 [(validator.string) = { sanitise_pua: true, optional: true }]; - string sanitise_length = 41 [(validator.string) = { len: "2", sanitise_pua: true, optional: true }]; - optional string optional_string = 42 [(validator.string) = {}]; - - // field without any validation - string no_validation = 50; - - oneof contact_oneof { - string fax = 51; - string phone = 52 [(validator.string) = { len: "11" }]; - } - - // Required inner message - InnerMessage msg_required = 53 [(validator.msg_required) = true]; - - message NestedMessage { - string val = 1 [ - (validator.string) = { len: "1:100" } - ]; - - message InnerNestedMessage { - string inner_val = 1 [ - (validator.string) = { len: "1:100" } - ]; - } - - string nested_email = 54 [(validator.email) = {}]; - - repeated string member_emails = 55 [ - (validator.email) = {}, - (validator.repeated_len_gte) = 2, - (validator.repeated_len_lte) = 5 - ]; - } - - NestedMessage nested_message = 56; - - map not_supported = 57; - - message Contact { - string phone = 1 [(validator.optional) = true ]; - string email = 2 [(validator.email) = {}]; - } - repeated Contact contacts_with_length_constraint = 58 [ - (validator.repeated_len_gte) = 1, - (validator.repeated_len_lte) = 10 - ]; - repeated Contact contacts_without_length_constraint = 59; - - // returns an error if the string cannot be parsed as a S12 id - string s12_id = 60 [(validator.id) = { s12id: true }]; - - // InnerMessage can contain a legacy id too - InnerMessageWithS12Id inner_s12_id = 61; - - string all_id = 62 [(validator.id) = { optional: true, legacy: true, s12id: true }]; - - string url = 63 [(validator.url) = {}]; - string url_all_opts = 64 [(validator.url) = { - optional: true, - schemes: ["ftp", "ftps"], - allow_fragment: true, - allow_http: true - }]; - - string timezone = 65 [ - (validator.timezone) = {} - ]; - - string timezone_optional = 66 [ - (validator.timezone) = { - optional: true - } - ]; - - string long_string = 67 [(validator.unsafe_string) = { len: ":30000", optional: true }]; -} - -message LogOnlyValidationMessage { - string image_id = 1 [(validator.uuid) = true, (validator.id) = { legacy: true, s12id: true, log_only: true}]; - string inspection_id = 2 [(validator.id) = { legacy: true, s12id: true}]; - string owner_id = 3 [(validator.id) = { legacy: true, s12id: true, log_only: true}]; - string title = 4 [(validator.unsafe_string) = { - len: "1:10", - optional: true, - multiline: true, - replace_unsafe: false, - sanitise_pua: true, - log_only: true - }]; - string name = 5 [(validator.unsafe_string) = { len: "1:5", sanitise_pua: true, symbols: [COMMON, CURRENCY, MARK, PUNCTUATION, MODIFIER, OTHER]}]; - double latitude = 6 [(validator.number) = { optional: true, range: "-90:90" }]; - double longitude = 7 [(validator.number) = { optional: true, log_only: true, range: "-180:180"}]; - int32 accuracy = 9 [(validator.number) = { optional: true, log_only: true, range: "0:10000"}]; - string answer = 10 [(validator.simple_string) = { optional: true, min_len: 0, max_len: 40, log_only: true }]; - string note = 11 [(validator.simple_string) = { optional: true, min_len: 5, max_len: 40 }]; -} - -message LowercaseValidationMessage { - string uuidv4 = 1 [(validator.id) = {lowercase_only: true}]; - string uuidv4_log_only = 2 [(validator.id) = {lowercase_only: true, log_only: true}]; - - string s12id = 3 [(validator.id) = {lowercase_only: true, s12id: true}]; - string s12id_log_only = 4 [(validator.id) = {lowercase_only: true, s12id: true, log_only: true}]; - - string legacy = 5 [(validator.id) = {lowercase_only: true, legacy: true}]; - string legacy_log_only = 6 [(validator.id) = {lowercase_only: true, legacy: true, log_only: true}]; - - string rev_id = 7 [(validator.regex) = "^((\\d)+-([0-9a-f]){32})?$"]; - string question_id = 8 [(validator.id) = {legacy: true}]; - - string item_id = 9 [(validator.id) = {optional: true, s12id: true}]; -} - -message OuterMessageUsingNestedMessage { - ValTestMessage.NestedMessage some_message = 1; -} - -message InnerMessage { - string id = 1 [(validator.uuid) = true]; -} - -message InnerMessageWithLegacyId { - string id = 1 [(validator.id) = { legacy: true }]; -} - -message InnerMessageWithS12Id { - string id = 1 [(validator.id) = { s12id: true }]; -} - -message NestedLevel3Message { - string org_id5 = 1 [(validator.string) = { len: "5"}]; -} -message NestedLevel2Message { - string org_id4 = 1 [(validator.string) = { len: "4"}]; - NestedLevel3Message org_nested = 2; -} -message NestedLevel1Message { - string org_id3 = 1 [(validator.string) = { len: "3"}]; - NestedLevel2Message org_nested = 2; -} -message MyReqMessage { - string user_id = 1 [(validator.string) = { len: "2"}]; - NestedLevel1Message org_nested = 2; -} - -message ScimEmail { - string value = 3 [ (validator.email) = {} ]; -} - -message ScimUser { - repeated ScimEmail emails = 5; -} - -// Uncomment to test invalid validator option for Message-type field -// message InvalidMessageValidation { -// // Validation must be defined in ScimEmail.value field as it can't be applied on the message -// repeated ScimEmail invalid_val = 1 [(validator.string) = {}]; -// } - -message MyMessageWithEnum { - MyEnum enum = 1 [(validator.enum_required) = true]; - repeated MyEnum enums = 2 [(validator.enum_required) = true]; - - enum MyEnum { - // Default is unspecified. - MY_ENUM_UNSPECIFIED = 0; - // First valid value. - MY_ENUM_FIRST = 1; - } -} - -message MyMessageWithRepeatedEnum { - repeated MyEnum enums = 1 [(validator.enum_required) = true]; - - enum MyEnum { - // Default is unspecified. - MY_ENUM_UNSPECIFIED = 0; - // First valid value. - MY_ENUM_FIRST = 1; - } -} - -// MyMessageWithRepeatedField ... -// gvalidator shouldn't generate empty for loop. -message MyMessageWithRepeatedField { - repeated int32 my_int = 1 [(validator.repeated_len_lte) = 5]; -} - -message MyOneOfMsg { - oneof my_field { - FirstType my_first_field = 1; - SecondType my_second_field = 2; - string my_third_field = 3 [(validator.length_gte) = 1]; - } - - message FirstType { - int64 value = 1 [(validator.int_gt) = 1]; - } - message SecondType { - int64 value = 1 [(validator.int_gt) = 2]; - } -} - -message NumberMessage { - double nan_allowed = 1 [(validator.number) = { allow_nan: true }]; - double nan_disallowed = 2 [(validator.number) = { allow_nan: false }]; - double default_nan = 3; // no validator - double optional_no_nan_value = 4 [(validator.number) = { allow_nan: false, optional: true }]; - double optional_only = 5 [(validator.number) = { optional: true }]; - double range_basic = 6 [(validator.number) = { optional: true, range: "1:10" }]; - double range_low = 7 [(validator.number) = { optional: true, range: "1:" }]; - double range_high = 8 [(validator.number) = { optional: true, range: ":10" }]; - double range_novalues = 9 [(validator.number) = { optional: true, range: ":" }]; - double range_not_optional = 10 [(validator.number) = { optional: false, range: "1:10" }]; - int32 int_test = 11 [(validator.number) = { range: "1:99" }]; - int64 int64_test = 12 [(validator.number) = { range: "-100:100", optional: true }]; - uint32 uint_test = 13 [(validator.number) = { range: "5:99", optional: true }]; - repeated int32 repeated_int = 14 [(validator.number) = { range: "10:20", optional: true }]; - message NestedNumber { - int64 value = 1 [(validator.number) = { range: ":100", optional: true }]; - } - NestedNumber nested_number = 15; -} - -message NonUrlMessage { - // Returns an error if the string contains a full URL - string reject_url_test = 1 [(validator.unsafe_string) = {reject_url: true, optional: true}]; - // Replaces partial URLs with a "safer" version - string break_partial_url_test = 2 [(validator.unsafe_string) = {break_partial_url: true, optional: true}]; -} diff --git a/protobuf/protoc-gen-govalidator/valtest/valtest.validator.pb.go b/protobuf/protoc-gen-govalidator/valtest/valtest.validator.pb.go deleted file mode 100644 index 4d903f8..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/valtest.validator.pb.go +++ /dev/null @@ -1,1376 +0,0 @@ -// Code generated by protoc-gen-govalidator. DO NOT EDIT. -// versions: -// protoc-gen-govalidator v2.7.0 -// protoc v5.28.2 -// source: valtest.proto - -package valtest - -import ( - fmt "fmt" - proto "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" - transform "golang.org/x/text/transform" - norm "golang.org/x/text/unicode/norm" - regexp "regexp" - strings "strings" - time "time" - utf8 "unicode/utf8" -) - -func (m *ValTestMessage) Validate() error { - if !proto.IsUUIDv4(m.Id) { - isValidId := false - if !isValidId { - return fmt.Errorf(`id: value must be parsable as UUIDv4`) - } - } - for _, item := range m.Ids { - if !proto.IsUUIDv4(item) { - isValidId := false - if !isValidId { - return fmt.Errorf(`ids: value must be parsable as UUIDv4`) - } - } - } - if m.MediaId != "" { - if !proto.IsUUIDv4(m.MediaId) { - isValidId := false - if !isValidId { - return fmt.Errorf(`media_id: value must be parsable as UUIDv4`) - } - } - } - if !proto.IsUUIDv4(m.LegacyId) { - isValidId := false - if proto.IsLegacyID(m.LegacyId, false) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`legacy_id: value must be parsable as UUIDv4 or legacy ID`) - } - } - if m.InnerLegacyId != nil { - if v, ok := interface{}(m.InnerLegacyId).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("inner_legacy_id", err) - } - } - } - if !proto.IsUUID(m.Uuid) { - isValidId := false - if !isValidId { - return fmt.Errorf(`uuid: value must be parsable as UUID`) - } - } - if !proto.IsValidEmail(m.Email, false) { - return fmt.Errorf(`email: value must be parsable as an email address`) - } - if m.OptEmail != "" { - if !proto.IsValidEmail(m.OptEmail, false) { - return fmt.Errorf(`opt_email: value must be parsable as an email address`) - } - } - if !norm.NFC.IsNormalString(m.Description) && norm.NFD.IsNormalString(m.Description) { - // normalise NFD to NFC string - var normErr error - m.Description, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Description) - if normErr != nil { - return fmt.Errorf(`description: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.Description, utf8.RuneError) { - return fmt.Errorf(`description: value must must have valid encoding`) - } else if !utf8.ValidString(m.Description) { - return fmt.Errorf(`description: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_Description = len(m.Description) - if !(_len_ValTestMessage_Description >= 1 && _len_ValTestMessage_Description <= 750) { - return fmt.Errorf(`description: value must have a length between 1 and 750`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.Description) { - return fmt.Errorf(`description: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.Password) && norm.NFD.IsNormalString(m.Password) { - // normalise NFD to NFC string - var normErr error - m.Password, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Password) - if normErr != nil { - return fmt.Errorf(`password: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.Password, utf8.RuneError) { - return fmt.Errorf(`password: value must must have valid encoding`) - } else if !utf8.ValidString(m.Password) { - return fmt.Errorf(`password: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_Password = len(m.Password) - if !(_len_ValTestMessage_Password >= 8 && _len_ValTestMessage_Password <= 130) { - return fmt.Errorf(`password: value must have a length between 8 and 130`) - } - if !_regex_51116fcfa477f1949f7055f2f1bf33db.MatchString(m.Password) { - return fmt.Errorf(`password: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.Title) && norm.NFD.IsNormalString(m.Title) { - // normalise NFD to NFC string - var normErr error - m.Title, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Title) - if normErr != nil { - return fmt.Errorf(`title: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.Title, utf8.RuneError) { - return fmt.Errorf(`title: value must must have valid encoding`) - } else if !utf8.ValidString(m.Title) { - return fmt.Errorf(`title: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_Title = len(m.Title) - if !(_len_ValTestMessage_Title >= 3 && _len_ValTestMessage_Title <= 50) { - return fmt.Errorf(`title: value must have a length between 3 and 50`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.Title) { - return fmt.Errorf(`title: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.FixedString) && norm.NFD.IsNormalString(m.FixedString) { - // normalise NFD to NFC string - var normErr error - m.FixedString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.FixedString) - if normErr != nil { - return fmt.Errorf(`fixed_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.FixedString, utf8.RuneError) { - return fmt.Errorf(`fixed_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.FixedString) { - return fmt.Errorf(`fixed_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_FixedString = len(m.FixedString) - if !(_len_ValTestMessage_FixedString == 4) { - return fmt.Errorf(`fixed_string: value must have length 4`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.FixedString) { - return fmt.Errorf(`fixed_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.RuneString) && norm.NFD.IsNormalString(m.RuneString) { - // normalise NFD to NFC string - var normErr error - m.RuneString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.RuneString) - if normErr != nil { - return fmt.Errorf(`rune_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.RuneString, utf8.RuneError) { - return fmt.Errorf(`rune_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.RuneString) { - return fmt.Errorf(`rune_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_RuneString = utf8.RuneCountInString(m.RuneString) - if !(_len_ValTestMessage_RuneString == 4) { - return fmt.Errorf(`rune_string: value must have length 4`) - } - if !_regex_471b9980a6f67c9193bc7044ec96c4da.MatchString(m.RuneString) { - return fmt.Errorf(`rune_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.ReplaceString) && norm.NFD.IsNormalString(m.ReplaceString) { - // normalise NFD to NFC string - var normErr error - m.ReplaceString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.ReplaceString) - if normErr != nil { - return fmt.Errorf(`replace_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.ReplaceString, utf8.RuneError) { - return fmt.Errorf(`replace_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.ReplaceString) { - return fmt.Errorf(`replace_string: value must must be a valid UTF-8-encoded string`) - } - m.ReplaceString = proto.UnsafeCharReplacer.Replace(m.ReplaceString) - var _len_ValTestMessage_ReplaceString = len(m.ReplaceString) - if !(_len_ValTestMessage_ReplaceString >= 1 && _len_ValTestMessage_ReplaceString <= 130) { - return fmt.Errorf(`replace_string: value must have a length between 1 and 130`) - } - if !_regex_7f420dacf785a9f7b630597663705292.MatchString(m.ReplaceString) { - return fmt.Errorf(`replace_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.NotReplaceString) && norm.NFD.IsNormalString(m.NotReplaceString) { - // normalise NFD to NFC string - var normErr error - m.NotReplaceString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.NotReplaceString) - if normErr != nil { - return fmt.Errorf(`not_replace_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.NotReplaceString, utf8.RuneError) { - return fmt.Errorf(`not_replace_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.NotReplaceString) { - return fmt.Errorf(`not_replace_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_NotReplaceString = len(m.NotReplaceString) - if !(_len_ValTestMessage_NotReplaceString >= 1 && _len_ValTestMessage_NotReplaceString <= 130) { - return fmt.Errorf(`not_replace_string: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.NotReplaceString) { - return fmt.Errorf(`not_replace_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.AllowString) && norm.NFD.IsNormalString(m.AllowString) { - // normalise NFD to NFC string - var normErr error - m.AllowString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.AllowString) - if normErr != nil { - return fmt.Errorf(`allow_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.AllowString, utf8.RuneError) { - return fmt.Errorf(`allow_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.AllowString) { - return fmt.Errorf(`allow_string: value must must be a valid UTF-8-encoded string`) - } - m.AllowString = strings.ReplaceAll(m.AllowString, "\u0023", "\u0020") - var _len_ValTestMessage_AllowString = len(m.AllowString) - if !(_len_ValTestMessage_AllowString >= 1 && _len_ValTestMessage_AllowString <= 130) { - return fmt.Errorf(`allow_string: value must have a length between 1 and 130`) - } - if !_regex_2d8966526d95f557bf61ba41d6e869ca.MatchString(m.AllowString) { - return fmt.Errorf(`allow_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.SymbolString) && norm.NFD.IsNormalString(m.SymbolString) { - // normalise NFD to NFC string - var normErr error - m.SymbolString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.SymbolString) - if normErr != nil { - return fmt.Errorf(`symbol_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.SymbolString, utf8.RuneError) { - return fmt.Errorf(`symbol_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.SymbolString) { - return fmt.Errorf(`symbol_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_SymbolString = len(m.SymbolString) - if !(_len_ValTestMessage_SymbolString >= 1 && _len_ValTestMessage_SymbolString <= 130) { - return fmt.Errorf(`symbol_string: value must have a length between 1 and 130`) - } - if !_regex_cfc4f3f27c72b7eff33e9065de4993b8.MatchString(m.SymbolString) { - return fmt.Errorf(`symbol_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.SymbolsString) && norm.NFD.IsNormalString(m.SymbolsString) { - // normalise NFD to NFC string - var normErr error - m.SymbolsString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.SymbolsString) - if normErr != nil { - return fmt.Errorf(`symbols_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.SymbolsString, utf8.RuneError) { - return fmt.Errorf(`symbols_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.SymbolsString) { - return fmt.Errorf(`symbols_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_SymbolsString = len(m.SymbolsString) - if !(_len_ValTestMessage_SymbolsString >= 1 && _len_ValTestMessage_SymbolsString <= 130) { - return fmt.Errorf(`symbols_string: value must have a length between 1 and 130`) - } - if !_regex_c5418abde4a1025792e46f9de3e163a8.MatchString(m.SymbolsString) { - return fmt.Errorf(`symbols_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.NewlineString) && norm.NFD.IsNormalString(m.NewlineString) { - // normalise NFD to NFC string - var normErr error - m.NewlineString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.NewlineString) - if normErr != nil { - return fmt.Errorf(`newline_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.NewlineString, utf8.RuneError) { - return fmt.Errorf(`newline_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.NewlineString) { - return fmt.Errorf(`newline_string: value must must be a valid UTF-8-encoded string`) - } - m.NewlineString = strings.ReplaceAll(m.NewlineString, "\r", "") - var _len_ValTestMessage_NewlineString = len(m.NewlineString) - if !(_len_ValTestMessage_NewlineString >= 1 && _len_ValTestMessage_NewlineString <= 130) { - return fmt.Errorf(`newline_string: value must have a length between 1 and 130`) - } - if !_regex_b87d0bf989a4ccd3a8f851bcdcfadd5b.MatchString(m.NewlineString) { - return fmt.Errorf(`newline_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.InvalidEncodingString) && norm.NFD.IsNormalString(m.InvalidEncodingString) { - // normalise NFD to NFC string - var normErr error - m.InvalidEncodingString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.InvalidEncodingString) - if normErr != nil { - return fmt.Errorf(`invalid_encoding_string: value must must be normalisable to NFC`) - } - } - var _len_ValTestMessage_InvalidEncodingString = len(m.InvalidEncodingString) - if !(_len_ValTestMessage_InvalidEncodingString >= 1 && _len_ValTestMessage_InvalidEncodingString <= 130) { - return fmt.Errorf(`invalid_encoding_string: value must have a length between 1 and 130`) - } - if !_regex_721ec450fcf3c35a27a9e280064d4c50.MatchString(m.InvalidEncodingString) { - return fmt.Errorf(`invalid_encoding_string: value must only have valid characters`) - } - if m.OptString != "" { - if !norm.NFC.IsNormalString(m.OptString) && norm.NFD.IsNormalString(m.OptString) { - // normalise NFD to NFC string - var normErr error - m.OptString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.OptString) - if normErr != nil { - return fmt.Errorf(`opt_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.OptString, utf8.RuneError) { - return fmt.Errorf(`opt_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.OptString) { - return fmt.Errorf(`opt_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_OptString = len(m.OptString) - if !(_len_ValTestMessage_OptString >= 1 && _len_ValTestMessage_OptString <= 130) { - return fmt.Errorf(`opt_string: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.OptString) { - return fmt.Errorf(`opt_string: value must only have valid characters`) - } - } - if !norm.NFC.IsNormalString(m.TrimString) && norm.NFD.IsNormalString(m.TrimString) { - // normalise NFD to NFC string - var normErr error - m.TrimString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.TrimString) - if normErr != nil { - return fmt.Errorf(`trim_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.TrimString, utf8.RuneError) { - return fmt.Errorf(`trim_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.TrimString) { - return fmt.Errorf(`trim_string: value must must be a valid UTF-8-encoded string`) - } - m.TrimString = strings.TrimSpace(m.TrimString) - var _len_ValTestMessage_TrimString = len(m.TrimString) - if !(_len_ValTestMessage_TrimString >= 1 && _len_ValTestMessage_TrimString <= 130) { - return fmt.Errorf(`trim_string: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.TrimString) { - return fmt.Errorf(`trim_string: value must only have valid characters`) - } - if !norm.NFC.IsNormalString(m.AllString) && norm.NFD.IsNormalString(m.AllString) { - // normalise NFD to NFC string - var normErr error - m.AllString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.AllString) - if normErr != nil { - return fmt.Errorf(`all_string: value must must be normalisable to NFC`) - } - } - m.AllString = strings.ReplaceAll(m.AllString, "\u003E", "\u02C3") - m.AllString = proto.SymbolCharReplacer.Replace(m.AllString) - var _len_ValTestMessage_AllString = len(m.AllString) - if !(_len_ValTestMessage_AllString >= 1 && _len_ValTestMessage_AllString <= 130) { - return fmt.Errorf(`all_string: value must have a length between 1 and 130`) - } - if !_regex_d834caddc03154e20f75eb8af178a1ac.MatchString(m.AllString) { - return fmt.Errorf(`all_string: value must only have valid characters`) - } - if m.Name != "" { - if !norm.NFC.IsNormalString(m.Name) && norm.NFD.IsNormalString(m.Name) { - // normalise NFD to NFC string - var normErr error - m.Name, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Name) - if normErr != nil { - return fmt.Errorf(`name: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.Name, utf8.RuneError) { - return fmt.Errorf(`name: value must must have valid encoding`) - } else if !utf8.ValidString(m.Name) { - return fmt.Errorf(`name: value must must be a valid UTF-8-encoded string`) - } - m.Name = strings.ReplaceAll(m.Name, "\u0027", "\u2019") - m.Name = strings.ReplaceAll(m.Name, "\u002D", "\u2212") - var _len_ValTestMessage_Name = len(m.Name) - if !(_len_ValTestMessage_Name >= 1 && _len_ValTestMessage_Name <= 50) { - return fmt.Errorf(`name: value must have a length between 1 and 50`) - } - if !_regex_d4a3ad03e6e76d647c361a8c16ac9395.MatchString(m.Name) { - return fmt.Errorf(`name: value must only have valid characters`) - } - } - if m.ScTitle != "" { - if !norm.NFC.IsNormalString(m.ScTitle) && norm.NFD.IsNormalString(m.ScTitle) { - // normalise NFD to NFC string - var normErr error - m.ScTitle, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.ScTitle) - if normErr != nil { - return fmt.Errorf(`sc_title: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.ScTitle, utf8.RuneError) { - return fmt.Errorf(`sc_title: value must must have valid encoding`) - } else if !utf8.ValidString(m.ScTitle) { - return fmt.Errorf(`sc_title: value must must be a valid UTF-8-encoded string`) - } - m.ScTitle = proto.UnsafeCharReplacer.Replace(m.ScTitle) - var _len_ValTestMessage_ScTitle = len(m.ScTitle) - if !(_len_ValTestMessage_ScTitle >= 1 && _len_ValTestMessage_ScTitle <= 500) { - return fmt.Errorf(`sc_title: value must have a length between 1 and 500`) - } - if !_regex_7f420dacf785a9f7b630597663705292.MatchString(m.ScTitle) { - return fmt.Errorf(`sc_title: value must only have valid characters`) - } - } - if m.ScPermissive != "" { - if !norm.NFC.IsNormalString(m.ScPermissive) && norm.NFD.IsNormalString(m.ScPermissive) { - // normalise NFD to NFC string - var normErr error - m.ScPermissive, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.ScPermissive) - if normErr != nil { - return fmt.Errorf(`sc_permissive: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.ScPermissive, utf8.RuneError) { - return fmt.Errorf(`sc_permissive: value must must have valid encoding`) - } else if !utf8.ValidString(m.ScPermissive) { - return fmt.Errorf(`sc_permissive: value must must be a valid UTF-8-encoded string`) - } - m.ScPermissive = proto.UnsafeCharReplacer.Replace(m.ScPermissive) - m.ScPermissive = proto.SymbolCharReplacer.Replace(m.ScPermissive) - m.ScPermissive = proto.RegexPua.ReplaceAllString(m.ScPermissive, "") - var _len_ValTestMessage_ScPermissive = len(m.ScPermissive) - if !(_len_ValTestMessage_ScPermissive >= 1 && _len_ValTestMessage_ScPermissive <= 1000) { - return fmt.Errorf(`sc_permissive: value must have a length between 1 and 1000`) - } - if !_regex_b15160b6f45559b046acfd0ffd80eb84.MatchString(m.ScPermissive) { - return fmt.Errorf(`sc_permissive: value must only have valid characters`) - } - } - if m.NotSanitisePua != "" { - if !norm.NFC.IsNormalString(m.NotSanitisePua) && norm.NFD.IsNormalString(m.NotSanitisePua) { - // normalise NFD to NFC string - var normErr error - m.NotSanitisePua, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.NotSanitisePua) - if normErr != nil { - return fmt.Errorf(`not_sanitise_pua: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.NotSanitisePua, utf8.RuneError) { - return fmt.Errorf(`not_sanitise_pua: value must must have valid encoding`) - } else if !utf8.ValidString(m.NotSanitisePua) { - return fmt.Errorf(`not_sanitise_pua: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_NotSanitisePua = len(m.NotSanitisePua) - if !(_len_ValTestMessage_NotSanitisePua >= 1 && _len_ValTestMessage_NotSanitisePua <= 130) { - return fmt.Errorf(`not_sanitise_pua: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.NotSanitisePua) { - return fmt.Errorf(`not_sanitise_pua: value must only have valid characters`) - } - } - if m.SanitisePua != "" { - if !norm.NFC.IsNormalString(m.SanitisePua) && norm.NFD.IsNormalString(m.SanitisePua) { - // normalise NFD to NFC string - var normErr error - m.SanitisePua, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.SanitisePua) - if normErr != nil { - return fmt.Errorf(`sanitise_pua: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.SanitisePua, utf8.RuneError) { - return fmt.Errorf(`sanitise_pua: value must must have valid encoding`) - } else if !utf8.ValidString(m.SanitisePua) { - return fmt.Errorf(`sanitise_pua: value must must be a valid UTF-8-encoded string`) - } - m.SanitisePua = proto.RegexPua.ReplaceAllString(m.SanitisePua, "") - var _len_ValTestMessage_SanitisePua = len(m.SanitisePua) - if !(_len_ValTestMessage_SanitisePua >= 1 && _len_ValTestMessage_SanitisePua <= 130) { - return fmt.Errorf(`sanitise_pua: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.SanitisePua) { - return fmt.Errorf(`sanitise_pua: value must only have valid characters`) - } - } - if m.SanitiseLength != "" { - if !norm.NFC.IsNormalString(m.SanitiseLength) && norm.NFD.IsNormalString(m.SanitiseLength) { - // normalise NFD to NFC string - var normErr error - m.SanitiseLength, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.SanitiseLength) - if normErr != nil { - return fmt.Errorf(`sanitise_length: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.SanitiseLength, utf8.RuneError) { - return fmt.Errorf(`sanitise_length: value must must have valid encoding`) - } else if !utf8.ValidString(m.SanitiseLength) { - return fmt.Errorf(`sanitise_length: value must must be a valid UTF-8-encoded string`) - } - m.SanitiseLength = proto.RegexPua.ReplaceAllString(m.SanitiseLength, "") - var _len_ValTestMessage_SanitiseLength = len(m.SanitiseLength) - if !(_len_ValTestMessage_SanitiseLength == 2) { - return fmt.Errorf(`sanitise_length: value must have length 2`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.SanitiseLength) { - return fmt.Errorf(`sanitise_length: value must only have valid characters`) - } - } - if m.OptionalString != nil { - if !norm.NFC.IsNormalString(*m.OptionalString) && norm.NFD.IsNormalString(*m.OptionalString) { - // normalise NFD to NFC string - var normErr error - *m.OptionalString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), *m.OptionalString) - if normErr != nil { - return fmt.Errorf(`optional_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(*m.OptionalString, utf8.RuneError) { - return fmt.Errorf(`optional_string: value must must have valid encoding`) - } else if !utf8.ValidString(*m.OptionalString) { - return fmt.Errorf(`optional_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_OptionalString = len(*m.OptionalString) - if !(_len_ValTestMessage_OptionalString >= 1 && _len_ValTestMessage_OptionalString <= 130) { - return fmt.Errorf(`optional_string: value must have a length between 1 and 130`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(*m.OptionalString) { - return fmt.Errorf(`optional_string: value must only have valid characters`) - } - } - if x, ok := m.ContactOneof.(*ValTestMessage_Phone); ok { - if !norm.NFC.IsNormalString(x.Phone) && norm.NFD.IsNormalString(x.Phone) { - // normalise NFD to NFC string - var normErr error - x.Phone, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), x.Phone) - if normErr != nil { - return fmt.Errorf(`phone: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(x.Phone, utf8.RuneError) { - return fmt.Errorf(`phone: value must must have valid encoding`) - } else if !utf8.ValidString(x.Phone) { - return fmt.Errorf(`phone: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_Phone = len(x.Phone) - if !(_len_ValTestMessage_Phone == 11) { - return fmt.Errorf(`phone: value must have length 11`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(x.Phone) { - return fmt.Errorf(`phone: value must only have valid characters`) - } - } - if m.MsgRequired == nil { - return fmt.Errorf("field msg_required is required") - } - if m.MsgRequired != nil { - if v, ok := interface{}(m.MsgRequired).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("msg_required", err) - } - } - } - if m.NestedMessage != nil { - if v, ok := interface{}(m.NestedMessage).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("nested_message", err) - } - } - } - // Validation of proto3 map<> fields is unsupported. - if !(len(m.ContactsWithLengthConstraint) >= 1) { - return fmt.Errorf(`contacts_with_length_constraint: length must be greater than or equal to 1`) - } - if !(len(m.ContactsWithLengthConstraint) <= 10) { - return fmt.Errorf(`contacts_with_length_constraint: length must be lesser than or equal to 10`) - } - if len(m.ContactsWithLengthConstraint) > 0 { - for _, item := range m.ContactsWithLengthConstraint { - if item != nil { - if v, ok := interface{}(item).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("contacts_with_length_constraint", err) - } - } - } - } - } - if len(m.ContactsWithoutLengthConstraint) > 0 { - for _, item := range m.ContactsWithoutLengthConstraint { - if item != nil { - if v, ok := interface{}(item).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("contacts_without_length_constraint", err) - } - } - } - } - } - if !proto.IsUUIDv4(m.S12Id) { - isValidId := false - if !isValidId && proto.IsS12ID(m.S12Id, false) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`s12_id: value must be parsable as UUIDv4 or S12 ID`) - } - } - if m.InnerS12Id != nil { - if v, ok := interface{}(m.InnerS12Id).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("inner_s12_id", err) - } - } - } - if m.AllId != "" { - if !proto.IsUUIDv4(m.AllId) { - isValidId := false - if proto.IsLegacyID(m.AllId, false) { - isValidId = true - } - if !isValidId && proto.IsS12ID(m.AllId, false) { - isValidId = true - } - if !isValidId && proto.IsLongPrefixedLegacyID(m.AllId) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`all_id: value must be parsable as UUIDv4 or legacy ID or S12 ID`) - } - } - } - _schemes_ValTestMessage_Url := []string{"https"} - if _, err := proto.IsValidURL(m.Url, _schemes_ValTestMessage_Url, false); err != nil { - return fmt.Errorf(`url: value must be parsable as a URL: %v`, err) - } - if m.UrlAllOpts != "" { - _schemes_ValTestMessage_UrlAllOpts := []string{"ftp", "ftps", "http"} - if _, err := proto.IsValidURL(m.UrlAllOpts, _schemes_ValTestMessage_UrlAllOpts, true); err != nil { - return fmt.Errorf(`url_all_opts: value must be parsable as a URL: %v`, err) - } - } - if m.Timezone == "" { - return fmt.Errorf("field timezone is required") - } - if tz, err := time.LoadLocation(m.Timezone); err != nil || tz == nil { - return fmt.Errorf(`timezone: value must be a valid IANA TZ database value`) - } - if m.TimezoneOptional != "" { - if tz, err := time.LoadLocation(m.TimezoneOptional); err != nil || tz == nil { - return fmt.Errorf(`timezone_optional: value must be a valid IANA TZ database value`) - } - } - if m.LongString != "" { - if !norm.NFC.IsNormalString(m.LongString) && norm.NFD.IsNormalString(m.LongString) { - // normalise NFD to NFC string - var normErr error - m.LongString, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.LongString) - if normErr != nil { - return fmt.Errorf(`long_string: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.LongString, utf8.RuneError) { - return fmt.Errorf(`long_string: value must must have valid encoding`) - } else if !utf8.ValidString(m.LongString) { - return fmt.Errorf(`long_string: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_LongString = len(m.LongString) - if !(_len_ValTestMessage_LongString >= 1 && _len_ValTestMessage_LongString <= 30000) { - return fmt.Errorf(`long_string: value must have a length between 1 and 30000`) - } - if !_regex_1bb1e0a2437db38577f49b4f31ccfca2.MatchString(m.LongString) { - return fmt.Errorf(`long_string: value must only have valid characters`) - } - } - return nil -} - -func (m *ValTestMessage_NestedMessage) Validate() error { - if !norm.NFC.IsNormalString(m.Val) && norm.NFD.IsNormalString(m.Val) { - // normalise NFD to NFC string - var normErr error - m.Val, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Val) - if normErr != nil { - return fmt.Errorf(`val: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.Val, utf8.RuneError) { - return fmt.Errorf(`val: value must must have valid encoding`) - } else if !utf8.ValidString(m.Val) { - return fmt.Errorf(`val: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_NestedMessage_Val = len(m.Val) - if !(_len_ValTestMessage_NestedMessage_Val >= 1 && _len_ValTestMessage_NestedMessage_Val <= 100) { - return fmt.Errorf(`val: value must have a length between 1 and 100`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.Val) { - return fmt.Errorf(`val: value must only have valid characters`) - } - if !proto.IsValidEmail(m.NestedEmail, false) { - return fmt.Errorf(`nested_email: value must be parsable as an email address`) - } - if !(len(m.MemberEmails) >= 2) { - return fmt.Errorf(`member_emails: length must be greater than or equal to 2`) - } - if !(len(m.MemberEmails) <= 5) { - return fmt.Errorf(`member_emails: length must be lesser than or equal to 5`) - } - for _, item := range m.MemberEmails { - if !proto.IsValidEmail(item, false) { - return fmt.Errorf(`member_emails: value must be parsable as an email address`) - } - } - return nil -} - -func (m *ValTestMessage_NestedMessage_InnerNestedMessage) Validate() error { - if !norm.NFC.IsNormalString(m.InnerVal) && norm.NFD.IsNormalString(m.InnerVal) { - // normalise NFD to NFC string - var normErr error - m.InnerVal, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.InnerVal) - if normErr != nil { - return fmt.Errorf(`inner_val: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.InnerVal, utf8.RuneError) { - return fmt.Errorf(`inner_val: value must must have valid encoding`) - } else if !utf8.ValidString(m.InnerVal) { - return fmt.Errorf(`inner_val: value must must be a valid UTF-8-encoded string`) - } - var _len_ValTestMessage_NestedMessage_InnerNestedMessage_InnerVal = len(m.InnerVal) - if !(_len_ValTestMessage_NestedMessage_InnerNestedMessage_InnerVal >= 1 && _len_ValTestMessage_NestedMessage_InnerNestedMessage_InnerVal <= 100) { - return fmt.Errorf(`inner_val: value must have a length between 1 and 100`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.InnerVal) { - return fmt.Errorf(`inner_val: value must only have valid characters`) - } - return nil -} - -func (m *ValTestMessage_Contact) Validate() error { - if m.Phone != "" { - } - if !proto.IsValidEmail(m.Email, false) { - return fmt.Errorf(`email: value must be parsable as an email address`) - } - return nil -} - -func (m *LogOnlyValidationMessage) Validate() error { - if !proto.IsUUID(m.ImageId) { - return fmt.Errorf(`image_id: value must be parsable as a UUID`) - } - if !proto.IsUUIDv4(m.ImageId) { - isValidId := false - if proto.IsLegacyID(m.ImageId, false) { - isValidId = true - } - if !isValidId && proto.IsS12ID(m.ImageId, false) { - isValidId = true - } - if !isValidId && proto.IsLongPrefixedLegacyID(m.ImageId) { - isValidId = true - } - if !isValidId { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "image_id", "be parsable as UUIDv4 or legacy ID or S12 ID", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.ImageId), 50))) - } - } - if !proto.IsUUIDv4(m.InspectionId) { - isValidId := false - if proto.IsLegacyID(m.InspectionId, false) { - isValidId = true - } - if !isValidId && proto.IsS12ID(m.InspectionId, false) { - isValidId = true - } - if !isValidId && proto.IsLongPrefixedLegacyID(m.InspectionId) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`inspection_id: value must be parsable as UUIDv4 or legacy ID or S12 ID`) - } - } - if !proto.IsUUIDv4(m.OwnerId) { - isValidId := false - if proto.IsLegacyID(m.OwnerId, false) { - isValidId = true - } - if !isValidId && proto.IsS12ID(m.OwnerId, false) { - isValidId = true - } - if !isValidId && proto.IsLongPrefixedLegacyID(m.OwnerId) { - isValidId = true - } - if !isValidId { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "owner_id", "be parsable as UUIDv4 or legacy ID or S12 ID", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.OwnerId), 50))) - } - } - if m.Title != "" { - if !norm.NFC.IsNormalString(m.Title) && norm.NFD.IsNormalString(m.Title) { - // normalise NFD to NFC string - var normErr error - m.Title, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Title) - if normErr != nil { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "title", "must be normalisable to NFC", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Title), 50))) - } - } - if strings.ContainsRune(m.Title, utf8.RuneError) { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "title", "must have valid encoding", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Title), 50))) - } else if !utf8.ValidString(m.Title) { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "title", "must be a valid UTF-8-encoded string", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Title), 50))) - } - m.Title = strings.ReplaceAll(m.Title, "\r", "") - m.Title = proto.RegexPua.ReplaceAllString(m.Title, "") - var _len_LogOnlyValidationMessage_Title = len(m.Title) - if !(_len_LogOnlyValidationMessage_Title >= 1 && _len_LogOnlyValidationMessage_Title <= 10) { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "title", "have a length between 1 and 10", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Title), 50))) - } - if !_regex_7d80f76b8ba61834c54bce3793157935.MatchString(m.Title) { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "title", "only have valid characters", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Title), 50))) - } - } - if !norm.NFC.IsNormalString(m.Name) && norm.NFD.IsNormalString(m.Name) { - // normalise NFD to NFC string - var normErr error - m.Name, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.Name) - if normErr != nil { - return fmt.Errorf(`name: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.Name, utf8.RuneError) { - return fmt.Errorf(`name: value must must have valid encoding`) - } else if !utf8.ValidString(m.Name) { - return fmt.Errorf(`name: value must must be a valid UTF-8-encoded string`) - } - m.Name = proto.RegexPua.ReplaceAllString(m.Name, "") - var _len_LogOnlyValidationMessage_Name = len(m.Name) - if !(_len_LogOnlyValidationMessage_Name >= 1 && _len_LogOnlyValidationMessage_Name <= 5) { - return fmt.Errorf(`name: value must have a length between 1 and 5`) - } - if !_regex_b3f79e2470927c095fff6ea841e2a650.MatchString(m.Name) { - return fmt.Errorf(`name: value must only have valid characters`) - } - if m.Latitude != 0 { - // Range check lower bounds - if m.Latitude < -90 { - return fmt.Errorf(`latitude: value must be greater than or equal to -90`) - } - // Range check upper bounds - if m.Latitude > 90 { - return fmt.Errorf(`latitude: value must be less than or equal to 90`) - } - } - if m.Longitude != 0 { - // Range check lower bounds - if m.Longitude < -180 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "longitude", "be greater than or equal to -180", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Longitude), 50))) - } - // Range check upper bounds - if m.Longitude > 180 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "longitude", "be less than or equal to 180", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Longitude), 50))) - } - } - if m.Accuracy != 0 { - // Range check lower bounds - if m.Accuracy < 0 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "accuracy", "be greater than or equal to 0", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Accuracy), 50))) - } - // Range check upper bounds - if m.Accuracy > 10000 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "accuracy", "be less than or equal to 10000", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Accuracy), 50))) - } - } - if m.Answer != "" { - var length = utf8.RuneCountInString(m.Answer) - if length > 40 || length < 0 { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "answer", "have a length between 0 and 40", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Answer), 50))) - } - } - if m.Note != "" { - var length = utf8.RuneCountInString(m.Note) - if length > 40 || length < 5 { - return fmt.Errorf(`note: value must have a length between 5 and 40`) - } - } - return nil -} - -const _regex_val_LowercaseValidationMessage_RevId = `^((\d)+-([0-9a-f]){32})?$` - -var _regex_LowercaseValidationMessage_RevId = regexp.MustCompile(_regex_val_LowercaseValidationMessage_RevId) - -func (m *LowercaseValidationMessage) Validate() error { - if !proto.IsUUIDv4(m.Uuidv4) { - isValidId := false - if !isValidId { - return fmt.Errorf(`uuidv4: value must be parsable as UUIDv4`) - } - } - if !proto.IsUUIDv4(m.Uuidv4LogOnly) { - isValidId := false - if !isValidId { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "uuidv4_log_only", "be parsable as UUIDv4", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.Uuidv4LogOnly), 50))) - } - } - if !proto.IsUUIDv4(m.S12Id) { - isValidId := false - if !isValidId && proto.IsS12ID(m.S12Id, true) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`s12id: value must be parsable as UUIDv4 or S12 ID`) - } - } - if !proto.IsUUIDv4(m.S12IdLogOnly) { - isValidId := false - if !isValidId && proto.IsS12ID(m.S12IdLogOnly, true) { - isValidId = true - } - if !isValidId { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "s12id_log_only", "be parsable as UUIDv4 or S12 ID", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.S12IdLogOnly), 50))) - } - } - if !proto.IsUUIDv4(m.Legacy) { - isValidId := false - if proto.IsLegacyID(m.Legacy, true) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`legacy: value must be parsable as UUIDv4 or legacy ID`) - } - } - if !proto.IsUUIDv4(m.LegacyLogOnly) { - isValidId := false - if proto.IsLegacyID(m.LegacyLogOnly, true) { - isValidId = true - } - if !isValidId { - fmt.Printf("[log-only] %s: value must be %s: Base64Encoded input: %s\n", "legacy_log_only", "be parsable as UUIDv4 or legacy ID", proto.Base64Encode(proto.FirstCharactersFromString(fmt.Sprintf("%v", m.LegacyLogOnly), 50))) - } - } - if !_regex_LowercaseValidationMessage_RevId.MatchString(m.RevId) { - return fmt.Errorf(`rev_id: value must be a string conforming to predefined pattern`) - } - if !proto.IsUUIDv4(m.QuestionId) { - isValidId := false - if proto.IsLegacyID(m.QuestionId, false) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`question_id: value must be parsable as UUIDv4 or legacy ID`) - } - } - if m.ItemId != "" { - if !proto.IsUUIDv4(m.ItemId) { - isValidId := false - if !isValidId && proto.IsS12ID(m.ItemId, false) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`item_id: value must be parsable as UUIDv4 or S12 ID`) - } - } - } - return nil -} - -func (m *OuterMessageUsingNestedMessage) Validate() error { - if m.SomeMessage != nil { - if v, ok := interface{}(m.SomeMessage).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("some_message", err) - } - } - } - return nil -} - -func (m *InnerMessage) Validate() error { - if !proto.IsUUID(m.Id) { - return fmt.Errorf(`id: value must be parsable as a UUID`) - } - return nil -} - -func (m *InnerMessageWithLegacyId) Validate() error { - if !proto.IsUUIDv4(m.Id) { - isValidId := false - if proto.IsLegacyID(m.Id, false) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`id: value must be parsable as UUIDv4 or legacy ID`) - } - } - return nil -} - -func (m *InnerMessageWithS12Id) Validate() error { - if !proto.IsUUIDv4(m.Id) { - isValidId := false - if !isValidId && proto.IsS12ID(m.Id, false) { - isValidId = true - } - if !isValidId { - return fmt.Errorf(`id: value must be parsable as UUIDv4 or S12 ID`) - } - } - return nil -} - -func (m *NestedLevel3Message) Validate() error { - if !norm.NFC.IsNormalString(m.OrgId5) && norm.NFD.IsNormalString(m.OrgId5) { - // normalise NFD to NFC string - var normErr error - m.OrgId5, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.OrgId5) - if normErr != nil { - return fmt.Errorf(`org_id5: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.OrgId5, utf8.RuneError) { - return fmt.Errorf(`org_id5: value must must have valid encoding`) - } else if !utf8.ValidString(m.OrgId5) { - return fmt.Errorf(`org_id5: value must must be a valid UTF-8-encoded string`) - } - var _len_NestedLevel3Message_OrgId5 = len(m.OrgId5) - if !(_len_NestedLevel3Message_OrgId5 == 5) { - return fmt.Errorf(`org_id5: value must have length 5`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.OrgId5) { - return fmt.Errorf(`org_id5: value must only have valid characters`) - } - return nil -} - -func (m *NestedLevel2Message) Validate() error { - if !norm.NFC.IsNormalString(m.OrgId4) && norm.NFD.IsNormalString(m.OrgId4) { - // normalise NFD to NFC string - var normErr error - m.OrgId4, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.OrgId4) - if normErr != nil { - return fmt.Errorf(`org_id4: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.OrgId4, utf8.RuneError) { - return fmt.Errorf(`org_id4: value must must have valid encoding`) - } else if !utf8.ValidString(m.OrgId4) { - return fmt.Errorf(`org_id4: value must must be a valid UTF-8-encoded string`) - } - var _len_NestedLevel2Message_OrgId4 = len(m.OrgId4) - if !(_len_NestedLevel2Message_OrgId4 == 4) { - return fmt.Errorf(`org_id4: value must have length 4`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.OrgId4) { - return fmt.Errorf(`org_id4: value must only have valid characters`) - } - if m.OrgNested != nil { - if v, ok := interface{}(m.OrgNested).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("org_nested", err) - } - } - } - return nil -} - -func (m *NestedLevel1Message) Validate() error { - if !norm.NFC.IsNormalString(m.OrgId3) && norm.NFD.IsNormalString(m.OrgId3) { - // normalise NFD to NFC string - var normErr error - m.OrgId3, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.OrgId3) - if normErr != nil { - return fmt.Errorf(`org_id3: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.OrgId3, utf8.RuneError) { - return fmt.Errorf(`org_id3: value must must have valid encoding`) - } else if !utf8.ValidString(m.OrgId3) { - return fmt.Errorf(`org_id3: value must must be a valid UTF-8-encoded string`) - } - var _len_NestedLevel1Message_OrgId3 = len(m.OrgId3) - if !(_len_NestedLevel1Message_OrgId3 == 3) { - return fmt.Errorf(`org_id3: value must have length 3`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.OrgId3) { - return fmt.Errorf(`org_id3: value must only have valid characters`) - } - if m.OrgNested != nil { - if v, ok := interface{}(m.OrgNested).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("org_nested", err) - } - } - } - return nil -} - -func (m *MyReqMessage) Validate() error { - if !norm.NFC.IsNormalString(m.UserId) && norm.NFD.IsNormalString(m.UserId) { - // normalise NFD to NFC string - var normErr error - m.UserId, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.UserId) - if normErr != nil { - return fmt.Errorf(`user_id: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.UserId, utf8.RuneError) { - return fmt.Errorf(`user_id: value must must have valid encoding`) - } else if !utf8.ValidString(m.UserId) { - return fmt.Errorf(`user_id: value must must be a valid UTF-8-encoded string`) - } - var _len_MyReqMessage_UserId = len(m.UserId) - if !(_len_MyReqMessage_UserId == 2) { - return fmt.Errorf(`user_id: value must have length 2`) - } - if !_regex_d4db71516b8749dc594e5bf604c6a110.MatchString(m.UserId) { - return fmt.Errorf(`user_id: value must only have valid characters`) - } - if m.OrgNested != nil { - if v, ok := interface{}(m.OrgNested).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("org_nested", err) - } - } - } - return nil -} - -func (m *ScimEmail) Validate() error { - if !proto.IsValidEmail(m.Value, false) { - return fmt.Errorf(`value: value must be parsable as an email address`) - } - return nil -} - -func (m *ScimUser) Validate() error { - if len(m.Emails) > 0 { - for _, item := range m.Emails { - if item != nil { - if v, ok := interface{}(item).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("emails", err) - } - } - } - } - } - return nil -} - -func (m *MyMessageWithEnum) Validate() error { - if int(m.Enum) == 0 { - return fmt.Errorf("field enum must be specified and a non-zero value") - } - for _, item := range m.Enums { - if int(item) == 0 { - return fmt.Errorf("field enums must be specified and a non-zero value") - } - } - return nil -} - -func (m *MyMessageWithRepeatedEnum) Validate() error { - for _, item := range m.Enums { - if int(item) == 0 { - return fmt.Errorf("field enums must be specified and a non-zero value") - } - } - return nil -} - -func (m *MyMessageWithRepeatedField) Validate() error { - if !(len(m.MyInt) <= 5) { - return fmt.Errorf(`my_int: length must be lesser than or equal to 5`) - } - return nil -} - -func (m *MyOneOfMsg) Validate() error { - if x, ok := m.MyField.(*MyOneOfMsg_MyFirstField); ok { - if x.MyFirstField != nil { - if v, ok := interface{}(x.MyFirstField).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("my_first_field", err) - } - } - } - } - if x, ok := m.MyField.(*MyOneOfMsg_MySecondField); ok { - if x.MySecondField != nil { - if v, ok := interface{}(x.MySecondField).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("my_second_field", err) - } - } - } - } - if x, ok := m.MyField.(*MyOneOfMsg_MyThirdField); ok { - if !(len(x.MyThirdField) >= 1) { - return fmt.Errorf(`my_third_field: value must have length greater than or equal to 1`) - } - } - return nil -} - -func (m *MyOneOfMsg_FirstType) Validate() error { - if !(m.Value > 1) { - return fmt.Errorf(`value: value must be greater than 1`) - } - return nil -} - -func (m *MyOneOfMsg_SecondType) Validate() error { - if !(m.Value > 2) { - return fmt.Errorf(`value: value must be greater than 2`) - } - return nil -} - -func (m *NumberMessage) Validate() error { - // This statement checks for NaN value without using Math package - if m.NanDisallowed != m.NanDisallowed { - return fmt.Errorf(`nan_disallowed: value must not be NaN`) - } - if m.OptionalNoNanValue != 0 { - // This statement checks for NaN value without using Math package - if m.OptionalNoNanValue != m.OptionalNoNanValue { - return fmt.Errorf(`optional_no_nan_value: value must not be NaN`) - } - } - if m.OptionalOnly != 0 { - } - if m.RangeBasic != 0 { - // Range check lower bounds - if m.RangeBasic < 1 { - return fmt.Errorf(`range_basic: value must be greater than or equal to 1`) - } - // Range check upper bounds - if m.RangeBasic > 10 { - return fmt.Errorf(`range_basic: value must be less than or equal to 10`) - } - } - if m.RangeLow != 0 { - // Range check lower bounds - if m.RangeLow < 1 { - return fmt.Errorf(`range_low: value must be greater than or equal to 1`) - } - } - if m.RangeHigh != 0 { - // Range check upper bounds - if m.RangeHigh > 10 { - return fmt.Errorf(`range_high: value must be less than or equal to 10`) - } - } - if m.RangeNovalues != 0 { - } - // Range check lower bounds - if m.RangeNotOptional < 1 { - return fmt.Errorf(`range_not_optional: value must be greater than or equal to 1`) - } - // Range check upper bounds - if m.RangeNotOptional > 10 { - return fmt.Errorf(`range_not_optional: value must be less than or equal to 10`) - } - // Range check lower bounds - if m.IntTest < 1 { - return fmt.Errorf(`int_test: value must be greater than or equal to 1`) - } - // Range check upper bounds - if m.IntTest > 99 { - return fmt.Errorf(`int_test: value must be less than or equal to 99`) - } - if m.Int64Test != 0 { - // Range check lower bounds - if m.Int64Test < -100 { - return fmt.Errorf(`int64_test: value must be greater than or equal to -100`) - } - // Range check upper bounds - if m.Int64Test > 100 { - return fmt.Errorf(`int64_test: value must be less than or equal to 100`) - } - } - if m.UintTest != 0 { - // Range check lower bounds - if m.UintTest < 5 { - return fmt.Errorf(`uint_test: value must be greater than or equal to 5`) - } - // Range check upper bounds - if m.UintTest > 99 { - return fmt.Errorf(`uint_test: value must be less than or equal to 99`) - } - } - for _, item := range m.RepeatedInt { - if item != 0 { - // Range check lower bounds - if item < 10 { - return fmt.Errorf(`repeated_int: value must be greater than or equal to 10`) - } - // Range check upper bounds - if item > 20 { - return fmt.Errorf(`repeated_int: value must be less than or equal to 20`) - } - } - } - if m.NestedNumber != nil { - if v, ok := interface{}(m.NestedNumber).(proto.Validator); ok { - if err := v.Validate(); err != nil { - return proto.FieldError("nested_number", err) - } - } - } - return nil -} - -func (m *NumberMessage_NestedNumber) Validate() error { - if m.Value != 0 { - // Range check upper bounds - if m.Value > 100 { - return fmt.Errorf(`value: value must be less than or equal to 100`) - } - } - return nil -} - -func (m *NonUrlMessage) Validate() error { - if m.RejectUrlTest != "" { - if !norm.NFC.IsNormalString(m.RejectUrlTest) && norm.NFD.IsNormalString(m.RejectUrlTest) { - // normalise NFD to NFC string - var normErr error - m.RejectUrlTest, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.RejectUrlTest) - if normErr != nil { - return fmt.Errorf(`reject_url_test: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.RejectUrlTest, utf8.RuneError) { - return fmt.Errorf(`reject_url_test: value must must have valid encoding`) - } else if !utf8.ValidString(m.RejectUrlTest) { - return fmt.Errorf(`reject_url_test: value must must be a valid UTF-8-encoded string`) - } - if proto.RejectURLMatcher.MatchString(m.RejectUrlTest) { - return fmt.Errorf(`reject_url_test: value must not contain a URL`) - } - var _len_NonUrlMessage_RejectUrlTest = len(m.RejectUrlTest) - if !(_len_NonUrlMessage_RejectUrlTest >= 1 && _len_NonUrlMessage_RejectUrlTest <= 130) { - return fmt.Errorf(`reject_url_test: value must have a length between 1 and 130`) - } - if !_regex_1bb1e0a2437db38577f49b4f31ccfca2.MatchString(m.RejectUrlTest) { - return fmt.Errorf(`reject_url_test: value must only have valid characters`) - } - } - if m.BreakPartialUrlTest != "" { - if !norm.NFC.IsNormalString(m.BreakPartialUrlTest) && norm.NFD.IsNormalString(m.BreakPartialUrlTest) { - // normalise NFD to NFC string - var normErr error - m.BreakPartialUrlTest, _, normErr = transform.String(transform.Chain(norm.NFD, norm.NFC), m.BreakPartialUrlTest) - if normErr != nil { - return fmt.Errorf(`break_partial_url_test: value must must be normalisable to NFC`) - } - } - if strings.ContainsRune(m.BreakPartialUrlTest, utf8.RuneError) { - return fmt.Errorf(`break_partial_url_test: value must must have valid encoding`) - } else if !utf8.ValidString(m.BreakPartialUrlTest) { - return fmt.Errorf(`break_partial_url_test: value must must be a valid UTF-8-encoded string`) - } - m.BreakPartialUrlTest = proto.BreakURLMatcher.ReplaceAllString(m.BreakPartialUrlTest, ". $1") - var _len_NonUrlMessage_BreakPartialUrlTest = len(m.BreakPartialUrlTest) - if !(_len_NonUrlMessage_BreakPartialUrlTest >= 1 && _len_NonUrlMessage_BreakPartialUrlTest <= 130) { - return fmt.Errorf(`break_partial_url_test: value must have a length between 1 and 130`) - } - if !_regex_1bb1e0a2437db38577f49b4f31ccfca2.MatchString(m.BreakPartialUrlTest) { - return fmt.Errorf(`break_partial_url_test: value must only have valid characters`) - } - } - return nil -} diff --git a/protobuf/protoc-gen-govalidator/valtest/valtest.validator_regex.pb.go b/protobuf/protoc-gen-govalidator/valtest/valtest.validator_regex.pb.go deleted file mode 100644 index d052f2b..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/valtest.validator_regex.pb.go +++ /dev/null @@ -1,107 +0,0 @@ -// Code generated by protoc-gen-govalidator. DO NOT EDIT. -// versions: -// protoc-gen-govalidator v2.7.0 -// protoc v5.28.2 -// source: valtest.proto - -package valtest - -import ( - _ "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" - regexp "regexp" -) - -// Pattern for ValTestMessage_Description -const _regex_val_d4db71516b8749dc594e5bf604c6a110 = `^[\pL\pN\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{2013}]+$` - -var _regex_d4db71516b8749dc594e5bf604c6a110 = regexp.MustCompile(_regex_val_d4db71516b8749dc594e5bf604c6a110) - -// Pattern for ValTestMessage_Password -const _regex_val_51116fcfa477f1949f7055f2f1bf33db = `^[\pL\pN\x{0020}\x{0021}\x{0022}\x{0023}\x{0024}\x{0025}\x{0026}\x{0027}\x{0028}\x{0029}\x{002A}\x{002B}\x{002C}\x{002D}\x{002E}\x{002F}\x{003A}\x{003B}\x{003C}\x{003D}\x{003E}\x{003F}\x{0040}\x{005B}\x{005C}\x{005D}\x{005E}\x{005F}\x{0060}\x{007B}\x{007C}\x{007D}\x{007E}\x{00BF}\x{2013}]+$` - -var _regex_51116fcfa477f1949f7055f2f1bf33db = regexp.MustCompile(_regex_val_51116fcfa477f1949f7055f2f1bf33db) - -// ValTestMessage_Title is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_FixedString is using regex d4db71516b8749dc594e5bf604c6a110 -// Pattern for ValTestMessage_RuneString -const _regex_val_471b9980a6f67c9193bc7044ec96c4da = `^[\pL\pN\pSo\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{200D}\x{2013}]+$` - -var _regex_471b9980a6f67c9193bc7044ec96c4da = regexp.MustCompile(_regex_val_471b9980a6f67c9193bc7044ec96c4da) - -// Pattern for ValTestMessage_ReplaceString -const _regex_val_7f420dacf785a9f7b630597663705292 = `^[\pL\pN\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{02C2}\x{02C3}\x{037E}\x{2013}\x{2019}\x{201D}\x{2052}\x{2212}\x{2215}\x{2217}\x{2E40}\x{FF01}\x{FF0B}\x{FF3C}\x{FFE8}]+$` - -var _regex_7f420dacf785a9f7b630597663705292 = regexp.MustCompile(_regex_val_7f420dacf785a9f7b630597663705292) - -// ValTestMessage_NotReplaceString is using regex d4db71516b8749dc594e5bf604c6a110 -// Pattern for ValTestMessage_AllowString -const _regex_val_2d8966526d95f557bf61ba41d6e869ca = `^[\pL\pN\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{007E}\x{00BF}\x{2013}]+$` - -var _regex_2d8966526d95f557bf61ba41d6e869ca = regexp.MustCompile(_regex_val_2d8966526d95f557bf61ba41d6e869ca) - -// Pattern for ValTestMessage_SymbolString -const _regex_val_cfc4f3f27c72b7eff33e9065de4993b8 = `^[\pL\pN\pSc\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{2013}]+$` - -var _regex_cfc4f3f27c72b7eff33e9065de4993b8 = regexp.MustCompile(_regex_val_cfc4f3f27c72b7eff33e9065de4993b8) - -// Pattern for ValTestMessage_SymbolsString -const _regex_val_c5418abde4a1025792e46f9de3e163a8 = `^[\pL\pM\pN\pSo\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{200D}\x{2013}]+$` - -var _regex_c5418abde4a1025792e46f9de3e163a8 = regexp.MustCompile(_regex_val_c5418abde4a1025792e46f9de3e163a8) - -// Pattern for ValTestMessage_NewlineString -const _regex_val_b87d0bf989a4ccd3a8f851bcdcfadd5b = `^[\pL\pN\x{000A}\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{2013}]+$` - -var _regex_b87d0bf989a4ccd3a8f851bcdcfadd5b = regexp.MustCompile(_regex_val_b87d0bf989a4ccd3a8f851bcdcfadd5b) - -// Pattern for ValTestMessage_InvalidEncodingString -const _regex_val_721ec450fcf3c35a27a9e280064d4c50 = `^[\pL\pN\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{2013}\x{FFFD}]+$` - -var _regex_721ec450fcf3c35a27a9e280064d4c50 = regexp.MustCompile(_regex_val_721ec450fcf3c35a27a9e280064d4c50) - -// ValTestMessage_OptString is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_TrimString is using regex d4db71516b8749dc594e5bf604c6a110 -// Pattern for ValTestMessage_AllString -const _regex_val_d834caddc03154e20f75eb8af178a1ac = `^[\pL\pM\pN\pPo\pSc\pSk\pSm\pSo\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{007E}\x{00BF}\x{02C3}\x{104B}\x{200D}\x{2013}\x{2018}\x{2019}\x{201C}\x{201D}\x{2022}\x{FFFD}}]+$` - -var _regex_d834caddc03154e20f75eb8af178a1ac = regexp.MustCompile(_regex_val_d834caddc03154e20f75eb8af178a1ac) - -// Pattern for ValTestMessage_Name -const _regex_val_d4a3ad03e6e76d647c361a8c16ac9395 = `^[\pL\pN\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{00BF}\x{2013}\x{2019}\x{2212}]+$` - -var _regex_d4a3ad03e6e76d647c361a8c16ac9395 = regexp.MustCompile(_regex_val_d4a3ad03e6e76d647c361a8c16ac9395) - -// ValTestMessage_ScTitle is using regex 7f420dacf785a9f7b630597663705292 -// Pattern for ValTestMessage_ScPermissive -const _regex_val_b15160b6f45559b046acfd0ffd80eb84 = `^[\pL\pM\pN\pPo\pSc\pSk\pSm\pSo\x{0020}\x{0028}\x{0029}\x{002C}\x{002E}\x{003A}\x{003F}\x{0040}\x{005B}\x{005D}\x{005F}\x{007E}\x{00BF}\x{02C2}\x{02C3}\x{037E}\x{104B}\x{200D}\x{2013}\x{2018}\x{2019}\x{201C}\x{201D}\x{2022}\x{2052}\x{2212}\x{2215}\x{2217}\x{2E40}\x{FF01}\x{FF0B}\x{FF3C}\x{FFE8}}]+$` - -var _regex_b15160b6f45559b046acfd0ffd80eb84 = regexp.MustCompile(_regex_val_b15160b6f45559b046acfd0ffd80eb84) - -// ValTestMessage_NotSanitisePua is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_SanitisePua is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_SanitiseLength is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_OptionalString is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_Phone is using regex d4db71516b8749dc594e5bf604c6a110 -// Pattern for ValTestMessage_LongString -const _regex_val_1bb1e0a2437db38577f49b4f31ccfca2 = `^[\pL\pN\x{0020}\x{0021}\x{0022}\x{0023}\x{0025}\x{0026}\x{0027}\x{0028}\x{0029}\x{002A}\x{002C}\x{002D}\x{002E}\x{002F}\x{003A}\x{003F}\x{0040}\x{005B}\x{005C}\x{005D}\x{005F}\x{00BF}\x{2013}]+$` - -var _regex_1bb1e0a2437db38577f49b4f31ccfca2 = regexp.MustCompile(_regex_val_1bb1e0a2437db38577f49b4f31ccfca2) - -// ValTestMessage_NestedMessage_Val is using regex d4db71516b8749dc594e5bf604c6a110 -// ValTestMessage_NestedMessage_InnerNestedMessage_InnerVal is using regex d4db71516b8749dc594e5bf604c6a110 -// Pattern for LogOnlyValidationMessage_Title -const _regex_val_7d80f76b8ba61834c54bce3793157935 = `^[\pL\pN\x{000A}\x{0020}\x{0021}\x{0022}\x{0023}\x{0025}\x{0026}\x{0027}\x{0028}\x{0029}\x{002A}\x{002C}\x{002D}\x{002E}\x{002F}\x{003A}\x{003F}\x{0040}\x{005B}\x{005C}\x{005D}\x{005F}\x{00BF}\x{2013}]+$` - -var _regex_7d80f76b8ba61834c54bce3793157935 = regexp.MustCompile(_regex_val_7d80f76b8ba61834c54bce3793157935) - -// Pattern for LogOnlyValidationMessage_Name -const _regex_val_b3f79e2470927c095fff6ea841e2a650 = `^[\pL\pM\pN\pPo\pSc\pSk\pSm\pSo\x{0020}\x{0021}\x{0022}\x{0023}\x{0025}\x{0026}\x{0027}\x{0028}\x{0029}\x{002A}\x{002C}\x{002D}\x{002E}\x{002F}\x{003A}\x{003F}\x{0040}\x{005B}\x{005C}\x{005D}\x{005F}\x{007E}\x{00BF}\x{104B}\x{200D}\x{2013}\x{2018}\x{2019}\x{201C}\x{201D}\x{2022}]+$` - -var _regex_b3f79e2470927c095fff6ea841e2a650 = regexp.MustCompile(_regex_val_b3f79e2470927c095fff6ea841e2a650) - -// NestedLevel3Message_OrgId5 is using regex d4db71516b8749dc594e5bf604c6a110 -// NestedLevel2Message_OrgId4 is using regex d4db71516b8749dc594e5bf604c6a110 -// NestedLevel1Message_OrgId3 is using regex d4db71516b8749dc594e5bf604c6a110 -// MyReqMessage_UserId is using regex d4db71516b8749dc594e5bf604c6a110 -// NonUrlMessage_RejectUrlTest is using regex 1bb1e0a2437db38577f49b4f31ccfca2 -// NonUrlMessage_BreakPartialUrlTest is using regex 1bb1e0a2437db38577f49b4f31ccfca2 diff --git a/protobuf/protoc-gen-govalidator/valtest/valtest_test.go b/protobuf/protoc-gen-govalidator/valtest/valtest_test.go deleted file mode 100644 index d236261..0000000 --- a/protobuf/protoc-gen-govalidator/valtest/valtest_test.go +++ /dev/null @@ -1,2382 +0,0 @@ -package valtest - -import ( - "bufio" - "fmt" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "math" - "os" - "strings" - "testing" - - "github.com/SafetyCulture/s12-proto/s12/protobuf/proto" -) - -const ( - id string = "92b6c2f9-abd8-48bc-a2c9-bf70e969751a" - legacyId string = "56341C6E-35A7-4C97-9C5E-7AC79673EAB2" - s12Id string = "audit_f6dad1c9334040739b1e67ca70f4cf4d" - legacyLongIdFail string = "00EAE67E-2160-4C2E-BEB1-E5558A2696A7-9-00000190327E0675" // length = 49 (without dashes) - legacyLongId1 string = "00EAE67E-2160-4C2E-BEB1-E5558A2696A7-90-00000190327E0675" // length = 50 (without dashes) - legacyLongId2 string = "005F2E38-8426-48AF-94DE-5FEA3A396EEA-891-00000153F68896DC" // length = 51 (without dashes) - legacyLongId3 string = "007B516E-53F1-4AA0-ABAF-8C78342A2C82-2388-00000221F1C2BD1E" // length = 52 (without dashes) - legacyLongId4 string = "00709A17-151F-4CFC-B412-F080343ED84D-11977-000010227B4C60A9" // length = 53 (without dashes) - email string = "email@example.com" - password string = "1234567!" - name string = "Γιώργος Νταλάρας" - idv4 string = "92b6c2f9-abd8-48bc-a2c9-bf70e969751a" - uuidNotV4 string = "e07b6ac0-8a05-11e2-9951-ddd1182f65d9" - valid bool = false - invalid bool = true - emptyString string = "" -) - -var invalidEmails = []string{ - "first.last@domain.com.au>", // trailing ">"" is invalid - "email", - "example@example.com66", - "example@domain", // missing domain name - "example@example.com�", - "example@example.co uk", - // "bbbccc.aa@,abcdef.com.uk", // TODO PA: this is currently considered valid by govalidator - "m _example@example.com", // space is invalid - "mail@127.0.0.1", - "test@gmail.com3", - "1@1.1", - "email.ending@dot.com.", - "invalid.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64@aa257aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", - "invalid.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa65@aa256aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", -} - -var validEmails = []string{ - "first.last@domain.com.au", - "email@gmail.com", - "example@safetyculture.io", - "example1234@non-existing-domain123837.com", // still a valid email format - "name@組織.香港", - "example+alias@EXAMPLE.COM", - "example|2@example.com", - "mULtiCase@exAMplE.cOm", - // user part max 64 chars, domain part max 256 chars: - "valid.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa64@aa256aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com", -} - -var validSafeStrings = []string{ - `abc`, - `Hello`, - `Γιώργος Νταλάρας`, - "file:///valid_safe_strings.txt", -} - -var validReplaceUnsafeStrings = []string{ - ``, - `' OR 1=1`, - `../etc/passwd`, - `1+1=2/4&a|b`, -} - -var testTitles = []string{ - // "file:///testdata/NOCOMMIT_valid_strings.txt", -} - -var testPermissive = []string{ - // "file:///testdata/NOCOMMIT_emoticon_strings.txt", - // "file:///testdata/NOCOMMIT_actions-issues-PUA.txt", -} - -var invalidSafeStrings = []string{ - ``, - `' OR 1=1`, - `../etc/passwd`, - `1+1=2/4&a|b`, - "file:///invalid_safe_strings.txt", -} - -var validNames = []string{ - "file:///valid_names.txt", -} - -var validURLs = []string{ - "https://example/", // technically valid - might not want to accept such format - "https://example.com", - "https://example.com/a", - "https://example.com/index.html?a=b&c=d", - "https://user@example.com", - "https://user:cred@example.com", // not an actual credential - "https://example.com/" + strings.Repeat("a", 900), - "https://example.com/a+", // trailing whitespace encoded - "https://example.com/a%20", // trailing whitespace encoded - "https://example.com/a?b=ftp%3A//user%3Acred%40example.com/file.html%3Fq%3D%27b%27%26test%3D%22something%2526%22", // several encoded and double-encoded URL-reserved chars - "https://app.safetyculture.com/path/action?lang=en-US", - "https://host.tld:88", - "https://example.com:88/test", - "https://xn--tlphone-byab/abc", // punnycode, technically valid - might not want to accept such format -} - -var invalidURLs = []string{ - "https", - "https:/", - "https://", - "https:///", - "https:example.com", - "https:/example.com", - "https//:example.com", - "https://example.com/" + strings.Repeat("a", 1000), // too long - "ftp://example.com/", // default scheme is https - "https://example.com/a#fragment", // fragment not allowed unless option enabled - "https://example.com/\na", - " https://example.com/a", // leading whitespace - "\thttps://example.com/a", // leading whitespace - "https://example.com/a ", // trailing whitespace not encoded, most browsers will just strip it but technically invalid - "file:///etc/passwd", - "javascript:alert(1)", - "/absolute_url", // require URL (with scheme, domain), not URI - "./relative_url", - "../relative/url", - "https://example.com/λά.html", // invalid runes in path - "https://invalid-unicodé-domainλά.com/abc", // invalid runes in domain -} - -var valMsg = ValTestMessage{ - Id: id, - Ids: []string{id, id}, - LegacyId: legacyId, - S12Id: s12Id, - MediaId: id, - InnerLegacyId: &InnerMessageWithLegacyId{Id: id}, - InnerS12Id: &InnerMessageWithS12Id{Id: s12Id}, - Uuid: id, - Email: email, - OptEmail: email, - Description: "François Truffaut 久保田 利伸 text", - Password: password, - Title: "Short text, ok", - FixedString: "abcd", - RuneString: "çois", - ReplaceString: "With 'unsafe' \"", - NotReplaceString: "Safe chars ç only 123.", - AllowString: "Accept ~ and #", - SymbolString: "Accept $ £ ¥ €", - SymbolsString: "Accept 🌏 💯 and a\u030C", // ǎ as in a + the caron - NewlineString: "Accept\nNewlines\n\rYeeha", - InvalidEncodingString: "Accept invalid \xe9", - OptString: "Optional", - TrimString: " Trim me \t", - AllString: " Lot of checks here>", - Name: "Sinéad O'Connor", - NoValidation: "' OR 1=1", - ContactOneof: &ValTestMessage_Phone{Phone: "14574560123"}, - MsgRequired: &InnerMessage{Id: id}, - NestedMessage: &ValTestMessage_NestedMessage{ - Val: "inner val", - // InnerNestedMessage: &ValTestMessage_NestedMessage_InnerNestedMessage{ - // InnerVal: "abc def", - // }, - NestedEmail: email, - MemberEmails: []string{ - email, - email, - }, - }, - ContactsWithLengthConstraint: []*ValTestMessage_Contact{ - {Phone: "abc", Email: "test@example.com"}, - {Phone: "", Email: "test2@example.com"}, - }, - Url: "https://example.com/test", - UrlAllOpts: "http://app.safetyculture.com/report/media?param=test#fragment", - // NotSupported: , - Timezone: "Australia/Sydney", - LongString: strings.Repeat("x", 30000), -} - -// omit optional fields here -var valMsgOpts = ValTestMessage{ - Id: id, - Ids: []string{id, id}, - LegacyId: legacyId, - S12Id: s12Id, - InnerLegacyId: &InnerMessageWithLegacyId{Id: legacyId}, - InnerS12Id: &InnerMessageWithS12Id{Id: s12Id}, - Uuid: id, - Email: email, - Description: "François Truffaut 久保田 利伸 text", - Password: password, - Title: "Short text, ok", - FixedString: "abcd", - RuneString: "çois", - ReplaceString: "With 'unsafe' \"", - NotReplaceString: "Safe chars ç only 123.", - AllowString: "Accept ~ and #", - SymbolString: "Accept $ £ ¥ €", - SymbolsString: "Accept 🌏 💯 and a\u030C", // ǎ as in a + the caron - NewlineString: "Accept\nNewlines\n\rYeeha", - InvalidEncodingString: "Accept invalid \xe9", - TrimString: " Trim me \t", - AllString: " Lot of checks here>", - NoValidation: "' OR 1=1", - ContactOneof: &ValTestMessage_Phone{Phone: "14574560123"}, - MsgRequired: &InnerMessage{Id: id}, - NestedMessage: &ValTestMessage_NestedMessage{ - Val: "inner val", - // InnerNestedMessage: &ValTestMessage_NestedMessage_InnerNestedMessage{ - // InnerVal: "abc def", - // }, - NestedEmail: email, - MemberEmails: []string{ - email, - email, - }, - }, - ContactsWithLengthConstraint: []*ValTestMessage_Contact{ - {Phone: "abc", Email: "test@example.com"}, - }, - Url: "https://example.com/test", - // NotSupported: , - Timezone: "Australia/Sydney", -} - -func readFiles(list []string) []string { - // read string array and add contents from file for file handlers - outList := []string{} - for _, filename := range list { - if !strings.HasPrefix(filename, "file:///") { - outList = append(outList, filename) - continue - } - // read file - path, _ := os.Getwd() - filename = strings.Replace(filename, "file:///", path+"/", 1) - f, err := os.Open(filename) - if err != nil { - fmt.Fprintf(os.Stderr, "Cannot open: %v\n", err) - continue - } else { - fmt.Println("ADDED file", filename) - } - lines := bufio.NewScanner(f) - // add each line of the file as test input - for lines.Scan() { - outList = append(outList, lines.Text()) - } - } - - return outList -} - -func genString(len int) string { - return strings.Repeat("A", len) -} - -func replaceEmpty(s string) string { - if s == emptyString { - return "" - } - return s -} - -func getValMsg(m ValTestMessage) *ValTestMessage { - newMsg := valMsg - if m.Id != "" { - newMsg.Id = replaceEmpty(m.Id) - } - if m.Ids != nil { - newMsg.Ids = m.Ids - } - if m.LegacyId != "" { - newMsg.LegacyId = replaceEmpty(m.LegacyId) - } - if m.S12Id != "" { - newMsg.S12Id = replaceEmpty(m.S12Id) - } - if m.AllId != "" { - newMsg.AllId = replaceEmpty(m.AllId) - } - if m.MediaId != "" { - newMsg.MediaId = replaceEmpty(m.MediaId) - } - if m.Uuid != "" { - newMsg.Uuid = replaceEmpty(m.Uuid) - } - // if m.InnerLegacyId != "" { - // newMsg.InnerLegacyId = m.InnerLegacyId - // } - if m.Email != "" { - newMsg.Email = replaceEmpty(m.Email) - } - if m.OptEmail != "" { - newMsg.OptEmail = replaceEmpty(m.OptEmail) - } - if m.Description != "" { - newMsg.Description = replaceEmpty(m.Description) - } - if m.Password != "" { - newMsg.Password = replaceEmpty(m.Password) - } - if m.Title != "" { - newMsg.Title = replaceEmpty(m.Title) - } - if m.FixedString != "" { - newMsg.FixedString = replaceEmpty(m.FixedString) - } - if m.RuneString != "" { - newMsg.RuneString = replaceEmpty(m.RuneString) - } - if m.ReplaceString != "" { - newMsg.ReplaceString = replaceEmpty(m.ReplaceString) - } - if m.NotReplaceString != "" { - newMsg.NotReplaceString = replaceEmpty(m.NotReplaceString) - } - if m.AllowString != "" { - newMsg.AllowString = replaceEmpty(m.AllowString) - } - if m.SymbolString != "" { - newMsg.SymbolString = replaceEmpty(m.SymbolString) - } - if m.SymbolsString != "" { - newMsg.SymbolsString = replaceEmpty(m.SymbolsString) - } - if m.NewlineString != "" { - newMsg.NewlineString = replaceEmpty(m.NewlineString) - } - if m.InvalidEncodingString != "" { - newMsg.InvalidEncodingString = replaceEmpty(m.InvalidEncodingString) - } - if m.OptString != "" { - newMsg.OptString = replaceEmpty(m.OptString) - } - if m.TrimString != "" { - newMsg.TrimString = replaceEmpty(m.TrimString) - } - if m.AllString != "" { - newMsg.AllString = replaceEmpty(m.AllString) - } - if m.Name != "" { - newMsg.Name = replaceEmpty(m.Name) - } - if m.ScTitle != "" { - newMsg.ScTitle = replaceEmpty(m.ScTitle) - } - if m.ScPermissive != "" { - newMsg.ScPermissive = replaceEmpty(m.ScPermissive) - } - if m.NotSanitisePua != "" { - newMsg.NotSanitisePua = replaceEmpty(m.NotSanitisePua) - } - if m.SanitisePua != "" { - newMsg.SanitisePua = replaceEmpty(m.SanitisePua) - } - if m.SanitiseLength != "" { - newMsg.SanitiseLength = replaceEmpty(m.SanitiseLength) - } - if m.OptionalString != nil { - newMsg.OptionalString = m.OptionalString - } - if m.NoValidation != "" { - newMsg.NoValidation = replaceEmpty(m.NoValidation) - } - // if m.ContactOneof != "" { - // newMsg.ContactOneof = m.ContactOneof - // } - // if m.MsgRequired != "" { - // newMsg.MsgRequired = m.MsgRequired - // } - if m.Url != "" { - newMsg.Url = replaceEmpty(m.Url) - } - if m.UrlAllOpts != "" { - newMsg.UrlAllOpts = replaceEmpty(m.UrlAllOpts) - } - if m.Timezone != "" { - newMsg.Timezone = replaceEmpty(m.Timezone) - } - if m.TimezoneOptional != "" { - newMsg.TimezoneOptional = replaceEmpty(m.TimezoneOptional) - } - if m.LongString != "" { - newMsg.LongString = replaceEmpty(m.LongString) - } - return &newMsg -} - -func TestValidationRules(t *testing.T) { - - sb := strings.Builder{} - for i := 0; i < 2001; i++ { - sb.WriteRune('a') - } - - emptyStr := "" - optionalStr := "optional" - - type TestSet struct { - name string - input proto.Validator - shouldError bool - } - - tests := []TestSet{ - { - "ValidMessage", - &valMsg, - valid, - }, - { - "ValidMessageNoOptFields", - &valMsgOpts, - valid, - }, - { - "InvalidId", - getValMsg(ValTestMessage{Id: "abc"}), - invalid, - }, - { - "InvalidIdWithUUIDNotV4", - getValMsg(ValTestMessage{Id: uuidNotV4}), - invalid, - }, - { - "InvalidLegacyId", - getValMsg(ValTestMessage{LegacyId: legacyLongIdFail}), - invalid, - }, - { - "ValidLegacyIdLong1", - getValMsg(ValTestMessage{LegacyId: legacyLongId1}), - valid, - }, - { - "ValidLegacyIdLong2", - getValMsg(ValTestMessage{LegacyId: legacyLongId2}), - valid, - }, - { - "ValidLegacyIdLong3", - getValMsg(ValTestMessage{LegacyId: legacyLongId3}), - valid, - }, - { - "ValidLegacyIdLong4", - getValMsg(ValTestMessage{LegacyId: legacyLongId4}), - valid, - }, - { - "InvalidIds", - getValMsg(ValTestMessage{Ids: []string{id, "audit_invalid", id}}), - invalid, - }, - { - "ValidS12ID", - getValMsg(ValTestMessage{S12Id: s12Id}), - valid, - }, - { - "InvalidS12ID", - getValMsg(ValTestMessage{S12Id: "fake_id"}), - invalid, - }, - { - "InvalidUUIDwithS12Id", - getValMsg(ValTestMessage{Id: s12Id}), - invalid, - }, - { - "InvalidUUIDwithLegacyId", - getValMsg(ValTestMessage{Id: legacyId}), - invalid, - }, - { - "InvalidLegacyIdwithS12Id", - getValMsg(ValTestMessage{LegacyId: s12Id}), - invalid, - }, - { - "InvalidS12IdWithLegacyId", - getValMsg(ValTestMessage{S12Id: legacyId}), - invalid, - }, - { - "ValidIdAllOptsUUID", - getValMsg(ValTestMessage{AllId: id}), - valid, - }, - { - "ValidIdAllOptsLegacyId", - getValMsg(ValTestMessage{AllId: legacyId}), - valid, - }, - { - "ValidIdAllOptsS12Id", - getValMsg(ValTestMessage{AllId: s12Id}), - valid, - }, - { - "ValidS12IDUppercase", - getValMsg(ValTestMessage{S12Id: "audit_C6C011ED4ADE460DA04BDA730834B667"}), - valid, - }, - { - "ValidIDAnyVersionWithUUIDv4", - getValMsg(ValTestMessage{Uuid: id}), - valid, - }, - { - "ValidIDAnyVersionWithUUIDNotV4", - getValMsg(ValTestMessage{Uuid: uuidNotV4}), - valid, - }, - { - "InvalidIDAnyVersionWithInvalidId", - getValMsg(ValTestMessage{Uuid: "invalid"}), - invalid, - }, - { - "ValidIdAllOptsLongPrefixedLegacyId50", - getValMsg(ValTestMessage{AllId: "audit_1CC51EFA600C4F6285B9652A32D714D69500000013D6801111"}), - valid, - }, - { - "ValidIdAllOptsLongPrefixedLegacyId51", - getValMsg(ValTestMessage{AllId: "audit_0CEE3E70B3584D40B1E7B4A485C19D8A23500000154D3322222"}), - valid, - }, - { - "ValidIdAllOptsLongPrefixedLegacyId52", - getValMsg(ValTestMessage{AllId: "audit_072F8B1B16594188A8B906ACED430CA889670000153EA8333333"}), - valid, - }, - { - "ValidIdAllOptsLongPrefixedLegacyId53", - getValMsg(ValTestMessage{AllId: "template_5033F701076E47FCA698F84E05557A6D2024300002267A4444444"}), - valid, - }, - { - "InValidIdAllOptsLongPrefixedLegacyId54", - getValMsg(ValTestMessage{AllId: "template_5033F701076E47FCA698F84E05557A6D2024300002267A44444445"}), - invalid, - }, - { - "InValidIdAllOptsLongPrefixedLegacyId44", - getValMsg(ValTestMessage{AllId: "template_5033F7A698F84E05557A6D2024300002267A44444445"}), - invalid, - }, - { - "ValidEmail", - getValMsg(ValTestMessage{Email: email}), - valid, - }, { - "ValidDescriptionLen1", - getValMsg(ValTestMessage{Description: genString(1)}), - valid, - }, { - "ValidDescriptionLen2", - getValMsg(ValTestMessage{Description: genString(2)}), - valid, - }, { - "ValidDescriptionLen50", - getValMsg(ValTestMessage{Description: genString(50)}), - valid, - }, { - "ValidDescriptionLen100", - getValMsg(ValTestMessage{Description: genString(100)}), - valid, - }, { - "ValidDescriptionLen750", - getValMsg(ValTestMessage{Description: genString(750)}), - valid, - }, { - "InvalidDescriptionLen751", - getValMsg(ValTestMessage{Description: genString(751)}), - invalid, - }, { - "InvalidDescriptionLen0", - getValMsg(ValTestMessage{Description: emptyString}), - invalid, - }, { - "InvalidDescriptionLen10k", - getValMsg(ValTestMessage{Description: genString(10000)}), - invalid, - }, { - "InvalidEncoding", - getValMsg(ValTestMessage{Description: "X\xe9X invalid X\xa3X encoding"}), - invalid, - }, { - "InvalidPUA", - getValMsg(ValTestMessage{NotSanitisePua: "X\uf0a7X InvalidPUA"}), - invalid, - }, { - "ValidSanitisedPUA", - getValMsg(ValTestMessage{SanitisePua: "X\uf0a7X ValidSanitisedPUA"}), - valid, - }, { - "ValidSanitisedLength", - getValMsg(ValTestMessage{SanitiseLength: "A\uf0a7B"}), // sanitised to length 2 (AB) - valid, - }, { - "InvalidSanitisedLength", - getValMsg(ValTestMessage{SanitiseLength: "A\uf0a7"}), // sanitised to length 1 (A) - invalid, - }, { - "InvalidBidiRtL", - getValMsg(ValTestMessage{ScPermissive: "InvalidBidi RtL\u200f"}), - invalid, - }, { - "InvalidBidiLtR", - getValMsg(ValTestMessage{ScPermissive: "\u200eInvalidBidi LtR"}), - invalid, - }, { - "ValidPasswordLong", - getValMsg(ValTestMessage{Password: "XCzUDDdpwvFR@MoGzsVP@hvjmNqjPG2bNb9G6uz7"}), // not a real password - valid, - }, { - "ValidPasswordShort", - getValMsg(ValTestMessage{Password: "12345678"}), // not a real password - valid, - }, { - "ValidPasswordUnsafeChars", - getValMsg(ValTestMessage{Password: "<$pass>'|\"../etc/password"}), // not a real password - valid, - }, { - "InvalidPasswordLength", - getValMsg(ValTestMessage{Password: "1234567"}), // not a real password - invalid, - }, { - "ValidFixedLenString", - getValMsg(ValTestMessage{FixedString: "1234"}), - valid, - }, { - "InvalidFixedLenStringMB", - getValMsg(ValTestMessage{FixedString: "123é"}), // é takes up 2 bytes, making this len 5 instead of 4 - invalid, - }, { - "InvalidFixedLenStringTooShort", - getValMsg(ValTestMessage{FixedString: "123"}), - invalid, - }, { - "InvalidFixedLenStringTooLong", - getValMsg(ValTestMessage{FixedString: "12345"}), - invalid, - }, { - "ValidRuneLenStringSB", - getValMsg(ValTestMessage{RuneString: "123é"}), // len 4 in runes, 5 in bytes - valid, - }, { - "ValidRuneLenStringNFD", - getValMsg(ValTestMessage{RuneString: "123e\u0301"}), // this NFD string (e + ´) will be normalised to NFC string before len check so still 4 bytes - valid, - }, { - "ValidRuneLenStringMB", - getValMsg(ValTestMessage{RuneString: "AAA🌏"}), // will result in 7 bytes and 4 runes - valid, - }, { - "ValidMinMaxLenStringL3", - getValMsg(ValTestMessage{Title: "123"}), // len between 3 and 50 - valid, - }, { - "ValidMinMaxLenStringL4", - getValMsg(ValTestMessage{Title: "1234"}), // len between 3 and 50 - valid, - }, { - "ValidMinMaxLenStringL49", - getValMsg(ValTestMessage{Title: genString(49)}), // len between 3 and 50 - valid, - }, { - "ValidMinMaxLenStringL50", - getValMsg(ValTestMessage{Title: genString(50)}), // len between 3 and 50 - valid, - }, { - "InvalidMinMaxLenStringL51", - getValMsg(ValTestMessage{Title: genString(51)}), // len between 3 and 50 - invalid, - }, { - "InvalidMinMaxLenStringL2", - getValMsg(ValTestMessage{Title: "12"}), // len between 3 and 50 - invalid, - }, { - "InvalidMinMaxLenStringL0", - getValMsg(ValTestMessage{Title: emptyString}), // len between 3 and 50 - invalid, - }, { - "ValidReplaceUnsafe", - getValMsg(ValTestMessage{ReplaceString: "