diff --git a/vendor/README.md b/vendor/README.md index 951f649..4f44091 100644 --- a/vendor/README.md +++ b/vendor/README.md @@ -10,4 +10,4 @@ TODO - [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway): [v1.4.1](https://github.com/grpc-ecosystem/grpc-gateway/releases/tag/v1.4.1) - [grpc-middleware](https://github.com/grpc-ecosystem/go-grpc-middleware): [v1.0.0](https://github.com/grpc-ecosystem/go-grpc-middleware/releases/tag/v1.0.0) - [pubsub](https://godoc.org/github.com/docker/docker/pkg/pubsub): [v17.03.2-ce](https://github.com/moby/moby/releases/tag/v17.03.2-ce) - +- [go-proto-validators](https://github.com/mwitkow/go-proto-validators): [0950a7](https://github.com/mwitkow/go-proto-validators/tree/0950a79900071e9f3f5979b78078c599376422fd) diff --git a/vendor/github.com/mwitkow/go-proto-validators/.gitignore b/vendor/github.com/mwitkow/go-proto-validators/.gitignore new file mode 100755 index 0000000..5f452f6 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/.gitignore @@ -0,0 +1,89 @@ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +### Go template +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof +### Vim template +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ +### Linux template +*~ + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# Created by .ignore support plugin (hsz.mobi) diff --git a/vendor/github.com/mwitkow/go-proto-validators/.travis.yml b/vendor/github.com/mwitkow/go-proto-validators/.travis.yml new file mode 100755 index 0000000..7c43822 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/.travis.yml @@ -0,0 +1,18 @@ +language: go +sudo: false + +go: + - 1.5 + - 1.6 + +before_install: + - ./install_protoc.sh + - export PATH=$PATH:$HOME/soft/protobuf + +install: + - go get github.com/stretchr/testify + - go get github.com/gogo/protobuf/protoc-gen-gogo + - go get github.com/golang/protobuf/protoc-gen-go + +script: + - make test diff --git a/vendor/github.com/mwitkow/go-proto-validators/LICENSE.txt b/vendor/github.com/mwitkow/go-proto-validators/LICENSE.txt new file mode 100755 index 0000000..b2b0650 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/github.com/mwitkow/go-proto-validators/Makefile b/vendor/github.com/mwitkow/go-proto-validators/Makefile new file mode 100755 index 0000000..ff1bc0d --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/Makefile @@ -0,0 +1,45 @@ +# Copyright 2016 Michal Witkowski. All Rights Reserved. +# See LICENSE for licensing terms. + +export PATH := ${GOPATH}/bin:${PATH} + +install: + @echo "--- Installing govalidators to GOPATH" + go install github.com/mwitkow/go-proto-validators/protoc-gen-govalidators + +regenerate_test_gogo: + @echo "Regenerating test .proto files with gogo imports" + (protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=test \ + --gogo_out=test/gogo \ + --govalidators_out=gogoimport=true:test/gogo test/*.proto) + +regenerate_test_golang: + @echo "--- Regenerating test .proto files with golang imports" + (protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=test \ + --go_out=test/golang \ + --govalidators_out=test/golang test/*.proto) + +regenerate_example: install + @echo "--- Regenerating example directory" + (protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=. \ + --go_out=. \ + --govalidators_out=. examples/*.proto) + +test: install regenerate_test_gogo regenerate_test_golang + @echo "Running tests" + go test -v ./... + +regenerate: + @echo "--- Regenerating validator.proto" + (protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=${GOPATH}/src/github.com/gogo/protobuf/protobuf \ + --proto_path=. \ + --gogo_out=Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. \ + validator.proto) diff --git a/vendor/github.com/mwitkow/go-proto-validators/README.md b/vendor/github.com/mwitkow/go-proto-validators/README.md new file mode 100755 index 0000000..3df5ea8 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/README.md @@ -0,0 +1,132 @@ +# Golang ProtoBuf Validator Compiler + +[![Travis Build](https://travis-ci.org/mwitkow/go-proto-validators.svg)](https://travis-ci.org/mwitkow/go-proto-validators) +[![Apache 2.0 License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) + +A `protoc` plugin that generates `Validate() error` functions on Go proto `struct`s based on field options inside `.proto` +files. The validation functions are code-generated and thus don't suffer on performance from tag-based reflection on +deeply-nested messages. + +## Paint me a code picture + +Let's take the following `proto3` snippet: + +```proto +syntax = "proto3"; +package validator.examples; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message InnerMessage { + // some_integer can only be in range (1, 100). + int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 100}]; + // some_float can only be in range (0;1). + double some_float = 2 [(validator.field) = {float_gte: 0, float_lte: 1}]; +} + +message OuterMessage { + // important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax). + string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage. + InnerMessage inner = 2 [(validator.field) = {msg_exists : true}]; +} +``` + +First, the **`required` keyword is back** for `proto3`, under the guise of `msg_exists`. The painful `if-nil` checks are taken care of! + +Second, the expected values in fields are now part of the contract `.proto` file. No more hunting down conditions in code! + +Third, the generated code is understandable and has clear understandable error messages. Take a look: + +```go +func (this *InnerMessage) Validate() error { + if !(this.SomeInteger > 0) { + return fmt.Errorf("validation error: InnerMessage.SomeInteger must be greater than '0'") + } + if !(this.SomeInteger < 100) { + return fmt.Errorf("validation error: InnerMessage.SomeInteger must be less than '100'") + } + if !(this.SomeFloat >= 0) { + return fmt.Errorf("validation error: InnerMessage.SomeFloat must be greater than or equal to '0'") + } + if !(this.SomeFloat <= 1) { + return fmt.Errorf("validation error: InnerMessage.SomeFloat must be less than or equal to '1'") + } + return nil +} + +var _regex_OuterMessage_ImportantString = regexp.MustCompile("^[a-z]{2,5}$") + +func (this *OuterMessage) Validate() error { + if !_regex_OuterMessage_ImportantString.MatchString(this.ImportantString) { + return fmt.Errorf("validation error: OuterMessage.ImportantString must conform to regex '^[a-z]{2,5}$'") + } + if nil == this.Inner { + return fmt.Errorf("validation error: OuterMessage.Inner message must exist") + } + if this.Inner != nil { + if err := validators.CallValidatorIfExists(this.Inner); err != nil { + return err + } + } + return nil +} +``` + +## Installing and using + +The `protoc` compiler expects to find plugins named `proto-gen-XYZ` on the execution `$PATH`. So first: + +```sh +export PATH=${PATH}:${GOPATH}/bin +``` + +Then, do the usual + +```sh +go get github.com/mwitkow/go-proto-validators/protoc-gen-govalidators +``` + +Your `protoc` builds probably look very simple like: + +```sh +protoc \ + --proto_path=. \ + --go_out=. \ + *.proto +``` + +That's fine, until you encounter `.proto` includes. Because `go-proto-validators` uses field options inside the `.proto` +files themselves, it's `.proto` definition (and the Google `descriptor.proto` itself) need to on the `protoc` include +path. Hence the above becomes: + +```sh +protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=${GOPATH}/src/github.com/google/protobuf/src \ + --proto_path=. \ + --go_out=. \ + --govalidators_out=. \ + *.proto +``` + +Or with gogo protobufs: + +```sh +protoc \ + --proto_path=${GOPATH}/src \ + --proto_path=${GOPATH}/src/github.com/gogo/protobuf/protobuf \ + --proto_path=. \ + --gogo_out=. \ + --govalidators_out=gogoimport=true:. \ + *.proto +``` + +Basically the magical incantation (apart from includes) is the `--govalidators_out`. That triggers the +`protoc-gen-govalidators` plugin to generate `mymessage.validator.pb.go`. That's it :) + +###License + +`go-proto-validators` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. + + + diff --git a/vendor/github.com/mwitkow/go-proto-validators/examples/.gitignore b/vendor/github.com/mwitkow/go-proto-validators/examples/.gitignore new file mode 100755 index 0000000..fefa436 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/examples/.gitignore @@ -0,0 +1 @@ +!*.pb.go \ No newline at end of file diff --git a/vendor/github.com/mwitkow/go-proto-validators/examples/nested.pb.go b/vendor/github.com/mwitkow/go-proto-validators/examples/nested.pb.go new file mode 100755 index 0000000..96bc418 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/examples/nested.pb.go @@ -0,0 +1,83 @@ +// Code generated by protoc-gen-go. +// source: examples/nested.proto +// DO NOT EDIT! + +/* +Package validator_examples is a generated protocol buffer package. + +It is generated from these files: + examples/nested.proto + +It has these top-level messages: + InnerMessage + OuterMessage +*/ +package validator_examples + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/mwitkow/go-proto-validators" + +// 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. +const _ = proto.ProtoPackageIsVersion1 + +type InnerMessage struct { + // some_integer can only be in range (1, 100). + SomeInteger int32 `protobuf:"varint,1,opt,name=some_integer,json=someInteger" json:"some_integer,omitempty"` +} + +func (m *InnerMessage) Reset() { *m = InnerMessage{} } +func (m *InnerMessage) String() string { return proto.CompactTextString(m) } +func (*InnerMessage) ProtoMessage() {} +func (*InnerMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +type OuterMessage struct { + // important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax). + ImportantString string `protobuf:"bytes,1,opt,name=important_string,json=importantString" json:"important_string,omitempty"` + // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage. + Inner *InnerMessage `protobuf:"bytes,2,opt,name=inner" json:"inner,omitempty"` +} + +func (m *OuterMessage) Reset() { *m = OuterMessage{} } +func (m *OuterMessage) String() string { return proto.CompactTextString(m) } +func (*OuterMessage) ProtoMessage() {} +func (*OuterMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *OuterMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +func init() { + proto.RegisterType((*InnerMessage)(nil), "validator.examples.InnerMessage") + proto.RegisterType((*OuterMessage)(nil), "validator.examples.OuterMessage") +} + +var fileDescriptor0 = []byte{ + // 245 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x12, 0x4d, 0xad, 0x48, 0xcc, + 0x2d, 0xc8, 0x49, 0x2d, 0xd6, 0xcf, 0x4b, 0x2d, 0x2e, 0x49, 0x4d, 0xd1, 0x2b, 0x28, 0xca, 0x2f, + 0xc9, 0x17, 0x12, 0x2a, 0x4b, 0xcc, 0xc9, 0x4c, 0x49, 0x2c, 0xc9, 0x2f, 0xd2, 0x83, 0x29, 0x90, + 0x32, 0x4b, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0x2d, 0xcf, 0x2c, + 0xc9, 0xce, 0x2f, 0xd7, 0x4f, 0xcf, 0xd7, 0x05, 0x6b, 0xd0, 0x85, 0xab, 0x2f, 0xd6, 0x47, 0x68, + 0x05, 0x4b, 0x29, 0x59, 0x73, 0xf1, 0x78, 0xe6, 0xe5, 0xa5, 0x16, 0xf9, 0xa6, 0x16, 0x17, 0x27, + 0xa6, 0xa7, 0x0a, 0x69, 0x73, 0xf1, 0x14, 0xe7, 0xe7, 0xa6, 0xc6, 0x67, 0xe6, 0x95, 0xa4, 0xa6, + 0xa7, 0x16, 0x49, 0x30, 0x2a, 0x30, 0x6a, 0xb0, 0x3a, 0x71, 0x3c, 0xba, 0x2f, 0xcf, 0x22, 0xc0, + 0x20, 0x91, 0x12, 0xc4, 0x0d, 0x92, 0xf5, 0x84, 0x48, 0x2a, 0xf5, 0x32, 0x72, 0xf1, 0xf8, 0x97, + 0x96, 0x20, 0x74, 0xdb, 0x72, 0x09, 0x64, 0xe6, 0x16, 0xe4, 0x17, 0x95, 0x24, 0xe6, 0x95, 0xc4, + 0x17, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x83, 0x4d, 0xe0, 0x74, 0x12, 0x02, 0x9a, 0xc0, 0xc7, 0xc5, + 0x13, 0x17, 0x9d, 0xa8, 0x5b, 0x15, 0x5b, 0x6d, 0xa4, 0x63, 0x5a, 0xab, 0x12, 0xc4, 0x0f, 0x57, + 0x1b, 0x0c, 0x56, 0x2a, 0x64, 0xc7, 0xc5, 0x9a, 0x09, 0x72, 0x8c, 0x04, 0x13, 0x50, 0x0f, 0xb7, + 0x91, 0x82, 0x1e, 0xa6, 0x47, 0xf5, 0x90, 0x5d, 0xeb, 0xc4, 0x06, 0x34, 0x15, 0xa8, 0x36, 0x08, + 0xa2, 0x2d, 0x89, 0x0d, 0xec, 0x27, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0x68, 0xd9, + 0xd5, 0x38, 0x01, 0x00, 0x00, +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/examples/nested.proto b/vendor/github.com/mwitkow/go-proto-validators/examples/nested.proto new file mode 100755 index 0000000..5689c03 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/examples/nested.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package validator.examples; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message InnerMessage { + // some_integer can only be in range (1, 100). + int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 100}]; +} + +message OuterMessage { + // important_string must be a lowercase alpha-numeric of 5 to 30 characters (RE2 syntax). + string important_string = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage. + InnerMessage inner = 2 [(validator.field) = {msg_exists : true}]; +} \ No newline at end of file diff --git a/vendor/github.com/mwitkow/go-proto-validators/examples/nested.validator.pb.go b/vendor/github.com/mwitkow/go-proto-validators/examples/nested.validator.pb.go new file mode 100755 index 0000000..3ee7b1b --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/examples/nested.validator.pb.go @@ -0,0 +1,54 @@ +// Code generated by protoc-gen-gogo. +// source: examples/nested.proto +// DO NOT EDIT! + +/* +Package validator_examples is a generated protocol buffer package. + +It is generated from these files: + examples/nested.proto + +It has these top-level messages: + InnerMessage + OuterMessage +*/ +package validator_examples + +import regexp "regexp" +import fmt "fmt" +import github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators" +import proto "github.com/golang/protobuf/proto" +import math "math" +import _ "github.com/mwitkow/go-proto-validators" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +func (this *InnerMessage) Validate() error { + if !(this.SomeInteger > 0) { + return fmt.Errorf("validation error: InnerMessage.SomeInteger must be greater than '0'") + } + if !(this.SomeInteger < 100) { + return fmt.Errorf("validation error: InnerMessage.SomeInteger must be less than '100'") + } + return nil +} + +var _regex_OuterMessage_ImportantString = regexp.MustCompile("^[a-z]{2,5}$") + +func (this *OuterMessage) Validate() error { + if !_regex_OuterMessage_ImportantString.MatchString(this.ImportantString) { + return fmt.Errorf("validation error: OuterMessage.ImportantString must conform to regex " + "^[a-z]{2,5}$") + } + if nil == this.Inner { + return fmt.Errorf("validation error: OuterMessage.Inner message must exist") + } + if this.Inner != nil { + if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Inner); err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/helper.go b/vendor/github.com/mwitkow/go-proto-validators/helper.go new file mode 100755 index 0000000..9a3ee9b --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/helper.go @@ -0,0 +1,39 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package validator + +import "strings" + +// Validator is a general interface that allows a message to be validated. +type Validator interface { + Validate() error +} + +func CallValidatorIfExists(candidate interface{}) error { + if validator, ok := candidate.(Validator); ok { + return validator.Validate() + } + return nil +} + +type fieldError struct { + fieldStack []string + nestedErr error +} + +func (f *fieldError) Error() string { + return "invalid field " + strings.Join(f.fieldStack, ".") + ": " + f.nestedErr.Error() +} + +// FieldError wraps a given Validator error providing a message call stack. +func FieldError(fieldName string, err error) error { + if fErr, ok := err.(*fieldError); ok { + fErr.fieldStack = append([]string{fieldName}, fErr.fieldStack...) + return err + } + return &fieldError{ + fieldStack: []string{fieldName}, + nestedErr: err, + } +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/install_protoc.sh b/vendor/github.com/mwitkow/go-proto-validators/install_protoc.sh new file mode 100755 index 0000000..d7ec41c --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/install_protoc.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# Copyright 2016 Michal Witkowski. All Rights Reserved. +# See LICENSE for licensing terms. +# +# This script installs protobuf compiler `protoc` into PATH. + +version=${PROTOBUF_VERSION:-"3.0.0-beta-2"} +dst_dir="${HOME}/soft/protobuf" + +# Fail on issues. +set -e + +echo "Downloading and installing protoc ${version}" + +mkdir -p ${dst_dir} + +wget https://github.com/google/protobuf/releases/download/v${version}/protoc-${version}-linux-x86_64.zip -O ${dst_dir}/dist.zip + +cd ${dst_dir} +unzip -o dist.zip + +echo "Proto in \$PROTOBUF_DIR=${PROTOBUF_DIR}" diff --git a/vendor/github.com/mwitkow/go-proto-validators/plugin/plugin.go b/vendor/github.com/mwitkow/go-proto-validators/plugin/plugin.go new file mode 100755 index 0000000..221c0a5 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/plugin/plugin.go @@ -0,0 +1,591 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +/* + +The validator plugin generates a Validate method for each message. +By default, if none of the message's fields are annotated with the gogo validator annotation, it returns a nil. +In case some of the fields are annotated, the Validate function returns nil upon sucessful validation, or an error +describing why the validation failed. +The Validate method is called recursively for all submessage of the message. + +TODO(michal): ADD COMMENTS. + +Equal is enabled using the following extensions: + + - equal + - equal_all + +While VerboseEqual is enable dusing the following extensions: + + - verbose_equal + - verbose_equal_all + +The equal plugin also generates a test given it is enabled using one of the following extensions: + + - testgen + - testgen_all + +Let us look at: + + github.com/gogo/protobuf/test/example/example.proto + +Btw all the output can be seen at: + + github.com/gogo/protobuf/test/example/* + +The following message: + + + +given to the equal plugin, will generate the following code: + + + +and the following test code: + + +*/ +package plugin + +import ( + "fmt" + "os" + "reflect" + "strconv" + "strings" + + "github.com/gogo/protobuf/gogoproto" + "github.com/gogo/protobuf/proto" + descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" + "github.com/gogo/protobuf/protoc-gen-gogo/generator" + "github.com/gogo/protobuf/vanity" + "github.com/mwitkow/go-proto-validators" +) + +type plugin struct { + *generator.Generator + generator.PluginImports + regexPkg generator.Single + fmtPkg generator.Single + protoPkg generator.Single + validatorPkg generator.Single + useGogoImport bool +} + +func NewPlugin(useGogoImport bool) generator.Plugin { + return &plugin{useGogoImport: useGogoImport} +} + +func (p *plugin) Name() string { + return "validator" +} + +func (p *plugin) Init(g *generator.Generator) { + p.Generator = g +} + +func (p *plugin) Generate(file *generator.FileDescriptor) { + if !p.useGogoImport { + vanity.TurnOffGogoImport(file.FileDescriptorProto) + } + p.PluginImports = generator.NewPluginImports(p.Generator) + p.regexPkg = p.NewImport("regexp") + p.fmtPkg = p.NewImport("fmt") + p.validatorPkg = p.NewImport("github.com/mwitkow/go-proto-validators") + + for _, msg := range file.Messages() { + if msg.DescriptorProto.GetOptions().GetMapEntry() { + continue + } + p.generateRegexVars(file, msg) + if gogoproto.IsProto3(file.FileDescriptorProto) { + p.generateProto3Message(file, msg) + } else { + p.generateProto2Message(file, msg) + } + + } +} + +func getFieldValidatorIfAny(field *descriptor.FieldDescriptorProto) *validator.FieldValidator { + if field.Options != nil { + v, err := proto.GetExtension(field.Options, validator.E_Field) + if err == nil && v.(*validator.FieldValidator) != nil { + return (v.(*validator.FieldValidator)) + } + } + return nil +} + +func (p *plugin) isSupportedInt(field *descriptor.FieldDescriptorProto) bool { + switch *(field.Type) { + case descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_INT64: + return true + case descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_UINT64: + return true + case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: + return true + } + return false +} + +func (p *plugin) isSupportedFloat(field *descriptor.FieldDescriptorProto) bool { + switch *(field.Type) { + case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_DOUBLE: + return true + case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_FIXED64: + return true + case descriptor.FieldDescriptorProto_TYPE_SFIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED64: + return true + } + return false +} + +func (p *plugin) generateRegexVars(file *generator.FileDescriptor, message *generator.Descriptor) { + ccTypeName := generator.CamelCaseSlice(message.TypeName()) + for _, field := range message.Field { + validator := getFieldValidatorIfAny(field) + if validator != nil && validator.Regex != nil { + fieldName := p.GetFieldName(message, field) + p.P(`var `, p.regexName(ccTypeName, fieldName), ` = `, p.regexPkg.Use(), `.MustCompile(`, "`", *validator.Regex, "`", `)`) + } + } +} + +func (p *plugin) generateProto2Message(file *generator.FileDescriptor, message *generator.Descriptor) { + ccTypeName := generator.CamelCaseSlice(message.TypeName()) + + p.P(`func (this *`, ccTypeName, `) Validate() error {`) + p.In() + for _, field := range message.Field { + fieldName := p.GetFieldName(message, field) + fieldValidator := getFieldValidatorIfAny(field) + if fieldValidator == nil && !field.IsMessage() { + continue + } + if p.validatorWithMessageExists(fieldValidator) { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a proto2 message, validator.msg_exists has no effect\n", ccTypeName, fieldName) + } + variableName := "this." + fieldName + repeated := field.IsRepeated() + nullable := gogoproto.IsNullable(field) + // For proto2 syntax, only Gogo generates non-pointer fields + nonpointer := gogoproto.ImportsGoGoProto(file.FileDescriptorProto) && !gogoproto.IsNullable(field) + if repeated { + p.generateRepeatedCountValidator(variableName, ccTypeName, fieldName, fieldValidator) + if field.IsMessage() || p.validatorWithNonRepeatedConstraint(fieldValidator) { + p.P(`for _, item := range `, variableName, `{`) + p.In() + variableName = "item" + } + } else if nullable { + p.P(`if `, variableName, ` != nil {`) + p.In() + if !field.IsBytes() { + variableName = "*(" + variableName + ")" + } + } else if nonpointer { + // can use the field directly + } else if !field.IsMessage() { + variableName = `this.Get` + fieldName + `()` + } + if !repeated && fieldValidator != nil { + if fieldValidator.RepeatedCountMin != nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is not repeated, validator.min_elts has no effects\n", ccTypeName, fieldName) + } + if fieldValidator.RepeatedCountMax != nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is not repeated, validator.max_elts has no effects\n", ccTypeName, fieldName) + } + } + if field.IsString() { + p.generateStringValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if p.isSupportedInt(field) { + p.generateIntValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if p.isSupportedFloat(field) { + p.generateFloatValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if field.IsBytes() { + p.generateLengthValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if field.IsMessage() { + if repeated && nullable { + variableName = "*(item)" + } + p.P(`if err := `, p.validatorPkg.Use(), `.CallValidatorIfExists(&(`, variableName, `)); err != nil {`) + p.In() + p.P(`return `, p.validatorPkg.Use(), `.FieldError("`, fieldName, `", err)`) + p.Out() + p.P(`}`) + } + if repeated { + // end the repeated loop + if field.IsMessage() || p.validatorWithNonRepeatedConstraint(fieldValidator) { + // This internal 'if' cannot be refactored as it would change semantics with respect to the corresponding prelude 'if's + p.Out() + p.P(`}`) + } + } else if nullable { + // end the if around nullable + p.Out() + p.P(`}`) + } + } + p.P(`return nil`) + p.Out() + p.P(`}`) +} + +func (p *plugin) generateProto3Message(file *generator.FileDescriptor, message *generator.Descriptor) { + ccTypeName := generator.CamelCaseSlice(message.TypeName()) + p.P(`func (this *`, ccTypeName, `) Validate() error {`) + p.In() + for _, field := range message.Field { + fieldValidator := getFieldValidatorIfAny(field) + if fieldValidator == nil && !field.IsMessage() { + continue + } + isOneOf := field.OneofIndex != nil + fieldName := p.GetOneOfFieldName(message, field) + variableName := "this." + fieldName + repeated := field.IsRepeated() + // Golang's proto3 has no concept of unset primitive fields + nullable := (gogoproto.IsNullable(field) || !gogoproto.ImportsGoGoProto(file.FileDescriptorProto)) && field.IsMessage() + if p.fieldIsProto3Map(file, message, field) { + p.P(`// Validation of proto3 map<> fields is unsupported.`) + continue + } + if isOneOf { + p.In() + oneOfName := p.GetFieldName(message, field) + oneOfType := p.OneOfTypeName(message, field) + //if x, ok := m.GetType().(*OneOfMessage3_OneInt); ok { + p.P(`if oneOfNester, ok := this.Get` + oneOfName + `().(* ` + oneOfType + `); ok {`) + variableName = "oneOfNester." + p.GetOneOfFieldName(message, field) + } + if repeated { + p.generateRepeatedCountValidator(variableName, ccTypeName, fieldName, fieldValidator) + if field.IsMessage() || p.validatorWithNonRepeatedConstraint(fieldValidator) { + p.P(`for _, item := range `, variableName, `{`) + p.In() + variableName = "item" + } + } else if fieldValidator != nil { + if fieldValidator.RepeatedCountMin != nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is not repeated, validator.min_elts has no effects\n", ccTypeName, fieldName) + } + if fieldValidator.RepeatedCountMax != nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is not repeated, validator.max_elts has no effects\n", ccTypeName, fieldName) + } + } + if field.IsString() { + p.generateStringValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if p.isSupportedInt(field) { + p.generateIntValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if p.isSupportedFloat(field) { + p.generateFloatValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if field.IsBytes() { + p.generateLengthValidator(variableName, ccTypeName, fieldName, fieldValidator) + } else if field.IsMessage() { + if p.validatorWithMessageExists(fieldValidator) { + if nullable && !repeated { + p.P(`if nil == `, variableName, `{`) + p.In() + p.P(`return `, p.validatorPkg.Use(), `.FieldError("`, fieldName, `",`, p.fmtPkg.Use(), `.Errorf("message must exist"))`) + p.Out() + p.P(`}`) + } else if repeated { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is repeated, validator.msg_exists has no effect\n", ccTypeName, fieldName) + } else if !nullable { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a nullable=false, validator.msg_exists has no effect\n", ccTypeName, fieldName) + } + } + if nullable { + p.P(`if `, variableName, ` != nil {`) + p.In() + } else { + // non-nullable fields in proto3 store actual structs, we need pointers to operate on interfaces + variableName = "&(" + variableName + ")" + } + p.P(`if err := `, p.validatorPkg.Use(), `.CallValidatorIfExists(`, variableName, `); err != nil {`) + p.In() + p.P(`return `, p.validatorPkg.Use(), `.FieldError("`, fieldName, `", err)`) + p.Out() + p.P(`}`) + if nullable { + p.Out() + p.P(`}`) + } + } + if repeated && (field.IsMessage() || p.validatorWithNonRepeatedConstraint(fieldValidator)) { + // end the repeated loop + p.Out() + p.P(`}`) + } + if isOneOf { + // end the oneof if statement + p.Out() + p.P(`}`) + } + } + p.P(`return nil`) + p.Out() + p.P(`}`) +} + +func (p *plugin) generateIntValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { + if fv.IntGt != nil { + p.P(`if !(`, variableName, ` > `, fv.IntGt, `) {`) + p.In() + errorStr := fmt.Sprintf(`be greater than '%d'`, fv.GetIntGt()) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + if fv.IntLt != nil { + p.P(`if !(`, variableName, ` < `, fv.IntLt, `) {`) + p.In() + errorStr := fmt.Sprintf(`be less than '%d'`, fv.GetIntLt()) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } +} + +func (p *plugin) generateLengthValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { + if fv.LengthGt != nil { + p.P(`if !( len(`, variableName, `) > `, fv.LengthGt, `) {`) + p.In() + errorStr := fmt.Sprintf(`length be greater than '%d'`, fv.GetLengthGt()) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + + if fv.LengthLt != nil { + p.P(`if !( len(`, variableName, `) < `, fv.LengthLt, `) {`) + p.In() + errorStr := fmt.Sprintf(`length be less than '%d'`, fv.GetLengthLt()) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + + if fv.LengthEq != nil { + p.P(`if !( len(`, variableName, `) == `, fv.LengthEq, `) {`) + p.In() + errorStr := fmt.Sprintf(`length be not equal '%d'`, fv.GetLengthEq()) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + +} + +func (p *plugin) generateFloatValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { + upperIsStrict := true + lowerIsStrict := true + + // First check for incompatible constraints (i.e flt_lt & flt_lte both defined, etc) and determine the real limits. + if fv.FloatEpsilon != nil && fv.FloatLt == nil && fv.FloatGt == nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v has no 'float_lt' or 'float_gt' field so setting 'float_epsilon' has no effect.", ccTypeName, fieldName) + } + if fv.FloatLt != nil && fv.FloatLte != nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v has both 'float_lt' and 'float_lte' constraints, only the strictest will be used.", ccTypeName, fieldName) + strictLimit := fv.GetFloatLt() + if fv.FloatEpsilon != nil { + strictLimit += fv.GetFloatEpsilon() + } + + if fv.GetFloatLte() < strictLimit { + upperIsStrict = false + } + } else if fv.FloatLte != nil { + upperIsStrict = false + } + + if fv.FloatGt != nil && fv.FloatGte != nil { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v has both 'float_gt' and 'float_gte' constraints, only the strictest will be used.", ccTypeName, fieldName) + strictLimit := fv.GetFloatGt() + if fv.FloatEpsilon != nil { + strictLimit -= fv.GetFloatEpsilon() + } + + if fv.GetFloatGte() > strictLimit { + lowerIsStrict = false + } + } else if fv.FloatGte != nil { + lowerIsStrict = false + } + + // Generate the constraint checking code. + errorStr := "" + compareStr := "" + if fv.FloatGt != nil || fv.FloatGte != nil { + compareStr = fmt.Sprint(`if !(`, variableName) + if lowerIsStrict { + errorStr = fmt.Sprintf(`be strictly greater than '%g'`, fv.GetFloatGt()) + if fv.FloatEpsilon != nil { + errorStr += fmt.Sprintf(` with a tolerance of '%g'`, fv.GetFloatEpsilon()) + compareStr += fmt.Sprint(` + `, fv.GetFloatEpsilon()) + } + compareStr += fmt.Sprint(` > `, fv.GetFloatGt(), `) {`) + } else { + errorStr = fmt.Sprintf(`be greater than or equal to '%g'`, fv.GetFloatGte()) + compareStr += fmt.Sprint(` >= `, fv.GetFloatGte(), `) {`) + } + p.P(compareStr) + p.In() + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + + if fv.FloatLt != nil || fv.FloatLte != nil { + compareStr = fmt.Sprint(`if !(`, variableName) + if upperIsStrict { + errorStr = fmt.Sprintf(`be strictly lower than '%g'`, fv.GetFloatLt()) + if fv.FloatEpsilon != nil { + errorStr += fmt.Sprintf(` with a tolerance of '%g'`, fv.GetFloatEpsilon()) + compareStr += fmt.Sprint(` - `, fv.GetFloatEpsilon()) + } + compareStr += fmt.Sprint(` < `, fv.GetFloatLt(), `) {`) + } else { + errorStr = fmt.Sprintf(`be lower than or equal to '%g'`, fv.GetFloatLte()) + compareStr += fmt.Sprint(` <= `, fv.GetFloatLte(), `) {`) + } + p.P(compareStr) + p.In() + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } +} + +func (p *plugin) generateStringValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { + if fv.Regex != nil { + p.P(`if !`, p.regexName(ccTypeName, fieldName), `.MatchString(`, variableName, `) {`) + p.In() + errorStr := "be a string conforming to regex " + strconv.Quote(fv.GetRegex()) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + if fv.StringNotEmpty != nil && fv.GetStringNotEmpty() { + p.P(`if `, variableName, ` == "" {`) + p.In() + errorStr := "not be an empty string" + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + p.generateLengthValidator(variableName, ccTypeName, fieldName, fv) + +} + +func (p *plugin) generateRepeatedCountValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { + if fv == nil { + return + } + if fv.RepeatedCountMin != nil { + compareStr := fmt.Sprint(`if len(`, variableName, `) < `, fv.GetRepeatedCountMin(), ` {`) + p.P(compareStr) + p.In() + errorStr := fmt.Sprint(`contain at least `, fv.GetRepeatedCountMin(), ` elements`) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } + if fv.RepeatedCountMax != nil { + compareStr := fmt.Sprint(`if len(`, variableName, `) > `, fv.GetRepeatedCountMax(), ` {`) + p.P(compareStr) + p.In() + errorStr := fmt.Sprint(`contain at most `, fv.GetRepeatedCountMax(), ` elements`) + p.generateErrorString(variableName, fieldName, errorStr, fv) + p.Out() + p.P(`}`) + } +} + +func (p *plugin) generateErrorString(variableName string, fieldName string, specificError string, fv *validator.FieldValidator) { + if fv.GetHumanError() == "" { + p.P(`return `, p.validatorPkg.Use(), `.FieldError("`, fieldName, `",`, p.fmtPkg.Use(), ".Errorf(`value '%v' must ", specificError, "`", `, `, variableName, `))`) + } else { + p.P(`return `, p.validatorPkg.Use(), `.FieldError("`, fieldName, `",`, p.fmtPkg.Use(), ".Errorf(`", fv.GetHumanError(), "`))") + } + +} + +func (p *plugin) fieldIsProto3Map(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) bool { + // Context from descriptor.proto + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + if field.GetType() != descriptor.FieldDescriptorProto_TYPE_MESSAGE || !field.IsRepeated() { + return false + } + typeName := field.GetTypeName() + var msg *descriptor.DescriptorProto + if strings.HasPrefix(typeName, ".") { + // Fully qualified case, look up in global map, must work or fail badly. + msg = p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor).DescriptorProto + } else { + // Nested, relative case. + msg = file.GetNestedMessage(message.DescriptorProto, field.GetTypeName()) + } + return msg.GetOptions().GetMapEntry() +} + +func (p *plugin) validatorWithAnyConstraint(fv *validator.FieldValidator) bool { + if fv == nil { + return false + } + + // Need to use reflection in order to be future-proof for new types of constraints. + v := reflect.ValueOf(fv) + for i := 0; i < v.NumField(); i++ { + if v.Field(i).Interface() != nil { + return true + } + } + return false +} + +func (p *plugin) validatorWithMessageExists(fv *validator.FieldValidator) bool { + return fv != nil && fv.MsgExists != nil && *(fv.MsgExists) +} + +func (p *plugin) validatorWithNonRepeatedConstraint(fv *validator.FieldValidator) bool { + if fv == nil { + return false + } + + // Need to use reflection in order to be future-proof for new types of constraints. + v := reflect.ValueOf(*fv) + for i := 0; i < v.NumField(); i++ { + if v.Type().Field(i).Name != "RepeatedCountMin" && v.Type().Field(i).Name != "RepeatedCountMax" && v.Field(i).Pointer() != 0 { + return true + } + } + return false +} + +func (p *plugin) regexName(ccTypeName string, fieldName string) string { + return "_regex_" + ccTypeName + "_" + fieldName +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/protoc-gen-govalidators/main.go b/vendor/github.com/mwitkow/go-proto-validators/protoc-gen-govalidators/main.go new file mode 100755 index 0000000..2aacf29 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/protoc-gen-govalidators/main.go @@ -0,0 +1,67 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package main + +import ( + "io/ioutil" + "os" + "strconv" + "strings" + + "github.com/gogo/protobuf/proto" + "github.com/gogo/protobuf/protoc-gen-gogo/generator" + validator_plugin "github.com/mwitkow/go-proto-validators/plugin" +) + +func main() { + gen := generator.New() + + data, err := ioutil.ReadAll(os.Stdin) + if err != nil { + gen.Error(err, "reading input") + } + + if err := proto.Unmarshal(data, gen.Request); err != nil { + gen.Error(err, "parsing input proto") + } + + if len(gen.Request.FileToGenerate) == 0 { + gen.Fail("no files to generate") + } + + useGogoImport := false + // Match parsing algorithm from Generator.CommandLineParameters + for _, parameter := range strings.Split(gen.Request.GetParameter(), ",") { + kvp := strings.SplitN(parameter, "=", 2) + // We only care about key-value pairs where the key is "gogoimport" + if len(kvp) != 2 || kvp[0] != "gogoimport" { + continue + } + useGogoImport, err = strconv.ParseBool(kvp[1]) + if err != nil { + gen.Error(err, "parsing gogoimport option") + } + } + + gen.CommandLineParameters(gen.Request.GetParameter()) + + gen.WrapTypes() + gen.SetPackageNames() + gen.BuildTypeNameMap() + gen.GeneratePlugin(validator_plugin.NewPlugin(useGogoImport)) + + for i := 0; i < len(gen.Response.File); i++ { + gen.Response.File[i].Name = proto.String(strings.Replace(*gen.Response.File[i].Name, ".pb.go", ".validator.pb.go", -1)) + } + + // Send back the results. + data, err = proto.Marshal(gen.Response) + if err != nil { + gen.Error(err, "failed to marshal output proto") + } + _, err = os.Stdout.Write(data) + if err != nil { + gen.Error(err, "failed to write output proto") + } +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/.gitignore b/vendor/github.com/mwitkow/go-proto-validators/test/.gitignore new file mode 100755 index 0000000..f8fcb25 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/.gitignore @@ -0,0 +1,2 @@ +*.pb.go +Makefile \ No newline at end of file diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/gogo/validator_test.go b/vendor/github.com/mwitkow/go-proto-validators/test/gogo/validator_test.go new file mode 100755 index 0000000..5f34906 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/gogo/validator_test.go @@ -0,0 +1,488 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package validatortest + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + stableBytes = make([]byte, 12) +) + +func buildProto3(someString string, someInt uint32, identifier string, someValue int64, someDoubleStrict float64, + someFloatStrict float32, someDouble float64, someFloat float32, nonEmptyString string, repeatedCount uint32, someStringLength string, someBytes []byte) *ValidatorMessage3 { + goodEmbeddedProto3 := &ValidatorMessage3_Embedded{ + Identifier: identifier, + SomeValue: someValue, + } + + goodProto3 := &ValidatorMessage3{ + SomeString: someString, + SomeStringRep: []string{someString, "xyz34"}, + SomeStringNoQuotes: someString, + SomeStringUnescaped: someString, + + SomeInt: someInt, + SomeIntRep: []uint32{someInt, 12, 13, 14, 15, 16}, + SomeIntRepNonNull: []uint32{someInt, 102}, + + SomeEmbedded: nil, + SomeEmbeddedNonNullable: *goodEmbeddedProto3, + SomeEmbeddedExists: goodEmbeddedProto3, + SomeEmbeddedRep: []*ValidatorMessage3_Embedded{goodEmbeddedProto3}, + SomeEmbeddedRepNonNullable: []ValidatorMessage3_Embedded{*goodEmbeddedProto3}, + + StrictSomeDouble: someDoubleStrict, + StrictSomeDoubleRep: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeDoubleRepNonNull: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeFloat: someFloatStrict, + StrictSomeFloatRep: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatRepNonNull: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + + SomeDouble: someDouble, + SomeDoubleRep: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeDoubleRepNonNull: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeFloat: someFloat, + SomeFloatRep: []float32{someFloat, 0.5, 0.55, 0.6}, + SomeFloatRepNonNull: []float32{someFloat, 0.5, 0.55, 0.6}, + + SomeNonEmptyString: nonEmptyString, + SomeStringEqReq: someStringLength, + SomeStringLtReq: someStringLength, + SomeStringGtReq: someStringLength, + + SomeBytesLtReq: someBytes, + SomeBytesGtReq: someBytes, + SomeBytesEqReq: someBytes, + RepeatedBaseType: []int32{}, + } + + goodProto3.Repeated = make([]int32, repeatedCount, repeatedCount) + + return goodProto3 +} + +func buildProto2(someString string, someInt uint32, identifier string, someValue int64, someDoubleStrict float64, + someFloatStrict float32, someDouble float64, someFloat float32, nonEmptyString string, repeatedCount uint32, someStringLength string, someBytes []byte) *ValidatorMessage { + goodEmbeddedProto2 := &ValidatorMessage_Embedded{ + Identifier: &identifier, + SomeValue: &someValue, + } + + goodProto2 := &ValidatorMessage{ + StringReq: &someString, + StringReqNonNull: someString, + + StringOpt: nil, + StringOptNonNull: someString, + + StringUnescaped: &someString, + + IntReq: &someInt, + IntReqNonNull: someInt, + IntRep: []uint32{someInt, 12, 13, 14, 15, 16}, + IntRepNonNull: []uint32{someInt, 12, 13, 14, 15, 16}, + + EmbeddedReq: goodEmbeddedProto2, + EmbeddedNonNull: *goodEmbeddedProto2, + EmbeddedRep: []*ValidatorMessage_Embedded{goodEmbeddedProto2}, + EmbeddedRepNonNullable: []ValidatorMessage_Embedded{*goodEmbeddedProto2}, + + StrictSomeDoubleReq: &someDoubleStrict, + StrictSomeDoubleReqNonNull: someDoubleStrict, + StrictSomeDoubleRep: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeDoubleRepNonNull: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatReq: &someFloatStrict, + StrictSomeFloatReqNonNull: someFloatStrict, + StrictSomeFloatRep: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatRepNonNull: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + + SomeDoubleReq: &someDouble, + SomeDoubleReqNonNull: someDouble, + SomeDoubleRep: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeDoubleRepNonNull: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeFloatReq: &someFloat, + SomeFloatReqNonNull: someFloat, + SomeFloatRep: []float32{someFloat, 0.5, 0.55, 0.6}, + SomeFloatRepNonNull: []float32{someFloat, 0.5, 0.55, 0.6}, + + SomeNonEmptyString: &nonEmptyString, + SomeStringEqReq: &someStringLength, + SomeStringLtReq: &someStringLength, + SomeStringGtReq: &someStringLength, + + SomeBytesLtReq: someBytes, + SomeBytesGtReq: someBytes, + SomeBytesEqReq: someBytes, + RepeatedBaseType: []int32{}, + } + + goodProto2.Repeated = make([]int32, repeatedCount, repeatedCount) + + return goodProto2 +} + +func TestGoodProto3(t *testing.T) { + var err error + goodProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + err = goodProto3.Validate() + if err != nil { + t.Fatalf("unexpected fail in validator: %v", err) + } +} + +func TestGoodProto2(t *testing.T) { + var err error + goodProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + err = goodProto2.Validate() + if err != nil { + t.Fatalf("unexpected fail in validator: %v", err) + } +} + +func TestStringRegex(t *testing.T) { + tooLong1Proto3 := buildProto3("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong1Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooLong2Proto3 := buildProto3("-%ab", 11, "bad#", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong2Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooLong1Proto2 := buildProto2("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong1Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooLong2Proto2 := buildProto2("-%ab", 11, "bad#", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong2Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } +} + +func TestIntLowerBounds(t *testing.T) { + lowerThan10Proto3 := buildProto3("-%ab", 9, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan10Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan10Proto2 := buildProto2("-%ab", 9, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan10Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", -1, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", -1, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } +} + +func TestIntUpperBounds(t *testing.T) { + greaterThan100Proto3 := buildProto3("-%ab", 11, "abba", 101, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan100Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan100Proto2 := buildProto2("-%ab", 11, "abba", 101, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan100Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } +} + +func TestDoubleStrictLowerBounds(t *testing.T) { + lowerThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.3, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.3, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.300000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan035EpsilonProto3.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } + greaterThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.300000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan035EpsilonProto2.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } +} + +func TestDoubleStrictUpperBounds(t *testing.T) { + greaterThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.70000000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.70000000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.6999999999, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan065EpsilonProto3.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } + lowerThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.6999999999, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan065EpsilonProto2.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } +} + +func TestFloatStrictLowerBounds(t *testing.T) { + lowerThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.2999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.2999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.3000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := greaterThan035EpsilonProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + greaterThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.3000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := greaterThan035EpsilonProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestFloatStrictUpperBounds(t *testing.T) { + greaterThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.7000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.7000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.6999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := lowerThan065EpsilonProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + lowerThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.6999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := lowerThan065EpsilonProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestDoubleNonStrictLowerBounds(t *testing.T) { + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.2499999, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.2499999, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.25, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.25, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestDoubleNonStrictUpperBounds(t *testing.T) { + higherThan1Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75111111, 0.5, "x", 4, "1234567890", stableBytes) + if higherThan1Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + higherThan1Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75111111, 0.5, "x", 4, "1234567890", stableBytes) + if higherThan1Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestFloatNonStrictLowerBounds(t *testing.T) { + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.2499999, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.2499999, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.25, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.25, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestFloatNonStrictUpperBounds(t *testing.T) { + higherThan1Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75111111, "x", 4, "1234567890", stableBytes) + if higherThan1Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + higherThan1Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75111111, "x", 4, "1234567890", stableBytes) + if higherThan1Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestStringNonEmpty(t *testing.T) { + emptyStringProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "", 4, "1234567890", stableBytes) + if emptyStringProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + emptyStringProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "", 4, "1234567890", stableBytes) + if emptyStringProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + nonEmptyStringProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := nonEmptyStringProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + nonEmptyStringProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := nonEmptyStringProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestRepeatedEltsCount(t *testing.T) { + notEnoughEltsProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 1, "1234567890", stableBytes) + if notEnoughEltsProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + notEnoughEltsProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 1, "1234567890", stableBytes) + if notEnoughEltsProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooManyEltsProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 14, "1234567890", stableBytes) + if tooManyEltsProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooManyEltsProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 14, "1234567890", stableBytes) + if tooManyEltsProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + validEltsCountProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := validEltsCountProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + validEltsCountProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := validEltsCountProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestMsgExist(t *testing.T) { + someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + someProto3.SomeEmbedded = nil + if err := someProto3.Validate(); err != nil { + t.Fatalf("validate shouldn't fail on missing SomeEmbedded, not annotated") + } + someProto3.SomeEmbeddedExists = nil + if err := someProto3.Validate(); err == nil { + t.Fatalf("expected fail due to lacking SomeEmbeddedExists") + } else if !strings.HasPrefix(err.Error(), "invalid field SomeEmbeddedExists:") { + t.Fatalf("expected fieldError, got '%v'", err) + } +} + +func TestNestedError3(t *testing.T) { + someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + someProto3.SomeEmbeddedExists.SomeValue = 101 // should be less than 101 + if err := someProto3.Validate(); err == nil { + t.Fatalf("expected fail due to nested SomeEmbeddedExists.SomeValue being wrong") + } else if !strings.HasPrefix(err.Error(), "invalid field SomeEmbeddedExists.SomeValue:") { + t.Fatalf("expected fieldError, got '%v'", err) + } +} + +func TestCustomError_Proto3(t *testing.T) { + someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + someProto3.CustomErrorInt = 30 + expectedErr := "invalid field CustomErrorInt: My Custom Error" + if err := someProto3.Validate(); err == nil { + t.Fatalf("validate should fail on missing CustomErrorInt") + } else if err.Error() != expectedErr { + t.Fatalf("validation error should be '%s' but was '%s'", expectedErr, err.Error()) + } +} + +func TestMapAlwaysPassesUntilFixedProperly(t *testing.T) { + example := &ValidatorMapMessage3{} + if err := example.Validate(); err != nil { + t.Fatalf("map validators should always pass") + } +} + +func TestOneOf_NestedMessage(t *testing.T) { + example := &OneOfMessage3{ + SomeInt: 30, + Type: &OneOfMessage3_OneMsg{ + OneMsg: &ExternalMsg{ + Identifier: "999", // bad + SomeValue: 99, // good + }, + }, + Something: &OneOfMessage3_ThreeInt{ + ThreeInt: 100, // > 20 + }, + } + err := example.Validate() + assert.Error(t, err, "nested message in oneof should fail validation on ExternalMsg") + assert.Contains(t, err.Error(), "OneMsg.Identifier", "error must err on the ExternalMsg.Identifier") +} + +func TestOneOf_NestedInt(t *testing.T) { + example := &OneOfMessage3{ + SomeInt: 30, + Type: &OneOfMessage3_OneMsg{ + OneMsg: &ExternalMsg{ + Identifier: "abba", // good + SomeValue: 99, // good + }, + }, + Something: &OneOfMessage3_ThreeInt{ + ThreeInt: 19, // > 20 + }, + } + err := example.Validate() + assert.Error(t, err, "nested message in oneof should fail validation on ThreeInt") + assert.Contains(t, err.Error(), "ThreeInt", "error must err on the ThreeInt.ThreeInt") +} + +func TestOneOf_Passes(t *testing.T) { + example := &OneOfMessage3{ + SomeInt: 30, + Type: &OneOfMessage3_OneMsg{ + OneMsg: &ExternalMsg{ + Identifier: "abba", // good + SomeValue: 99, // good + }, + }, + Something: &OneOfMessage3_FourInt{ + FourInt: 101, // > 101 + }, + } + err := example.Validate() + assert.NoError(t, err, "This message should pass all validation") +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/golang/validator_test.go b/vendor/github.com/mwitkow/go-proto-validators/test/golang/validator_test.go new file mode 100755 index 0000000..8668359 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/golang/validator_test.go @@ -0,0 +1,512 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package validatortest + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + stableBytes = make([]byte, 12) +) + +func buildProto3(someString string, someInt uint32, identifier string, someValue int64, someDoubleStrict float64, + someFloatStrict float32, someDouble float64, someFloat float32, nonEmptyString string, repeatedCount uint32, + someStringLength string, someBytes []byte) *ValidatorMessage3 { + goodEmbeddedProto3 := &ValidatorMessage3_Embedded{ + Identifier: identifier, + SomeValue: someValue, + } + + goodProto3 := &ValidatorMessage3{ + SomeString: someString, + SomeStringRep: []string{someString, "xyz34"}, + SomeStringNoQuotes: someString, + SomeStringUnescaped: someString, + + SomeInt: someInt, + SomeIntRep: []uint32{someInt, 12, 13, 14, 15, 16}, + SomeIntRepNonNull: []uint32{someInt, 102}, + + SomeEmbedded: nil, + SomeEmbeddedNonNullable: goodEmbeddedProto3, + SomeEmbeddedExists: goodEmbeddedProto3, + SomeEmbeddedRep: []*ValidatorMessage3_Embedded{goodEmbeddedProto3}, + SomeEmbeddedRepNonNullable: []*ValidatorMessage3_Embedded{goodEmbeddedProto3}, + + StrictSomeDouble: someDoubleStrict, + StrictSomeDoubleRep: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeDoubleRepNonNull: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeFloat: someFloatStrict, + StrictSomeFloatRep: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatRepNonNull: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + + SomeDouble: someDouble, + SomeDoubleRep: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeDoubleRepNonNull: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeFloat: someFloat, + SomeFloatRep: []float32{someFloat, 0.5, 0.55, 0.6}, + SomeFloatRepNonNull: []float32{someFloat, 0.5, 0.55, 0.6}, + + SomeNonEmptyString: nonEmptyString, + SomeStringEqReq: someStringLength, + SomeStringLtReq: someStringLength, + SomeStringGtReq: someStringLength, + + SomeBytesLtReq: someBytes, + SomeBytesGtReq: someBytes, + SomeBytesEqReq: someBytes, + + RepeatedBaseType: []int32{}, + } + + goodProto3.Repeated = make([]int32, repeatedCount, repeatedCount) + + return goodProto3 +} + +func buildProto2(someString string, someInt uint32, identifier string, someValue int64, someDoubleStrict float64, someFloatStrict float32, someDouble float64, someFloat float32, nonEmptyString string, repeatedCount uint32, someStringLength string, someBytes []byte) *ValidatorMessage { + goodEmbeddedProto2 := &ValidatorMessage_Embedded{ + Identifier: &identifier, + SomeValue: &someValue, + } + + goodProto2 := &ValidatorMessage{ + StringReq: &someString, + StringReqNonNull: &someString, + + StringOpt: nil, + StringOptNonNull: &someString, + + StringUnescaped: &someString, + + IntReq: &someInt, + IntReqNonNull: &someInt, + IntRep: []uint32{someInt, 12, 13, 14, 15, 16}, + IntRepNonNull: []uint32{someInt, 12, 13, 14, 15, 16}, + + EmbeddedReq: goodEmbeddedProto2, + EmbeddedNonNull: goodEmbeddedProto2, + EmbeddedRep: []*ValidatorMessage_Embedded{goodEmbeddedProto2}, + EmbeddedRepNonNullable: []*ValidatorMessage_Embedded{goodEmbeddedProto2}, + + StrictSomeDoubleReq: &someDoubleStrict, + StrictSomeDoubleReqNonNull: &someDoubleStrict, + StrictSomeDoubleRep: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeDoubleRepNonNull: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatReq: &someFloatStrict, + StrictSomeFloatReqNonNull: &someFloatStrict, + StrictSomeFloatRep: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatRepNonNull: []float32{someFloatStrict, 0.5, 0.55, 0.6}, + + SomeDoubleReq: &someDouble, + SomeDoubleReqNonNull: &someDouble, + SomeDoubleRep: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeDoubleRepNonNull: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeFloatReq: &someFloat, + SomeFloatReqNonNull: &someFloat, + SomeFloatRep: []float32{someFloat, 0.5, 0.55, 0.6}, + SomeFloatRepNonNull: []float32{someFloat, 0.5, 0.55, 0.6}, + + SomeNonEmptyString: &nonEmptyString, + SomeStringEqReq: &someStringLength, + SomeStringLtReq: &someStringLength, + SomeStringGtReq: &someStringLength, + SomeBytesLtReq: someBytes, + SomeBytesGtReq: someBytes, + SomeBytesEqReq: someBytes, + RepeatedBaseType: []int32{}, + } + + goodProto2.Repeated = make([]int32, repeatedCount, repeatedCount) + + return goodProto2 +} + +func TestGoodProto3(t *testing.T) { + var err error + goodProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + err = goodProto3.Validate() + if err != nil { + t.Fatalf("unexpected fail in validator: %v", err) + } +} + +func TestGoodProto2(t *testing.T) { + var err error + goodProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + err = goodProto2.Validate() + if err != nil { + t.Fatalf("unexpected fail in validator: %v", err) + } +} + +func TestStringRegex(t *testing.T) { + tooLong1Proto3 := buildProto3("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong1Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooLong2Proto3 := buildProto3("-%ab", 11, "bad#", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong2Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooLong1Proto2 := buildProto2("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong1Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooLong2Proto2 := buildProto2("-%ab", 11, "bad#", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if tooLong2Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } +} + +func TestIntLowerBounds(t *testing.T) { + lowerThan10Proto3 := buildProto3("-%ab", 9, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan10Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan10Proto2 := buildProto2("-%ab", 9, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan10Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", -1, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", -1, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } +} + +func TestIntUpperBounds(t *testing.T) { + greaterThan100Proto3 := buildProto3("-%ab", 11, "abba", 101, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan100Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan100Proto2 := buildProto2("-%ab", 11, "abba", 101, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan100Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } +} + +func TestDoubleStrictLowerBounds(t *testing.T) { + lowerThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.3, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.3, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.300000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan035EpsilonProto3.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } + greaterThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.300000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan035EpsilonProto2.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } +} + +func TestDoubleStrictUpperBounds(t *testing.T) { + greaterThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.70000000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.70000000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.6999999999, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan065EpsilonProto3.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } + lowerThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.6999999999, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan065EpsilonProto2.Validate() != nil { + t.Fatalf("unexpected fail in validator") + } +} + +func TestFloatStrictLowerBounds(t *testing.T) { + lowerThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.2999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.2999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan035EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.3000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := greaterThan035EpsilonProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + greaterThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.3000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := greaterThan035EpsilonProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestFloatStrictUpperBounds(t *testing.T) { + greaterThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.7000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + greaterThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.7000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if greaterThan065EpsilonProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.6999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := lowerThan065EpsilonProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + lowerThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.6999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := lowerThan065EpsilonProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestDoubleNonStrictLowerBounds(t *testing.T) { + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.2499999, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.2499999, 0.5, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.25, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.25, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestDoubleNonStrictUpperBounds(t *testing.T) { + higherThan1Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75111111, 0.5, "x", 4, "1234567890", stableBytes) + if higherThan1Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + higherThan1Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75111111, 0.5, "x", 4, "1234567890", stableBytes) + if higherThan1Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75, 0.5, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestFloatNonStrictLowerBounds(t *testing.T) { + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.2499999, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.2499999, "x", 4, "1234567890", stableBytes) + if lowerThan0Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.25, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.25, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestFloatNonStrictUpperBounds(t *testing.T) { + higherThan1Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75111111, "x", 4, "1234567890", stableBytes) + if higherThan1Proto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + higherThan1Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75111111, "x", 4, "1234567890", stableBytes) + if higherThan1Proto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75, "x", 4, "1234567890", stableBytes) + if err := equalTo0Proto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestStringNonEmpty(t *testing.T) { + emptyStringProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "", 4, "1234567890", stableBytes) + if emptyStringProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + emptyStringProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "", 4, "1234567890", stableBytes) + if emptyStringProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + nonEmptyStringProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := nonEmptyStringProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + nonEmptyStringProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := nonEmptyStringProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestRepeatedEltsCount(t *testing.T) { + notEnoughEltsProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 1, "1234567890", stableBytes) + if notEnoughEltsProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + notEnoughEltsProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 1, "1234567890", stableBytes) + if notEnoughEltsProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooManyEltsProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 14, "1234567890", stableBytes) + if tooManyEltsProto3.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + tooManyEltsProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 14, "1234567890", stableBytes) + if tooManyEltsProto2.Validate() == nil { + t.Fatalf("expected fail in validator, but it didn't happen") + } + validEltsCountProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := validEltsCountProto3.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } + validEltsCountProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := validEltsCountProto2.Validate(); err != nil { + t.Fatalf("unexpected fail in validator %v", err) + } +} + +func TestMsgExist(t *testing.T) { + someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + someProto3.SomeEmbedded = nil + if err := someProto3.Validate(); err != nil { + t.Fatalf("validate shouldn't fail on missing SomeEmbedded, not annotated") + } + someProto3.SomeEmbeddedExists = nil + if err := someProto3.Validate(); err == nil { + t.Fatalf("expected fail due to lacking SomeEmbeddedExists") + } else if !strings.HasPrefix(err.Error(), "invalid field SomeEmbeddedExists:") { + t.Fatalf("expected fieldError, got '%v'", err) + } +} + +func TestStringLengthValidator(t *testing.T) { + StringLengthErrorProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "abc456", stableBytes) + if err := StringLengthErrorProto3.Validate(); err == nil { + t.Fatalf("validate shouldn't fail on error length") + } + + StringLengthSuccess := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := StringLengthSuccess.Validate(); err != nil { + t.Fatalf("validate shouldn't fail on equal length") + } +} + +func TestBytesLengthValidator(t *testing.T) { + StringLengthErrorProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "abc456", []byte("anc")) + if err := StringLengthErrorProto3.Validate(); err == nil { + t.Fatalf("validate shouldn't fail on error length") + } + + StringLengthSuccess := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + if err := StringLengthSuccess.Validate(); err != nil { + t.Fatalf("validate shouldn't fail on equal length") + } +} + +func TestNestedError3(t *testing.T) { + someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + someProto3.SomeEmbeddedExists.SomeValue = 101 // should be less than 101 + if err := someProto3.Validate(); err == nil { + t.Fatalf("expected fail due to nested SomeEmbeddedNonNullable.SomeValue being wrong") + } else if !strings.HasPrefix(err.Error(), "invalid field SomeEmbeddedNonNullable.SomeValue:") { + t.Fatalf("expected fieldError, got '%v'", err) + } +} + +func TestCustomError_Proto3(t *testing.T) { + someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes) + someProto3.CustomErrorInt = 30 + expectedErr := "invalid field CustomErrorInt: My Custom Error" + if err := someProto3.Validate(); err == nil { + t.Fatalf("validate should fail on missing CustomErrorInt") + } else if err.Error() != expectedErr { + t.Fatalf("validation error should be '%s' but was '%s'", expectedErr, err.Error()) + } +} + +func TestMapAlwaysPassesUntilFixedProperly(t *testing.T) { + example := &ValidatorMapMessage3{} + if err := example.Validate(); err != nil { + t.Fatalf("map validators should always pass") + } +} + +func TestOneOf_NestedMessage(t *testing.T) { + example := &OneOfMessage3{ + SomeInt: 30, + Type: &OneOfMessage3_OneMsg{ + OneMsg: &ExternalMsg{ + Identifier: "999", // bad + SomeValue: 99, // good + }, + }, + Something: &OneOfMessage3_ThreeInt{ + ThreeInt: 100, // > 20 + }, + } + err := example.Validate() + assert.Error(t, err, "nested message in oneof should fail validation on ExternalMsg") + assert.Contains(t, err.Error(), "OneMsg.Identifier", "error must err on the ExternalMsg.Identifier") +} + +func TestOneOf_NestedInt(t *testing.T) { + example := &OneOfMessage3{ + SomeInt: 30, + Type: &OneOfMessage3_OneMsg{ + OneMsg: &ExternalMsg{ + Identifier: "abba", // good + SomeValue: 99, // good + }, + }, + Something: &OneOfMessage3_ThreeInt{ + ThreeInt: 19, // > 20 + }, + } + err := example.Validate() + assert.Error(t, err, "nested message in oneof should fail validation on ThreeInt") + assert.Contains(t, err.Error(), "ThreeInt", "error must err on the ThreeInt.ThreeInt") +} + +func TestOneOf_Passes(t *testing.T) { + example := &OneOfMessage3{ + SomeInt: 30, + Type: &OneOfMessage3_OneMsg{ + OneMsg: &ExternalMsg{ + Identifier: "abba", // good + SomeValue: 99, // good + }, + }, + Something: &OneOfMessage3_FourInt{ + FourInt: 101, // > 101 + }, + } + err := example.Validate() + assert.NoError(t, err, "This message should pass all validation") +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto2.proto b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto2.proto new file mode 100755 index 0000000..e0e95ae --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto2.proto @@ -0,0 +1,78 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +syntax = "proto2"; +package validatortest; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message ValidatorMessage { + // Embedded message test structure. + message Embedded { + optional string Identifier = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + required int64 SomeValue = 2 [(validator.field) = {int_gt: 0, int_lt: 100}]; + } + + // String regex constraint tests. + required string StringReq = 1 [(validator.field) = {regex: "^.{2,5}$"}]; + required string StringReqNonNull = 2 [(validator.field) = {regex: "^.{2,5}$"}, (gogoproto.nullable) = false]; + optional string StringOpt = 3 [(validator.field) = {regex: "^.{2,5}$"}]; + optional string StringOptNonNull = 4 [(validator.field) = {regex: "^.{2,5}$"}, (gogoproto.nullable) = false]; + required string StringUnescaped = 5 [(validator.field) = {regex: "[\\p{L}\\p{N}]({\\p{L}\\p{N}_- ]{0,28}[\\p{L}\\p{N}])?."}]; + + // Strict integer inequality constraint tests. + required uint32 IntReq = 6 [(validator.field) = {int_gt: 10}]; + required uint32 IntReqNonNull = 7 [(validator.field) = {int_gt: 0}, (gogoproto.nullable) = false]; + repeated uint32 IntRep = 8 [(validator.field) = {int_gt: 10}]; + repeated uint32 IntRepNonNull = 9 [(validator.field) = {int_gt: 0}]; + + // Embedded message recursive constraint tests. + required Embedded embeddedReq = 10; + required Embedded embeddedNonNull = 11 [(gogoproto.nullable) = false]; + repeated Embedded embeddedRep = 12; + repeated Embedded embeddedRepNonNullable = 13 [(gogoproto.nullable) = false]; + + // Custom error tests. + optional int32 CustomErrorInt = 16 [(validator.field) = {int_gt: 10, human_error: "My Custom Error"}]; + + // Strict floating-point inequality constraint tests. + // With this epsilon value, the limits become + // SomeFloat+0.05 > 0.35 + // SomeFloat-0.05 < 0.65 + required double StrictSomeDoubleReq = 17 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + required double StrictSomeDoubleReqNonNull = 18 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}, (gogoproto.nullable) = false]; + repeated double StrictSomeDoubleRep = 19 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + repeated double StrictSomeDoubleRepNonNull = 20 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + required float StrictSomeFloatReq = 21 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + required float StrictSomeFloatReqNonNull = 22 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}, (gogoproto.nullable) = false]; + repeated float StrictSomeFloatRep = 23 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + repeated float StrictSomeFloatRepNonNull = 24 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + + // Non-strict floating-point inequality constraint tests. + required double SomeDoubleReq = 25 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + required double SomeDoubleReqNonNull = 26 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}, (gogoproto.nullable) = false]; + repeated double SomeDoubleRep = 27 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + repeated double SomeDoubleRepNonNull = 28 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + required float SomeFloatReq = 29 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + required float SomeFloatReqNonNull = 30 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}, (gogoproto.nullable) = false]; + repeated float SomeFloatRep = 31 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + repeated float SomeFloatRepNonNull = 32 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + + // String not-empty constraint tests. + required string SomeNonEmptyString = 33 [(validator.field) = {string_not_empty: true}]; + + // Repeated base-type without constraint tests. + repeated int32 RepeatedBaseType = 34; + + // Repeated element count constraint tests. + repeated int32 Repeated = 35 [(validator.field) = {repeated_count_min: 2, repeated_count_max: 5}]; + + optional string SomeStringLtReq = 36 [(validator.field) = {length_gt: 2}]; + optional string SomeStringGtReq = 37 [(validator.field) = {length_lt: 12}]; + optional string SomeStringEqReq = 38 [(validator.field) = {length_eq: 10}]; + optional bytes SomeBytesLtReq = 39 [(validator.field) = {length_gt: 5}]; + optional bytes SomeBytesGtReq = 40 [(validator.field) = {length_lt: 20}]; + optional bytes SomeBytesEqReq = 41 [(validator.field) = {length_eq: 12}]; + +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3.proto b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3.proto new file mode 100755 index 0000000..dd0b9dd --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3.proto @@ -0,0 +1,72 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +syntax = "proto3"; +package validatortest; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message ValidatorMessage3 { + // Embedded message test structure. + message Embedded { + string Identifier = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + int64 SomeValue = 2 [(validator.field) = {int_gt: 0, int_lt: 100}]; + } + + // String regex constraint tests. + string SomeString = 1 [(validator.field) = {regex: "^.{2,5}$"}]; + repeated string SomeStringRep = 2 [(validator.field) = {regex: "^.{2,5}$"}]; + string SomeStringNoQuotes = 3 [(validator.field) = {regex: "^[^\"]{2,5}$"}]; + string SomeStringUnescaped = 4 [(validator.field) = {regex: "[\\p{L}\\p{N}]({\\p{L}\\p{N}_- ]{0,28}[\\p{L}\\p{N}])?."}]; + + // Strict integer inequality constraint tests. + uint32 SomeInt = 6 [(validator.field) = {int_gt: 10}]; + repeated uint32 SomeIntRep = 7 [(validator.field) = {int_gt: 10}]; + repeated uint32 SomeIntRepNonNull = 8 [(validator.field) = {int_gt: 10}]; + + // Embedded message existence and recursive constraint tests. + Embedded someEmbedded = 10; + Embedded someEmbeddedNonNullable = 11 [(gogoproto.nullable) = false]; + Embedded someEmbeddedExists = 12 [(validator.field) = {msg_exists : true}]; + repeated Embedded someEmbeddedRep = 14; + repeated Embedded someEmbeddedRepNonNullable = 15 [(gogoproto.nullable) = false]; + + // Custom error tests. + int32 CustomErrorInt = 16 [(validator.field) = {int_lt: 10, human_error: "My Custom Error"}]; + + // Strict floating-point inequality constraint tests. + // With this epsilon value, the limits become + // SomeFloat+0.05 > 0.35 + // SomeFloat-0.05 < 0.65 + double StrictSomeDouble = 17 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + repeated double StrictSomeDoubleRep = 19 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + repeated double StrictSomeDoubleRepNonNull = 20 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + float StrictSomeFloat = 21 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + repeated float StrictSomeFloatRep = 22 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + repeated float StrictSomeFloatRepNonNull = 23 [(validator.field) = {float_gt: 0.35, float_lt: 0.65, float_epsilon: 0.05}]; + + // Non-strict floating-point inequality constraint tests. + double SomeDouble = 24 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + repeated double SomeDoubleRep = 25 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + repeated double SomeDoubleRepNonNull = 26 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + float SomeFloat = 27 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + repeated float SomeFloatRep = 28 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + repeated float SomeFloatRepNonNull = 30 [(validator.field) = {float_gte: 0.25, float_lte: 0.75}]; + + // String not-empty constraint tests. + string SomeNonEmptyString = 31 [(validator.field) = {string_not_empty: true}]; + + // Repeated base-type without constraint tests. + repeated int32 RepeatedBaseType = 32; + + // Repeated element count constraint tests. + repeated int32 Repeated = 33 [(validator.field) = {repeated_count_min: 2, repeated_count_max: 5}]; + string SomeStringLtReq = 36 [(validator.field) = {length_gt: 2}]; + string SomeStringGtReq = 37 [(validator.field) = {length_lt: 12}]; + string SomeStringEqReq = 38 [(validator.field) = {length_eq: 10}]; + + bytes SomeBytesLtReq = 39 [(validator.field) = {length_gt: 5}]; + bytes SomeBytesGtReq = 40 [(validator.field) = {length_lt: 20}]; + bytes SomeBytesEqReq = 41 [(validator.field) = {length_eq: 12}]; +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3_map.proto b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3_map.proto new file mode 100755 index 0000000..f8799b1 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3_map.proto @@ -0,0 +1,26 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +syntax = "proto3"; +package validatortest; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message ValueType { + string something = 1 ; +} + +// This needs to be able to compile. Fixes https://github.com/mwitkow/go-proto-validators/issues/1 +message ValidatorMapMessage3 { + map SomeStringMap = 1; + + message NestedType { + string something = 1 ; + } + + map SomeExtMap = 2; + map SomeNestedMap = 3; +} + + diff --git a/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3_oneof.proto b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3_oneof.proto new file mode 100755 index 0000000..2170ed5 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/test/validator_proto3_oneof.proto @@ -0,0 +1,28 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +syntax = "proto3"; +package validatortest; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; +import "github.com/mwitkow/go-proto-validators/validator.proto"; + +message ExternalMsg { + string Identifier = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + int64 SomeValue = 2 [(validator.field) = {int_gt: 0, int_lt: 100}]; +} + +message OneOfMessage3 { + uint32 SomeInt = 1 [(validator.field) = {int_gt: 10}]; + + oneof type { + ExternalMsg one_msg = 2; + uint32 one_int = 3 [(validator.field) = {int_gt: 20}]; + uint32 two_int = 4 [(validator.field) = {int_gt: 100}]; + } + + oneof something { + uint32 three_int = 5 [(validator.field) = {int_gt: 20}]; + uint32 four_int = 6 [(validator.field) = {int_gt: 100}]; + } +} \ No newline at end of file diff --git a/vendor/github.com/mwitkow/go-proto-validators/validator.pb.go b/vendor/github.com/mwitkow/go-proto-validators/validator.pb.go new file mode 100755 index 0000000..755e6ed --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/validator.pb.go @@ -0,0 +1,238 @@ +// Code generated by protoc-gen-gogo. +// source: validator.proto +// DO NOT EDIT! + +/* +Package validator is a generated protocol buffer package. + +It is generated from these files: + validator.proto + +It has these top-level messages: + FieldValidator +*/ +package validator + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/gogo/protobuf/protoc-gen-gogo/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.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type FieldValidator struct { + // Uses a Golang RE2-syntax regex to match the field contents. + Regex *string `protobuf:"bytes,1,opt,name=regex" json:"regex,omitempty"` + // Field value of integer strictly greater than this value. + IntGt *int64 `protobuf:"varint,2,opt,name=int_gt,json=intGt" json:"int_gt,omitempty"` + // Field value of integer strictly smaller than this value. + IntLt *int64 `protobuf:"varint,3,opt,name=int_lt,json=intLt" json:"int_lt,omitempty"` + // Used for nested message types, requires that the message type exists. + MsgExists *bool `protobuf:"varint,4,opt,name=msg_exists,json=msgExists" json:"msg_exists,omitempty"` + // Human error specifies a user-customizable error that is visible to the user. + HumanError *string `protobuf:"bytes,5,opt,name=human_error,json=humanError" json:"human_error,omitempty"` + // Field value of double strictly greater than this value. + // Note that this value can only take on a valid floating point + // value. Use together with float_epsilon if you need something more specific. + FloatGt *float64 `protobuf:"fixed64,6,opt,name=float_gt,json=floatGt" json:"float_gt,omitempty"` + // Field value of double strictly smaller than this value. + // Note that this value can only take on a valid floating point + // value. Use together with float_epsilon if you need something more specific. + FloatLt *float64 `protobuf:"fixed64,7,opt,name=float_lt,json=floatLt" json:"float_lt,omitempty"` + // Field value of double describing the epsilon within which + // any comparison should be considered to be true. For example, + // when using float_gt = 0.35, using a float_epsilon of 0.05 + // would mean that any value above 0.30 is acceptable. It can be + // thought of as a {float_value_condition} +- {float_epsilon}. + // If unset, no correction for floating point inaccuracies in + // comparisons will be attempted. + FloatEpsilon *float64 `protobuf:"fixed64,8,opt,name=float_epsilon,json=floatEpsilon" json:"float_epsilon,omitempty"` + // Floating-point value compared to which the field content should be greater or equal. + FloatGte *float64 `protobuf:"fixed64,9,opt,name=float_gte,json=floatGte" json:"float_gte,omitempty"` + // Floating-point value compared to which the field content should be smaller or equal. + FloatLte *float64 `protobuf:"fixed64,10,opt,name=float_lte,json=floatLte" json:"float_lte,omitempty"` + // Used for string fields, requires the string to be not empty (i.e different from ""). + StringNotEmpty *bool `protobuf:"varint,11,opt,name=string_not_empty,json=stringNotEmpty" json:"string_not_empty,omitempty"` + // Repeated field with at least this number of elements. + RepeatedCountMin *int64 `protobuf:"varint,12,opt,name=repeated_count_min,json=repeatedCountMin" json:"repeated_count_min,omitempty"` + // Repeated field with at most this number of elements. + RepeatedCountMax *int64 `protobuf:"varint,13,opt,name=repeated_count_max,json=repeatedCountMax" json:"repeated_count_max,omitempty"` + // Field value of length greater than this value. + LengthGt *int64 `protobuf:"varint,14,opt,name=length_gt,json=lengthGt" json:"length_gt,omitempty"` + // Field value of length smaller than this value. + LengthLt *int64 `protobuf:"varint,15,opt,name=length_lt,json=lengthLt" json:"length_lt,omitempty"` + // Field value of integer strictly equal this value. + LengthEq *int64 `protobuf:"varint,16,opt,name=length_eq,json=lengthEq" json:"length_eq,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FieldValidator) Reset() { *m = FieldValidator{} } +func (m *FieldValidator) String() string { return proto.CompactTextString(m) } +func (*FieldValidator) ProtoMessage() {} +func (*FieldValidator) Descriptor() ([]byte, []int) { return fileDescriptorValidator, []int{0} } + +func (m *FieldValidator) GetRegex() string { + if m != nil && m.Regex != nil { + return *m.Regex + } + return "" +} + +func (m *FieldValidator) GetIntGt() int64 { + if m != nil && m.IntGt != nil { + return *m.IntGt + } + return 0 +} + +func (m *FieldValidator) GetIntLt() int64 { + if m != nil && m.IntLt != nil { + return *m.IntLt + } + return 0 +} + +func (m *FieldValidator) GetMsgExists() bool { + if m != nil && m.MsgExists != nil { + return *m.MsgExists + } + return false +} + +func (m *FieldValidator) GetHumanError() string { + if m != nil && m.HumanError != nil { + return *m.HumanError + } + return "" +} + +func (m *FieldValidator) GetFloatGt() float64 { + if m != nil && m.FloatGt != nil { + return *m.FloatGt + } + return 0 +} + +func (m *FieldValidator) GetFloatLt() float64 { + if m != nil && m.FloatLt != nil { + return *m.FloatLt + } + return 0 +} + +func (m *FieldValidator) GetFloatEpsilon() float64 { + if m != nil && m.FloatEpsilon != nil { + return *m.FloatEpsilon + } + return 0 +} + +func (m *FieldValidator) GetFloatGte() float64 { + if m != nil && m.FloatGte != nil { + return *m.FloatGte + } + return 0 +} + +func (m *FieldValidator) GetFloatLte() float64 { + if m != nil && m.FloatLte != nil { + return *m.FloatLte + } + return 0 +} + +func (m *FieldValidator) GetStringNotEmpty() bool { + if m != nil && m.StringNotEmpty != nil { + return *m.StringNotEmpty + } + return false +} + +func (m *FieldValidator) GetRepeatedCountMin() int64 { + if m != nil && m.RepeatedCountMin != nil { + return *m.RepeatedCountMin + } + return 0 +} + +func (m *FieldValidator) GetRepeatedCountMax() int64 { + if m != nil && m.RepeatedCountMax != nil { + return *m.RepeatedCountMax + } + return 0 +} + +func (m *FieldValidator) GetLengthGt() int64 { + if m != nil && m.LengthGt != nil { + return *m.LengthGt + } + return 0 +} + +func (m *FieldValidator) GetLengthLt() int64 { + if m != nil && m.LengthLt != nil { + return *m.LengthLt + } + return 0 +} + +func (m *FieldValidator) GetLengthEq() int64 { + if m != nil && m.LengthEq != nil { + return *m.LengthEq + } + return 0 +} + +var E_Field = &proto.ExtensionDesc{ + ExtendedType: (*google_protobuf.FieldOptions)(nil), + ExtensionType: (*FieldValidator)(nil), + Field: 65020, + Name: "validator.field", + Tag: "bytes,65020,opt,name=field", + Filename: "validator.proto", +} + +func init() { + proto.RegisterType((*FieldValidator)(nil), "validator.FieldValidator") + proto.RegisterExtension(E_Field) +} + +func init() { proto.RegisterFile("validator.proto", fileDescriptorValidator) } + +var fileDescriptorValidator = []byte{ + // 392 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x6c, 0x92, 0xcf, 0x8f, 0x93, 0x40, + 0x14, 0xc7, 0x83, 0xbb, 0xec, 0xc2, 0xb0, 0xdb, 0x6d, 0x26, 0x9a, 0x4c, 0x35, 0x8d, 0x44, 0x2f, + 0x1c, 0x0c, 0x4d, 0x3c, 0x7a, 0xd4, 0x60, 0x2f, 0xf8, 0x23, 0x1c, 0x3c, 0x78, 0x21, 0x58, 0x5e, + 0xa7, 0x93, 0x0c, 0x33, 0x74, 0xe6, 0xd5, 0xe0, 0x3f, 0xe0, 0x3f, 0xad, 0x07, 0xc3, 0x20, 0x85, + 0x4d, 0x7a, 0x9c, 0xcf, 0xe7, 0xcb, 0x1b, 0x78, 0x7c, 0xc9, 0xc3, 0xcf, 0x4a, 0x8a, 0xba, 0x42, + 0x6d, 0xd2, 0xd6, 0x68, 0xd4, 0x34, 0x3c, 0x83, 0xe7, 0x31, 0xd7, 0x9a, 0x4b, 0xd8, 0x38, 0xf1, + 0xe3, 0xb4, 0xdf, 0xd4, 0x60, 0x77, 0x46, 0xb4, 0xe7, 0xf0, 0xab, 0xdf, 0xd7, 0x64, 0xf1, 0x51, + 0x80, 0xac, 0xbf, 0x8d, 0x0f, 0xd1, 0xa7, 0xc4, 0x37, 0xc0, 0xa1, 0x63, 0x5e, 0xec, 0x25, 0x61, + 0x31, 0x1c, 0xe8, 0x33, 0x72, 0x23, 0x14, 0x96, 0x1c, 0xd9, 0x93, 0xd8, 0x4b, 0xae, 0x0a, 0x5f, + 0x28, 0xdc, 0xe2, 0x88, 0x25, 0xb2, 0xab, 0x33, 0xce, 0x91, 0xae, 0x09, 0x69, 0x2c, 0x2f, 0xa1, + 0x13, 0x16, 0x2d, 0xbb, 0x8e, 0xbd, 0x24, 0x28, 0xc2, 0xc6, 0xf2, 0xcc, 0x01, 0xfa, 0x92, 0x44, + 0x87, 0x53, 0x53, 0xa9, 0x12, 0x8c, 0xd1, 0x86, 0xf9, 0xee, 0x22, 0xe2, 0x50, 0xd6, 0x13, 0xba, + 0x22, 0xc1, 0x5e, 0xea, 0xca, 0xdd, 0x77, 0x13, 0x7b, 0x89, 0x57, 0xdc, 0xba, 0xf3, 0x16, 0x27, + 0x25, 0x91, 0xdd, 0xce, 0x54, 0x8e, 0xf4, 0x35, 0xb9, 0x1f, 0x14, 0xb4, 0x56, 0x48, 0xad, 0x58, + 0xe0, 0xfc, 0x9d, 0x83, 0xd9, 0xc0, 0xe8, 0x0b, 0x12, 0x8e, 0xa3, 0x81, 0x85, 0x2e, 0x10, 0xfc, + 0x9f, 0x0d, 0x93, 0x94, 0x08, 0x8c, 0xcc, 0x64, 0x8e, 0x40, 0x13, 0xb2, 0xb4, 0x68, 0x84, 0xe2, + 0xa5, 0xd2, 0x58, 0x42, 0xd3, 0xe2, 0x2f, 0x16, 0xb9, 0x4f, 0x5b, 0x0c, 0xfc, 0xb3, 0xc6, 0xac, + 0xa7, 0xf4, 0x0d, 0xa1, 0x06, 0x5a, 0xa8, 0x10, 0xea, 0x72, 0xa7, 0x4f, 0x0a, 0xcb, 0x46, 0x28, + 0x76, 0xe7, 0x36, 0xb4, 0x1c, 0xcd, 0x87, 0x5e, 0x7c, 0x12, 0xea, 0x52, 0xba, 0xea, 0xd8, 0xfd, + 0xa5, 0x74, 0xd5, 0xf5, 0xaf, 0x28, 0x41, 0x71, 0x3c, 0xf4, 0xbb, 0x59, 0xb8, 0x50, 0x30, 0x80, + 0x2d, 0xce, 0xa4, 0x44, 0xf6, 0x30, 0x97, 0xf9, 0x5c, 0xc2, 0x91, 0x2d, 0xe7, 0x32, 0x3b, 0xbe, + 0xfb, 0x4a, 0xfc, 0x7d, 0xdf, 0x03, 0xba, 0x4e, 0x87, 0xd2, 0xa4, 0x63, 0x69, 0x52, 0xd7, 0x8f, + 0x2f, 0x2d, 0x0a, 0xad, 0x2c, 0xfb, 0xfb, 0xa7, 0xff, 0xd1, 0xd1, 0xdb, 0x55, 0x3a, 0xf5, 0xee, + 0x71, 0x81, 0x8a, 0x61, 0xd0, 0xfb, 0xe8, 0xfb, 0xd4, 0xc4, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xec, 0x56, 0x30, 0x88, 0xa6, 0x02, 0x00, 0x00, +} diff --git a/vendor/github.com/mwitkow/go-proto-validators/validator.proto b/vendor/github.com/mwitkow/go-proto-validators/validator.proto new file mode 100755 index 0000000..88f19a6 --- /dev/null +++ b/vendor/github.com/mwitkow/go-proto-validators/validator.proto @@ -0,0 +1,66 @@ +// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +// Protocol Buffers extensions for defining auto-generateable validators for messages. + +// TODO(mwitkow): Add example. + + +syntax = "proto2"; +package validator; + +import "google/protobuf/descriptor.proto"; + +option go_package = "validator"; + +// TODO(mwitkow): Email protobuf-global-extension-registry@google.com to get an extension ID. + +extend google.protobuf.FieldOptions { + optional FieldValidator field = 65020; +} + +message FieldValidator { + // Uses a Golang RE2-syntax regex to match the field contents. + optional string regex = 1; + // Field value of integer strictly greater than this value. + optional int64 int_gt = 2; + // Field value of integer strictly smaller than this value. + optional int64 int_lt = 3; + // Used for nested message types, requires that the message type exists. + optional bool msg_exists = 4; + // Human error specifies a user-customizable error that is visible to the user. + optional string human_error = 5; + // Field value of double strictly greater than this value. + // Note that this value can only take on a valid floating point + // value. Use together with float_epsilon if you need something more specific. + optional double float_gt = 6; + // Field value of double strictly smaller than this value. + // Note that this value can only take on a valid floating point + // value. Use together with float_epsilon if you need something more specific. + optional double float_lt = 7; + // Field value of double describing the epsilon within which + // any comparison should be considered to be true. For example, + // when using float_gt = 0.35, using a float_epsilon of 0.05 + // would mean that any value above 0.30 is acceptable. It can be + // thought of as a {float_value_condition} +- {float_epsilon}. + // If unset, no correction for floating point inaccuracies in + // comparisons will be attempted. + optional double float_epsilon = 8; + // Floating-point value compared to which the field content should be greater or equal. + optional double float_gte = 9; + // Floating-point value compared to which the field content should be smaller or equal. + optional double float_lte = 10; + // Used for string fields, requires the string to be not empty (i.e different from ""). + optional bool string_not_empty = 11; + // Repeated field with at least this number of elements. + optional int64 repeated_count_min = 12; + // Repeated field with at most this number of elements. + optional int64 repeated_count_max = 13; + // Field value of length greater than this value. + optional int64 length_gt = 14; + // Field value of length smaller than this value. + optional int64 length_lt = 15; + // Field value of integer strictly equal this value. + optional int64 length_eq = 16; + +}