Skip to content

Instantly share code, notes, and snippets.

@rodaine
Last active July 9, 2021 06:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodaine/0b65e59207da0b799214564ec33e5087 to your computer and use it in GitHub Desktop.
Save rodaine/0b65e59207da0b799214564ec33e5087 to your computer and use it in GitHub Desktop.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1-devel
// protoc v3.17.3
// source: foo.proto
package foo
import (
_ "github.com/envoyproxy/protoc-gen-validate/validate"
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 MyThingy struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to Type:
// *MyThingy_StringValue
// *MyThingy_Int64Value
// *MyThingy_DoubleValue
// *MyThingy_BooleanValue
Type isMyThingy_Type `protobuf_oneof:"type"`
LastUpdated *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=last_updated,json=lastUpdated,proto3" json:"last_updated,omitempty"`
}
func (x *MyThingy) Reset() {
*x = MyThingy{}
if protoimpl.UnsafeEnabled {
mi := &file_foo_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MyThingy) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MyThingy) ProtoMessage() {}
func (x *MyThingy) ProtoReflect() protoreflect.Message {
mi := &file_foo_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 MyThingy.ProtoReflect.Descriptor instead.
func (*MyThingy) Descriptor() ([]byte, []int) {
return file_foo_proto_rawDescGZIP(), []int{0}
}
func (m *MyThingy) GetType() isMyThingy_Type {
if m != nil {
return m.Type
}
return nil
}
func (x *MyThingy) GetStringValue() string {
if x, ok := x.GetType().(*MyThingy_StringValue); ok {
return x.StringValue
}
return ""
}
func (x *MyThingy) GetInt64Value() int64 {
if x, ok := x.GetType().(*MyThingy_Int64Value); ok {
return x.Int64Value
}
return 0
}
func (x *MyThingy) GetDoubleValue() float64 {
if x, ok := x.GetType().(*MyThingy_DoubleValue); ok {
return x.DoubleValue
}
return 0
}
func (x *MyThingy) GetBooleanValue() bool {
if x, ok := x.GetType().(*MyThingy_BooleanValue); ok {
return x.BooleanValue
}
return false
}
func (x *MyThingy) GetLastUpdated() *timestamppb.Timestamp {
if x != nil {
return x.LastUpdated
}
return nil
}
type isMyThingy_Type interface {
isMyThingy_Type()
}
type MyThingy_StringValue struct {
StringValue string `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"`
}
type MyThingy_Int64Value struct {
Int64Value int64 `protobuf:"varint,4,opt,name=int64_value,json=int64Value,proto3,oneof"`
}
type MyThingy_DoubleValue struct {
DoubleValue float64 `protobuf:"fixed64,6,opt,name=double_value,json=doubleValue,proto3,oneof"`
}
type MyThingy_BooleanValue struct {
BooleanValue bool `protobuf:"varint,8,opt,name=boolean_value,json=booleanValue,proto3,oneof"`
}
func (*MyThingy_StringValue) isMyThingy_Type() {}
func (*MyThingy_Int64Value) isMyThingy_Type() {}
func (*MyThingy_DoubleValue) isMyThingy_Type() {}
func (*MyThingy_BooleanValue) isMyThingy_Type() {}
var File_foo_proto protoreflect.FileDescriptor
var file_foo_proto_rawDesc = []byte{
0x0a, 0x09, 0x66, 0x6f, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x66, 0x6f, 0x6f,
0x1a, 0x0e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
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, 0x22, 0xf6, 0x01, 0x0a, 0x08, 0x4d, 0x79, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x79, 0x12, 0x2f,
0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x72, 0x05, 0x10, 0x01, 0x18, 0xe8, 0x07,
0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62,
0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25, 0x0a, 0x0d, 0x62, 0x6f, 0x6f, 0x6c, 0x65,
0x61, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00,
0x52, 0x0c, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3d,
0x0a, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x09,
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,
0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x0b, 0x0a,
0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x42, 0x18, 0x5a, 0x16, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x64, 0x61, 0x69, 0x6e, 0x65,
0x2f, 0x66, 0x6f, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_foo_proto_rawDescOnce sync.Once
file_foo_proto_rawDescData = file_foo_proto_rawDesc
)
func file_foo_proto_rawDescGZIP() []byte {
file_foo_proto_rawDescOnce.Do(func() {
file_foo_proto_rawDescData = protoimpl.X.CompressGZIP(file_foo_proto_rawDescData)
})
return file_foo_proto_rawDescData
}
var file_foo_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_foo_proto_goTypes = []interface{}{
(*MyThingy)(nil), // 0: foo.MyThingy
(*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp
}
var file_foo_proto_depIdxs = []int32{
1, // 0: foo.MyThingy.last_updated:type_name -> google.protobuf.Timestamp
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_foo_proto_init() }
func file_foo_proto_init() {
if File_foo_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_foo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MyThingy); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
file_foo_proto_msgTypes[0].OneofWrappers = []interface{}{
(*MyThingy_StringValue)(nil),
(*MyThingy_Int64Value)(nil),
(*MyThingy_DoubleValue)(nil),
(*MyThingy_BooleanValue)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_foo_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_foo_proto_goTypes,
DependencyIndexes: file_foo_proto_depIdxs,
MessageInfos: file_foo_proto_msgTypes,
}.Build()
File_foo_proto = out.File
file_foo_proto_rawDesc = nil
file_foo_proto_goTypes = nil
file_foo_proto_depIdxs = nil
}
// Code generated by protoc-gen-validate. DO NOT EDIT.
// source: foo.proto
package foo
import (
"bytes"
"errors"
"fmt"
"net"
"net/mail"
"net/url"
"regexp"
"strings"
"time"
"unicode/utf8"
"google.golang.org/protobuf/types/known/anypb"
)
// ensure the imports are used
var (
_ = bytes.MinRead
_ = errors.New("")
_ = fmt.Print
_ = utf8.UTFMax
_ = (*regexp.Regexp)(nil)
_ = (*strings.Reader)(nil)
_ = net.IPv4len
_ = time.Duration(0)
_ = (*url.URL)(nil)
_ = (*mail.Address)(nil)
_ = anypb.Any{}
)
// Validate checks the field values on MyThingy with the rules defined in the
// proto definition for this message. If any rules are violated, the first
// error encountered is returned, or nil if there are no violations.
func (m *MyThingy) Validate() error {
return m.validate(false)
}
// ValidateAll checks the field values on MyThingy with the rules defined in
// the proto definition for this message. If any rules are violated, the
// result is a list of violation errors wrapped in MyThingyMultiError, or nil
// if none found.
func (m *MyThingy) ValidateAll() error {
return m.validate(true)
}
func (m *MyThingy) validate(all bool) error {
if m == nil {
return nil
}
var errors []error
if all {
switch v := interface{}(m.GetLastUpdated()).(type) {
case interface{ ValidateAll() error }:
if err := v.ValidateAll(); err != nil {
errors = append(errors, MyThingyValidationError{
field: "LastUpdated",
reason: "embedded message failed validation",
cause: err,
})
}
case interface{ Validate() error }:
if err := v.Validate(); err != nil {
errors = append(errors, MyThingyValidationError{
field: "LastUpdated",
reason: "embedded message failed validation",
cause: err,
})
}
}
} else if v, ok := interface{}(m.GetLastUpdated()).(interface{ Validate() error }); ok {
if err := v.Validate(); err != nil {
return MyThingyValidationError{
field: "LastUpdated",
reason: "embedded message failed validation",
cause: err,
}
}
}
switch m.Type.(type) {
case *MyThingy_StringValue:
if l := utf8.RuneCountInString(m.GetStringValue()); l < 1 || l > 1000 {
err := MyThingyValidationError{
field: "StringValue",
reason: "value length must be between 1 and 1000 runes, inclusive",
}
if !all {
return err
}
errors = append(errors, err)
}
case *MyThingy_Int64Value:
// no validation rules for Int64Value
case *MyThingy_DoubleValue:
// no validation rules for DoubleValue
case *MyThingy_BooleanValue:
// no validation rules for BooleanValue
default:
err := MyThingyValidationError{
field: "Type",
reason: "value is required",
}
if !all {
return err
}
errors = append(errors, err)
}
if len(errors) > 0 {
return MyThingyMultiError(errors)
}
return nil
}
// MyThingyMultiError is an error wrapping multiple validation errors returned
// by MyThingy.ValidateAll() if the designated constraints aren't met.
type MyThingyMultiError []error
// Error returns a concatenation of all the error messages it wraps.
func (m MyThingyMultiError) Error() string {
var msgs []string
for _, err := range m {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "; ")
}
// AllErrors returns a list of validation violation errors.
func (m MyThingyMultiError) AllErrors() []error { return m }
// MyThingyValidationError is the validation error returned by
// MyThingy.Validate if the designated constraints aren't met.
type MyThingyValidationError struct {
field string
reason string
cause error
key bool
}
// Field function returns field value.
func (e MyThingyValidationError) Field() string { return e.field }
// Reason function returns reason value.
func (e MyThingyValidationError) Reason() string { return e.reason }
// Cause function returns cause value.
func (e MyThingyValidationError) Cause() error { return e.cause }
// Key function returns key value.
func (e MyThingyValidationError) Key() bool { return e.key }
// ErrorName returns error name.
func (e MyThingyValidationError) ErrorName() string { return "MyThingyValidationError" }
// Error satisfies the builtin error interface
func (e MyThingyValidationError) Error() string {
cause := ""
if e.cause != nil {
cause = fmt.Sprintf(" | caused by: %v", e.cause)
}
key := ""
if e.key {
key = "key for "
}
return fmt.Sprintf(
"invalid %sMyThingy.%s: %s%s",
key,
e.field,
e.reason,
cause)
}
var _ error = MyThingyValidationError{}
var _ interface {
Field() string
Reason() string
Key() bool
Cause() error
ErrorName() string
} = MyThingyValidationError{}
// protoc --go_out="paths=source_relative:." --validate_out="lang=go,paths=source_relative:." foo.proto
syntax="proto3";
package foo;
import "validate.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/rodaine/foo";
message MyThingy {
oneof type {
option (validate.required) = true;
string string_value = 2 [(validate.rules).string = {min_len: 1, max_len: 1000}];
int64 int64_value = 4;
double double_value = 6;
bool boolean_value = 8;
}
google.protobuf.Timestamp last_updated = 9;
}
package foo
import (
"google.golang.org/protobuf/types/known/timestamppb"
"testing"
)
func TestMyThingy(t *testing.T) {
tests := []struct{
name string
in *MyThingy
valid bool
}{
{
"with type",
&MyThingy{
Type: &MyThingy_Int64Value{Int64Value: 123},
LastUpdated: timestamppb.Now(),
},
true,
},
{
"with nil type",
&MyThingy{
Type: nil,
LastUpdated: timestamppb.Now(),
},
false,
},
{
"no type",
&MyThingy{LastUpdated: timestamppb.Now()},
false,
},
{
"nil in",
nil,
true,
},
{
"typed nil",
&MyThingy{Type: (*MyThingy_Int64Value)(nil)},
false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.in.Validate()
if test.valid && err != nil {
t.Fatalf("wanted no error, got %v", err)
} else if !test.valid && err == nil {
t.Fatal("wanted error, got nil")
}
})
}
}
module github.com/rodaine/foo
go 1.16
require (
github.com/envoyproxy/protoc-gen-validate v0.6.1
google.golang.org/protobuf v1.27.1
)
→ go test -v .
=== RUN TestMyThingy
=== RUN TestMyThingy/with_type
=== RUN TestMyThingy/with_nil_type
=== RUN TestMyThingy/no_type
=== RUN TestMyThingy/nil_in
=== RUN TestMyThingy/typed_nil
foo_test.go:53: wanted error, got nil
--- FAIL: TestMyThingy (0.00s)
--- PASS: TestMyThingy/with_type (0.00s)
--- PASS: TestMyThingy/with_nil_type (0.00s)
--- PASS: TestMyThingy/no_type (0.00s)
--- PASS: TestMyThingy/nil_in (0.00s)
--- FAIL: TestMyThingy/typed_nil (0.00s)
FAIL
FAIL github.com/rodaine/foo 0.105s
FAIL
@rodaine
Copy link
Author

rodaine commented Jul 9, 2021

Generated with versions:

protoc-gen-go v1.27.1-devel
protoc v3.17.3
protoc-gen-validate 4f41f10 (current master at the time of writing)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment