From eadb0993bf279a8ab3c15bb9aec0579d7d5495d7 Mon Sep 17 00:00:00 2001 From: Adphi Date: Fri, 24 Sep 2021 12:53:24 +0200 Subject: [PATCH] add casttype support for repeated scalar fields --- patch/casttype.go | 37 +++++++-- patch/go.proto | 2 +- patch/gopb/go.pb.go | 2 +- patch/patcher.go | 2 - tests/message/message.extensions.go | 3 + tests/message/message_casttypes.pb.go | 105 +++++++++++++++++++++----- tests/message/message_casttypes.proto | 10 ++- tests/message/message_test.go | 20 +++++ tests/plugin/validate.pb.go | 59 +++++++++------ tests/plugin/validate.pb.validate.go | 28 +++++++ tests/plugin/validate.proto | 5 ++ 11 files changed, 219 insertions(+), 54 deletions(-) diff --git a/patch/casttype.go b/patch/casttype.go index 02db2e2..bf4a566 100644 --- a/patch/casttype.go +++ b/patch/casttype.go @@ -22,6 +22,30 @@ func (p *Patcher) patchTypeDef(id *ast.Ident, obj types.Object) { astutil.AddNamedImport(p.fset, f, pkgImport, pkg) castType = pkgImport + "." + name } + + castDecl := func(v *ast.Field) bool { + switch t := v.Type.(type){ + case *ast.Ident: + t.Name = castType + return true + case *ast.ArrayType: + if strings.HasPrefix(castType, "[]") { + if id, ok := t.Elt.(*ast.Ident); ok { + id.Name = strings.TrimPrefix(castType, "[]") + return true + } + } else { + v.Type = &ast.Ident{ + Name: castType, + } + return true + } + default: + return false + } + return false + } + // Cast Field definition if id.Obj != nil && id.Obj.Decl != nil { v, ok := id.Obj.Decl.(*ast.Field) @@ -29,11 +53,10 @@ func (p *Patcher) patchTypeDef(id *ast.Ident, obj types.Object) { log.Printf("Warning: casttype declared for non-field object: %v `%s`", obj, castType) return } - t, ok := v.Type.(*ast.Ident) - if ok { - t.Name = castType - return + if !castDecl(v) { + log.Printf("Warning: unsupported casttype type: %T `%s`", v.Type, castType) } + return } switch obj.Type().(type) { // Cast Getter signature @@ -47,10 +70,10 @@ func (p *Patcher) patchTypeDef(id *ast.Ident, obj types.Object) { log.Printf("Warning: unexpected return count for getter: %v `%d`", obj, l) return } - if ident, ok := n.Type.Results.List[0].Type.(*ast.Ident); ok { - ident.Name = castType - return + if !castDecl(n.Type.Results.List[0]) { + log.Printf("Warning: unsupported casttype type: %T `%s`", n.Type.Results.List[0].Type, castType) } + return } } diff --git a/patch/go.proto b/patch/go.proto index 41d13e7..5ae6ea0 100644 --- a/patch/go.proto +++ b/patch/go.proto @@ -24,7 +24,7 @@ message Options { // The casstype option changes the generated field type. // All generated code assumes that this type is castable to the protocol buffer field type, // so it does not work for messages types. - // Not supported for repeated fields. + // Rrepeated fields are also supported, both as '[]Type' or 'Types' where Types is a named slice type. optional string casttype = 3; // The getter option renames the generated getter method (default: Get) diff --git a/patch/gopb/go.pb.go b/patch/gopb/go.pb.go index 1c80d32..72ec283 100644 --- a/patch/gopb/go.pb.go +++ b/patch/gopb/go.pb.go @@ -41,7 +41,7 @@ type Options struct { // The casstype option changes the generated field type. // All generated code assumes that this type is castable to the protocol buffer field type, // so it does not work for messages types. - // Not supported for repeated fields. + // Rrepeated fields are also supported, both as '[]Type' or 'Types' where Types is a named slice type. Casttype *string `protobuf:"bytes,3,opt,name=casttype" json:"casttype,omitempty"` // The getter option renames the generated getter method (default: Get) // so a custom getter can be implemented in its place. diff --git a/patch/patcher.go b/patch/patcher.go index 0b30ce7..564e918 100644 --- a/patch/patcher.go +++ b/patch/patcher.go @@ -319,8 +319,6 @@ func (p *Patcher) scanField(f *protogen.Field) { // check casttype if typ := opts.GetCasttype(); typ != "" { switch { - case f.Desc.IsList(): - log.Printf("Warning: casttype declared for repeated field: %s", f.Desc.Name()) case f.Message != nil: log.Printf("Warning: casttype declared for message field: %s", f.Desc.Name()) case f.Oneof != nil: diff --git a/tests/message/message.extensions.go b/tests/message/message.extensions.go index 4718488..1fe14f0 100644 --- a/tests/message/message.extensions.go +++ b/tests/message/message.extensions.go @@ -1,6 +1,7 @@ package message type Name string +type Names []string type Int32 int32 @@ -15,3 +16,5 @@ type Double float64 type Uint32 uint32 type Uint64 uint64 + +type Strings []string diff --git a/tests/message/message_casttypes.pb.go b/tests/message/message_casttypes.pb.go index f5e986a..084366d 100644 --- a/tests/message/message_casttypes.pb.go +++ b/tests/message/message_casttypes.pb.go @@ -196,18 +196,65 @@ func (*MessageWithOneOfCustomType_StringField) isMessageWithOneOfCustomType_OneO func (*MessageWithOneOfCustomType_Int64Field) isMessageWithOneOfCustomType_OneOf() {} +type MessageWithCustomRepeatedTypes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RepeatedStringField []String `protobuf:"bytes,1,rep,name=repeated_string_field,json=repeatedStringField,proto3" json:"repeated_string_field,omitempty"` +} + +func (x *MessageWithCustomRepeatedTypes) Reset() { + *x = MessageWithCustomRepeatedTypes{} + if protoimpl.UnsafeEnabled { + mi := &file_tests_message_message_casttypes_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageWithCustomRepeatedTypes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageWithCustomRepeatedTypes) ProtoMessage() {} + +func (x *MessageWithCustomRepeatedTypes) ProtoReflect() protoreflect.Message { + mi := &file_tests_message_message_casttypes_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 MessageWithCustomRepeatedTypes.ProtoReflect.Descriptor instead. +func (*MessageWithCustomRepeatedTypes) Descriptor() ([]byte, []int) { + return file_tests_message_message_casttypes_proto_rawDescGZIP(), []int{2} +} + +func (x *MessageWithCustomRepeatedTypes) GetRepeatedStringField() []String { + if x != nil { + return x.RepeatedStringField + } + return nil +} + type MessageWithRepeatedCustomTypes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - StringField []string `protobuf:"bytes,1,rep,name=string_field,json=stringField,proto3" json:"string_field,omitempty"` + RepeatedStringField Strings `protobuf:"bytes,1,rep,name=repeated_string_field,json=repeatedStringField,proto3" json:"repeated_string_field,omitempty"` } func (x *MessageWithRepeatedCustomTypes) Reset() { *x = MessageWithRepeatedCustomTypes{} if protoimpl.UnsafeEnabled { - mi := &file_tests_message_message_casttypes_proto_msgTypes[2] + mi := &file_tests_message_message_casttypes_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -220,7 +267,7 @@ func (x *MessageWithRepeatedCustomTypes) String() string { func (*MessageWithRepeatedCustomTypes) ProtoMessage() {} func (x *MessageWithRepeatedCustomTypes) ProtoReflect() protoreflect.Message { - mi := &file_tests_message_message_casttypes_proto_msgTypes[2] + mi := &file_tests_message_message_casttypes_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -233,12 +280,12 @@ func (x *MessageWithRepeatedCustomTypes) ProtoReflect() protoreflect.Message { // Deprecated: Use MessageWithRepeatedCustomTypes.ProtoReflect.Descriptor instead. func (*MessageWithRepeatedCustomTypes) Descriptor() ([]byte, []int) { - return file_tests_message_message_casttypes_proto_rawDescGZIP(), []int{2} + return file_tests_message_message_casttypes_proto_rawDescGZIP(), []int{3} } -func (x *MessageWithRepeatedCustomTypes) GetStringField() []string { +func (x *MessageWithRepeatedCustomTypes) GetRepeatedStringField() Strings { if x != nil { - return x.StringField + return x.RepeatedStringField } return nil } @@ -281,16 +328,23 @@ var file_tests_message_message_casttypes_proto_rawDesc = []byte{ 0x64, 0x12, 0x2e, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x42, 0x0b, 0xca, 0xb5, 0x03, 0x07, 0x1a, 0x05, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x42, 0x08, 0x0a, 0x06, 0x6f, 0x6e, 0x65, 0x5f, 0x6f, 0x66, 0x22, 0x51, 0x0a, 0x1e, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x2f, 0x0a, - 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x42, 0x0c, 0xca, 0xb5, 0x03, 0x08, 0x1a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x2a, - 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x74, - 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x74, 0x65, 0x73, - 0x74, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x64, 0x42, 0x08, 0x0a, 0x06, 0x6f, 0x6e, 0x65, 0x5f, 0x6f, 0x66, 0x22, 0x64, 0x0a, 0x1e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x42, 0x0a, + 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0e, 0xca, 0xb5, + 0x03, 0x0a, 0x1a, 0x08, 0x5b, 0x5d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x13, 0x72, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x22, 0x63, 0x0a, 0x1e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x57, 0x69, 0x74, 0x68, + 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x15, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x42, 0x0d, 0xca, 0xb5, 0x03, 0x09, 0x1a, 0x07, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x73, 0x52, 0x13, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x70, + 0x61, 0x74, 0x63, 0x68, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -305,11 +359,12 @@ func file_tests_message_message_casttypes_proto_rawDescGZIP() []byte { return file_tests_message_message_casttypes_proto_rawDescData } -var file_tests_message_message_casttypes_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_tests_message_message_casttypes_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_tests_message_message_casttypes_proto_goTypes = []interface{}{ (*MessageWithCustomTypes)(nil), // 0: tests.message.MessageWithCustomTypes (*MessageWithOneOfCustomType)(nil), // 1: tests.message.MessageWithOneOfCustomType - (*MessageWithRepeatedCustomTypes)(nil), // 2: tests.message.MessageWithRepeatedCustomTypes + (*MessageWithCustomRepeatedTypes)(nil), // 2: tests.message.MessageWithCustomRepeatedTypes + (*MessageWithRepeatedCustomTypes)(nil), // 3: tests.message.MessageWithRepeatedCustomTypes } var file_tests_message_message_casttypes_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -350,6 +405,18 @@ func file_tests_message_message_casttypes_proto_init() { } } file_tests_message_message_casttypes_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageWithCustomRepeatedTypes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_tests_message_message_casttypes_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MessageWithRepeatedCustomTypes); i { case 0: return &v.state @@ -372,7 +439,7 @@ func file_tests_message_message_casttypes_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_tests_message_message_casttypes_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/tests/message/message_casttypes.proto b/tests/message/message_casttypes.proto index 24fb0e1..5e07da7 100644 --- a/tests/message/message_casttypes.proto +++ b/tests/message/message_casttypes.proto @@ -6,8 +6,6 @@ import "patch/go.proto"; option go_package = "github.com/alta/protopatch/tests/message"; - - message MessageWithCustomTypes { string string_field = 1 [(go.field).casttype = "String"]; int32 int32_field = 2 [(go.field).casttype = "Int32"]; @@ -24,3 +22,11 @@ message MessageWithOneOfCustomType { int64 int64_field = 3 [(go.field).casttype = "Int64"]; } } + +message MessageWithCustomRepeatedTypes { + repeated string repeated_string_field = 1 [(go.field).casttype = "[]String"]; +} + +message MessageWithRepeatedCustomTypes { + repeated string repeated_string_field = 1 [(go.field).casttype = "Strings"]; +} diff --git a/tests/message/message_test.go b/tests/message/message_test.go index ca0a15c..4d21955 100644 --- a/tests/message/message_test.go +++ b/tests/message/message_test.go @@ -138,3 +138,23 @@ func TestMessageWithCustomTypes(t *testing.T) { assert.Equal(t, Uint32(42), m.Uint32Field) assert.Equal(t, Uint64(42), m.Uint64Field) } + +func TestMessageWithCustomRepeatedTypes(t *testing.T) { + slice := []String{"one", "two"} + m := &MessageWithCustomRepeatedTypes{ + RepeatedStringField: slice, + } + tests.ValidateMessage(t, m) + var _ []String = m.RepeatedStringField + assert.Equal(t, slice, m.RepeatedStringField) +} + +func TestMessageWithRepeatedCustomTypes(t *testing.T) { + slice := Strings{"one", "two"} + m := &MessageWithRepeatedCustomTypes{ + RepeatedStringField: slice, + } + tests.ValidateMessage(t, m) + var _ Strings = m.RepeatedStringField + assert.Equal(t, slice, m.RepeatedStringField) +} diff --git a/tests/plugin/validate.pb.go b/tests/plugin/validate.pb.go index 896a146..e77e150 100644 --- a/tests/plugin/validate.pb.go +++ b/tests/plugin/validate.pb.go @@ -77,9 +77,10 @@ type Interface struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name github_com_alta_protopatch_tests_message.Name `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Status InterfaceStatus `protobuf:"varint,2,opt,name=status,proto3,enum=tests.plugin.Interface_Status" json:"status,omitempty"` - Addresses []*IPAddress `protobuf:"bytes,3,rep,name=addresses,proto3" json:"addresses,omitempty"` + Name github_com_alta_protopatch_tests_message.Name `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Status InterfaceStatus `protobuf:"varint,2,opt,name=status,proto3,enum=tests.plugin.Interface_Status" json:"status,omitempty"` + Addresses []*IPAddress `protobuf:"bytes,3,rep,name=addresses,proto3" json:"addresses,omitempty"` + Aliases github_com_alta_protopatch_tests_message.Names `protobuf:"bytes,4,rep,name=aliases,proto3" json:"aliases,omitempty"` } func (x *Interface) Reset() { @@ -135,6 +136,13 @@ func (x *Interface) GetAddresses() []*IPAddress { return nil } +func (x *Interface) GetAliases() github_com_alta_protopatch_tests_message.Names { + if x != nil { + return x.Aliases + } + return nil +} + type IPAddress struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -223,7 +231,7 @@ var file_tests_plugin_validate_proto_rawDesc = []byte{ 0x65, 0x73, 0x74, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x1a, 0x0e, 0x70, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe0, 0x02, 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd7, 0x03, 0x0a, 0x09, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x61, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x4d, 0xca, 0xb5, 0x03, 0x2f, 0x1a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x70, 0x61, 0x74, @@ -238,24 +246,31 @@ var file_tests_plugin_validate_proto_rawDesc = []byte{ 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x49, 0x50, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, - 0x22, 0x75, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x07, 0x55, 0x4e, - 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x13, 0xca, 0xb5, 0x03, 0x0f, 0x0a, 0x0d, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x0a, 0x02, - 0x55, 0x50, 0x10, 0x01, 0x1a, 0x0e, 0xca, 0xb5, 0x03, 0x0a, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x55, 0x70, 0x12, 0x1a, 0x0a, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x1a, 0x10, - 0xca, 0xb5, 0x03, 0x0c, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x44, 0x6f, 0x77, 0x6e, - 0x1a, 0x15, 0xca, 0xb5, 0x03, 0x11, 0x0a, 0x0f, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x69, 0x0a, 0x09, 0x49, 0x50, 0x41, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x27, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x11, 0xca, 0xb5, 0x03, 0x06, 0x0a, 0x04, 0x49, 0x50, 0x56, 0x34, 0xfa, 0x42, - 0x04, 0x72, 0x02, 0x78, 0x01, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x28, 0x0a, - 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x12, 0xca, 0xb5, 0x03, - 0x06, 0x0a, 0x04, 0x49, 0x50, 0x56, 0x36, 0xfa, 0x42, 0x05, 0x72, 0x03, 0x80, 0x01, 0x01, 0x48, - 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x42, 0x09, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x61, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x75, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x42, 0x5b, 0xca, 0xb5, 0x03, 0x30, 0x1a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x70, 0x61, + 0x74, 0x63, 0x68, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x10, 0x0a, 0xfa, + 0x42, 0x1c, 0x92, 0x01, 0x19, 0x22, 0x17, 0x72, 0x15, 0x10, 0x02, 0x18, 0x0a, 0x32, 0x0f, 0x5b, + 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x2e, 0x2d, 0x5f, 0x5d, 0x2a, 0x52, 0x07, + 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x22, 0x75, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x20, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x1a, 0x13, + 0xca, 0xb5, 0x03, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x0a, 0x02, 0x55, 0x50, 0x10, 0x01, 0x1a, 0x0e, 0xca, 0xb5, 0x03, + 0x0a, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x55, 0x70, 0x12, 0x1a, 0x0a, 0x04, 0x44, + 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x1a, 0x10, 0xca, 0xb5, 0x03, 0x0c, 0x0a, 0x0a, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x44, 0x6f, 0x77, 0x6e, 0x1a, 0x15, 0xca, 0xb5, 0x03, 0x11, 0x0a, 0x0f, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x69, + 0x0a, 0x09, 0x49, 0x50, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x27, 0x0a, 0x04, 0x69, + 0x70, 0x76, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0xca, 0xb5, 0x03, 0x06, 0x0a, + 0x04, 0x49, 0x50, 0x56, 0x34, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x78, 0x01, 0x48, 0x00, 0x52, 0x04, + 0x69, 0x70, 0x76, 0x34, 0x12, 0x28, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x12, 0xca, 0xb5, 0x03, 0x06, 0x0a, 0x04, 0x49, 0x50, 0x56, 0x36, 0xfa, 0x42, + 0x05, 0x72, 0x03, 0x80, 0x01, 0x01, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x42, 0x09, + 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/tests/plugin/validate.pb.validate.go b/tests/plugin/validate.pb.validate.go index 0b374b6..d1886ab 100644 --- a/tests/plugin/validate.pb.validate.go +++ b/tests/plugin/validate.pb.validate.go @@ -83,6 +83,32 @@ func (m *Interface) Validate() error { } + if len([]string(m.GetAliases())) > 10 { + return InterfaceValidationError{ + field: "Aliases", + reason: "value must contain no more than 10 item(s)", + } + } + + for idx, item := range m.GetAliases() { + _, _ = idx, item + + if l := utf8.RuneCountInString(item); l < 2 || l > 10 { + return InterfaceValidationError{ + field: fmt.Sprintf("Aliases[%v]", idx), + reason: "value length must be between 2 and 10 runes, inclusive", + } + } + + if !_Interface_Aliases_Pattern.MatchString(item) { + return InterfaceValidationError{ + field: fmt.Sprintf("Aliases[%v]", idx), + reason: "value does not match regex pattern \"[0-9a-zA-Z.-_]*\"", + } + } + + } + return nil } @@ -146,6 +172,8 @@ var _Interface_Status_NotInLookup = map[InterfaceStatus]struct{}{ 0: {}, } +var _Interface_Aliases_Pattern = regexp.MustCompile("[0-9a-zA-Z.-_]*") + // Validate checks the field values on IPAddress with the rules defined in the // proto definition for this message. If any rules are violated, an error is returned. func (m *IPAddress) Validate() error { diff --git a/tests/plugin/validate.proto b/tests/plugin/validate.proto index a26b6a9..31be6e5 100644 --- a/tests/plugin/validate.proto +++ b/tests/plugin/validate.proto @@ -20,6 +20,11 @@ message Interface { not_in: [0] }]; repeated IPAddress addresses = 3; + repeated string aliases = 4 [ + (go.field).casttype = "github.com/alta/protopatch/tests/message.Names", + (validate.rules).repeated = {max_items: 10}, + (validate.rules).repeated.items.string = {min_len: 2, max_len: 10, pattern: "[0-9a-zA-Z.-_]*"} + ]; } message IPAddress {