diff --git a/Gopkg.toml b/Gopkg.toml index eef028dcc..dc09ce53c 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -10,6 +10,10 @@ branch = "master" name = "golang.org/x/net" +[[constraint]] + name = "github.com/gogo/protobuf" + version = "1.1.1" + [[constraint]] branch = "master" name = "github.com/iancoleman/strcase" diff --git a/Makefile b/Makefile index 3c5e9ff42..2b18024fb 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,20 @@ GO_IMPORT_SPACES := ${VALIDATE_IMPORT},\ Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,\ Mgoogle/protobuf/wrappers.proto=github.com/golang/protobuf/ptypes/wrappers,\ Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor,\ + Mgogoproto/gogo.proto=${PACKAGE}/gogoproto GO_IMPORT:=$(subst $(space),,$(GO_IMPORT_SPACES)) +# protoc-gen-gogo parameters +GOGO_IMPORT_SPACES := ${VALIDATE_IMPORT},\ + Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types,\ + Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,\ + Mgoogle/protobuf/struct.proto=github.com/gogo/protobuf/types,\ + Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,\ + Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,\ + Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/types,\ + Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto +GOGO_IMPORT:=$(subst $(space),,$(GOGO_IMPORT_SPACES)) + .PHONY: build build: validate/validate.pb.go # generates the PGV binary and installs it into $$GOPATH/bin @@ -35,6 +47,8 @@ gazelle: buildozer 'replace deps @com_github_golang_protobuf//ptypes:go_default_library_gen @com_github_golang_protobuf//ptypes:go_default_library' '//...:%go_library' buildozer 'replace deps @io_bazel_rules_go//proto/wkt:duration_go_proto @com_github_golang_protobuf//ptypes/duration:go_default_library' '//...:%go_library' buildozer 'replace deps @io_bazel_rules_go//proto/wkt:timestamp_go_proto @com_github_golang_protobuf//ptypes/timestamp:go_default_library' '//...:%go_library' + buildozer 'replace deps //vendor/github.com/gogo/protobuf/proto:go_default_library @com_github_gogo_protobuf//proto:go_default_library' '//...:%go_library' + buildozer 'replace deps //vendor/github.com/gogo/protobuf/types:go_default_library @com_github_gogo_protobuf//types:go_default_library' '//...:%go_library' .PHONY: lint lint: bin/golint bin/shadow @@ -50,6 +64,9 @@ bin/shadow: bin/golint: GOBIN=$(shell pwd)/bin go install golang.org/x/lint/golint +bin/gogofast: + go build -o $@ ./vendor/github.com/gogo/protobuf/protoc-gen-gogofast + bin/protoc-gen-go: GOBIN=$(shell pwd)/bin go install github.com/golang/protobuf/protoc-gen-go @@ -57,38 +74,48 @@ bin/harness: cd tests && go build -o ../bin/harness ./harness/executor .PHONY: harness -harness: testcases tests/harness/go/harness.pb.go tests/harness/go/main/go-harness tests/harness/cc/cc-harness bin/harness +harness: testcases tests/harness/go/harness.pb.go tests/harness/gogo/harness.pb.go tests/harness/go/main/go-harness tests/harness/gogo/main/go-harness tests/harness/cc/cc-harness bin/harness # runs the test harness, validating a series of test cases in all supported languages - ./bin/harness -go -cc + ./bin/harness -go -gogo -cc .PHONY: bazel-harness bazel-harness: # runs the test harness via bazel - bazel run //tests/harness/executor:executor --incompatible_new_actions_api=false -- -go -cc -java -python + bazel run //tests/harness/executor:executor --incompatible_new_actions_api=false -- -go -gogo -cc -java -python .PHONY: testcases -testcases: bin/protoc-gen-go +testcases: bin/gogofast bin/protoc-gen-go # generate the test harness case protos rm -r tests/harness/cases/go || true mkdir tests/harness/cases/go rm -r tests/harness/cases/other_package/go || true mkdir tests/harness/cases/other_package/go + rm -r tests/harness/cases/gogo || true + mkdir tests/harness/cases/gogo + rm -r tests/harness/cases/other_package/gogo || true + mkdir tests/harness/cases/other_package/gogo # protoc-gen-go makes us go a package at a time cd tests/harness/cases/other_package && \ protoc \ -I . \ -I ../../../.. \ --go_out="${GO_IMPORT}:./go" \ + --plugin=protoc-gen-gogofast=$(shell pwd)/bin/gogofast \ --plugin=protoc-gen-go=$(shell pwd)/bin/protoc-gen-go \ + --gogofast_out="${GOGO_IMPORT}:./gogo" \ --validate_out="lang=go:./go" \ + --validate_out="lang=gogo:./gogo" \ ./*.proto cd tests/harness/cases && \ protoc \ -I . \ -I ../../.. \ --go_out="Mtests/harness/cases/other_package/embed.proto=${PACKAGE}/tests/harness/cases/other_package/go,${GO_IMPORT}:./go" \ + --plugin=protoc-gen-gogofast=$(shell pwd)/bin/gogofast \ --plugin=protoc-gen-go=$(shell pwd)/bin/protoc-gen-go \ + --gogofast_out="Mtests/harness/cases/other_package/embed.proto=${PACKAGE}/tests/harness/cases/other_package/gogo,${GOGO_IMPORT}:./gogo" \ --validate_out="lang=go,Mtests/harness/cases/other_package/embed.proto=${PACKAGE}/tests/harness/cases/other_package/go:./go" \ + --validate_out="lang=gogo,Mtests/harness/cases/other_package/embed.proto=${PACKAGE}/tests/harness/cases/other_package/gogo:./gogo" \ ./*.proto tests/harness/go/harness.pb.go: bin/protoc-gen-go @@ -97,10 +124,20 @@ tests/harness/go/harness.pb.go: bin/protoc-gen-go --plugin=protoc-gen-go=$(shell pwd)/bin/protoc-gen-go \ --go_out="${GO_IMPORT}:./go" harness.proto +tests/harness/gogo/harness.pb.go: bin/gogofast + # generates the test harness protos + cd tests/harness && protoc -I . \ + --plugin=protoc-gen-gogofast=$(shell pwd)/bin/gogofast \ + --gogofast_out="${GOGO_IMPORT}:./gogo" harness.proto + tests/harness/go/main/go-harness: # generates the go-specific test harness cd tests && go build -o ./harness/go/main/go-harness ./harness/go/main +tests/harness/gogo/main/go-harness: + # generates the gogo-specific test harness + cd tests && go build -o ./harness/gogo/main/go-harness ./harness/gogo/main + tests/harness/cc/cc-harness: tests/harness/cc/harness.cc # generates the C++-specific test harness # use bazel which knows how to pull in the C++ common proto libraries @@ -119,11 +156,17 @@ ci: lint bazel testcases bazel-harness build_generation_tests clean: (which bazel && bazel clean) || true rm -f \ + bin/gogofast \ bin/protoc-gen-go \ bin/harness \ tests/harness/cc/cc-harness \ tests/harness/go/main/go-harness \ + tests/harness/gogo/main/go-harness \ + tests/harness/gogo/harness.pb.go \ + tests/harness/gogo/harness.pb.go \ tests/harness/go/harness.pb.go rm -rf \ tests/harness/cases/go \ - tests/harness/cases/other_package/go + tests/harness/cases/other_package/go \ + tests/harness/cases/gogo \ + tests/harness/cases/other_package/gogo \ diff --git a/README.md b/README.md index ed512c802..847897959 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ make build - **`lang`**: specify the target language to generate. Currently, the only supported options are: - `go` + - `gogo` for [gogo proto](https://github.com/gogo/protobuf) (experimental) - `cc` for c++ (partially implemented) - `java` - `python` @@ -105,6 +106,30 @@ All messages generated include the new `Validate() error` method. PGV requires n **Note**: by default **example.pb.validate.go** is nested in a directory structure that matches your `option go_package` name. You can change this using the protoc parameter `paths=source_relative:.`. Then `--validate_out` will output the file where it is expected. See Google's protobuf documenation or [packages and input paths](https://github.com/golang/protobuf#packages-and-input-paths) or [parameters](https://github.com/golang/protobuf#parameters) for more information. +#### Gogo + +There is an experimental support for [gogo +protobuf](https://github.com/gogo/protobuf) plugin for `go`. Use the following +command to generate `gogo`-compatible validation code: + +```sh +protoc \ + -I . \ + -I ${GOPATH}/src \ + -I ${GOPATH}/src/github.com/envoyproxy/protoc-gen-validate \ + --gogofast_out=":../generated"\ + --validate_out="lang=gogo:../generated" \ example.proto +``` + +Gogo support has the following limitations: +- only `gogofast` plugin is supported and tested, meaning that the fields + should be properly annotated with `gogoproto` annotations; +- `gogoproto.nullable` is supported on fields; +- `gogoproto.stdduration` is supported on fields; +- `gogoproto.stdtime` is supported on fields; + +**Note**: by default **example.pb.validate.go** is nested in a directory structure that matches your `option go_package` name. You can change this using the protoc parameter `paths=source_relative:.`. Then `--validate_out` will output the file where it is expected. See Google's protobuf documenation or [packages and input paths](https://github.com/golang/protobuf#packages-and-input-paths) or [parameters](https://github.com/golang/protobuf#parameters) for more information. + #### Java Java generation is integrated with the existing protobuf toolchain for java projects. For Maven projects, add the diff --git a/bazel/pgv_proto_library.bzl b/bazel/pgv_proto_library.bzl index 7e9227367..a98aa30f6 100644 --- a/bazel/pgv_proto_library.bzl +++ b/bazel/pgv_proto_library.bzl @@ -22,6 +22,24 @@ def pgv_go_proto_library(name, proto = None, deps = [], **kwargs): **kwargs ) +def pgv_gogo_proto_library(name, proto = None, deps = [], **kwargs): + go_proto_compiler( + name = "pgv_plugin_gogo", + suffix = ".pb.validate.go", + valid_archive = False, + plugin = "//:protoc-gen-validate", + options = ["lang=gogo"], + ) + + go_proto_library( + name = name, + proto = proto, + deps = ["//validate:go_default_library"] + deps, + compilers = ["@io_bazel_rules_go//proto:gogo_proto", "pgv_plugin_gogo"], + visibility = ["//visibility:public"], + **kwargs + ) + def pgv_cc_proto_library( name, deps = [], diff --git a/go.mod b/go.mod index 95aeb0360..00340a0ed 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/envoyproxy/protoc-gen-validate go 1.14 require ( + github.com/gogo/protobuf v1.3.1 github.com/golang/protobuf v1.3.1 github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7 github.com/lyft/protoc-gen-star v0.4.10 diff --git a/go.sum b/go.sum index 827703c38..c616b11c2 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,13 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7 h1:ux/56T2xqZO/3cP1I2F86qpeoYPCOzk+KF/UH/Ar+lk= github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/lyft/protoc-gen-star v0.4.10 h1:yekjh68Yp+AF+IXd/0vLd+DQv+eb6joCTA6qxRmtE2A= github.com/lyft/protoc-gen-star v0.4.10/go.mod h1:mE8fbna26u7aEA2QCVvvfBU/ZrPgocG1206xAFPcs94= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -31,6 +35,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 h1:SjQ2+AKWgZLc1xej6WSzL+Dfs5Uyd5xcZH1mGC411IA= diff --git a/gogoproto/BUILD.bazel b/gogoproto/BUILD.bazel new file mode 100644 index 000000000..fb349d2dc --- /dev/null +++ b/gogoproto/BUILD.bazel @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") +load("@rules_proto//proto:defs.bzl", "proto_library") + +go_library( + name = "go_default_library", + embed = [":gogoproto_go_proto"], + importpath = "github.com/envoyproxy/protoc-gen-validate/gogoproto", + visibility = ["//visibility:public"], +) + +proto_library( + name = "gogoproto_proto", + srcs = ["gogo.proto"], + visibility = ["//visibility:public"], + deps = ["@com_google_protobuf//:descriptor_proto"], +) + +go_proto_library( + name = "gogoproto_go_proto", + importpath = "github.com/envoyproxy/protoc-gen-validate/gogoproto", + proto = ":gogoproto_proto", + visibility = ["//visibility:public"], +) diff --git a/gogoproto/README.md b/gogoproto/README.md new file mode 100644 index 000000000..8fd954577 --- /dev/null +++ b/gogoproto/README.md @@ -0,0 +1,4 @@ +This directory contains a copy of the +[gogoproto](https://github.com/gogo/protobuf) annotations processed using the +regular protoc golang plugin. The annotations are needed to import the protobuf +descriptor declarations into the validation plugin. diff --git a/gogoproto/gogo.pb.go b/gogoproto/gogo.pb.go new file mode 100644 index 000000000..4bc4a3d18 --- /dev/null +++ b/gogoproto/gogo.pb.go @@ -0,0 +1,792 @@ +// Code generated by protoc-gen-go. +// source: gogoproto/gogo.proto +// DO NOT EDIT! + +/* +Package gogoproto is a generated protocol buffer package. + +It is generated from these files: + gogoproto/gogo.proto + +It has these top-level messages: +*/ +package gogoproto + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +var E_GoprotoEnumPrefix = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62001, + Name: "gogoproto.goproto_enum_prefix", + Tag: "varint,62001,opt,name=goproto_enum_prefix,json=goprotoEnumPrefix", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoEnumStringer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62021, + Name: "gogoproto.goproto_enum_stringer", + Tag: "varint,62021,opt,name=goproto_enum_stringer,json=goprotoEnumStringer", + Filename: "gogoproto/gogo.proto", +} + +var E_EnumStringer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62022, + Name: "gogoproto.enum_stringer", + Tag: "varint,62022,opt,name=enum_stringer,json=enumStringer", + Filename: "gogoproto/gogo.proto", +} + +var E_EnumCustomname = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumOptions)(nil), + ExtensionType: (*string)(nil), + Field: 62023, + Name: "gogoproto.enum_customname", + Tag: "bytes,62023,opt,name=enum_customname,json=enumCustomname", + Filename: "gogoproto/gogo.proto", +} + +var E_Enumdecl = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 62024, + Name: "gogoproto.enumdecl", + Tag: "varint,62024,opt,name=enumdecl", + Filename: "gogoproto/gogo.proto", +} + +var E_EnumvalueCustomname = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.EnumValueOptions)(nil), + ExtensionType: (*string)(nil), + Field: 66001, + Name: "gogoproto.enumvalue_customname", + Tag: "bytes,66001,opt,name=enumvalue_customname,json=enumvalueCustomname", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoGettersAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63001, + Name: "gogoproto.goproto_getters_all", + Tag: "varint,63001,opt,name=goproto_getters_all,json=goprotoGettersAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoEnumPrefixAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63002, + Name: "gogoproto.goproto_enum_prefix_all", + Tag: "varint,63002,opt,name=goproto_enum_prefix_all,json=goprotoEnumPrefixAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoStringerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63003, + Name: "gogoproto.goproto_stringer_all", + Tag: "varint,63003,opt,name=goproto_stringer_all,json=goprotoStringerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_VerboseEqualAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63004, + Name: "gogoproto.verbose_equal_all", + Tag: "varint,63004,opt,name=verbose_equal_all,json=verboseEqualAll", + Filename: "gogoproto/gogo.proto", +} + +var E_FaceAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63005, + Name: "gogoproto.face_all", + Tag: "varint,63005,opt,name=face_all,json=faceAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GostringAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63006, + Name: "gogoproto.gostring_all", + Tag: "varint,63006,opt,name=gostring_all,json=gostringAll", + Filename: "gogoproto/gogo.proto", +} + +var E_PopulateAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63007, + Name: "gogoproto.populate_all", + Tag: "varint,63007,opt,name=populate_all,json=populateAll", + Filename: "gogoproto/gogo.proto", +} + +var E_StringerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63008, + Name: "gogoproto.stringer_all", + Tag: "varint,63008,opt,name=stringer_all,json=stringerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_OnlyoneAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63009, + Name: "gogoproto.onlyone_all", + Tag: "varint,63009,opt,name=onlyone_all,json=onlyoneAll", + Filename: "gogoproto/gogo.proto", +} + +var E_EqualAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63013, + Name: "gogoproto.equal_all", + Tag: "varint,63013,opt,name=equal_all,json=equalAll", + Filename: "gogoproto/gogo.proto", +} + +var E_DescriptionAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63014, + Name: "gogoproto.description_all", + Tag: "varint,63014,opt,name=description_all,json=descriptionAll", + Filename: "gogoproto/gogo.proto", +} + +var E_TestgenAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63015, + Name: "gogoproto.testgen_all", + Tag: "varint,63015,opt,name=testgen_all,json=testgenAll", + Filename: "gogoproto/gogo.proto", +} + +var E_BenchgenAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63016, + Name: "gogoproto.benchgen_all", + Tag: "varint,63016,opt,name=benchgen_all,json=benchgenAll", + Filename: "gogoproto/gogo.proto", +} + +var E_MarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63017, + Name: "gogoproto.marshaler_all", + Tag: "varint,63017,opt,name=marshaler_all,json=marshalerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_UnmarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63018, + Name: "gogoproto.unmarshaler_all", + Tag: "varint,63018,opt,name=unmarshaler_all,json=unmarshalerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_StableMarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63019, + Name: "gogoproto.stable_marshaler_all", + Tag: "varint,63019,opt,name=stable_marshaler_all,json=stableMarshalerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_SizerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63020, + Name: "gogoproto.sizer_all", + Tag: "varint,63020,opt,name=sizer_all,json=sizerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoEnumStringerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63021, + Name: "gogoproto.goproto_enum_stringer_all", + Tag: "varint,63021,opt,name=goproto_enum_stringer_all,json=goprotoEnumStringerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_EnumStringerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63022, + Name: "gogoproto.enum_stringer_all", + Tag: "varint,63022,opt,name=enum_stringer_all,json=enumStringerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_UnsafeMarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63023, + Name: "gogoproto.unsafe_marshaler_all", + Tag: "varint,63023,opt,name=unsafe_marshaler_all,json=unsafeMarshalerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_UnsafeUnmarshalerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63024, + Name: "gogoproto.unsafe_unmarshaler_all", + Tag: "varint,63024,opt,name=unsafe_unmarshaler_all,json=unsafeUnmarshalerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoExtensionsMapAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63025, + Name: "gogoproto.goproto_extensions_map_all", + Tag: "varint,63025,opt,name=goproto_extensions_map_all,json=goprotoExtensionsMapAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoUnrecognizedAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63026, + Name: "gogoproto.goproto_unrecognized_all", + Tag: "varint,63026,opt,name=goproto_unrecognized_all,json=goprotoUnrecognizedAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GogoprotoImport = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63027, + Name: "gogoproto.gogoproto_import", + Tag: "varint,63027,opt,name=gogoproto_import,json=gogoprotoImport", + Filename: "gogoproto/gogo.proto", +} + +var E_ProtosizerAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63028, + Name: "gogoproto.protosizer_all", + Tag: "varint,63028,opt,name=protosizer_all,json=protosizerAll", + Filename: "gogoproto/gogo.proto", +} + +var E_CompareAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63029, + Name: "gogoproto.compare_all", + Tag: "varint,63029,opt,name=compare_all,json=compareAll", + Filename: "gogoproto/gogo.proto", +} + +var E_TypedeclAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63030, + Name: "gogoproto.typedecl_all", + Tag: "varint,63030,opt,name=typedecl_all,json=typedeclAll", + Filename: "gogoproto/gogo.proto", +} + +var E_EnumdeclAll = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FileOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 63031, + Name: "gogoproto.enumdecl_all", + Tag: "varint,63031,opt,name=enumdecl_all,json=enumdeclAll", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoGetters = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64001, + Name: "gogoproto.goproto_getters", + Tag: "varint,64001,opt,name=goproto_getters,json=goprotoGetters", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoStringer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64003, + Name: "gogoproto.goproto_stringer", + Tag: "varint,64003,opt,name=goproto_stringer,json=goprotoStringer", + Filename: "gogoproto/gogo.proto", +} + +var E_VerboseEqual = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64004, + Name: "gogoproto.verbose_equal", + Tag: "varint,64004,opt,name=verbose_equal,json=verboseEqual", + Filename: "gogoproto/gogo.proto", +} + +var E_Face = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64005, + Name: "gogoproto.face", + Tag: "varint,64005,opt,name=face", + Filename: "gogoproto/gogo.proto", +} + +var E_Gostring = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64006, + Name: "gogoproto.gostring", + Tag: "varint,64006,opt,name=gostring", + Filename: "gogoproto/gogo.proto", +} + +var E_Populate = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64007, + Name: "gogoproto.populate", + Tag: "varint,64007,opt,name=populate", + Filename: "gogoproto/gogo.proto", +} + +var E_Stringer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 67008, + Name: "gogoproto.stringer", + Tag: "varint,67008,opt,name=stringer", + Filename: "gogoproto/gogo.proto", +} + +var E_Onlyone = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64009, + Name: "gogoproto.onlyone", + Tag: "varint,64009,opt,name=onlyone", + Filename: "gogoproto/gogo.proto", +} + +var E_Equal = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64013, + Name: "gogoproto.equal", + Tag: "varint,64013,opt,name=equal", + Filename: "gogoproto/gogo.proto", +} + +var E_Description = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64014, + Name: "gogoproto.description", + Tag: "varint,64014,opt,name=description", + Filename: "gogoproto/gogo.proto", +} + +var E_Testgen = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64015, + Name: "gogoproto.testgen", + Tag: "varint,64015,opt,name=testgen", + Filename: "gogoproto/gogo.proto", +} + +var E_Benchgen = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64016, + Name: "gogoproto.benchgen", + Tag: "varint,64016,opt,name=benchgen", + Filename: "gogoproto/gogo.proto", +} + +var E_Marshaler = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64017, + Name: "gogoproto.marshaler", + Tag: "varint,64017,opt,name=marshaler", + Filename: "gogoproto/gogo.proto", +} + +var E_Unmarshaler = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64018, + Name: "gogoproto.unmarshaler", + Tag: "varint,64018,opt,name=unmarshaler", + Filename: "gogoproto/gogo.proto", +} + +var E_StableMarshaler = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64019, + Name: "gogoproto.stable_marshaler", + Tag: "varint,64019,opt,name=stable_marshaler,json=stableMarshaler", + Filename: "gogoproto/gogo.proto", +} + +var E_Sizer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64020, + Name: "gogoproto.sizer", + Tag: "varint,64020,opt,name=sizer", + Filename: "gogoproto/gogo.proto", +} + +var E_UnsafeMarshaler = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64023, + Name: "gogoproto.unsafe_marshaler", + Tag: "varint,64023,opt,name=unsafe_marshaler,json=unsafeMarshaler", + Filename: "gogoproto/gogo.proto", +} + +var E_UnsafeUnmarshaler = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64024, + Name: "gogoproto.unsafe_unmarshaler", + Tag: "varint,64024,opt,name=unsafe_unmarshaler,json=unsafeUnmarshaler", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoExtensionsMap = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64025, + Name: "gogoproto.goproto_extensions_map", + Tag: "varint,64025,opt,name=goproto_extensions_map,json=goprotoExtensionsMap", + Filename: "gogoproto/gogo.proto", +} + +var E_GoprotoUnrecognized = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64026, + Name: "gogoproto.goproto_unrecognized", + Tag: "varint,64026,opt,name=goproto_unrecognized,json=goprotoUnrecognized", + Filename: "gogoproto/gogo.proto", +} + +var E_Protosizer = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64028, + Name: "gogoproto.protosizer", + Tag: "varint,64028,opt,name=protosizer", + Filename: "gogoproto/gogo.proto", +} + +var E_Compare = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64029, + Name: "gogoproto.compare", + Tag: "varint,64029,opt,name=compare", + Filename: "gogoproto/gogo.proto", +} + +var E_Typedecl = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 64030, + Name: "gogoproto.typedecl", + Tag: "varint,64030,opt,name=typedecl", + Filename: "gogoproto/gogo.proto", +} + +var E_Nullable = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65001, + Name: "gogoproto.nullable", + Tag: "varint,65001,opt,name=nullable", + Filename: "gogoproto/gogo.proto", +} + +var E_Embed = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65002, + Name: "gogoproto.embed", + Tag: "varint,65002,opt,name=embed", + Filename: "gogoproto/gogo.proto", +} + +var E_Customtype = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65003, + Name: "gogoproto.customtype", + Tag: "bytes,65003,opt,name=customtype", + Filename: "gogoproto/gogo.proto", +} + +var E_Customname = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65004, + Name: "gogoproto.customname", + Tag: "bytes,65004,opt,name=customname", + Filename: "gogoproto/gogo.proto", +} + +var E_Jsontag = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65005, + Name: "gogoproto.jsontag", + Tag: "bytes,65005,opt,name=jsontag", + Filename: "gogoproto/gogo.proto", +} + +var E_Moretags = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65006, + Name: "gogoproto.moretags", + Tag: "bytes,65006,opt,name=moretags", + Filename: "gogoproto/gogo.proto", +} + +var E_Casttype = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65007, + Name: "gogoproto.casttype", + Tag: "bytes,65007,opt,name=casttype", + Filename: "gogoproto/gogo.proto", +} + +var E_Castkey = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65008, + Name: "gogoproto.castkey", + Tag: "bytes,65008,opt,name=castkey", + Filename: "gogoproto/gogo.proto", +} + +var E_Castvalue = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 65009, + Name: "gogoproto.castvalue", + Tag: "bytes,65009,opt,name=castvalue", + Filename: "gogoproto/gogo.proto", +} + +var E_Stdtime = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65010, + Name: "gogoproto.stdtime", + Tag: "varint,65010,opt,name=stdtime", + Filename: "gogoproto/gogo.proto", +} + +var E_Stdduration = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 65011, + Name: "gogoproto.stdduration", + Tag: "varint,65011,opt,name=stdduration", + Filename: "gogoproto/gogo.proto", +} + +func init() { + proto.RegisterExtension(E_GoprotoEnumPrefix) + proto.RegisterExtension(E_GoprotoEnumStringer) + proto.RegisterExtension(E_EnumStringer) + proto.RegisterExtension(E_EnumCustomname) + proto.RegisterExtension(E_Enumdecl) + proto.RegisterExtension(E_EnumvalueCustomname) + proto.RegisterExtension(E_GoprotoGettersAll) + proto.RegisterExtension(E_GoprotoEnumPrefixAll) + proto.RegisterExtension(E_GoprotoStringerAll) + proto.RegisterExtension(E_VerboseEqualAll) + proto.RegisterExtension(E_FaceAll) + proto.RegisterExtension(E_GostringAll) + proto.RegisterExtension(E_PopulateAll) + proto.RegisterExtension(E_StringerAll) + proto.RegisterExtension(E_OnlyoneAll) + proto.RegisterExtension(E_EqualAll) + proto.RegisterExtension(E_DescriptionAll) + proto.RegisterExtension(E_TestgenAll) + proto.RegisterExtension(E_BenchgenAll) + proto.RegisterExtension(E_MarshalerAll) + proto.RegisterExtension(E_UnmarshalerAll) + proto.RegisterExtension(E_StableMarshalerAll) + proto.RegisterExtension(E_SizerAll) + proto.RegisterExtension(E_GoprotoEnumStringerAll) + proto.RegisterExtension(E_EnumStringerAll) + proto.RegisterExtension(E_UnsafeMarshalerAll) + proto.RegisterExtension(E_UnsafeUnmarshalerAll) + proto.RegisterExtension(E_GoprotoExtensionsMapAll) + proto.RegisterExtension(E_GoprotoUnrecognizedAll) + proto.RegisterExtension(E_GogoprotoImport) + proto.RegisterExtension(E_ProtosizerAll) + proto.RegisterExtension(E_CompareAll) + proto.RegisterExtension(E_TypedeclAll) + proto.RegisterExtension(E_EnumdeclAll) + proto.RegisterExtension(E_GoprotoGetters) + proto.RegisterExtension(E_GoprotoStringer) + proto.RegisterExtension(E_VerboseEqual) + proto.RegisterExtension(E_Face) + proto.RegisterExtension(E_Gostring) + proto.RegisterExtension(E_Populate) + proto.RegisterExtension(E_Stringer) + proto.RegisterExtension(E_Onlyone) + proto.RegisterExtension(E_Equal) + proto.RegisterExtension(E_Description) + proto.RegisterExtension(E_Testgen) + proto.RegisterExtension(E_Benchgen) + proto.RegisterExtension(E_Marshaler) + proto.RegisterExtension(E_Unmarshaler) + proto.RegisterExtension(E_StableMarshaler) + proto.RegisterExtension(E_Sizer) + proto.RegisterExtension(E_UnsafeMarshaler) + proto.RegisterExtension(E_UnsafeUnmarshaler) + proto.RegisterExtension(E_GoprotoExtensionsMap) + proto.RegisterExtension(E_GoprotoUnrecognized) + proto.RegisterExtension(E_Protosizer) + proto.RegisterExtension(E_Compare) + proto.RegisterExtension(E_Typedecl) + proto.RegisterExtension(E_Nullable) + proto.RegisterExtension(E_Embed) + proto.RegisterExtension(E_Customtype) + proto.RegisterExtension(E_Customname) + proto.RegisterExtension(E_Jsontag) + proto.RegisterExtension(E_Moretags) + proto.RegisterExtension(E_Casttype) + proto.RegisterExtension(E_Castkey) + proto.RegisterExtension(E_Castvalue) + proto.RegisterExtension(E_Stdtime) + proto.RegisterExtension(E_Stdduration) +} + +func init() { proto.RegisterFile("gogoproto/gogo.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 1182 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x98, 0x4b, 0x6f, 0x1c, 0x45, + 0x10, 0x80, 0x85, 0x70, 0x64, 0x6f, 0xf9, 0x85, 0xd7, 0xc6, 0x84, 0x08, 0x44, 0x72, 0xe3, 0x64, + 0x9f, 0x22, 0x94, 0xb6, 0x22, 0xcb, 0xb1, 0x1c, 0x2b, 0x08, 0x83, 0x65, 0xe2, 0x00, 0xe2, 0xb0, + 0x9a, 0xdd, 0x6d, 0x4f, 0x16, 0x66, 0xa6, 0x87, 0x99, 0x9e, 0x28, 0xce, 0x0d, 0x85, 0x87, 0x10, + 0xe2, 0x8d, 0x04, 0x09, 0x49, 0x80, 0x03, 0xef, 0x67, 0x78, 0x5e, 0xb9, 0xf0, 0xb8, 0xf2, 0x1f, + 0xb8, 0x00, 0xe6, 0xed, 0x9b, 0x2f, 0xa8, 0x66, 0xaa, 0x66, 0x7b, 0xd6, 0x2b, 0x75, 0xef, 0x6d, + 0x76, 0xdd, 0xdf, 0xb7, 0x35, 0x55, 0xd3, 0x55, 0xd3, 0x86, 0x19, 0x5f, 0xf9, 0x2a, 0x4e, 0x94, + 0x56, 0xf3, 0x78, 0x35, 0x97, 0x5f, 0xd6, 0x6b, 0xe5, 0xb7, 0x87, 0x0e, 0xfb, 0x4a, 0xf9, 0x81, + 0x9c, 0xcf, 0x3f, 0x35, 0xb3, 0xad, 0xf9, 0xb6, 0x4c, 0x5b, 0x49, 0x27, 0xd6, 0x2a, 0x29, 0x16, + 0x8b, 0x7b, 0x61, 0x9a, 0x16, 0x37, 0x64, 0x94, 0x85, 0x8d, 0x38, 0x91, 0x5b, 0x9d, 0xf3, 0xf5, + 0xdb, 0xe6, 0x0a, 0x72, 0x8e, 0xc9, 0xb9, 0x95, 0x28, 0x0b, 0xef, 0x8b, 0x75, 0x47, 0x45, 0xe9, + 0xc1, 0xeb, 0xbf, 0xdc, 0x78, 0xf8, 0x86, 0x3b, 0x47, 0x36, 0xa6, 0x08, 0xc5, 0xbf, 0xad, 0xe7, + 0xa0, 0xd8, 0x80, 0x9b, 0x2b, 0xbe, 0x54, 0x27, 0x9d, 0xc8, 0x97, 0x89, 0xc5, 0xf8, 0x3d, 0x19, + 0xa7, 0x0d, 0xe3, 0xfd, 0x84, 0x8a, 0x65, 0x18, 0x1f, 0xc4, 0xf5, 0x03, 0xb9, 0xc6, 0xa4, 0x29, + 0x59, 0x85, 0xc9, 0x5c, 0xd2, 0xca, 0x52, 0xad, 0xc2, 0xc8, 0x0b, 0xa5, 0x45, 0xf3, 0x63, 0xae, + 0xa9, 0x6d, 0x4c, 0x20, 0xb6, 0x5c, 0x52, 0x42, 0xc0, 0x08, 0x7e, 0xd3, 0x96, 0xad, 0xc0, 0x62, + 0xf8, 0x89, 0x02, 0x29, 0xd7, 0x8b, 0x33, 0x30, 0x83, 0xd7, 0xe7, 0xbc, 0x20, 0x93, 0x66, 0x24, + 0x47, 0xfa, 0x7a, 0xce, 0xe0, 0x32, 0x96, 0xfd, 0x7c, 0x71, 0x28, 0x0f, 0x67, 0xba, 0x14, 0x18, + 0x31, 0x19, 0x55, 0xf4, 0xa5, 0xd6, 0x32, 0x49, 0x1b, 0x5e, 0xd0, 0x2f, 0xbc, 0x93, 0x9d, 0xa0, + 0x34, 0x5e, 0xda, 0xa9, 0x56, 0x71, 0xb5, 0x20, 0x97, 0x82, 0x40, 0x6c, 0xc2, 0x2d, 0x7d, 0x9e, + 0x0a, 0x07, 0xe7, 0x65, 0x72, 0xce, 0xec, 0x7b, 0x32, 0x50, 0xbb, 0x0e, 0xfc, 0x7d, 0x59, 0x4b, + 0x07, 0xe7, 0x1b, 0xe4, 0xac, 0x13, 0xcb, 0x25, 0x45, 0xe3, 0xdd, 0x30, 0x75, 0x4e, 0x26, 0x4d, + 0x95, 0xca, 0x86, 0x7c, 0x2c, 0xf3, 0x02, 0x07, 0xdd, 0x15, 0xd2, 0x4d, 0x12, 0xb8, 0x82, 0x1c, + 0xba, 0x8e, 0xc1, 0xc8, 0x96, 0xd7, 0x92, 0x0e, 0x8a, 0xab, 0xa4, 0x18, 0xc6, 0xf5, 0x88, 0x2e, + 0xc1, 0x98, 0xaf, 0x8a, 0x5b, 0x72, 0xc0, 0xaf, 0x11, 0x3e, 0xca, 0x0c, 0x29, 0x62, 0x15, 0x67, + 0x81, 0xa7, 0x5d, 0x22, 0x78, 0x93, 0x15, 0xcc, 0x90, 0x62, 0x80, 0xb4, 0xbe, 0xc5, 0x8a, 0xd4, + 0xc8, 0xe7, 0x22, 0x8c, 0xaa, 0x28, 0xd8, 0x56, 0x91, 0x4b, 0x10, 0x6f, 0x93, 0x01, 0x08, 0x41, + 0xc1, 0x02, 0xd4, 0x5c, 0x0b, 0xf1, 0xce, 0x0e, 0x6f, 0x0f, 0xae, 0xc0, 0x2a, 0x4c, 0x72, 0x83, + 0xea, 0xa8, 0xc8, 0x41, 0xf1, 0x2e, 0x29, 0x26, 0x0c, 0x8c, 0x6e, 0x43, 0xcb, 0x54, 0xfb, 0xd2, + 0x45, 0xf2, 0x1e, 0xdf, 0x06, 0x21, 0x94, 0xca, 0xa6, 0x8c, 0x5a, 0x67, 0xdd, 0x0c, 0xef, 0x73, + 0x2a, 0x99, 0x41, 0xc5, 0x32, 0x8c, 0x87, 0x5e, 0x92, 0x9e, 0xf5, 0x02, 0xa7, 0x72, 0x7c, 0x40, + 0x8e, 0xb1, 0x12, 0xa2, 0x8c, 0x64, 0xd1, 0x20, 0x9a, 0x0f, 0x39, 0x23, 0x06, 0x46, 0x5b, 0x2f, + 0xd5, 0x5e, 0x33, 0x90, 0x8d, 0x41, 0x6c, 0x1f, 0xf1, 0xd6, 0x2b, 0xd8, 0x35, 0xd3, 0xb8, 0x00, + 0xb5, 0xb4, 0x73, 0xc1, 0x49, 0xf3, 0x31, 0x57, 0x3a, 0x07, 0x10, 0x7e, 0x08, 0x6e, 0xed, 0x3b, + 0x26, 0x1c, 0x64, 0x9f, 0x90, 0x6c, 0xb6, 0xcf, 0xa8, 0xa0, 0x96, 0x30, 0xa8, 0xf2, 0x53, 0x6e, + 0x09, 0xb2, 0xc7, 0xb5, 0x0e, 0x33, 0x59, 0x94, 0x7a, 0x5b, 0x83, 0x65, 0xed, 0x33, 0xce, 0x5a, + 0xc1, 0x56, 0xb2, 0x76, 0x1a, 0x66, 0xc9, 0x38, 0x58, 0x5d, 0x3f, 0xe7, 0xc6, 0x5a, 0xd0, 0x9b, + 0xd5, 0xea, 0x3e, 0x0c, 0x87, 0xca, 0x74, 0x9e, 0xd7, 0x32, 0x4a, 0x91, 0x69, 0x84, 0x5e, 0xec, + 0x60, 0xbe, 0x4e, 0x66, 0xee, 0xf8, 0x2b, 0xa5, 0x60, 0xcd, 0x8b, 0x51, 0xfe, 0x20, 0x1c, 0x64, + 0x79, 0x16, 0x25, 0xb2, 0xa5, 0xfc, 0xa8, 0x73, 0x41, 0xb6, 0x1d, 0xd4, 0x5f, 0xf4, 0x94, 0x6a, + 0xd3, 0xc0, 0xd1, 0x7c, 0x0a, 0x6e, 0x2a, 0xdf, 0x55, 0x1a, 0x9d, 0x30, 0x56, 0x89, 0xb6, 0x18, + 0xbf, 0xe4, 0x4a, 0x95, 0xdc, 0xa9, 0x1c, 0x13, 0x2b, 0x30, 0x91, 0x7f, 0x74, 0x7d, 0x24, 0xbf, + 0x22, 0xd1, 0x78, 0x97, 0xa2, 0xc6, 0xd1, 0x52, 0x61, 0xec, 0x25, 0x2e, 0xfd, 0xef, 0x6b, 0x6e, + 0x1c, 0x84, 0x50, 0xe3, 0xd0, 0xdb, 0xb1, 0xc4, 0x69, 0xef, 0x60, 0xf8, 0x86, 0x1b, 0x07, 0x33, + 0xa4, 0xe0, 0x17, 0x06, 0x07, 0xc5, 0xb7, 0xac, 0x60, 0xa6, 0xd8, 0x03, 0x93, 0x3d, 0xef, 0x03, + 0xf5, 0x3b, 0xf6, 0x59, 0xd6, 0x64, 0x9a, 0x7a, 0x7e, 0x29, 0x7a, 0x7c, 0x97, 0x3a, 0x47, 0xf5, + 0x75, 0x40, 0xdc, 0x83, 0x45, 0xaa, 0x0e, 0x6d, 0xbb, 0xec, 0xe2, 0x6e, 0x59, 0xa7, 0xca, 0xcc, + 0x16, 0x27, 0x61, 0xbc, 0x32, 0xb0, 0xed, 0xaa, 0x27, 0x48, 0x35, 0x66, 0xce, 0x6b, 0x71, 0x14, + 0x86, 0x70, 0xf8, 0xda, 0xf1, 0x27, 0x09, 0xcf, 0x97, 0x8b, 0xe3, 0x30, 0xc2, 0x43, 0xd7, 0x8e, + 0x3e, 0x45, 0x68, 0x89, 0x20, 0xce, 0x03, 0xd7, 0x8e, 0x3f, 0xcd, 0x38, 0x23, 0x88, 0xbb, 0xa7, + 0xf0, 0xbb, 0x67, 0x87, 0xa8, 0x69, 0x72, 0xee, 0x16, 0x60, 0x98, 0x26, 0xad, 0x9d, 0x7e, 0x86, + 0x7e, 0x9c, 0x09, 0x71, 0x17, 0x1c, 0x70, 0x4c, 0xf8, 0x73, 0x84, 0x16, 0xeb, 0xc5, 0x32, 0x8c, + 0x1a, 0xd3, 0xd5, 0x8e, 0x3f, 0x4f, 0xb8, 0x49, 0x61, 0xe8, 0x34, 0x5d, 0xed, 0x82, 0x17, 0x38, + 0x74, 0x22, 0x30, 0x6d, 0x3c, 0x58, 0xed, 0xf4, 0x8b, 0x9c, 0x75, 0x46, 0xc4, 0x22, 0xd4, 0xca, + 0x66, 0x69, 0xe7, 0x5f, 0x22, 0xbe, 0xcb, 0x60, 0x06, 0x8c, 0x66, 0x6d, 0x57, 0xbc, 0xcc, 0x19, + 0x30, 0x28, 0xdc, 0x46, 0xbd, 0x03, 0xd8, 0x6e, 0x7a, 0x85, 0xb7, 0x51, 0xcf, 0xfc, 0xc5, 0x6a, + 0xe6, 0x3d, 0xcb, 0xae, 0x78, 0x95, 0xab, 0x99, 0xaf, 0xc7, 0x30, 0x7a, 0x27, 0x9a, 0xdd, 0xf1, + 0x1a, 0x87, 0xd1, 0x33, 0xd0, 0xc4, 0x3a, 0xd4, 0xf7, 0x4f, 0x33, 0xbb, 0xef, 0x75, 0xf2, 0x4d, + 0xed, 0x1b, 0x66, 0xe2, 0x01, 0x98, 0xed, 0x3f, 0xc9, 0xec, 0xd6, 0x4b, 0xbb, 0x3d, 0x67, 0x0f, + 0x73, 0x90, 0x89, 0xd3, 0xdd, 0xb3, 0x87, 0x39, 0xc5, 0xec, 0xda, 0xcb, 0xbb, 0xd5, 0xa3, 0xa9, + 0x39, 0xc4, 0xc4, 0x12, 0x40, 0x77, 0x80, 0xd8, 0x5d, 0x57, 0xc8, 0x65, 0x40, 0xb8, 0x35, 0x68, + 0x7e, 0xd8, 0xf9, 0xab, 0xbc, 0x35, 0x88, 0xc0, 0xad, 0xc1, 0xa3, 0xc3, 0x4e, 0x5f, 0xe3, 0xad, + 0xc1, 0x88, 0x58, 0x80, 0x91, 0x28, 0x0b, 0x02, 0x7c, 0xb6, 0xea, 0xb7, 0xf7, 0x19, 0x33, 0x32, + 0x68, 0x33, 0xfc, 0xeb, 0x1e, 0xc1, 0x0c, 0x88, 0xa3, 0x70, 0x40, 0x86, 0x4d, 0xd9, 0xb6, 0x91, + 0xbf, 0xed, 0x71, 0x3f, 0xc1, 0xd5, 0x62, 0x11, 0xa0, 0x38, 0xf9, 0x62, 0x14, 0x36, 0xf6, 0xf7, + 0xbd, 0xe2, 0x10, 0x6e, 0x20, 0x5d, 0x41, 0x7e, 0x74, 0xb6, 0x08, 0x76, 0xaa, 0x82, 0xfc, 0xb4, + 0x7c, 0x0c, 0x86, 0x1f, 0x49, 0x55, 0xa4, 0x3d, 0xdf, 0x46, 0xff, 0x41, 0x34, 0xaf, 0xc7, 0x84, + 0x85, 0x2a, 0x91, 0xda, 0xf3, 0x53, 0x1b, 0xfb, 0x27, 0xb1, 0x25, 0x80, 0x70, 0xcb, 0x4b, 0xb5, + 0xcb, 0x7d, 0xff, 0xc5, 0x30, 0x03, 0x18, 0x34, 0x5e, 0x3f, 0x2a, 0xb7, 0x6d, 0xec, 0xdf, 0x1c, + 0x34, 0xad, 0x17, 0xc7, 0xa1, 0x86, 0x97, 0xf9, 0x3f, 0x0d, 0x6c, 0xf0, 0x3f, 0x04, 0x77, 0x09, + 0xfc, 0xe5, 0x54, 0xb7, 0x75, 0xc7, 0x9e, 0xec, 0x7f, 0xa9, 0xd2, 0xbc, 0x5e, 0x2c, 0xc1, 0x68, + 0xaa, 0xdb, 0xed, 0x2c, 0xf1, 0xf2, 0xd9, 0x61, 0xc1, 0xff, 0xdb, 0x2b, 0x4f, 0xa4, 0x25, 0x73, + 0xe2, 0x08, 0x4c, 0xb7, 0x54, 0xd8, 0x0b, 0x9e, 0x80, 0x55, 0xb5, 0xaa, 0xd6, 0xf3, 0x5d, 0xf4, + 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x31, 0x62, 0x43, 0x54, 0x07, 0x13, 0x00, 0x00, +} diff --git a/gogoproto/gogo.proto b/gogoproto/gogo.proto new file mode 100644 index 000000000..b80c85653 --- /dev/null +++ b/gogoproto/gogo.proto @@ -0,0 +1,144 @@ +// Protocol Buffers for Go with Gadgets +// +// Copyright (c) 2013, The GoGo Authors. All rights reserved. +// http://github.com/gogo/protobuf +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; +package gogoproto; + +import "google/protobuf/descriptor.proto"; + +option java_package = "com.google.protobuf"; +option java_outer_classname = "GoGoProtos"; +option go_package = "github.com/gogo/protobuf/gogoproto"; + +extend google.protobuf.EnumOptions { + optional bool goproto_enum_prefix = 62001; + optional bool goproto_enum_stringer = 62021; + optional bool enum_stringer = 62022; + optional string enum_customname = 62023; + optional bool enumdecl = 62024; +} + +extend google.protobuf.EnumValueOptions { + optional string enumvalue_customname = 66001; +} + +extend google.protobuf.FileOptions { + optional bool goproto_getters_all = 63001; + optional bool goproto_enum_prefix_all = 63002; + optional bool goproto_stringer_all = 63003; + optional bool verbose_equal_all = 63004; + optional bool face_all = 63005; + optional bool gostring_all = 63006; + optional bool populate_all = 63007; + optional bool stringer_all = 63008; + optional bool onlyone_all = 63009; + + optional bool equal_all = 63013; + optional bool description_all = 63014; + optional bool testgen_all = 63015; + optional bool benchgen_all = 63016; + optional bool marshaler_all = 63017; + optional bool unmarshaler_all = 63018; + optional bool stable_marshaler_all = 63019; + + optional bool sizer_all = 63020; + + optional bool goproto_enum_stringer_all = 63021; + optional bool enum_stringer_all = 63022; + + optional bool unsafe_marshaler_all = 63023; + optional bool unsafe_unmarshaler_all = 63024; + + optional bool goproto_extensions_map_all = 63025; + optional bool goproto_unrecognized_all = 63026; + optional bool gogoproto_import = 63027; + optional bool protosizer_all = 63028; + optional bool compare_all = 63029; + optional bool typedecl_all = 63030; + optional bool enumdecl_all = 63031; + + optional bool goproto_registration = 63032; + optional bool messagename_all = 63033; + + optional bool goproto_sizecache_all = 63034; + optional bool goproto_unkeyed_all = 63035; +} + +extend google.protobuf.MessageOptions { + optional bool goproto_getters = 64001; + optional bool goproto_stringer = 64003; + optional bool verbose_equal = 64004; + optional bool face = 64005; + optional bool gostring = 64006; + optional bool populate = 64007; + optional bool stringer = 67008; + optional bool onlyone = 64009; + + optional bool equal = 64013; + optional bool description = 64014; + optional bool testgen = 64015; + optional bool benchgen = 64016; + optional bool marshaler = 64017; + optional bool unmarshaler = 64018; + optional bool stable_marshaler = 64019; + + optional bool sizer = 64020; + + optional bool unsafe_marshaler = 64023; + optional bool unsafe_unmarshaler = 64024; + + optional bool goproto_extensions_map = 64025; + optional bool goproto_unrecognized = 64026; + + optional bool protosizer = 64028; + optional bool compare = 64029; + + optional bool typedecl = 64030; + + optional bool messagename = 64033; + + optional bool goproto_sizecache = 64034; + optional bool goproto_unkeyed = 64035; +} + +extend google.protobuf.FieldOptions { + optional bool nullable = 65001; + optional bool embed = 65002; + optional string customtype = 65003; + optional string customname = 65004; + optional string jsontag = 65005; + optional string moretags = 65006; + optional string casttype = 65007; + optional string castkey = 65008; + optional string castvalue = 65009; + + optional bool stdtime = 65010; + optional bool stdduration = 65011; + optional bool wktpointer = 65012; + +} diff --git a/templates/BUILD.bazel b/templates/BUILD.bazel index 04d4fe052..338fdcbcf 100644 --- a/templates/BUILD.bazel +++ b/templates/BUILD.bazel @@ -8,6 +8,7 @@ go_library( deps = [ "//templates/cc:go_default_library", "//templates/go:go_default_library", + "//templates/gogo:go_default_library", "//templates/java:go_default_library", "//templates/shared:go_default_library", "@com_github_lyft_protoc_gen_star//:go_default_library", diff --git a/templates/gogo/BUILD.bazel b/templates/gogo/BUILD.bazel new file mode 100644 index 000000000..0f6b92b5c --- /dev/null +++ b/templates/gogo/BUILD.bazel @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "duration.go", + "file.go", + "message.go", + "register.go", + "required.go", + "timestamp.go", + ], + importpath = "github.com/envoyproxy/protoc-gen-validate/templates/gogo", + visibility = ["//visibility:public"], + deps = [ + "//templates/goshared:go_default_library", + "//vendor/github.com/lyft/protoc-gen-star:go_default_library", + ], +) diff --git a/templates/gogo/duration.go b/templates/gogo/duration.go new file mode 100644 index 000000000..c8b555ae7 --- /dev/null +++ b/templates/gogo/duration.go @@ -0,0 +1,30 @@ +package gogo + +const durationTpl = `{{ $f := .Field }}{{ $r := .Rules }} + {{ template "required" . }} + + {{ if or $r.In $r.NotIn $r.Lt $r.Lte $r.Gt $r.Gte $r.Const }} + {{ if .Gogo.StdDuration }} + {{ if .Gogo.Nullable }} + if d := {{ accessor . }}; d != nil { + dur := *d + {{ else }} + if true { + dur := {{ accessor . }} + {{ end }} + {{ else }} + {{ if .Gogo.Nullable }} + if d := {{ accessor . }}; d != nil { + dur, err := types.DurationFromProto(d) + if err != nil { return {{ errCause . "err" "value is not a valid duration" }} } + {{ else }} + if d := {{ accessor . }}; true { + dur, err := types.DurationFromProto(&d) + if err != nil { return {{ errCause . "err" "value is not a valid duration" }} } + {{ end }} + {{ end }} + + {{ template "durationcmp" . }} + } + {{ end }} +` diff --git a/templates/gogo/file.go b/templates/gogo/file.go new file mode 100644 index 000000000..0f19a3e4d --- /dev/null +++ b/templates/gogo/file.go @@ -0,0 +1,52 @@ +package gogo + +const fileTpl = `// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: {{ .InputPath }} + +package {{ pkg . }} + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "strings" + "time" + "unicode/utf8" + + "github.com/gogo/protobuf/types" + + {{ range $path, $pkg := enumPackages (externalEnums .) }} + {{ $pkg }} "{{ $path }}" + {{ end }} +) + +// 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) + _ = types.DynamicAny{} + + {{ range (externalEnums .) }} + _ = {{ pkg . }}.{{ name . }}(0) + {{ end }} +) + +// define the regex for a UUID once up-front +var _{{ snakeCase .File.InputPath.BaseName }}_uuidPattern = regexp.MustCompile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") + +{{ range .AllMessages }} + {{ template "msg" . }} +{{ end }} +` diff --git a/templates/gogo/message.go b/templates/gogo/message.go new file mode 100644 index 000000000..525eded02 --- /dev/null +++ b/templates/gogo/message.go @@ -0,0 +1,23 @@ +package gogo + +const messageTpl = ` + {{ $f := .Field }}{{ $r := .Rules }} + {{ template "required" . }} + + {{ if $r.GetSkip }} + // skipping validation for {{ $f.Name }} + {{ else }} + { + tmp := {{ accessor . }} + {{ if .Gogo.Nullable }} + if v, ok := interface{}(tmp).(interface{ Validate() error }); ok { + {{ else }} + if v, ok := interface{}(&tmp).(interface{ Validate() error }); ok { + {{ end }} + if err := v.Validate(); err != nil { + return {{ errCause . "err" "embedded message failed validation" }} + } + } + } + {{ end }} +` diff --git a/templates/gogo/register.go b/templates/gogo/register.go new file mode 100644 index 000000000..1fd7d9018 --- /dev/null +++ b/templates/gogo/register.go @@ -0,0 +1,18 @@ +package gogo + +import ( + "text/template" + + "github.com/lyft/protoc-gen-star" + + shared "github.com/envoyproxy/protoc-gen-validate/templates/goshared" +) + +func Register(tpl *template.Template, params pgs.Parameters) { + shared.Register(tpl, params) + template.Must(tpl.Parse(fileTpl)) + template.Must(tpl.New("required").Parse(requiredTpl)) + template.Must(tpl.New("timestamp").Parse(timestampTpl)) + template.Must(tpl.New("duration").Parse(durationTpl)) + template.Must(tpl.New("message").Parse(messageTpl)) +} diff --git a/templates/gogo/required.go b/templates/gogo/required.go new file mode 100644 index 000000000..07d9f3612 --- /dev/null +++ b/templates/gogo/required.go @@ -0,0 +1,11 @@ +package gogo + +const requiredTpl = ` + {{ if .Rules.GetRequired }} + {{ if .Gogo.Nullable }} + if {{ accessor . }} == nil { + return {{ err . "value is required" }} + } + {{ end }} + {{ end }} +` diff --git a/templates/gogo/timestamp.go b/templates/gogo/timestamp.go new file mode 100644 index 000000000..df05c6e97 --- /dev/null +++ b/templates/gogo/timestamp.go @@ -0,0 +1,28 @@ +package gogo + +const timestampTpl = `{{ $f := .Field }}{{ $r := .Rules }} + {{ template "required" . }} + + {{ if or $r.Lt $r.Lte $r.Gt $r.Gte $r.LtNow $r.GtNow $r.Within $r.Const }} + {{ if .Gogo.StdTime }} + {{ if .Gogo.Nullable }} + if ts := {{ accessor . }}; ts != nil { + {{ else }} + if ts := {{ accessor . }}; true { + {{ end }} + {{ else }} + {{ if .Gogo.Nullable }} + if t := {{ accessor . }}; t != nil { + ts, err := types.TimestampFromProto(t) + if err != nil { return {{ errCause . "err" "value is not a valid timestamp" }} } + {{ else }} + if t := {{ accessor . }}; true { + ts, err := types.TimestampFromProto(&t) + if err != nil { return {{ errCause . "err" "value is not a valid timestamp" }} } + {{ end }} + {{ end }} + + {{ template "timestampcmp" . }} + } + {{ end }} +` diff --git a/templates/pkg.go b/templates/pkg.go index 79dfa948c..fb7774285 100644 --- a/templates/pkg.go +++ b/templates/pkg.go @@ -7,6 +7,7 @@ import ( "github.com/lyft/protoc-gen-star/lang/go" "github.com/envoyproxy/protoc-gen-validate/templates/cc" "github.com/envoyproxy/protoc-gen-validate/templates/go" + "github.com/envoyproxy/protoc-gen-validate/templates/gogo" "github.com/envoyproxy/protoc-gen-validate/templates/java" "github.com/envoyproxy/protoc-gen-validate/templates/shared" ) @@ -25,6 +26,7 @@ func Template(params pgs.Parameters) map[string][]*template.Template { return map[string][]*template.Template{ "cc": {makeTemplate("h", cc.RegisterHeader, params), makeTemplate("cc", cc.RegisterModule, params)}, "go": {makeTemplate("go", golang.Register, params)}, + "gogo": {makeTemplate("go", gogo.Register, params)}, "java": {makeTemplate("java", java.Register, params)}, } } diff --git a/templates/shared/BUILD.bazel b/templates/shared/BUILD.bazel index a05531784..900d5dc7d 100644 --- a/templates/shared/BUILD.bazel +++ b/templates/shared/BUILD.bazel @@ -12,6 +12,7 @@ go_library( importpath = "github.com/envoyproxy/protoc-gen-validate/templates/shared", visibility = ["//visibility:public"], deps = [ + "//gogoproto:go_default_library", "//validate:go_default_library", # keep "@com_github_golang_protobuf//proto:go_default_library", "@com_github_lyft_protoc_gen_star//:go_default_library", diff --git a/templates/shared/context.go b/templates/shared/context.go index 7bf641086..368b3d6b6 100644 --- a/templates/shared/context.go +++ b/templates/shared/context.go @@ -5,6 +5,7 @@ import ( "fmt" "text/template" + "github.com/envoyproxy/protoc-gen-validate/gogoproto" "github.com/envoyproxy/protoc-gen-validate/validate" "github.com/golang/protobuf/proto" pgs "github.com/lyft/protoc-gen-star" @@ -14,6 +15,7 @@ type RuleContext struct { Field pgs.Field Rules proto.Message MessageRules *validate.MessageRules + Gogo Gogo Typ string WrapperTyp string @@ -23,9 +25,20 @@ type RuleContext struct { AccessorOverride string } +type Gogo struct { + Nullable bool + StdDuration bool + StdTime bool +} + func rulesContext(f pgs.Field) (out RuleContext, err error) { out.Field = f + out.Gogo.Nullable = true + f.Extension(gogoproto.E_Nullable, &out.Gogo.Nullable) + f.Extension(gogoproto.E_Stdduration, &out.Gogo.StdDuration) + f.Extension(gogoproto.E_Stdtime, &out.Gogo.StdTime) + var rules validate.FieldRules if _, err = f.Extension(validate.E_Rules, &rules); err != nil { return @@ -54,6 +67,7 @@ func (ctx RuleContext) Key(name, idx string) (out RuleContext, err error) { out.Field = ctx.Field out.AccessorOverride = name out.Index = idx + out.Gogo = ctx.Gogo out.Typ, out.Rules, out.MessageRules, _ = resolveRules(ctx.Field.Type().Key(), rules.GetKeys()) @@ -68,6 +82,7 @@ func (ctx RuleContext) Elem(name, idx string) (out RuleContext, err error) { out.Field = ctx.Field out.AccessorOverride = name out.Index = idx + out.Gogo = ctx.Gogo var rules *validate.FieldRules switch r := ctx.Rules.(type) { @@ -105,6 +120,7 @@ func (ctx RuleContext) Unwrap(name string) (out RuleContext, err error) { MessageRules: ctx.MessageRules, Typ: ctx.WrapperTyp, AccessorOverride: name, + Gogo: ctx.Gogo, }, nil } diff --git a/tests/go.mod b/tests/go.mod index 0dfe39efe..8bf7948fa 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -4,6 +4,7 @@ go 1.14 require ( github.com/envoyproxy/protoc-gen-validate v0.0.0 + github.com/gogo/protobuf v1.3.1 github.com/golang/protobuf v1.3.1 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b ) diff --git a/tests/go.sum b/tests/go.sum index 2b539cf6b..d354c7067 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -1,7 +1,11 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/lyft/protoc-gen-star v0.4.10/go.mod h1:mE8fbna26u7aEA2QCVvvfBU/ZrPgocG1206xAFPcs94= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -28,5 +32,13 @@ golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roY golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= diff --git a/tests/harness/BUILD b/tests/harness/BUILD index 8452c1a9e..3bf8a7d75 100644 --- a/tests/harness/BUILD +++ b/tests/harness/BUILD @@ -24,6 +24,20 @@ go_proto_library( visibility = ["//visibility:public"], ) +go_proto_library( + name = "harness_gogo_proto", + compilers = ["@io_bazel_rules_go//proto:gogo_proto"], + importpath = "github.com/envoyproxy/protoc-gen-validate/tests/harness/gogo", + proto = ":harness_proto", + visibility = ["//visibility:public"], + deps = [ + "@com_github_golang_protobuf//ptypes/any:go_default_library", + "@com_github_golang_protobuf//ptypes/timestamp:go_default_library", + "@com_github_golang_protobuf//ptypes/wrappers:go_default_library", + "@io_bazel_rules_go//proto/wkt:descriptor_go_proto", + ], +) + cc_proto_library( name = "harness_cc_proto", visibility = ["//visibility:public"], diff --git a/tests/harness/cases/BUILD b/tests/harness/cases/BUILD index 40f0d93b0..277fc3f1e 100644 --- a/tests/harness/cases/BUILD +++ b/tests/harness/cases/BUILD @@ -4,6 +4,7 @@ load( "//bazel:pgv_proto_library.bzl", "pgv_cc_proto_library", "pgv_go_proto_library", + "pgv_gogo_proto_library", "pgv_java_proto_library", "pgv_python_proto_library", ) @@ -52,6 +53,20 @@ pgv_go_proto_library( ], ) +pgv_gogo_proto_library( + name = "gogo", + importpath = "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/gogo", + proto = ":cases_proto", + deps = [ + "//tests/harness/cases/other_package:gogo", + "@com_github_golang_protobuf//ptypes:go_default_library", + "@com_github_golang_protobuf//ptypes/any:go_default_library", + "@com_github_golang_protobuf//ptypes/duration:go_default_library", + "@com_github_golang_protobuf//ptypes/timestamp:go_default_library", + "@com_github_golang_protobuf//ptypes/wrappers:go_default_library", + ], +) + pgv_cc_proto_library( name = "cc", cc_deps = [ diff --git a/tests/harness/cases/other_package/BUILD b/tests/harness/cases/other_package/BUILD index 3a11fbaa2..31c6f4dbe 100644 --- a/tests/harness/cases/other_package/BUILD +++ b/tests/harness/cases/other_package/BUILD @@ -8,6 +8,7 @@ load( "//bazel:pgv_proto_library.bzl", "pgv_cc_proto_library", "pgv_go_proto_library", + "pgv_gogo_proto_library", "pgv_java_proto_library", "pgv_python_proto_library", ) @@ -30,6 +31,15 @@ pgv_go_proto_library( ], ) +pgv_gogo_proto_library( + name = "gogo", + importpath = "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/other_package/gogo", + proto = ":embed_proto", + deps = [ + "@com_github_golang_protobuf//ptypes:go_default_library", + ], +) + pgv_cc_proto_library( name = "cc", visibility = ["//tests:__subpackages__"], diff --git a/tests/harness/executor/BUILD b/tests/harness/executor/BUILD index ddc3970a7..e083584cc 100644 --- a/tests/harness/executor/BUILD +++ b/tests/harness/executor/BUILD @@ -34,9 +34,11 @@ go_binary( data = ["//tests/harness/cc:cc-harness"] + select({ ":windows_x86_64": [ "//tests/harness/go/main:go-harness-exe", + "//tests/harness/gogo/main:go-harness-exe", ], "//conditions:default": [ "//tests/harness/go/main:go-harness-bin", + "//tests/harness/gogo/main:go-harness-bin", "//tests/harness/java:java-harness", "//tests/harness/python:python-harness", ], diff --git a/tests/harness/executor/executor.go b/tests/harness/executor/executor.go index e4023c0de..fe2c2a263 100644 --- a/tests/harness/executor/executor.go +++ b/tests/harness/executor/executor.go @@ -17,6 +17,7 @@ func init() { func main() { parallelism := flag.Int("parallelism", runtime.NumCPU(), "Number of test cases to run in parallel") goFlag := flag.Bool("go", false, "Run go test harness") + gogoFlag := flag.Bool("gogo", false, "Run gogo test harness") ccFlag := flag.Bool("cc", false, "Run c++ test harness") javaFlag := flag.Bool("java", false, "Run java test harness") pythonFlag := flag.Bool("python", false, "Run python test harness") @@ -24,7 +25,7 @@ func main() { flag.Parse() start := time.Now() - harnesses := Harnesses(*goFlag, *ccFlag, *javaFlag, *pythonFlag, *externalHarnessFlag) + harnesses := Harnesses(*goFlag, *gogoFlag, *ccFlag, *javaFlag, *pythonFlag, *externalHarnessFlag) successes, failures, skips := run(*parallelism, harnesses) log.Printf("Successes: %d | Failures: %d | Skips: %d (%v)", diff --git a/tests/harness/executor/harness.go b/tests/harness/executor/harness.go index ab854cdd9..92b7ebf5a 100644 --- a/tests/harness/executor/harness.go +++ b/tests/harness/executor/harness.go @@ -17,11 +17,14 @@ import ( "golang.org/x/net/context" ) -func Harnesses(goFlag, ccFlag, javaFlag, pythonFlag bool, externalHarnessFlag string) []Harness { +func Harnesses(goFlag bool, gogoFlag bool, ccFlag bool, javaFlag bool, pythonFlag bool, externalHarnessFlag string) []Harness { harnesses := make([]Harness, 0) if goFlag { harnesses = append(harnesses, InitHarness("tests/harness/go/main/go-harness")) } + if gogoFlag { + harnesses = append(harnesses, InitHarness("tests/harness/gogo/main/go-harness")) + } if ccFlag { harnesses = append(harnesses, InitHarness("tests/harness/cc/cc-harness")) } diff --git a/tests/harness/gogo/main/BUILD b/tests/harness/gogo/main/BUILD new file mode 100644 index 000000000..00bce4e3f --- /dev/null +++ b/tests/harness/gogo/main/BUILD @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( + name = "go_default_library", + srcs = ["harness.go"], + importpath = "github.com/envoyproxy/protoc-gen-validate/tests/harness/gogo/main", + visibility = ["//visibility:private"], + deps = [ + "//tests/harness:harness_gogo_proto", + "//tests/harness/cases:gogo", + "//tests/harness/cases/other_package:gogo", + "@com_github_gogo_protobuf//proto:go_default_library", + "@com_github_gogo_protobuf//types:go_default_library", + ], +) + +genrule( + name = "go-harness-bin", + srcs = [":main"], + outs = ["go-harness"], + cmd = "cp $(SRCS) $@", + visibility = ["//visibility:public"], +) + +genrule( + name = "go-harness-exe", + srcs = [":main"], + outs = ["go-harness.exe"], + cmd = "cp $(SRCS) $@", + visibility = ["//visibility:public"], +) + +go_binary( + name = "main", + embed = [":go_default_library"], + importpath = "github.com/envoyproxy/protoc-gen-validate/tests/harness/gogo/main", + visibility = ["//visibility:public"], +) diff --git a/tests/harness/gogo/main/harness.go b/tests/harness/gogo/main/harness.go new file mode 100644 index 000000000..25fe865af --- /dev/null +++ b/tests/harness/gogo/main/harness.go @@ -0,0 +1,59 @@ +package main + +import ( + "io/ioutil" + "log" + "os" + + "github.com/gogo/protobuf/proto" + "github.com/gogo/protobuf/types" + _ "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/gogo" + _ "github.com/envoyproxy/protoc-gen-validate/tests/harness/cases/other_package/gogo" + harness "github.com/envoyproxy/protoc-gen-validate/tests/harness/gogo" +) + +func main() { + b, err := ioutil.ReadAll(os.Stdin) + checkErr(err) + + tc := new(harness.TestCase) + checkErr(proto.Unmarshal(b, tc)) + + da := new(types.DynamicAny) + checkErr(types.UnmarshalAny(tc.Message, da)) + + msg := da.Message.(interface { + Validate() error + }) + checkValid(msg.Validate()) + +} + +func checkValid(err error) { + if err == nil { + resp(&harness.TestResult{Valid: true}) + } else { + resp(&harness.TestResult{Reason: err.Error()}) + } +} + +func checkErr(err error) { + if err == nil { + return + } + + resp(&harness.TestResult{ + Error: true, + Reason: err.Error(), + }) +} + +func resp(result *harness.TestResult) { + if b, err := proto.Marshal(result); err != nil { + log.Fatalf("could not marshal response: %v", err) + } else if _, err = os.Stdout.Write(b); err != nil { + log.Fatalf("could not write response: %v", err) + } + + os.Exit(0) +} diff --git a/tools.go b/tools.go index 635c9b94e..2a2e0c087 100644 --- a/tools.go +++ b/tools.go @@ -4,6 +4,7 @@ package main import ( _ "github.com/golang/protobuf/protoc-gen-go" + _ "github.com/gogo/protobuf/protoc-gen-gogofast" _ "golang.org/x/lint/golint" _ "golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow" _ "golang.org/x/net/context"