diff --git a/.gitignore b/.gitignore index 678e8bb..6ecd3a2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,4 @@ .vscode # Build and script artefacts. -deps/ bazel-* - diff --git a/BUILD.bazel b/BUILD.bazel index 9a1edd4..3bb16e9 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -8,76 +8,40 @@ gazelle( name = "gazelle", ) -# gazelle:prefix github.com/mwitkow/go-proto-validators # gazelle:build_file_name BUILD.bazel - -# By default resolve the top-level package to the gogo variant as it's required for the plugin compilation. -# gazelle:resolve go github.com/mwitkow/go-proto-validators //:validators_gogo +# gazelle:prefix github.com/mwitkow/go-proto-validators +# gazelle:proto_import_prefix github.com/mwitkow/go-proto-validators go_proto_compiler( name = "go_proto_validators", - options = ["gogoimport=false"], plugin = "//protoc-gen-govalidators", suffix = ".validator.pb.go", valid_archive = False, visibility = ["//visibility:public"], deps = [ - ":validators_golang", + ":go_default_library", ], ) -go_proto_compiler( - name = "gogo_proto_validators", - options = ["gogoimport=true"], - plugin = "//protoc-gen-govalidators", - suffix = ".validator.pb.go", - valid_archive = False, +proto_library( + name = "validators_proto", + srcs = ["validators.proto"], + import_prefix = "github.com/mwitkow/go-proto-validators", visibility = ["//visibility:public"], - deps = [ - ":validators_gogo", - ], -) - -go_proto_library( - name = "_validators_gogo", - compilers = [ - "@io_bazel_rules_go//proto:gogo_proto", - ], - importpath = "github.com/mwitkow/go-proto-validators", - proto = ":validator_proto", - visibility = ["//:__pkg__"], + deps = ["@com_google_protobuf//:descriptor_proto"], ) go_proto_library( - name = "_validators_golang", - compilers = [ - "@io_bazel_rules_go//proto:go_proto", - ], - importpath = "github.com/mwitkow/go-proto-validators", - proto = ":validator_proto", - visibility = ["//:__pkg__"], -) - -go_library( - name = "validators_gogo", - srcs = ["helper.go"], - embed = [":_validators_gogo"], + name = "validators_go_proto", importpath = "github.com/mwitkow/go-proto-validators", + proto = ":validators_proto", visibility = ["//visibility:public"], ) go_library( - name = "validators_golang", + name = "go_default_library", srcs = ["helper.go"], - embed = [":_validators_golang"], + embed = [":validators_go_proto"], importpath = "github.com/mwitkow/go-proto-validators", visibility = ["//visibility:public"], ) - -proto_library( - name = "validator_proto", - srcs = ["validator.proto"], - import_prefix = "github.com/mwitkow/go-proto-validators", - visibility = ["//visibility:public"], - deps = ["@com_google_protobuf//:descriptor_proto"], -) diff --git a/Makefile b/Makefile deleted file mode 100644 index 20a295c..0000000 --- a/Makefile +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2016 Michal Witkowski. All Rights Reserved. -# See LICENSE for licensing terms. - -mkfile_dir = "$(dir $(abspath $(lastword $(MAKEFILE_LIST))))" - -ifdef GOBIN -extra_path = "$(mkfile_dir)deps/bin:$(GOBIN)" -else -extra_path = "$(mkfile_dir)deps/bin:$(HOME)/go/bin" -endif - -prepare_deps: - @echo "--- Preparing dependencies." - @bash scripts/prepare-deps.sh - -gazelle: - @bash bazel run --run_under="cd ${mkfile_dir} && " @bazel_gazelle//cmd/gazelle -- update-repos -from_file=go.mod -to_macro=go_deps.bzl%go_repositories - @bash bazel run //:gazelle -- --mode=fix --exclude=deps --exclude=examples --exclude=test - -install: - @echo "--- Installing 'govalidators' binary to GOBIN." - go install github.com/mwitkow/go-proto-validators/protoc-gen-govalidators - -regenerate_test_gogo: prepare_deps install - @echo "--- Regenerating test .proto files with gogo imports" - export PATH=$(extra_path):$${PATH}; protoc \ - --proto_path=deps \ - --proto_path=deps/include \ - --proto_path=test \ - --gogo_out=test/gogo \ - --govalidators_out=gogoimport=true:test/gogo test/*.proto - -regenerate_test_golang: prepare_deps install - @echo "--- Regenerating test .proto files with golang imports" - export PATH=$(extra_path):$${PATH}; protoc \ - --proto_path=deps \ - --proto_path=deps/include \ - --proto_path=test \ - --go_out=test/golang \ - --govalidators_out=test/golang test/*.proto - -regenerate_example: prepare_deps install - @echo "--- Regenerating example directory" - export PATH=$(extra_path):$${PATH}; protoc \ - --proto_path=deps \ - --proto_path=deps/include \ - --proto_path=. \ - --go_out=. \ - --govalidators_out=. examples/*.proto - -test: regenerate_test_gogo regenerate_test_golang - @echo "Running tests" - go test -v ./... - -regenerate: prepare_deps - @echo "--- Regenerating validator.proto" - export PATH=$(extra_path):$${PATH}; protoc \ - --proto_path=deps \ - --proto_path=deps/include \ - --proto_path=deps/github.com/gogo/protobuf/protobuf \ - --proto_path=. \ - --gogo_out=Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. \ - validator.proto - -clean: - rm -rf "deps" diff --git a/README.md b/README.md index d6bb30b..aa4bbd9 100644 --- a/README.md +++ b/README.md @@ -139,3 +139,14 @@ Basically the magical incantation (apart from includes) is the `--govalidators_o ## License `go-proto-validators` is released under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details. + + +##Maanasa notes + +maanasa@Maanasas-MacBook-Air go-proto-validators % protoc \ +--proto_path=${GOPATH}/src \ +--proto_path=${GOPATH}/pkg/mod/github.com/gogo/protobuf@v1.3.2 \ +--proto_path=. \ +--gogo_out=. \ +--govalidators_out=gogoimport=true:. \ +*.proto \ No newline at end of file diff --git a/deps/3.10.0.zip b/deps/3.10.0.zip new file mode 100644 index 0000000..2554653 Binary files /dev/null and b/deps/3.10.0.zip differ diff --git a/deps/bin/protoc b/deps/bin/protoc new file mode 100755 index 0000000..6500be0 Binary files /dev/null and b/deps/bin/protoc differ diff --git a/deps/github.com/gogo/protobuf b/deps/github.com/gogo/protobuf new file mode 120000 index 0000000..0a56650 --- /dev/null +++ b/deps/github.com/gogo/protobuf @@ -0,0 +1 @@ +/Users/maanasa/go-workspace/pkg/mod/github.com/gogo/protobuf@v1.3.0 \ No newline at end of file diff --git a/deps/github.com/golang/protobuf b/deps/github.com/golang/protobuf new file mode 120000 index 0000000..9bb53a0 --- /dev/null +++ b/deps/github.com/golang/protobuf @@ -0,0 +1 @@ +/Users/maanasa/go-workspace/pkg/mod/github.com/golang/protobuf@v1.3.2 \ No newline at end of file diff --git a/deps/github.com/mwitkow/go-proto-validators b/deps/github.com/mwitkow/go-proto-validators new file mode 120000 index 0000000..3f2c035 --- /dev/null +++ b/deps/github.com/mwitkow/go-proto-validators @@ -0,0 +1 @@ +/Users/maanasa/go-workspace/src/github.com/maanasasubrahmanyam-sd/go-proto-validators \ No newline at end of file diff --git a/deps/include/google/protobuf/any.proto b/deps/include/google/protobuf/any.proto new file mode 100644 index 0000000..c9be854 --- /dev/null +++ b/deps/include/google/protobuf/any.proto @@ -0,0 +1,155 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/any"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := ptypes.MarshalAny(foo) +// ... +// foo := &pb.Foo{} +// if err := ptypes.UnmarshalAny(any, foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/deps/include/google/protobuf/api.proto b/deps/include/google/protobuf/api.proto new file mode 100644 index 0000000..f37ee2f --- /dev/null +++ b/deps/include/google/protobuf/api.proto @@ -0,0 +1,210 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/genproto/protobuf/api;api"; + +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. +message Api { + + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. + string name = 1; + + // The methods of this interface, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the interface. + repeated Option options = 3; + + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // interface, which must end in `v`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, non-GA interfaces. + // + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included interfaces. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an API interface. +message Method { + + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including interface plus the [root][] path if +// specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inherting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the interface which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/deps/include/google/protobuf/compiler/plugin.proto b/deps/include/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..665e5a7 --- /dev/null +++ b/deps/include/google/protobuf/compiler/plugin.proto @@ -0,0 +1,168 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option go_package = "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go"; + +import "google/protobuf/descriptor.proto"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + repeated FileDescriptorProto proto_file = 15; + + // The version number of protocol compiler. + optional Version compiler_version = 3; + +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + } + repeated File file = 15; +} diff --git a/deps/include/google/protobuf/descriptor.proto b/deps/include/google/protobuf/descriptor.proto new file mode 100644 index 0000000..a2102d7 --- /dev/null +++ b/deps/include/google/protobuf/descriptor.proto @@ -0,0 +1,885 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + optional string java_outer_classname = 8; + + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default = false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default = false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + optional bool php_generic_services = 42 [default = false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = false]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + // 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 implementations 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. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/deps/include/google/protobuf/duration.proto b/deps/include/google/protobuf/duration.proto new file mode 100644 index 0000000..99cb102 --- /dev/null +++ b/deps/include/google/protobuf/duration.proto @@ -0,0 +1,116 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/duration"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +// +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/deps/include/google/protobuf/empty.proto b/deps/include/google/protobuf/empty.proto new file mode 100644 index 0000000..03cacd2 --- /dev/null +++ b/deps/include/google/protobuf/empty.proto @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "github.com/golang/protobuf/ptypes/empty"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +// The JSON representation for `Empty` is empty JSON object `{}`. +message Empty {} diff --git a/deps/include/google/protobuf/field_mask.proto b/deps/include/google/protobuf/field_mask.proto new file mode 100644 index 0000000..4015b1a --- /dev/null +++ b/deps/include/google/protobuf/field_mask.proto @@ -0,0 +1,245 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/genproto/protobuf/field_mask;field_mask"; +option cc_enable_arenas = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing sub-message +// in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is duplicated or unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/deps/include/google/protobuf/source_context.proto b/deps/include/google/protobuf/source_context.proto new file mode 100644 index 0000000..f3b2c96 --- /dev/null +++ b/deps/include/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/genproto/protobuf/source_context;source_context"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/deps/include/google/protobuf/struct.proto b/deps/include/google/protobuf/struct.proto new file mode 100644 index 0000000..ed990e3 --- /dev/null +++ b/deps/include/google/protobuf/struct.proto @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/struct;structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of that +// variants, absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/deps/include/google/protobuf/timestamp.proto b/deps/include/google/protobuf/timestamp.proto new file mode 100644 index 0000000..cd35786 --- /dev/null +++ b/deps/include/google/protobuf/timestamp.proto @@ -0,0 +1,138 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/timestamp"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D +// ) to obtain a formatter capable of generating timestamps in this format. +// +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/deps/include/google/protobuf/type.proto b/deps/include/google/protobuf/type.proto new file mode 100644 index 0000000..e4b1d3a --- /dev/null +++ b/deps/include/google/protobuf/type.proto @@ -0,0 +1,187 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/genproto/protobuf/ptype;ptype"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + } + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + }; + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For protobuf built-in options (options defined in + // descriptor.proto), this is the short name. For example, `"map_entry"`. + // For custom options, it should be the fully-qualified name. For example, + // `"google.api.http"`. + string name = 1; + // The option's value packed in an Any message. If the value is a primitive, + // the corresponding wrapper type defined in google/protobuf/wrappers.proto + // should be used. If the value is an enum, it should be stored as an int32 + // value using the google.protobuf.Int32Value type. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; +} diff --git a/deps/include/google/protobuf/wrappers.proto b/deps/include/google/protobuf/wrappers.proto new file mode 100644 index 0000000..9ee41e3 --- /dev/null +++ b/deps/include/google/protobuf/wrappers.proto @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "github.com/golang/protobuf/ptypes/wrappers"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/deps/readme.txt b/deps/readme.txt new file mode 100644 index 0000000..b6c9f9b --- /dev/null +++ b/deps/readme.txt @@ -0,0 +1,15 @@ +Protocol Buffers - Google's data interchange format +Copyright 2008 Google Inc. +https://developers.google.com/protocol-buffers/ + +This package contains a precompiled binary version of the protocol buffer +compiler (protoc). This binary is intended for users who want to use Protocol +Buffers in languages other than C++ but do not want to compile protoc +themselves. To install, simply place this binary somewhere in your PATH. + +If you intend to use the included well known types then don't forget to +copy the contents of the 'include' directory somewhere as well, for example +into '/usr/local/include/'. + +Please refer to our official github site for more installation instructions: + https://github.com/protocolbuffers/protobuf diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index fefa436..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!*.pb.go \ No newline at end of file diff --git a/examples/BUILD.bazel b/examples/BUILD.bazel new file mode 100644 index 0000000..7f34150 --- /dev/null +++ b/examples/BUILD.bazel @@ -0,0 +1,39 @@ +load("@rules_proto//proto:defs.bzl", "proto_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") + +# gazelle:proto_import_prefix github.com/mwitkow/go-proto-validators +# gazelle:go_proto_compilers @io_bazel_rules_go//proto:go_proto,//:go_proto_validators +# gazelle:resolve proto go github.com/mwitkow/go-proto-validators/validators.proto //:go_default_library +# gazelle:exclude *.pb.go + +proto_library( + name = "validator_examples_proto", + srcs = [ + "enum.proto", + "nested.proto", + "uuid.proto", + ], + import_prefix = "github.com/mwitkow/go-proto-validators", + visibility = ["//visibility:public"], + deps = ["//:validators_proto"], +) + +go_proto_library( + name = "validator_examples_go_proto", + compilers = [ + "@io_bazel_rules_go//proto:go_proto", + "//:go_proto_validators", + ], + importpath = "github.com/mwitkow/go-proto-validators/examples", + proto = ":validator_examples_proto", + visibility = ["//visibility:public"], + deps = ["//:go_default_library"], +) + +go_library( + name = "go_default_library", + embed = [":validator_examples_go_proto"], + importpath = "github.com/mwitkow/go-proto-validators/examples", + visibility = ["//visibility:public"], +) diff --git a/examples/enum.pb.go b/examples/enum.pb.go index 6b325a7..7299436 100644 --- a/examples/enum.pb.go +++ b/examples/enum.pb.go @@ -1,25 +1,30 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: examples/enum.proto +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: github.com/mwitkow/go-proto-validators/examples/enum.proto package validator_examples import ( - fmt "fmt" proto "github.com/golang/protobuf/proto" _ "github.com/mwitkow/go-proto-validators" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 type Action int32 @@ -29,84 +34,178 @@ const ( Action_CHILL Action = 2 ) -var Action_name = map[int32]string{ - 0: "ALLOW", - 1: "DENY", - 2: "CHILL", -} +// Enum value maps for Action. +var ( + Action_name = map[int32]string{ + 0: "ALLOW", + 1: "DENY", + 2: "CHILL", + } + Action_value = map[string]int32{ + "ALLOW": 0, + "DENY": 1, + "CHILL": 2, + } +) -var Action_value = map[string]int32{ - "ALLOW": 0, - "DENY": 1, - "CHILL": 2, +func (x Action) Enum() *Action { + p := new(Action) + *p = x + return p } func (x Action) String() string { - return proto.EnumName(Action_name, int32(x)) + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } -func (Action) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_5e21dd5d0da6895c, []int{0} +func (Action) Descriptor() protoreflect.EnumDescriptor { + return file_github_com_mwitkow_go_proto_validators_examples_enum_proto_enumTypes[0].Descriptor() } -type SomeMsg struct { - Do Action `protobuf:"varint,1,opt,name=do,proto3,enum=validator.examples.Action" json:"do,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (Action) Type() protoreflect.EnumType { + return &file_github_com_mwitkow_go_proto_validators_examples_enum_proto_enumTypes[0] } -func (m *SomeMsg) Reset() { *m = SomeMsg{} } -func (m *SomeMsg) String() string { return proto.CompactTextString(m) } -func (*SomeMsg) ProtoMessage() {} -func (*SomeMsg) Descriptor() ([]byte, []int) { - return fileDescriptor_5e21dd5d0da6895c, []int{0} +func (x Action) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) } -func (m *SomeMsg) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SomeMsg.Unmarshal(m, b) +// Deprecated: Use Action.Descriptor instead. +func (Action) EnumDescriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescGZIP(), []int{0} } -func (m *SomeMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SomeMsg.Marshal(b, m, deterministic) + +type SomeMsg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Do Action `protobuf:"varint,1,opt,name=do,proto3,enum=validator.examples.Action" json:"do,omitempty"` } -func (m *SomeMsg) XXX_Merge(src proto.Message) { - xxx_messageInfo_SomeMsg.Merge(m, src) + +func (x *SomeMsg) Reset() { + *x = SomeMsg{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_mwitkow_go_proto_validators_examples_enum_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *SomeMsg) XXX_Size() int { - return xxx_messageInfo_SomeMsg.Size(m) + +func (x *SomeMsg) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *SomeMsg) XXX_DiscardUnknown() { - xxx_messageInfo_SomeMsg.DiscardUnknown(m) + +func (*SomeMsg) ProtoMessage() {} + +func (x *SomeMsg) ProtoReflect() protoreflect.Message { + mi := &file_github_com_mwitkow_go_proto_validators_examples_enum_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_SomeMsg proto.InternalMessageInfo +// Deprecated: Use SomeMsg.ProtoReflect.Descriptor instead. +func (*SomeMsg) Descriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescGZIP(), []int{0} +} -func (m *SomeMsg) GetDo() Action { - if m != nil { - return m.Do +func (x *SomeMsg) GetDo() Action { + if x != nil { + return x.Do } return Action_ALLOW } -func init() { - proto.RegisterEnum("validator.examples.Action", Action_name, Action_value) - proto.RegisterType((*SomeMsg)(nil), "validator.examples.SomeMsg") +var File_github_com_mwitkow_go_proto_validators_examples_enum_proto protoreflect.FileDescriptor + +var file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDesc = []byte{ + 0x0a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x73, 0x2f, 0x65, 0x6e, 0x75, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x1a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3e, 0x0a, 0x07, 0x53, 0x6f, 0x6d, + 0x65, 0x4d, 0x73, 0x67, 0x12, 0x33, 0x0a, 0x02, 0x64, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x1a, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x07, 0xe2, 0xdf, + 0x1f, 0x03, 0x88, 0x01, 0x01, 0x52, 0x02, 0x64, 0x6f, 0x2a, 0x28, 0x0a, 0x06, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x00, 0x12, 0x08, + 0x0a, 0x04, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x48, 0x49, 0x4c, + 0x4c, 0x10, 0x02, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescOnce sync.Once + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescData = file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDesc +) + +func file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescGZIP() []byte { + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescOnce.Do(func() { + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescData) + }) + return file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDescData } -func init() { proto.RegisterFile("examples/enum.proto", fileDescriptor_5e21dd5d0da6895c) } +var file_github_com_mwitkow_go_proto_validators_examples_enum_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_github_com_mwitkow_go_proto_validators_examples_enum_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_github_com_mwitkow_go_proto_validators_examples_enum_proto_goTypes = []interface{}{ + (Action)(0), // 0: validator.examples.Action + (*SomeMsg)(nil), // 1: validator.examples.SomeMsg +} +var file_github_com_mwitkow_go_proto_validators_examples_enum_proto_depIdxs = []int32{ + 0, // 0: validator.examples.SomeMsg.do:type_name -> validator.examples.Action + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} -var fileDescriptor_5e21dd5d0da6895c = []byte{ - // 183 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0xad, 0x48, 0xcc, - 0x2d, 0xc8, 0x49, 0x2d, 0xd6, 0x4f, 0xcd, 0x2b, 0xcd, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0x12, 0x2a, 0x4b, 0xcc, 0xc9, 0x4c, 0x49, 0x2c, 0xc9, 0x2f, 0xd2, 0x83, 0x49, 0x4b, 0x99, 0xa5, - 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe7, 0x96, 0x67, 0x96, 0x64, 0xe7, - 0x97, 0xeb, 0xa7, 0xe7, 0xeb, 0x82, 0x35, 0xe8, 0xc2, 0xd5, 0x17, 0xeb, 0x23, 0xb4, 0x82, 0xa5, - 0x94, 0xec, 0xb8, 0xd8, 0x83, 0xf3, 0x73, 0x53, 0x7d, 0x8b, 0xd3, 0x85, 0x8c, 0xb9, 0x98, 0x52, - 0xf2, 0x25, 0x18, 0x15, 0x18, 0x35, 0xf8, 0x8c, 0xa4, 0xf4, 0x30, 0xed, 0xd0, 0x73, 0x4c, 0x2e, - 0xc9, 0xcc, 0xcf, 0x73, 0x62, 0x7f, 0x74, 0x5f, 0x9e, 0xb9, 0x83, 0x91, 0x31, 0x88, 0x29, 0x25, - 0x5f, 0x4b, 0x83, 0x8b, 0x0d, 0x22, 0x2c, 0xc4, 0xc9, 0xc5, 0xea, 0xe8, 0xe3, 0xe3, 0x1f, 0x2e, - 0xc0, 0x20, 0xc4, 0xc1, 0xc5, 0xe2, 0xe2, 0xea, 0x17, 0x29, 0xc0, 0x08, 0x12, 0x74, 0xf6, 0xf0, - 0xf4, 0xf1, 0x11, 0x60, 0x4a, 0x62, 0x03, 0x5b, 0x68, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x8d, - 0x4f, 0x55, 0x68, 0xd3, 0x00, 0x00, 0x00, +func init() { file_github_com_mwitkow_go_proto_validators_examples_enum_proto_init() } +func file_github_com_mwitkow_go_proto_validators_examples_enum_proto_init() { + if File_github_com_mwitkow_go_proto_validators_examples_enum_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SomeMsg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDesc, + NumEnums: 1, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_mwitkow_go_proto_validators_examples_enum_proto_goTypes, + DependencyIndexes: file_github_com_mwitkow_go_proto_validators_examples_enum_proto_depIdxs, + EnumInfos: file_github_com_mwitkow_go_proto_validators_examples_enum_proto_enumTypes, + MessageInfos: file_github_com_mwitkow_go_proto_validators_examples_enum_proto_msgTypes, + }.Build() + File_github_com_mwitkow_go_proto_validators_examples_enum_proto = out.File + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_rawDesc = nil + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_goTypes = nil + file_github_com_mwitkow_go_proto_validators_examples_enum_proto_depIdxs = nil } diff --git a/examples/enum.proto b/examples/enum.proto index d666106..ab4735d 100644 --- a/examples/enum.proto +++ b/examples/enum.proto @@ -1,10 +1,8 @@ syntax = "proto3"; package validator.examples; -import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/mwitkow/go-proto-validators/validators.proto"; -message SomeMsg { - Action do = 1 [(validator.field) = {is_in_enum : true}]; -} +message SomeMsg { Action do = 1 [ (validator.field) = {is_in_enum : true} ]; } enum Action { ALLOW = 0; diff --git a/examples/enum.validator.pb.go b/examples/enum.validator.pb.go index 7c7dc18..f77549e 100644 --- a/examples/enum.validator.pb.go +++ b/examples/enum.validator.pb.go @@ -1,24 +1,16 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: examples/enum.proto +// Code generated by protoc-gen-govalidators. DO NOT EDIT. package validator_examples import ( - fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" - _ "github.com/mwitkow/go-proto-validators" - github_com_mwitkow_go_proto_validators "github.com/mwitkow/go-proto-validators" + errors "errors" + go_proto_validators "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 *SomeMsg) Validate() error { - if _, ok := Action_name[int32(this.Do)]; !ok { - return github_com_mwitkow_go_proto_validators.FieldError("Do", fmt.Errorf(`value '%v' must be a valid Action field`, this.Do)) +func (m *SomeMsg) Validate() error { + if _, ok := Action_name[int32(m.GetDo())]; !ok { + return go_proto_validators.FieldError("Do", errors.New("do should correspond to a valid enum value")) } + return nil } diff --git a/examples/nested.pb.go b/examples/nested.pb.go index e92155a..346e1bd 100644 --- a/examples/nested.pb.go +++ b/examples/nested.pb.go @@ -1,138 +1,233 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: examples/nested.proto +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: github.com/mwitkow/go-proto-validators/examples/nested.proto package validator_examples import ( - fmt "fmt" proto "github.com/golang/protobuf/proto" _ "github.com/mwitkow/go-proto-validators" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 type InnerMessage struct { - // some_integer can only be in range (1, 100). - SomeInteger int32 `protobuf:"varint,1,opt,name=some_integer,json=someInteger,proto3" json:"some_integer,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *InnerMessage) Reset() { *m = InnerMessage{} } -func (m *InnerMessage) String() string { return proto.CompactTextString(m) } -func (*InnerMessage) ProtoMessage() {} -func (*InnerMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_48ff2d59662eadb1, []int{0} + SomeInteger int32 `protobuf:"varint,1,opt,name=some_integer,json=someInteger,proto3" json:"some_integer,omitempty"` } -func (m *InnerMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_InnerMessage.Unmarshal(m, b) -} -func (m *InnerMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_InnerMessage.Marshal(b, m, deterministic) -} -func (m *InnerMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_InnerMessage.Merge(m, src) +func (x *InnerMessage) Reset() { + *x = InnerMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *InnerMessage) XXX_Size() int { - return xxx_messageInfo_InnerMessage.Size(m) + +func (x *InnerMessage) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *InnerMessage) XXX_DiscardUnknown() { - xxx_messageInfo_InnerMessage.DiscardUnknown(m) + +func (*InnerMessage) ProtoMessage() {} + +func (x *InnerMessage) ProtoReflect() protoreflect.Message { + mi := &file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_InnerMessage proto.InternalMessageInfo +// Deprecated: Use InnerMessage.ProtoReflect.Descriptor instead. +func (*InnerMessage) Descriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescGZIP(), []int{0} +} -func (m *InnerMessage) GetSomeInteger() int32 { - if m != nil { - return m.SomeInteger +func (x *InnerMessage) GetSomeInteger() int32 { + if x != nil { + return x.SomeInteger } return 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,proto3" json:"important_string,omitempty"` - // proto3 doesn't have `required`, the `msg_exist` enforces presence of InnerMessage. - Inner *InnerMessage `protobuf:"bytes,2,opt,name=inner,proto3" json:"inner,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *OuterMessage) Reset() { *m = OuterMessage{} } -func (m *OuterMessage) String() string { return proto.CompactTextString(m) } -func (*OuterMessage) ProtoMessage() {} -func (*OuterMessage) Descriptor() ([]byte, []int) { - return fileDescriptor_48ff2d59662eadb1, []int{1} -} + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields -func (m *OuterMessage) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OuterMessage.Unmarshal(m, b) + ImportantString string `protobuf:"bytes,1,opt,name=important_string,json=importantString,proto3" json:"important_string,omitempty"` + Inner *InnerMessage `protobuf:"bytes,2,opt,name=inner,proto3" json:"inner,omitempty"` } -func (m *OuterMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OuterMessage.Marshal(b, m, deterministic) -} -func (m *OuterMessage) XXX_Merge(src proto.Message) { - xxx_messageInfo_OuterMessage.Merge(m, src) + +func (x *OuterMessage) Reset() { + *x = OuterMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *OuterMessage) XXX_Size() int { - return xxx_messageInfo_OuterMessage.Size(m) + +func (x *OuterMessage) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *OuterMessage) XXX_DiscardUnknown() { - xxx_messageInfo_OuterMessage.DiscardUnknown(m) + +func (*OuterMessage) ProtoMessage() {} + +func (x *OuterMessage) ProtoReflect() protoreflect.Message { + mi := &file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -var xxx_messageInfo_OuterMessage proto.InternalMessageInfo +// Deprecated: Use OuterMessage.ProtoReflect.Descriptor instead. +func (*OuterMessage) Descriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescGZIP(), []int{1} +} -func (m *OuterMessage) GetImportantString() string { - if m != nil { - return m.ImportantString +func (x *OuterMessage) GetImportantString() string { + if x != nil { + return x.ImportantString } return "" } -func (m *OuterMessage) GetInner() *InnerMessage { - if m != nil { - return m.Inner +func (x *OuterMessage) GetInner() *InnerMessage { + if x != nil { + return x.Inner } return nil } -func init() { - proto.RegisterType((*InnerMessage)(nil), "validator.examples.InnerMessage") - proto.RegisterType((*OuterMessage)(nil), "validator.examples.OuterMessage") -} - -func init() { proto.RegisterFile("examples/nested.proto", fileDescriptor_48ff2d59662eadb1) } - -var fileDescriptor_48ff2d59662eadb1 = []byte{ - // 249 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x7a, 0x74, 0x5f, 0x9e, 0x8f, - 0x8b, 0x27, 0x2e, 0x3a, 0x51, 0xb7, 0x2a, 0xb6, 0xda, 0x48, 0xc7, 0xb4, 0x56, 0x25, 0x88, 0x1f, - 0xae, 0x36, 0x18, 0xac, 0x54, 0xc8, 0x8e, 0x8b, 0x35, 0x13, 0xe4, 0x18, 0x09, 0x26, 0x05, 0x46, - 0x0d, 0x6e, 0x23, 0x05, 0x3d, 0x4c, 0x8f, 0xea, 0x21, 0xbb, 0xd6, 0x89, 0xed, 0xd1, 0x7d, 0x79, - 0x26, 0x05, 0xc6, 0x20, 0x88, 0xb6, 0x24, 0x36, 0xb0, 0x9f, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x08, 0x68, 0xd9, 0xd5, 0x38, 0x01, 0x00, 0x00, +var File_github_com_mwitkow_go_proto_validators_examples_nested_proto protoreflect.FileDescriptor + +var file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDesc = []byte{ + 0x0a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x73, 0x2f, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x73, 0x1a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, + 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3b, 0x0a, 0x0c, 0x49, + 0x6e, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x0c, 0x73, + 0x6f, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x42, 0x08, 0xe2, 0xdf, 0x1f, 0x04, 0x10, 0x00, 0x18, 0x64, 0x52, 0x0b, 0x73, 0x6f, 0x6d, + 0x65, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x22, 0x8d, 0x01, 0x0a, 0x0c, 0x4f, 0x75, 0x74, + 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x10, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x12, 0xe2, 0xdf, 0x1f, 0x0e, 0x0a, 0x0c, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, + 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, 0x0f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x05, 0x69, 0x6e, 0x6e, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x49, 0x6e, 0x6e, + 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x20, + 0x01, 0x52, 0x05, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescOnce sync.Once + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescData = file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDesc +) + +func file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescGZIP() []byte { + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescOnce.Do(func() { + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescData) + }) + return file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDescData +} + +var file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_github_com_mwitkow_go_proto_validators_examples_nested_proto_goTypes = []interface{}{ + (*InnerMessage)(nil), // 0: validator.examples.InnerMessage + (*OuterMessage)(nil), // 1: validator.examples.OuterMessage +} +var file_github_com_mwitkow_go_proto_validators_examples_nested_proto_depIdxs = []int32{ + 0, // 0: validator.examples.OuterMessage.inner:type_name -> validator.examples.InnerMessage + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_github_com_mwitkow_go_proto_validators_examples_nested_proto_init() } +func file_github_com_mwitkow_go_proto_validators_examples_nested_proto_init() { + if File_github_com_mwitkow_go_proto_validators_examples_nested_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InnerMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OuterMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_mwitkow_go_proto_validators_examples_nested_proto_goTypes, + DependencyIndexes: file_github_com_mwitkow_go_proto_validators_examples_nested_proto_depIdxs, + MessageInfos: file_github_com_mwitkow_go_proto_validators_examples_nested_proto_msgTypes, + }.Build() + File_github_com_mwitkow_go_proto_validators_examples_nested_proto = out.File + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_rawDesc = nil + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_goTypes = nil + file_github_com_mwitkow_go_proto_validators_examples_nested_proto_depIdxs = nil } diff --git a/examples/nested.proto b/examples/nested.proto index cea61d2..93b424a 100644 --- a/examples/nested.proto +++ b/examples/nested.proto @@ -1,15 +1,17 @@ syntax = "proto3"; package validator.examples; -import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/mwitkow/go-proto-validators/validators.proto"; message InnerMessage { // some_integer can only be in range (1, 100). - int32 some_integer = 1 [(validator.field) = {int_gt: 0, int_lt: 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}]; + // 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} ]; } diff --git a/examples/nested.validator.pb.go b/examples/nested.validator.pb.go index 79100ab..19bfe1e 100644 --- a/examples/nested.validator.pb.go +++ b/examples/nested.validator.pb.go @@ -1,45 +1,39 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: examples/nested.proto +// Code generated by protoc-gen-govalidators. DO NOT EDIT. package validator_examples import ( - fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" - _ "github.com/mwitkow/go-proto-validators" + errors "errors" + go_proto_validators "github.com/mwitkow/go-proto-validators" regexp "regexp" - github_com_mwitkow_go_proto_validators "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 github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", fmt.Errorf(`value '%v' must be greater than '0'`, this.SomeInteger)) +func (m *InnerMessage) Validate() error { + if m.GetSomeInteger() <= 0 { + return go_proto_validators.FieldError("SomeInteger", errors.New("some_integer is not greater than 0")) } - if !(this.SomeInteger < 100) { - return github_com_mwitkow_go_proto_validators.FieldError("SomeInteger", fmt.Errorf(`value '%v' must be less than '100'`, this.SomeInteger)) + if m.GetSomeInteger() >= 100 { + return go_proto_validators.FieldError("SomeInteger", errors.New("some_integer is not smaller than 100")) } + return nil } -var _regex_OuterMessage_ImportantString = regexp.MustCompile(`^[a-z]{2,5}$`) +var OuterMessageImportantStringRE = regexp.MustCompile(`^[a-z]{2,5}$`) -func (this *OuterMessage) Validate() error { - if !_regex_OuterMessage_ImportantString.MatchString(this.ImportantString) { - return github_com_mwitkow_go_proto_validators.FieldError("ImportantString", fmt.Errorf(`value '%v' must be a string conforming to regex "^[a-z]{2,5}$"`, this.ImportantString)) - } - if nil == this.Inner { - return github_com_mwitkow_go_proto_validators.FieldError("Inner", fmt.Errorf("message must exist")) +func (m *OuterMessage) Validate() error { + if !OuterMessageImportantStringRE.MatchString(string(m.GetImportantString())) { + return go_proto_validators.FieldError("ImportantString", errors.New(`important_string should match regular expression "^[a-z]{2,5}$"`)) } - if this.Inner != nil { - if err := github_com_mwitkow_go_proto_validators.CallValidatorIfExists(this.Inner); err != nil { - return github_com_mwitkow_go_proto_validators.FieldError("Inner", err) + + if m.GetInner() != nil { + if err := go_proto_validators.CallValidatorIfExists(m.GetInner()); err != nil { + return go_proto_validators.FieldError("Inner", err) } } + if m.GetInner() == nil { + return go_proto_validators.FieldError("Inner", errors.New("inner should be set")) + } + return nil } diff --git a/examples/uuid.pb.go b/examples/uuid.pb.go index 175dd07..de55d7f 100644 --- a/examples/uuid.pb.go +++ b/examples/uuid.pb.go @@ -1,81 +1,154 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: examples/uuid.proto +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: github.com/mwitkow/go-proto-validators/examples/uuid.proto package validator_examples import ( - fmt "fmt" proto "github.com/golang/protobuf/proto" _ "github.com/mwitkow/go-proto-validators" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) -// 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.ProtoPackageIsVersion3 // please upgrade the proto package +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 type UUIDMsg struct { - // user_id must be a valid version 4 UUID. - UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UserId string `protobuf:"bytes,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"` } -func (m *UUIDMsg) Reset() { *m = UUIDMsg{} } -func (m *UUIDMsg) String() string { return proto.CompactTextString(m) } -func (*UUIDMsg) ProtoMessage() {} -func (*UUIDMsg) Descriptor() ([]byte, []int) { - return fileDescriptor_0029f00507e892b3, []int{0} +func (x *UUIDMsg) Reset() { + *x = UUIDMsg{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (m *UUIDMsg) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_UUIDMsg.Unmarshal(m, b) +func (x *UUIDMsg) String() string { + return protoimpl.X.MessageStringOf(x) } -func (m *UUIDMsg) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_UUIDMsg.Marshal(b, m, deterministic) + +func (*UUIDMsg) ProtoMessage() {} + +func (x *UUIDMsg) ProtoReflect() protoreflect.Message { + mi := &file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) } -func (m *UUIDMsg) XXX_Merge(src proto.Message) { - xxx_messageInfo_UUIDMsg.Merge(m, src) + +// Deprecated: Use UUIDMsg.ProtoReflect.Descriptor instead. +func (*UUIDMsg) Descriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescGZIP(), []int{0} } -func (m *UUIDMsg) XXX_Size() int { - return xxx_messageInfo_UUIDMsg.Size(m) + +func (x *UUIDMsg) GetUserId() string { + if x != nil { + return x.UserId + } + return "" } -func (m *UUIDMsg) XXX_DiscardUnknown() { - xxx_messageInfo_UUIDMsg.DiscardUnknown(m) + +var File_github_com_mwitkow_go_proto_validators_examples_uuid_proto protoreflect.FileDescriptor + +var file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDesc = []byte{ + 0x0a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x73, 0x2f, 0x75, 0x75, 0x69, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, + 0x1a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2b, 0x0a, 0x07, 0x55, 0x55, 0x49, + 0x44, 0x4d, 0x73, 0x67, 0x12, 0x20, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x90, 0x01, 0x04, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } -var xxx_messageInfo_UUIDMsg proto.InternalMessageInfo +var ( + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescOnce sync.Once + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescData = file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDesc +) -func (m *UUIDMsg) GetUserId() string { - if m != nil { - return m.UserId - } - return "" +func file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescGZIP() []byte { + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescOnce.Do(func() { + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescData) + }) + return file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDescData } -func init() { - proto.RegisterType((*UUIDMsg)(nil), "validator.examples.UUIDMsg") +var file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_goTypes = []interface{}{ + (*UUIDMsg)(nil), // 0: validator.examples.UUIDMsg +} +var file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -func init() { proto.RegisterFile("examples/uuid.proto", fileDescriptor_0029f00507e892b3) } - -var fileDescriptor_0029f00507e892b3 = []byte{ - // 144 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0xad, 0x48, 0xcc, - 0x2d, 0xc8, 0x49, 0x2d, 0xd6, 0x2f, 0x2d, 0xcd, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0x12, 0x2a, 0x4b, 0xcc, 0xc9, 0x4c, 0x49, 0x2c, 0xc9, 0x2f, 0xd2, 0x83, 0x49, 0x4b, 0x99, 0xa5, - 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe7, 0x96, 0x67, 0x96, 0x64, 0xe7, - 0x97, 0xeb, 0xa7, 0xe7, 0xeb, 0x82, 0x35, 0xe8, 0xc2, 0xd5, 0x17, 0xeb, 0x23, 0xb4, 0x82, 0xa5, - 0x94, 0x74, 0xb9, 0xd8, 0x43, 0x43, 0x3d, 0x5d, 0x7c, 0x8b, 0xd3, 0x85, 0x94, 0xb8, 0xd8, 0x4b, - 0x8b, 0x53, 0x8b, 0xe2, 0x33, 0x53, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38, 0x9d, 0x38, 0x1f, 0xdd, - 0x97, 0x67, 0x8d, 0x60, 0x9c, 0xc0, 0xc8, 0x12, 0xc4, 0x06, 0x92, 0xf1, 0x4c, 0x49, 0x62, 0x03, - 0xeb, 0x32, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x56, 0xba, 0x22, 0x98, 0x00, 0x00, 0x00, +func init() { file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_init() } +func file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_init() { + if File_github_com_mwitkow_go_proto_validators_examples_uuid_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UUIDMsg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_goTypes, + DependencyIndexes: file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_depIdxs, + MessageInfos: file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_msgTypes, + }.Build() + File_github_com_mwitkow_go_proto_validators_examples_uuid_proto = out.File + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_rawDesc = nil + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_goTypes = nil + file_github_com_mwitkow_go_proto_validators_examples_uuid_proto_depIdxs = nil } diff --git a/examples/uuid.proto b/examples/uuid.proto index 05d61ed..f67d39d 100644 --- a/examples/uuid.proto +++ b/examples/uuid.proto @@ -1,8 +1,8 @@ syntax = "proto3"; package validator.examples; -import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/mwitkow/go-proto-validators/validators.proto"; message UUIDMsg { // user_id must be a valid version 4 UUID. - string user_id = 1 [(validator.field) = {uuid_ver: 4, string_not_empty: true}]; + string user_id = 1 [ (validator.field) = {uuid_ver : 4} ]; } diff --git a/examples/uuid.validator.pb.go b/examples/uuid.validator.pb.go index b2652af..408ba13 100644 --- a/examples/uuid.validator.pb.go +++ b/examples/uuid.validator.pb.go @@ -1,30 +1,19 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: examples/uuid.proto +// Code generated by protoc-gen-govalidators. DO NOT EDIT. package validator_examples import ( - fmt "fmt" - math "math" - proto "github.com/golang/protobuf/proto" - _ "github.com/mwitkow/go-proto-validators" + errors "errors" + go_proto_validators "github.com/mwitkow/go-proto-validators" regexp "regexp" - github_com_mwitkow_go_proto_validators "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 +var UUIDMsgUserIdRE = regexp.MustCompile(`^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$`) -var _regex_UUIDMsg_UserId = regexp.MustCompile(`^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12})?$`) - -func (this *UUIDMsg) Validate() error { - if !_regex_UUIDMsg_UserId.MatchString(this.UserId) { - return github_com_mwitkow_go_proto_validators.FieldError("UserId", fmt.Errorf(`value '%v' must be a string conforming to regex "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12})?$"`, this.UserId)) - } - if this.UserId == "" { - return github_com_mwitkow_go_proto_validators.FieldError("UserId", fmt.Errorf(`value '%v' must not be an empty string`, this.UserId)) +func (m *UUIDMsg) Validate() error { + if !UUIDMsgUserIdRE.MatchString(string(m.GetUserId())) { + return go_proto_validators.FieldError("UserId", errors.New("user_id should match regular expression '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$'")) } + return nil } diff --git a/go.mod b/go.mod index 1668aa1..7aefe21 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,16 @@ -module github.com/mwitkow/go-proto-validators +module github.com/maanasasubrahmanyam-sd/go-proto-validators go 1.13 require ( - github.com/gogo/protobuf v1.3.0 +<<<<<<< HEAD + github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.3.2 + github.com/google/protobuf v3.17.3+incompatible // indirect + github.com/mwitkow/go-proto-validators v0.3.2 +======= + github.com/golang/protobuf v1.4.1 +>>>>>>> origin/protobuf-v2 github.com/stretchr/testify v1.3.0 + google.golang.org/protobuf v1.25.0 ) diff --git a/go.sum b/go.sum index 5761181..7c59413 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,120 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +<<<<<<< HEAD github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/protobuf v3.17.3+incompatible h1:h7Pp7VNvhBLFH+OZi7+C8ESh5Art+Hlk/zBUndkvGj0= +github.com/google/protobuf v3.17.3+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mwitkow/go-proto-validators v0.3.2 h1:qRlmpTzm2pstMKKzTdvwPCF5QfBNURSlAgN/R+qbKos= +github.com/mwitkow/go-proto-validators v0.3.2/go.mod h1:ej0Qp0qMgHN/KtDyUt+Q1/tA7a5VarXUOUxD+oeD30w= +======= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +>>>>>>> origin/protobuf-v2 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +<<<<<<< HEAD +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +======= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +>>>>>>> origin/protobuf-v2 diff --git a/go_deps.bzl b/go_deps.bzl index 8bd048b..9c5d82c 100644 --- a/go_deps.bzl +++ b/go_deps.bzl @@ -1,23 +1,77 @@ load("@bazel_gazelle//:deps.bzl", "go_repository") def go_repositories(): + go_repository( + name = "co_honnef_go_tools", + importpath = "honnef.co/go/tools", + sum = "h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=", + version = "v0.0.0-20190523083050-ea95bdfd59fc", + ) + go_repository( + name = "com_github_burntsushi_toml", + importpath = "github.com/BurntSushi/toml", + sum = "h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=", + version = "v0.3.1", + ) + go_repository( + name = "com_github_census_instrumentation_opencensus_proto", + importpath = "github.com/census-instrumentation/opencensus-proto", + sum = "h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=", + version = "v0.2.1", + ) + go_repository( + name = "com_github_client9_misspell", + importpath = "github.com/client9/misspell", + sum = "h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=", + version = "v0.3.4", + ) go_repository( name = "com_github_davecgh_go_spew", importpath = "github.com/davecgh/go-spew", sum = "h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=", version = "v1.1.0", ) + go_repository( + name = "com_github_envoyproxy_go_control_plane", + importpath = "github.com/envoyproxy/go-control-plane", + sum = "h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w=", + version = "v0.9.1-0.20191026205805-5f8ba28d4473", + ) + go_repository( + name = "com_github_envoyproxy_protoc_gen_validate", + importpath = "github.com/envoyproxy/protoc-gen-validate", + sum = "h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=", + version = "v0.1.0", + ) go_repository( name = "com_github_gogo_protobuf", importpath = "github.com/gogo/protobuf", sum = "h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=", version = "v1.3.0", ) + go_repository( + name = "com_github_golang_glog", + importpath = "github.com/golang/glog", + sum = "h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=", + version = "v0.0.0-20160126235308-23def4e6c14b", + ) + go_repository( + name = "com_github_golang_mock", + importpath = "github.com/golang/mock", + sum = "h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=", + version = "v1.1.1", + ) go_repository( name = "com_github_golang_protobuf", importpath = "github.com/golang/protobuf", - sum = "h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=", - version = "v1.3.2", + sum = "h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=", + version = "v1.4.1", + ) + go_repository( + name = "com_github_google_go_cmp", + importpath = "github.com/google/go-cmp", + sum = "h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=", + version = "v0.5.0", ) go_repository( name = "com_github_kisielk_errcheck", @@ -37,6 +91,12 @@ def go_repositories(): sum = "h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=", version = "v1.0.0", ) + go_repository( + name = "com_github_prometheus_client_model", + importpath = "github.com/prometheus/client_model", + sum = "h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=", + version = "v0.0.0-20190812154241-14fe0d1b01d4", + ) go_repository( name = "com_github_stretchr_objx", importpath = "github.com/stretchr/objx", @@ -49,9 +109,93 @@ def go_repositories(): sum = "h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=", version = "v1.3.0", ) + go_repository( + name = "com_google_cloud_go", + importpath = "cloud.google.com/go", + sum = "h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=", + version = "v0.26.0", + ) + go_repository( + name = "org_golang_google_appengine", + importpath = "google.golang.org/appengine", + sum = "h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=", + version = "v1.4.0", + ) + go_repository( + name = "org_golang_google_genproto", + importpath = "google.golang.org/genproto", + sum = "h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=", + version = "v0.0.0-20200526211855-cb27e3aa2013", + ) + go_repository( + name = "org_golang_google_grpc", + importpath = "google.golang.org/grpc", + sum = "h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=", + version = "v1.27.0", + ) + go_repository( + name = "org_golang_google_protobuf", + importpath = "google.golang.org/protobuf", + sum = "h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=", + version = "v1.25.0", + ) + go_repository( + name = "org_golang_x_crypto", + importpath = "golang.org/x/crypto", + sum = "h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=", + version = "v0.0.0-20190308221718-c2843e01d9a2", + ) + go_repository( + name = "org_golang_x_exp", + importpath = "golang.org/x/exp", + sum = "h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=", + version = "v0.0.0-20190121172915-509febef88a4", + ) + go_repository( + name = "org_golang_x_lint", + importpath = "golang.org/x/lint", + sum = "h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=", + version = "v0.0.0-20190313153728-d0100b6bd8b3", + ) + go_repository( + name = "org_golang_x_net", + importpath = "golang.org/x/net", + sum = "h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=", + version = "v0.0.0-20190311183353-d8887717615a", + ) + go_repository( + name = "org_golang_x_oauth2", + importpath = "golang.org/x/oauth2", + sum = "h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=", + version = "v0.0.0-20180821212333-d2e6202438be", + ) + go_repository( + name = "org_golang_x_sync", + importpath = "golang.org/x/sync", + sum = "h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=", + version = "v0.0.0-20190423024810-112230192c58", + ) + go_repository( + name = "org_golang_x_sys", + importpath = "golang.org/x/sys", + sum = "h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=", + version = "v0.0.0-20190215142949-d0b11bdaac8a", + ) + go_repository( + name = "org_golang_x_text", + importpath = "golang.org/x/text", + sum = "h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=", + version = "v0.3.0", + ) go_repository( name = "org_golang_x_tools", importpath = "golang.org/x/tools", - sum = "h1:NIou6eNFigscvKJmsbyez16S2cIS6idossORlFtSt2E=", - version = "v0.0.0-20181030221726-6c7e314b6563", + sum = "h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=", + version = "v0.0.0-20190524140312-2c0ae7006135", + ) + go_repository( + name = "org_golang_x_xerrors", + importpath = "golang.org/x/xerrors", + sum = "h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=", + version = "v0.0.0-20191204190536-9bdfabe68543", ) diff --git a/internal/generator/BUILD.bazel b/internal/generator/BUILD.bazel new file mode 100644 index 0000000..06994fc --- /dev/null +++ b/internal/generator/BUILD.bazel @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = [ + "genvalidators.go", + "types.go", + ], + importpath = "github.com/mwitkow/go-proto-validators/internal/generator", + visibility = ["//:__subpackages__"], + deps = [ + "//:go_default_library", + "@org_golang_google_protobuf//compiler/protogen:go_default_library", + "@org_golang_google_protobuf//proto:go_default_library", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + ], +) diff --git a/internal/generator/genvalidators.go b/internal/generator/genvalidators.go new file mode 100644 index 0000000..b12aae8 --- /dev/null +++ b/internal/generator/genvalidators.go @@ -0,0 +1,578 @@ +// Copyright Improbable Worlds Ltd. All Rights Reserved. +// See LICENSE for licensing terms. + +package generator + +import ( + "fmt" + "reflect" + "strconv" + + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + validator "github.com/mwitkow/go-proto-validators" +) + +func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile { + if len(file.Messages) == 0 { + return nil // if there are no messages then we should not generate anything. + } + + filename := file.GeneratedFilenamePrefix + ".validator.pb.go" + g := gen.NewGeneratedFile(filename, file.GoImportPath) + g.P("// Code generated by protoc-gen-govalidators. DO NOT EDIT.") + g.P() + g.P("package ", file.GoPackageName) + g.P() + + generateFileContent(gen, file, g) + return g +} + +var ( + errorsPkg = protogen.GoImportPath("errors") + fmtPkg = protogen.GoImportPath("fmt") + regepxPkg = protogen.GoImportPath("regexp") + validatorPkg = protogen.GoImportPath("github.com/mwitkow/go-proto-validators") +) + +func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) { + if !validateFileValidators(gen, file) { + return + } + + for _, msg := range file.Messages { + generateMessageValidators(file, msg, g) + } +} + +func validateFileValidators(gen *protogen.Plugin, file *protogen.File) bool { + isValid := true + for _, msg := range file.Messages { + isValid = isValid && validateMessageValidators(gen, msg) + } + return isValid +} + +func validateMessageValidators(gen *protogen.Plugin, msg *protogen.Message) bool { + if msg.Desc.IsMapEntry() { + return true + } + + // Note that we are not validating one-of validators as there's nothing to validate about them. + isValid := true + for _, field := range msg.Fields { + isValid = isValid && validateAllowedValidators(gen, field) && validateConflictingValidators(gen, field) + } + + for _, childMsg := range msg.Messages { + isValid = isValid && validateMessageValidators(gen, childMsg) + } + + return isValid +} + +func validateAllowedValidators(gen *protogen.Plugin, field *protogen.Field) bool { + val, ok := fieldValidator(field.Desc.Options()) + if !ok { + return true + } + + isValid := true + v := reflect.ValueOf(val).Elem() + for idx := 0; idx < v.NumField(); idx++ { + if v.Type().Field(idx).Type.Kind() != reflect.Ptr || v.Field(idx).IsNil() { + continue + } + + fieldName := v.Type().Field(idx).Name + + var allowed bool + for _, allowedValidator := range allowedValidators(field) { + if fieldName == validatorTypeToString[allowedValidator] { + allowed = true + break + } + } + if !allowed { + gen.Error(fmt.Errorf("field %q cannot have a validator of type %q", field.Desc.Name(), fieldName)) + isValid = false + } + } + return isValid +} + +func validateConflictingValidators(gen *protogen.Plugin, field *protogen.Field) bool { + val, ok := fieldValidator(field.Desc.Options()) + if !ok { + return true + } + + isValid := true + + // String-based validators. + valCount := 0 + if val.LengthEq != nil || val.LengthGt != nil || val.LengthLt != nil { + valCount++ + } + if val.Regex != nil { + valCount++ + } + if val.StringNotEmpty != nil { + valCount++ + } + if val.UuidVer != nil { + if val.GetUuidVer() < 0 || val.GetUuidVer() > 5 { + gen.Error(fmt.Errorf("field %q should have a uuid version value between 0 and 5", field.Desc.Name())) + isValid = false + } + valCount++ + } + if valCount > 1 { + gen.Error(fmt.Errorf( + "field %q can not have more than one of either a regex, string_not_empty, uuid_ver or any of the length_* validators", + field.Desc.FullName(), + )) + isValid = false + } + + // Integer-based validators. + if val.IntGt != nil && val.IntLt != nil && val.GetIntGt() > val.GetIntLt()-1 { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as its value can never be both greater than %d and lower than %d", + field.Desc.FullName(), + val.GetIntGt(), + val.GetIntLt(), + )) + isValid = false + } + + // Float-based validators. + if val.FloatEpsilon != nil && val.FloatGt == nil && val.FloatGte == nil && val.FloatLt == nil && val.FloatLte == nil { + gen.Error(fmt.Errorf("field %q can not have float_epsilon but no other float-value validator", field.Desc.Name())) + isValid = false + } + if val.FloatGt != nil && val.FloatGte != nil { + gen.Error(fmt.Errorf("field %q has redundant float_gt and float_gte validators, only use one", field.Desc.Name())) + isValid = false + } + if val.FloatLt != nil && val.FloatLte != nil { + gen.Error(fmt.Errorf("field %q has redundant float_lt and float_lte validators, only use one", field.Desc.Name())) + isValid = false + } + switch { + case val.FloatGt != nil && val.FloatLt != nil: + if val.GetFloatGt() >= val.GetFloatLt() { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as its value can never be both greater than %f and lower than %f", + field.Desc.Name(), + val.GetFloatGt(), val.GetFloatLt(), + )) + } + case val.FloatGt != nil && val.FloatLte != nil: + if val.GetFloatGt() >= val.GetFloatLte() { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as its value can never be both greater than %f and lower than or equal to %f", + field.Desc.Name(), + val.GetFloatGt(), val.GetFloatLte(), + )) + } + case val.FloatGte != nil && val.FloatLt != nil: + if val.GetFloatGte() >= val.GetFloatLt() { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as its value can never be both greater than or equal to %f and lower than %f", + field.Desc.Name(), + val.GetFloatGte(), val.GetFloatLt(), + )) + } + case val.FloatGte != nil && val.FloatLte != nil: + if val.GetFloatGte() > val.GetFloatLte() { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as its value can never be both greater than or equal to %f and lower than or equal to %f", + field.Desc.Name(), + val.GetFloatGte(), val.GetFloatLte(), + )) + } + } + + // Length-based validators. + if val.LengthEq != nil && (val.LengthGt != nil || val.LengthLt != nil) { + gen.Error(fmt.Errorf("field %q can not have both length_eq and any of length_gt or length_lt as validators", field.Desc.FullName())) + isValid = false + } + if val.LengthGt != nil && val.LengthLt != nil && (val.GetLengthGt() > val.GetLengthLt()-1) { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as its length can not be both greater than %d and lower than %d", + field.Desc.Name(), + val.GetLengthGt(), + val.GetLengthLt(), + )) + isValid = false + } + if val.RepeatedCountMax != nil && val.RepeatedCountMin != nil && (val.GetRepeatedCountMax() < val.GetRepeatedCountMin()) { + gen.Error(fmt.Errorf( + "field %q has conflicting validators as it can't have both at most %d elements and at least %d elements", + field.Desc.Name(), + val.GetRepeatedCountMax(), + val.GetRepeatedCountMin(), + )) + isValid = false + } + + return isValid +} + +func generateMessageValidators(file *protogen.File, msg *protogen.Message, g *protogen.GeneratedFile) { + if msg.Desc.IsMapEntry() { + return + } + + for _, childMsg := range msg.Messages { + generateMessageValidators(file, childMsg, g) + } + + generateRegexpVars(msg, g) + + g.P("func (m *", msg.GoIdent.GoName, ") Validate() error {") + defer func() { + g.P("return nil") + g.P("}") + g.P() + }() + + for _, oneOf := range msg.Oneofs { + val, ok := oneOfValidator(oneOf.Desc.Options()) + if !ok || !val.GetRequired() { + continue + } + + g.P("if m.Get", oneOf.GoName, "() == nil {") + g.P("return ", validatorPkg.Ident("FieldError"), `("`, oneOf.GoName, `", `, errorsPkg.Ident("New"), `("one of the fields must be set"))`) + g.P("}") + g.P() + } + + for _, field := range msg.Fields { + generateFieldValidators(file, field, g) + } +} + +const uuidPattern = "^[a-fA-F0-9]{8}-" + + "[a-fA-F0-9]{4}-" + + "[%s][a-fA-F0-9]{3}-" + + "[8|9|aA|bB][a-fA-F0-9]{3}-" + + "[a-fA-F0-9]{12}$" + +func generateRegexpVars(msg *protogen.Message, g *protogen.GeneratedFile) { + var hasRegexVars bool + for _, field := range msg.Fields { + val, ok := fieldValidator(field.Desc.Options()) + if !ok || (val.Regex == nil && val.UuidVer == nil) { + continue + } + + pattern := val.GetRegex() + if val.UuidVer != nil { + pattern = fmt.Sprintf(uuidPattern, strconv.Itoa(int(val.GetUuidVer()))) + if val.GetUuidVer() == 0 { + pattern = fmt.Sprintf(uuidPattern, "1-5") + } + } + g.P("var ", regexpVarName(field), " = ", regepxPkg.Ident("MustCompile"), "(`", pattern, "`)") + hasRegexVars = true + } + if hasRegexVars { + g.P() + } +} + +func regexpVarName(field *protogen.Field) string { + return field.Parent.GoIdent.GoName + field.GoName + "RE" +} + +func generateFieldValidators(file *protogen.File, field *protogen.Field, g *protogen.GeneratedFile) { + val, ok := fieldValidator(field.Desc.Options()) + if !ok && field.Message == nil { + return + } + + if file.Desc.Syntax().String() == "proto2" && field.Desc.Cardinality() == protoreflect.Optional { + g.P("if m.", field.GoName, " != nil {") + } + if field.Oneof != nil { + g.P("if _, ok := m.", field.Oneof.GoName, ".(*", field.GoIdent, "); ok {") + } + + iterate := field.Desc.Cardinality() == protoreflect.Repeated && (hasValueConstraints(val) || field.Message != nil) + + valueRef := fmt.Sprintf("m.Get%s()", field.GoName) + if val != nil && val.RepeatedCountMax != nil { + g.P("if len(", valueRef, ") > ", val.GetRepeatedCountMax(), " {") + printFieldErr(g, field, + fmtPkg.Ident("Errorf"), + `("`, + field.Desc.Name(), + " has %d elements whereas a maximum of ", + val.GetRepeatedCountMax(), + ` is allowed", len(`, + valueRef, + "))", + ) + g.P("}") + g.P() + } + if val != nil && val.RepeatedCountMin != nil { + g.P("if len(", valueRef, ") < ", val.GetRepeatedCountMin(), " {") + printFieldErr(g, field, + fmtPkg.Ident("Errorf"), + `("`, + field.Desc.Name(), + " has %d elements whereas a minimum of ", + val.GetRepeatedCountMin(), + ` is required", len(`, + valueRef, + "))", + ) + g.P("}") + g.P() + } + + if iterate { + if field.Desc.IsMap() && (field.Message.Desc.Fields().ByNumber(2).Kind() != protoreflect.MessageKind && !hasValueConstraints(val)) { + return + } + + g.P("for _, item := range ", valueRef, " {") + valueRef = "item" + } + + generateValueConstraints(field, valueRef, g) + + if iterate { + g.P("}") + } + if field.Oneof != nil { + g.P("}") + } + if file.Desc.Syntax().String() == "proto2" && field.Desc.Cardinality() == protoreflect.Optional { + g.P("}") + } + g.P() +} + +func generateValueConstraints(field *protogen.Field, valueRef string, g *protogen.GeneratedFile) { + if field.Message != nil && (!field.Desc.IsMap() || field.Message.Desc.Fields().ByNumber(2).Kind() == protoreflect.MessageKind) { + g.P("if ", valueRef, " != nil {") + g.P("if err := ", validatorPkg.Ident("CallValidatorIfExists"), "(", valueRef, "); err != nil {") + printFieldErr(g, field, "err") + g.P("}") + g.P("}") + } + + val, ok := fieldValidator(field.Desc.Options()) + if !ok { + return + } + + if val.FloatGt != nil { + l := val.GetFloatGt() - val.GetFloatEpsilon() + g.P("if ", valueRef, " <= ", l, " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " is not greater than ", l, `")`) + g.P("}") + } else if val.FloatGte != nil { + l := val.GetFloatGte() - val.GetFloatEpsilon() + g.P("if ", valueRef, " < ", l, " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " is not greater than or equal to ", l, `")`) + g.P("}") + } + + if val.FloatLt != nil { + l := val.GetFloatLt() + val.GetFloatEpsilon() + g.P("if ", valueRef, " >= ", l, " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " is not smaller than ", l, `")`) + g.P("}") + } else if val.FloatLte != nil { + l := val.GetFloatLte() + val.GetFloatEpsilon() + g.P("if ", valueRef, " > ", l, " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " is not smaller than or equal to ", l, `")`) + g.P("}") + } + + if val.IntGt != nil { + l := val.GetIntGt() + g.P("if ", valueRef, " <=", l, " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " is not greater than ", l, `")`) + g.P("}") + } + if val.IntLt != nil { + l := val.GetIntLt() + g.P("if ", valueRef, " >=", l, " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " is not smaller than ", l, `")`) + g.P("}") + } + + if val.IsInEnum != nil { + g.P("if _, ok := ", field.Enum.GoIdent.GoName, "_name[int32(", valueRef, ")]; !ok {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), ` should correspond to a valid enum value")`) + g.P("}") + } + + if val.LengthEq != nil { + g.P("if len(", valueRef, ") != ", val.GetLengthEq(), " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " should be of length ", val.GetLengthEq(), `")`) + g.P("}") + } + if val.LengthGt != nil { + g.P("if len(", valueRef, ") <= ", val.GetLengthGt(), " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " should have a length greater than ", val.GetLengthGt(), `")`) + g.P("}") + } + if val.LengthLt != nil { + g.P("if len(", valueRef, ") >= ", val.GetLengthLt(), " {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), " should have a length smaller than ", val.GetLengthLt(), `")`) + g.P("}") + } + + if val.GetMsgExists() { + g.P("if ", valueRef, " == nil {") + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), ` should be set")`) + g.P("}") + } + + if val.Regex != nil { + g.P("if !", regexpVarName(field), ".MatchString(string(", valueRef, ")) {") + printFieldErr(g, field, errorsPkg.Ident("New"), "(`", field.Desc.Name(), " should match regular expression ", strconv.Quote(val.GetRegex()), "`)") + g.P("}") + } + + if val.StringNotEmpty != nil { + g.P("if string(", valueRef, `) == "" {`) + printFieldErr(g, field, errorsPkg.Ident("New"), `("`, field.Desc.Name(), ` should not be empty")`) + g.P("}") + } + + if val.UuidVer != nil { + g.P("if !", regexpVarName(field), ".MatchString(string(", valueRef, ")) {") + printFieldErr(g, field, + errorsPkg.Ident("New"), + `("`, + field.Desc.Name(), + " should match regular expression '", + fmt.Sprintf(uuidPattern, strconv.Itoa(int(val.GetUuidVer()))), + `'")`, + ) + g.P("}") + } +} + +func printFieldErr(g *protogen.GeneratedFile, field *protogen.Field, errorString ...interface{}) { + val, ok := fieldValidator(field.Desc.Options()) + if ok && val.HumanError != nil { + errorString = []interface{}{errorsPkg.Ident("New"), `("`, val.GetHumanError(), `")`} + } + g.P(append(append([]interface{}{"return ", validatorPkg.Ident("FieldError"), `("`, field.GoName, `", `}, errorString...), ")")...) +} + +func fieldValidator(fieldOptions protoreflect.ProtoMessage) (*validator.FieldValidator, bool) { + ext := extractValidator(fieldOptions, validator.E_Field) + if ext == nil { + return nil, false + } + val, ok := ext.(*validator.FieldValidator) + return val, ok +} + +func oneOfValidator(fieldOptions protoreflect.ProtoMessage) (*validator.OneofValidator, bool) { + ext := extractValidator(fieldOptions, validator.E_Oneof) + if ext == nil { + return nil, false + } + val, ok := ext.(*validator.OneofValidator) + return val, ok +} + +func extractValidator(fieldOptions protoreflect.ProtoMessage, extType protoreflect.ExtensionType) interface{} { + // The supplied interface might be empty but will still not be comparible to a nil pointer. + // Hence we assert that the proto message is atleast valid before trying to extract our + // extension field. + if !fieldOptions.ProtoReflect().IsValid() { + return nil + } else if !proto.HasExtension(fieldOptions, extType) { + return nil + } + return proto.GetExtension(fieldOptions, extType) +} + +func hasValueConstraints(val *validator.FieldValidator) bool { + if val == nil { + return false + } + return val.FloatEpsilon != nil || + val.FloatGt != nil || + val.FloatGte != nil || + val.FloatLt != nil || + val.FloatLte != nil || + val.IntGt != nil || + val.IntLt != nil || + val.IsInEnum != nil || + val.LengthEq != nil || + val.LengthGt != nil || + val.LengthLt != nil || + val.MsgExists != nil || + val.Regex != nil || + val.StringNotEmpty != nil || + val.UuidVer != nil +} + +func allowedValidators(field *protogen.Field) []validatorType { + vals := []validatorType{humanErrorValidator} + + if field.Desc.Cardinality() == protoreflect.Repeated { + vals = append(vals, repeatedCountMaxValidator, repeatedCountMinValidator) + } + + switch field.Desc.Kind() { + case protoreflect.BytesKind, protoreflect.StringKind: + vals = append( + vals, + lengthEqValidator, + lengthGtValidator, + lengthLtValidator, + stringNotEmptyValidator, + uuidVerValidator, + regexValidator, + ) + case protoreflect.DoubleKind, protoreflect.Fixed32Kind, protoreflect.Fixed64Kind, + protoreflect.FloatKind, protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind: + vals = append( + vals, + floatEpsilonValidator, + floatGtValidator, + floatGteValidator, + floatLtValidator, + floatLteValidator, + ) + case protoreflect.EnumKind: + vals = append( + vals, + isInEnumValidator, + ) + case protoreflect.Int32Kind, protoreflect.Int64Kind, protoreflect.Sint32Kind, protoreflect.Sint64Kind, + protoreflect.Uint32Kind, protoreflect.Uint64Kind: + vals = append( + vals, + intGtValidator, + intLtValidator, + ) + case protoreflect.MessageKind: + if field.Desc.IsMap() && field.Message.Desc.Fields().ByNumber(2).Kind() != protoreflect.MessageKind { + return allowedValidators(field.Message.Fields[1]) + } + vals = append( + vals, msgExistsValidator, + ) + } + return vals +} diff --git a/internal/generator/types.go b/internal/generator/types.go new file mode 100644 index 0000000..5421fd2 --- /dev/null +++ b/internal/generator/types.go @@ -0,0 +1,47 @@ +package generator + +type validatorType uint8 + +const ( + unknownValidator validatorType = iota + floatEpsilonValidator + floatGtValidator + floatGteValidator + floatLtValidator + floatLteValidator + humanErrorValidator + intGtValidator + intLtValidator + isInEnumValidator + lengthEqValidator + lengthGtValidator + lengthLtValidator + msgExistsValidator + regexValidator + repeatedCountMaxValidator + repeatedCountMinValidator + stringNotEmptyValidator + uuidVerValidator +) + +var validatorTypeToString = map[validatorType]string{ + unknownValidator: "", + floatEpsilonValidator: "FloatEpsilon", + floatGtValidator: "FloatGt", + floatGteValidator: "FloatGte", + floatLtValidator: "FloatLt", + floatLteValidator: "FloatLte", + humanErrorValidator: "HumanError", + intGtValidator: "IntGt", + intLtValidator: "IntLt", + isInEnumValidator: "IsInEnum", + lengthEqValidator: "LengthEq", + lengthGtValidator: "LengthGt", + lengthLtValidator: "LengthLt", + msgExistsValidator: "MsgExists", + regexValidator: "Regex", + repeatedCountMaxValidator: "RepeatedCountMax", + repeatedCountMinValidator: "RepeatedCountMin", + stringNotEmptyValidator: "StringNotEmpty", + uuidVerValidator: "UuidVer", +} diff --git a/plugin/BUILD.bazel b/plugin/BUILD.bazel deleted file mode 100644 index 4b293fa..0000000 --- a/plugin/BUILD.bazel +++ /dev/null @@ -1,16 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["plugin.go"], - importpath = "github.com/mwitkow/go-proto-validators/plugin", - visibility = ["//visibility:public"], - deps = [ - "//:validators_gogo", - "@com_github_gogo_protobuf//gogoproto:go_default_library", - "@com_github_gogo_protobuf//proto:go_default_library", - "@com_github_gogo_protobuf//protoc-gen-gogo/descriptor:go_default_library", - "@com_github_gogo_protobuf//protoc-gen-gogo/generator:go_default_library", - "@com_github_gogo_protobuf//vanity:go_default_library", - ], -) diff --git a/plugin/plugin.go b/plugin/plugin.go index 1de26e7..6a59b48 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -1,67 +1,16 @@ -// 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" "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" "github.com/gogo/protobuf/protoc-gen-gogo/generator" "github.com/gogo/protobuf/vanity" + "os" - validator "github.com/mwitkow/go-proto-validators" + validator "github.com/maanasasubrahmanyam-sd/go-proto-validators/validator" ) const uuidPattern = "^([a-fA-F0-9]{8}-" + @@ -95,21 +44,22 @@ 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") + p.validatorPkg = p.NewImport("github.com/maanasasubrahmanyam-sd/go-proto-validators/validator") for _, msg := range file.Messages() { - if msg.DescriptorProto.GetOptions().GetMapEntry() { + /*if msg.DescriptorProto.GetOptions().GetMapEntry() { continue - } - p.generateRegexVars(file, msg) + }*/ + //p.generateRegexVars(file, msg) if gogoproto.IsProto3(file.FileDescriptorProto) { p.generateProto3Message(file, msg) - } else { + } /*else { p.generateProto2Message(file, msg) - } + }*/ } } @@ -123,7 +73,7 @@ func getFieldValidatorIfAny(field *descriptor.FieldDescriptorProto) *validator.F return nil } -func getOneofValidatorIfAny(oneof *descriptor.OneofDescriptorProto) *validator.OneofValidator { +/*func getOneofValidatorIfAny(oneof *descriptor.OneofDescriptorProto) *validator.OneofValidator { if oneof.Options != nil { v, err := proto.GetExtension(oneof.Options, validator.E_Oneof) if err == nil && v.(*validator.OneofValidator) != nil { @@ -131,9 +81,9 @@ func getOneofValidatorIfAny(oneof *descriptor.OneofDescriptorProto) *validator.O } } return nil -} +}*/ -func (p *plugin) isSupportedInt(field *descriptor.FieldDescriptorProto) bool { +/*func (p *plugin) isSupportedInt(field *descriptor.FieldDescriptorProto) bool { switch *(field.Type) { case descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_INT64: return true @@ -144,8 +94,8 @@ func (p *plugin) isSupportedInt(field *descriptor.FieldDescriptorProto) bool { } return false } - -func (p *plugin) isSupportedFloat(field *descriptor.FieldDescriptorProto) bool { +*/ +/*func (p *plugin) isSupportedFloat(field *descriptor.FieldDescriptorProto) bool { switch *(field.Type) { case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_DOUBLE: return true @@ -155,9 +105,9 @@ func (p *plugin) isSupportedFloat(field *descriptor.FieldDescriptorProto) bool { return true } return false -} +}*/ -func (p *plugin) generateRegexVars(file *generator.FileDescriptor, message *generator.Descriptor) { +/*func (p *plugin) generateRegexVars(file *generator.FileDescriptor, message *generator.Descriptor) { ccTypeName := generator.CamelCaseSlice(message.TypeName()) for _, field := range message.Field { validator := getFieldValidatorIfAny(field) @@ -178,7 +128,7 @@ func (p *plugin) generateRegexVars(file *generator.FileDescriptor, message *gene } } } -} +}*/ func (p *plugin) GetFieldName(message *generator.Descriptor, field *descriptor.FieldDescriptorProto) string { fieldName := p.Generator.GetFieldName(message, field) @@ -202,7 +152,7 @@ func (p *plugin) GetOneOfFieldName(message *generator.Descriptor, field *descrip return fieldName } -func (p *plugin) generateProto2Message(file *generator.FileDescriptor, message *generator.Descriptor) { +/*func (p *plugin) generateProto2Message(file *generator.FileDescriptor, message *generator.Descriptor) { ccTypeName := generator.CamelCaseSlice(message.TypeName()) p.P(`func (this *`, ccTypeName, `) Validate() error {`) @@ -283,14 +233,14 @@ func (p *plugin) generateProto2Message(file *generator.FileDescriptor, message * 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 _, oneof := range message.OneofDecl { + /*for _, oneof := range message.OneofDecl { oneofValidator := getOneofValidatorIfAny(oneof) if oneofValidator == nil { continue @@ -303,38 +253,38 @@ func (p *plugin) generateProto3Message(file *generator.FileDescriptor, message * p.Out() p.P(`}`) } - } + }*/ 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() + //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() && !(p.useGogoImport && gogoproto.IsEmbed(field)) - if p.fieldIsProto3Map(file, message, field) { + //nullable := (gogoproto.IsNullable(field) || !gogoproto.ImportsGoGoProto(file.FileDescriptorProto)) && field.IsMessage() && !(p.useGogoImport && gogoproto.IsEmbed(field)) + /*if p.fieldIsProto3Map(file, message, field) { p.P(`// Validation of proto3 map<> fields is unsupported.`) continue - } - if isOneOf { + }*/ + /*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 { + }*/ + /*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 { + }*/ /*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) } @@ -351,47 +301,86 @@ func (p *plugin) generateProto3Message(file *generator.FileDescriptor, message * } 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.generateLengthValidator(variableName, ccTypeName, fieldName, fieldValidator)*/ + //} else + if field.IsMessage() { + if p.validateRegex(fieldValidator) { + if(p.fieldIsCustomRegex(field)){ + fmt.Fprintf(os.Stderr, "WARNING: field %+v", field.GetTypeName()) + } + p.Out() + p.P(`}`) + } + /*if p.validatorWithFutureTimestamp(fieldValidator) { + if nullable && !repeated { + if p.fieldIsTimestamp(field) { + p.P(`if nil == `, variableName, `{`) + p.In() + p.P(`return `, p.fmtPkg.Use(), `.Errorf("field `, fieldName, ` cant be nil")`) + p.Out() + p.P(`}`) + //p.P(`ts`, fieldName, `, err := `, p.ptypesPkg.Use(), `.Timestamp(`, variableName, `)`) + p.P(`if err != nil {`) + p.In() + p.P(`return `, p.fmtPkg.Use(), `.Errorf("faield to convert `, fieldName, ` to Timestamp")`) + p.Out() + p.P(`}`) + //p.P(`if !ts`, fieldName, `.After(`, p.timePkg.Use(), `.Now()) {`) + p.In() + p.P(`return `, p.fmtPkg.Use(), `.Errorf("must be future timestamp")`) + p.Out() + p.P(`}`) + } else { + fmt.Fprintf(os.Stderr, "WARNING: field %+v", field.GetTypeName()) + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is not of type google.protobuf.Timestamp, validator.future_timestamp has no effect\n", ccTypeName, fieldName) + } + } else if repeated { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is repeated, validator.future_timestamp has no effect\n", ccTypeName, fieldName) + } else if !nullable { + fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a nullable=false, validator.future_timestamp has no effect\n", ccTypeName, fieldName) + } + }*//*else { + 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() - p.P(`return `, p.validatorPkg.Use(), `.FieldError("`, fieldName, `",`, p.fmtPkg.Use(), `.Errorf("message must exist"))`) + } 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(`}`) - } 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 { + }*/ + //} + /*if repeated && (field.IsMessage() || p.validatorWithNonRepeatedConstraint(fieldValidator)) { + // end the repeated loop 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(`}`) + if isOneOf { + // end the oneof if statement + p.Out() + p.P(`}`) + }*/ } } p.P(`return nil`) @@ -399,7 +388,7 @@ func (p *plugin) generateProto3Message(file *generator.FileDescriptor, message * p.P(`}`) } -func (p *plugin) generateIntValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { +/*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() @@ -416,9 +405,9 @@ func (p *plugin) generateIntValidator(variableName string, ccTypeName string, fi p.Out() p.P(`}`) } -} +}*/ -func (p *plugin) generateEnumValidator( +/*func (p *plugin) generateEnumValidator( field *descriptor.FieldDescriptorProto, variableName, ccTypeName, fieldName string, fv *validator.FieldValidator) { @@ -430,9 +419,9 @@ func (p *plugin) generateEnumValidator( p.Out() p.P(`}`) } -} +}*/ -func (p *plugin) generateLengthValidator(variableName string, ccTypeName string, fieldName string, fv *validator.FieldValidator) { +/*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() @@ -687,3 +676,29 @@ func (p *plugin) validatorWithNonRepeatedConstraint(fv *validator.FieldValidator func (p *plugin) regexName(ccTypeName string, fieldName string) string { return "_regex_" + ccTypeName + "_" + fieldName } + +func (p *plugin) validatorWithFutureTimestamp(fv *validator.FieldValidator) bool { + return fv != nil && fv.FutureTimestamp != nil && *(fv.FutureTimestamp) +}*/ + +func (p *plugin) validateRegex(fv *validator.FieldValidator) bool { // maanasa + //string s = "^[A-Za-z0-9]"; + if(*fv.CustomRegex == "maanasa"){ + return true + } + return false +} + +/*func (p *plugin) fieldIsTimestamp(field *descriptor.FieldDescriptorProto) bool { + if field.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE && field.GetTypeName() == ".google.protobuf.Timestamp" { + return true + } + return false +}*/ + +func (p *plugin) fieldIsCustomRegex(field *descriptor.FieldDescriptorProto) bool { + if field.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE && field.GetTypeName() == ".CustomRegex" { + return true + } + return false +} \ No newline at end of file diff --git a/protoc-gen-govalidators/BUILD.bazel b/protoc-gen-govalidators/BUILD.bazel index b1c1cf9..518a090 100644 --- a/protoc-gen-govalidators/BUILD.bazel +++ b/protoc-gen-govalidators/BUILD.bazel @@ -6,9 +6,8 @@ go_library( importpath = "github.com/mwitkow/go-proto-validators/protoc-gen-govalidators", visibility = ["//visibility:private"], deps = [ - "//plugin:go_default_library", - "@com_github_gogo_protobuf//proto:go_default_library", - "@com_github_gogo_protobuf//protoc-gen-gogo/generator:go_default_library", + "//internal/generator:go_default_library", + "@org_golang_google_protobuf//compiler/protogen:go_default_library", ], ) diff --git a/protoc-gen-govalidators/main.go b/protoc-gen-govalidators/main.go index 2aacf29..0a22f66 100644 --- a/protoc-gen-govalidators/main.go +++ b/protoc-gen-govalidators/main.go @@ -1,67 +1,27 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. +// Copyright Improbable Worlds Ltd.. All Rights Reserved. // See LICENSE for licensing terms. package main import ( - "io/ioutil" - "os" - "strconv" - "strings" + "google.golang.org/protobuf/compiler/protogen" +<<<<<<< HEAD "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/protoc-gen-gogo/generator" - validator_plugin "github.com/mwitkow/go-proto-validators/plugin" + validator_plugin "github.com/maanasasubrahmanyam-sd/go-proto-validators/plugin" +======= + "github.com/mwitkow/go-proto-validators/internal/generator" +>>>>>>> origin/protobuf-v2 ) 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") + protogen.Options{}.Run(func(gen *protogen.Plugin) error { + for _, f := range gen.Files { + if f.Generate { + generator.GenerateFile(gen, f) + } } - } - - 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") - } + return nil + }) } diff --git a/scripts/includes/deps.sh b/scripts/includes/deps.sh deleted file mode 100644 index 56a21c1..0000000 --- a/scripts/includes/deps.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env bash - -function install_protobuf() { - if [[ -z "${PROTOBUF_VERSION:-}" ]]; then - echo "Please set the version of protobuf to use via the PROTOBUF_VERSION environment variable." - exit 1 - fi - - local deps_dir os_string version - version="${PROTOBUF_VERSION}" - deps_dir="${PROJECT_DIR}/deps" - case "$(uname -s | tr "[:upper:]" "[:lower:]")" in - linux) - os_string="linux" - ;; - darwin) - os_string="osx" - ;; - *) - echo "This platform is not supported for running this script." - exit 1 - ;; - esac - - if [[ ! -e "${deps_dir}/${version}.zip" ]]; then - echo "Downloading and installing protoc ${version}." - mkdir -p "${deps_dir}" - - pushd "${deps_dir}" || exit 1 - rm -rf "${version}.zip" "${version}.zip.tmp" "bin" "include" - wget "https://github.com/google/protobuf/releases/download/v${version}/protoc-${version}-${os_string}-x86_64.zip" -O "${version}.zip.tmp" - unzip -o "${version}.zip.tmp" - chmod 755 "bin/protoc" - mv "${version}.zip.tmp" "${version}.zip" - popd || exit 1 - else - echo "Reusing existing protoc ${version}." - fi -} - -function setup_proto_deps() { - local dep dep_dir dep_location proto_deps - dep_dir="${PROJECT_DIR}/deps" - - proto_deps=( - "github.com/gogo/protobuf" - "github.com/golang/protobuf" - "github.com/mwitkow/go-proto-validators" - ) - - # Set up the target directory for symlinking in dependencies. - mkdir -p "${dep_dir}" - - # Ensure the module dependencies are available - go mod download - - for dep in "${proto_deps[@]}"; do - dep_location="$(go list -m -json "${dep}" | jq -rM '.Dir')" - - mkdir -p "${dep_dir}/$(dirname "${dep}")" - rm -f "${dep_dir}/${dep}" - ln -sf "${dep_location}" "${dep_dir}/${dep}" - done - - go install github.com/gogo/protobuf/protoc-gen-gogo - go install github.com/golang/protobuf/protoc-gen-go - - PATH="${GOBIN:-"${HOME}/go/bin"}:${PATH}" - export PATH -} diff --git a/scripts/lint.sh b/scripts/lint.sh new file mode 100755 index 0000000..e9a0b5c --- /dev/null +++ b/scripts/lint.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -e -u -o pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +cd "${repo_root}" + +function check_diff() { + if ! git diff --quiet; then + git diff + echo >&2 "---------------" + echo >&2 "Linting failure. A diff was detected. See above for the exact diff" + exit 1 + fi +} + +echo "Verifying go.mod is up-to-date." +go mod tidy +check_diff + +echo "Ensuring Bazel build configuration is up-to-date." +bazel run --run_under="cd $(pwd) && " @bazel_gazelle//cmd/gazelle -- update-repos -from_file=go.mod -to_macro=go_deps.bzl%go_repositories +bazel run //:gazelle +check_diff + +echo "Ensuring generated files are up-to-date." +./scripts/regenerate.sh + +check_diff diff --git a/scripts/prepare-deps.sh b/scripts/prepare-deps.sh deleted file mode 100644 index 8cca36d..0000000 --- a/scripts/prepare-deps.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -u -o pipefail - -PROJECT_DIR="$(dirname "${BASH_SOURCE[0]}")/.." -cd "${PROJECT_DIR}" -export PROJECT_DIR - -source scripts/includes/deps.sh - -install_protobuf -setup_proto_deps diff --git a/scripts/regenerate.sh b/scripts/regenerate.sh new file mode 100755 index 0000000..45bae2e --- /dev/null +++ b/scripts/regenerate.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e -u -o pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +cd "${repo_root}" + +bazel build //:validators_go_proto +cp bazel-bin/validators_go_proto_/github.com/mwitkow/go-proto-validators/validators.pb.go . +chmod 644 validators.pb.go + +bazel build //test:validatortest_go_proto +cp bazel-bin/test/validatortest_go_proto_/github.com/mwitkow/go-proto-validators/test/*.pb.go ./test +chmod 644 test/*.pb.go + +bazel build //examples:validator_examples_go_proto +cp bazel-bin/examples/validator_examples_go_proto_/github.com/mwitkow/go-proto-validators/examples/*.pb.go ./examples +chmod 644 test/*.pb.go diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 0000000..0fc66fa --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e -u -o pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +cd "${repo_root}" + +bazel build //... + +bazel test //... diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index f8fcb25..0000000 --- a/test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pb.go -Makefile \ No newline at end of file diff --git a/test/BUILD.bazel b/test/BUILD.bazel index 15efe82..85c995d 100644 --- a/test/BUILD.bazel +++ b/test/BUILD.bazel @@ -1,36 +1,49 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") load("@rules_proto//proto:defs.bzl", "proto_library") +# gazelle:proto_import_prefix +# gazelle:go_proto_compilers @io_bazel_rules_go//proto:go_proto,//:go_proto_validators +# gazelle:resolve proto go github.com/mwitkow/go-proto-validators/validators.proto //:go_default_library +# gazelle:exclude *.pb.go + proto_library( - name = "proto2", - srcs = ["validator_proto2.proto"], - deps = [ - "//:validator_proto", - "@gogo_special_proto//github.com/gogo/protobuf/gogoproto", + name = "validatortest_proto", + srcs = [ + "validator_proto2.proto", + "validator_proto3.proto", + "validator_proto3_map.proto", + "validator_proto3_oneof.proto", ], - visibility = ["//test:__subpackages__"], + visibility = ["//visibility:public"], + deps = ["//:validators_proto"], ) -proto_library( - name = "proto3", - srcs = ["validator_proto3.proto"], - deps = [ - "//:validator_proto", - "@gogo_special_proto//github.com/gogo/protobuf/gogoproto", +go_proto_library( + name = "validatortest_go_proto", + compilers = [ + "@io_bazel_rules_go//proto:go_proto", + "//:go_proto_validators", ], - visibility = ["//test:__subpackages__"], + importpath = "github.com/mwitkow/go-proto-validators/test", + proto = ":validatortest_proto", + visibility = ["//visibility:public"], + deps = ["//:go_default_library"], ) -proto_library( - name = "proto3_oneof", - srcs = ["validator_proto3_oneof.proto"], - deps = [ - "//:validator_proto", - ], - visibility = ["//test:__subpackages__"], +go_library( + name = "go_default_library", + embed = [":validatortest_go_proto"], + importpath = "github.com/mwitkow/go-proto-validators/test", + visibility = ["//visibility:public"], ) -proto_library( - name = "proto3_map", - srcs = ["validator_proto3_map.proto"], - visibility = ["//test:__subpackages__"], +go_test( + name = "go_default_test", + srcs = ["validator_test.go"], + embed = [":go_default_library"], + deps = [ + "@com_github_stretchr_testify//assert:go_default_library", + "@com_github_stretchr_testify//require:go_default_library", + ], ) diff --git a/test/gogo/BUILD.bazel b/test/gogo/BUILD.bazel deleted file mode 100644 index 9da8480..0000000 --- a/test/gogo/BUILD.bazel +++ /dev/null @@ -1,28 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_test") -load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") - -go_proto_library( - name = "gogo_proto", - importpath = "dummy", - protos = [ - "//test:proto2", - "//test:proto3", - "//test:proto3_oneof", - "//test:proto3_map", - ], - compilers = [ - "//:gogo_proto_validators", - "@io_bazel_rules_go//proto:gogo_proto", - ], - visibility = [":__pkg__"] -) - -go_test( - name = "go_default_test", - importpath = "dummy", - srcs = ["validator_test.go"], - embed = [":gogo_proto"], - deps = [ - "@com_github_stretchr_testify//assert:go_default_library", - ], -) diff --git a/test/gogo/validator_test.go b/test/gogo/validator_test.go index f08b865..0e29f6a 100644 --- a/test/gogo/validator_test.go +++ b/test/gogo/validator_test.go @@ -1,4 +1,4 @@ -// Copyright 2016 Michal Witkowski. All Rights Reserved. +/*// Copyright 2016 Michal Witkowski. All Rights Reserved. // See LICENSE for licensing terms. package validatortest @@ -21,7 +21,622 @@ const ( ) func buildProto3(someString string, someInt uint32, identifier string, - someValue int64, someDoubleStrict float64, someFloatStrict float32, someDouble float64, + someValue int64, someDoubleStrict float64, someFloatStrict /*// Copyright 2016 Michal Witkowski. All Rights Reserved. +// See LICENSE for licensing terms. + +package validatortest + +import ( +fmt "fmt" +"strings" +"testing" + +"github.com/stretchr/testify/assert" +) + +var ( +stableBytes = make([]byte, 12) +) + +const ( +uuid4 = "fbe91ff5-fee7-40d3-89a8-f3db6cf210be" +uuid1 = "66bb25e2-2e0d-11e9-b210-d663bd873d93" +) + +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, +optionalUUIDAny, uuid4 string, +someEnum int32, someEmbeddedEnum int32) *ValidatorMessage3 { +goodEmbeddedProto3 := &ValidatorMessage3_EmbeddedMessage{ +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_EmbeddedMessage{goodEmbeddedProto3}, +SomeEmbeddedRepNonNullable: []ValidatorMessage3_EmbeddedMessage{*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{}, + +UUIDAny: optionalUUIDAny, +UUID4NotEmpty: uuid4, + +SomeEnum: EnumProto3(someEnum), +SomeEmbeddedEnum: ValidatorMessage3_EmbeddedEnum(someEmbeddedEnum), + +ValidatorMessage3_EmbeddedMessage: *goodEmbeddedProto3, +} + +goodProto3.Repeated = make([]int32, 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, +optionalUUIDAny, uuid5 string, +someEnum int32, someEmbeddedEnum int32) *ValidatorMessage { +goodEmbeddedProto2 := &ValidatorMessage_EmbeddedMessage{ +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_EmbeddedMessage{goodEmbeddedProto2}, +EmbeddedRepNonNullable: []ValidatorMessage_EmbeddedMessage{*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{}, + +UUIDAny: &optionalUUIDAny, +UUID4NotEmpty: &uuid5, + +SomeEnum: (*EnumProto2)(&someEnum), +SomeEmbeddedEnum: (*ValidatorMessage_EmbeddedEnum)(&someEmbeddedEnum), +} + +goodProto2.Repeated = make([]int32, 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, uuid1, uuid4, 1, 1) +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, uuid1, uuid4, 1, 1) +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, uuid1, uuid4, 0, 0) +if tooLong1Proto3.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, uuid1, uuid4, 0, 0) +if tooLong1Proto2.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, uuid1, uuid4, 0, 0) +if tooLong2Proto3.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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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 TestValueIsInEnum(t *testing.T) { +outOfTopLevelEnumProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 2, 0) +if err := outOfTopLevelEnumProto3.Validate(); err == nil { +t.Fatalf("expected fail in validator, but it didn't happen") +} +outOfTopLevelEnumProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 2, 0) +if err := outOfTopLevelEnumProto2.Validate(); err == nil { +t.Fatalf("expected fail in validator, but it didn't happen") +} +outOfEmbeddedEnumProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 2) +if err := outOfEmbeddedEnumProto3.Validate(); err == nil { +t.Fatalf("expected fail in validator, but it didn't happen") +} +outOfEmbeddedEnumProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 2) +if err := outOfEmbeddedEnumProto2.Validate(); err == nil { +t.Fatalf("expected fail in validator, but it didn't happen") +} +} + +func TestNestedError3(t *testing.T) { +someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) +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, uuid1, uuid4, 0, 0) +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_Required(t *testing.T) { +example := &OneOfMessage3{ +SomeInt: 30, +} +err := example.Validate() +assert.Error(t, err, "oneof.required should fail if none of the oneof fields are set") +assert.Contains(t, err.Error(), "Something", "error must err on the Something field") +} + +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") +} + +func TestOneOf_Regex(t *testing.T) { +example := &OneOfMessage3{ +SomeInt: 30, +Something: &OneOfMessage3_FiveRegex{ +FiveRegex: "11", // fail +}, +} +err := example.Validate() +assert.Error(t, err, "regex applied to oneof field should fail validation on FiveRegex") +assert.Contains(t, err.Error(), "FiveRegex", "error must err on the FiveRegex") + +example = &OneOfMessage3{ +SomeInt: 30, +Something: &OneOfMessage3_FiveRegex{ +FiveRegex: "aaa", // pass +}, +} +err = example.Validate() +assert.NoError(t, err, "This message should pass all validation") +} + +func TestUUID4Validation(t *testing.T) { +testcases := []struct { +uuid string +fail bool +}{ +{ +uuid: uuid1, +fail: true, +}, +{ +uuid: uuid4, +fail: false, +}, +{ +uuid: "", +fail: true, +}, +{ +uuid: "66bb25e2-2e0d", +fail: true, +}, +{ +uuid: "1234abcd", +fail: true, +}, +} + +for _, tc := range testcases { +t.Run(fmt.Sprintf("proto2 uuid '%s'", tc.uuid), func(t *testing.T) { +msg := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, tc.uuid, 0, 0) + +err := msg.Validate() +failed := err != nil +if tc.fail != failed { +t.Errorf("Expected validation failure: %t, but got %t, err: %v", tc.fail, failed, err) +} +}) + +t.Run(fmt.Sprintf("proto3 uuid '%s'", tc.uuid), func(t *testing.T) { +msg := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, tc.uuid, 0, 0) + +err := msg.Validate() +failed := err != nil +if tc.fail != failed { +t.Errorf("Expected validation failure: %t, but got %t, err: %v", tc.fail, failed, err) +} +}) +} +} +*/float32, someDouble float64, someFloat float32, nonEmptyString string, repeatedCount uint32, someStringLength string, someBytes []byte, optionalUUIDAny, uuid4 string, @@ -613,3 +1228,4 @@ func TestUUID4Validation(t *testing.T) { }) } } +*/ \ No newline at end of file diff --git a/test/golang/BUILD.bazel b/test/golang/BUILD.bazel deleted file mode 100644 index 57ffc7b..0000000 --- a/test/golang/BUILD.bazel +++ /dev/null @@ -1,31 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_test") -load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library") - -go_proto_library( - name = "go_proto", - importpath = "dummy", - protos = [ - "//test:proto2", - "//test:proto3", - "//test:proto3_oneof", - "//test:proto3_map", - ], - compilers = [ - "//:go_proto_validators", - "@io_bazel_rules_go//proto:go_proto", - ], - deps = [ - "@com_github_gogo_protobuf//gogoproto:go_default_library", - ], - visibility = [":__pkg__"] -) - -go_test( - name = "go_default_test", - importpath = "dummy", - srcs = ["validator_test.go"], - embed = [":go_proto"], - deps = [ - "@com_github_stretchr_testify//assert:go_default_library", - ], -) diff --git a/test/validator_proto2.pb.go b/test/validator_proto2.pb.go new file mode 100644 index 0000000..92b1b1a --- /dev/null +++ b/test/validator_proto2.pb.go @@ -0,0 +1,694 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: test/validator_proto2.proto + +package validatortest + +import ( + proto "github.com/golang/protobuf/proto" + _ "github.com/mwitkow/go-proto-validators" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type EnumProto2 int32 + +const ( + EnumProto2_alpha2 EnumProto2 = 0 + EnumProto2_beta2 EnumProto2 = 1 +) + +// Enum value maps for EnumProto2. +var ( + EnumProto2_name = map[int32]string{ + 0: "alpha2", + 1: "beta2", + } + EnumProto2_value = map[string]int32{ + "alpha2": 0, + "beta2": 1, + } +) + +func (x EnumProto2) Enum() *EnumProto2 { + p := new(EnumProto2) + *p = x + return p +} + +func (x EnumProto2) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (EnumProto2) Descriptor() protoreflect.EnumDescriptor { + return file_test_validator_proto2_proto_enumTypes[0].Descriptor() +} + +func (EnumProto2) Type() protoreflect.EnumType { + return &file_test_validator_proto2_proto_enumTypes[0] +} + +func (x EnumProto2) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *EnumProto2) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = EnumProto2(num) + return nil +} + +// Deprecated: Use EnumProto2.Descriptor instead. +func (EnumProto2) EnumDescriptor() ([]byte, []int) { + return file_test_validator_proto2_proto_rawDescGZIP(), []int{0} +} + +type ValidatorMessage_EmbeddedEnum int32 + +const ( + ValidatorMessage_zero ValidatorMessage_EmbeddedEnum = 0 + ValidatorMessage_one ValidatorMessage_EmbeddedEnum = 1 +) + +// Enum value maps for ValidatorMessage_EmbeddedEnum. +var ( + ValidatorMessage_EmbeddedEnum_name = map[int32]string{ + 0: "zero", + 1: "one", + } + ValidatorMessage_EmbeddedEnum_value = map[string]int32{ + "zero": 0, + "one": 1, + } +) + +func (x ValidatorMessage_EmbeddedEnum) Enum() *ValidatorMessage_EmbeddedEnum { + p := new(ValidatorMessage_EmbeddedEnum) + *p = x + return p +} + +func (x ValidatorMessage_EmbeddedEnum) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValidatorMessage_EmbeddedEnum) Descriptor() protoreflect.EnumDescriptor { + return file_test_validator_proto2_proto_enumTypes[1].Descriptor() +} + +func (ValidatorMessage_EmbeddedEnum) Type() protoreflect.EnumType { + return &file_test_validator_proto2_proto_enumTypes[1] +} + +func (x ValidatorMessage_EmbeddedEnum) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ValidatorMessage_EmbeddedEnum) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ValidatorMessage_EmbeddedEnum(num) + return nil +} + +// Deprecated: Use ValidatorMessage_EmbeddedEnum.Descriptor instead. +func (ValidatorMessage_EmbeddedEnum) EnumDescriptor() ([]byte, []int) { + return file_test_validator_proto2_proto_rawDescGZIP(), []int{0, 0} +} + +type ValidatorMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StringReq *string `protobuf:"bytes,1,req,name=StringReq" json:"StringReq,omitempty"` + StringOpt *string `protobuf:"bytes,2,opt,name=StringOpt" json:"StringOpt,omitempty"` + StringNoQuotes *string `protobuf:"bytes,3,req,name=StringNoQuotes" json:"StringNoQuotes,omitempty"` + StringUnescaped *string `protobuf:"bytes,4,req,name=StringUnescaped" json:"StringUnescaped,omitempty"` + IntReq *uint32 `protobuf:"varint,5,req,name=IntReq" json:"IntReq,omitempty"` + IntRep []uint32 `protobuf:"varint,6,rep,name=IntRep" json:"IntRep,omitempty"` + EmbeddedReq *ValidatorMessage_EmbeddedMessage `protobuf:"bytes,7,req,name=embeddedReq" json:"embeddedReq,omitempty"` + EmbeddedRep []*ValidatorMessage_EmbeddedMessage `protobuf:"bytes,8,rep,name=embeddedRep" json:"embeddedRep,omitempty"` + CustomErrorInt *int32 `protobuf:"varint,9,opt,name=CustomErrorInt" json:"CustomErrorInt,omitempty"` + StrictSomeDoubleReq *float64 `protobuf:"fixed64,10,req,name=StrictSomeDoubleReq" json:"StrictSomeDoubleReq,omitempty"` + StrictSomeDoubleRep []float64 `protobuf:"fixed64,11,rep,name=StrictSomeDoubleRep" json:"StrictSomeDoubleRep,omitempty"` + StrictSomeFloatReq *float32 `protobuf:"fixed32,12,req,name=StrictSomeFloatReq" json:"StrictSomeFloatReq,omitempty"` + StrictSomeFloatRep []float32 `protobuf:"fixed32,13,rep,name=StrictSomeFloatRep" json:"StrictSomeFloatRep,omitempty"` + SomeDoubleReq *float64 `protobuf:"fixed64,14,req,name=SomeDoubleReq" json:"SomeDoubleReq,omitempty"` + SomeDoubleRep []float64 `protobuf:"fixed64,15,rep,name=SomeDoubleRep" json:"SomeDoubleRep,omitempty"` + SomeFloatReq *float32 `protobuf:"fixed32,16,req,name=SomeFloatReq" json:"SomeFloatReq,omitempty"` + SomeFloatRep []float32 `protobuf:"fixed32,17,rep,name=SomeFloatRep" json:"SomeFloatRep,omitempty"` + SomeNonEmptyString *string `protobuf:"bytes,18,req,name=SomeNonEmptyString" json:"SomeNonEmptyString,omitempty"` + RepeatedBaseType []int32 `protobuf:"varint,19,rep,name=RepeatedBaseType" json:"RepeatedBaseType,omitempty"` + Repeated []int32 `protobuf:"varint,20,rep,name=Repeated" json:"Repeated,omitempty"` + SomeStringLtReq *string `protobuf:"bytes,21,opt,name=SomeStringLtReq" json:"SomeStringLtReq,omitempty"` + SomeStringGtReq *string `protobuf:"bytes,22,opt,name=SomeStringGtReq" json:"SomeStringGtReq,omitempty"` + SomeStringEqReq *string `protobuf:"bytes,23,opt,name=SomeStringEqReq" json:"SomeStringEqReq,omitempty"` + SomeBytesLtReq []byte `protobuf:"bytes,24,opt,name=SomeBytesLtReq" json:"SomeBytesLtReq,omitempty"` + SomeBytesGtReq []byte `protobuf:"bytes,25,opt,name=SomeBytesGtReq" json:"SomeBytesGtReq,omitempty"` + SomeBytesEqReq []byte `protobuf:"bytes,26,opt,name=SomeBytesEqReq" json:"SomeBytesEqReq,omitempty"` + UUIDAny *string `protobuf:"bytes,27,opt,name=UUIDAny" json:"UUIDAny,omitempty"` + UUID4NotEmpty *string `protobuf:"bytes,28,req,name=UUID4NotEmpty" json:"UUID4NotEmpty,omitempty"` + SomeEnum *EnumProto2 `protobuf:"varint,29,req,name=someEnum,enum=validatortest.EnumProto2" json:"someEnum,omitempty"` + SomeEmbeddedEnum *ValidatorMessage_EmbeddedEnum `protobuf:"varint,30,req,name=someEmbeddedEnum,enum=validatortest.ValidatorMessage_EmbeddedEnum" json:"someEmbeddedEnum,omitempty"` +} + +func (x *ValidatorMessage) Reset() { + *x = ValidatorMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto2_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorMessage) ProtoMessage() {} + +func (x *ValidatorMessage) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto2_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorMessage.ProtoReflect.Descriptor instead. +func (*ValidatorMessage) Descriptor() ([]byte, []int) { + return file_test_validator_proto2_proto_rawDescGZIP(), []int{0} +} + +func (x *ValidatorMessage) GetStringReq() string { + if x != nil && x.StringReq != nil { + return *x.StringReq + } + return "" +} + +func (x *ValidatorMessage) GetStringOpt() string { + if x != nil && x.StringOpt != nil { + return *x.StringOpt + } + return "" +} + +func (x *ValidatorMessage) GetStringNoQuotes() string { + if x != nil && x.StringNoQuotes != nil { + return *x.StringNoQuotes + } + return "" +} + +func (x *ValidatorMessage) GetStringUnescaped() string { + if x != nil && x.StringUnescaped != nil { + return *x.StringUnescaped + } + return "" +} + +func (x *ValidatorMessage) GetIntReq() uint32 { + if x != nil && x.IntReq != nil { + return *x.IntReq + } + return 0 +} + +func (x *ValidatorMessage) GetIntRep() []uint32 { + if x != nil { + return x.IntRep + } + return nil +} + +func (x *ValidatorMessage) GetEmbeddedReq() *ValidatorMessage_EmbeddedMessage { + if x != nil { + return x.EmbeddedReq + } + return nil +} + +func (x *ValidatorMessage) GetEmbeddedRep() []*ValidatorMessage_EmbeddedMessage { + if x != nil { + return x.EmbeddedRep + } + return nil +} + +func (x *ValidatorMessage) GetCustomErrorInt() int32 { + if x != nil && x.CustomErrorInt != nil { + return *x.CustomErrorInt + } + return 0 +} + +func (x *ValidatorMessage) GetStrictSomeDoubleReq() float64 { + if x != nil && x.StrictSomeDoubleReq != nil { + return *x.StrictSomeDoubleReq + } + return 0 +} + +func (x *ValidatorMessage) GetStrictSomeDoubleRep() []float64 { + if x != nil { + return x.StrictSomeDoubleRep + } + return nil +} + +func (x *ValidatorMessage) GetStrictSomeFloatReq() float32 { + if x != nil && x.StrictSomeFloatReq != nil { + return *x.StrictSomeFloatReq + } + return 0 +} + +func (x *ValidatorMessage) GetStrictSomeFloatRep() []float32 { + if x != nil { + return x.StrictSomeFloatRep + } + return nil +} + +func (x *ValidatorMessage) GetSomeDoubleReq() float64 { + if x != nil && x.SomeDoubleReq != nil { + return *x.SomeDoubleReq + } + return 0 +} + +func (x *ValidatorMessage) GetSomeDoubleRep() []float64 { + if x != nil { + return x.SomeDoubleRep + } + return nil +} + +func (x *ValidatorMessage) GetSomeFloatReq() float32 { + if x != nil && x.SomeFloatReq != nil { + return *x.SomeFloatReq + } + return 0 +} + +func (x *ValidatorMessage) GetSomeFloatRep() []float32 { + if x != nil { + return x.SomeFloatRep + } + return nil +} + +func (x *ValidatorMessage) GetSomeNonEmptyString() string { + if x != nil && x.SomeNonEmptyString != nil { + return *x.SomeNonEmptyString + } + return "" +} + +func (x *ValidatorMessage) GetRepeatedBaseType() []int32 { + if x != nil { + return x.RepeatedBaseType + } + return nil +} + +func (x *ValidatorMessage) GetRepeated() []int32 { + if x != nil { + return x.Repeated + } + return nil +} + +func (x *ValidatorMessage) GetSomeStringLtReq() string { + if x != nil && x.SomeStringLtReq != nil { + return *x.SomeStringLtReq + } + return "" +} + +func (x *ValidatorMessage) GetSomeStringGtReq() string { + if x != nil && x.SomeStringGtReq != nil { + return *x.SomeStringGtReq + } + return "" +} + +func (x *ValidatorMessage) GetSomeStringEqReq() string { + if x != nil && x.SomeStringEqReq != nil { + return *x.SomeStringEqReq + } + return "" +} + +func (x *ValidatorMessage) GetSomeBytesLtReq() []byte { + if x != nil { + return x.SomeBytesLtReq + } + return nil +} + +func (x *ValidatorMessage) GetSomeBytesGtReq() []byte { + if x != nil { + return x.SomeBytesGtReq + } + return nil +} + +func (x *ValidatorMessage) GetSomeBytesEqReq() []byte { + if x != nil { + return x.SomeBytesEqReq + } + return nil +} + +func (x *ValidatorMessage) GetUUIDAny() string { + if x != nil && x.UUIDAny != nil { + return *x.UUIDAny + } + return "" +} + +func (x *ValidatorMessage) GetUUID4NotEmpty() string { + if x != nil && x.UUID4NotEmpty != nil { + return *x.UUID4NotEmpty + } + return "" +} + +func (x *ValidatorMessage) GetSomeEnum() EnumProto2 { + if x != nil && x.SomeEnum != nil { + return *x.SomeEnum + } + return EnumProto2_alpha2 +} + +func (x *ValidatorMessage) GetSomeEmbeddedEnum() ValidatorMessage_EmbeddedEnum { + if x != nil && x.SomeEmbeddedEnum != nil { + return *x.SomeEmbeddedEnum + } + return ValidatorMessage_zero +} + +type ValidatorMessage_EmbeddedMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identifier *string `protobuf:"bytes,1,opt,name=Identifier" json:"Identifier,omitempty"` + SomeValue *int64 `protobuf:"varint,2,req,name=SomeValue" json:"SomeValue,omitempty"` +} + +func (x *ValidatorMessage_EmbeddedMessage) Reset() { + *x = ValidatorMessage_EmbeddedMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto2_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorMessage_EmbeddedMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorMessage_EmbeddedMessage) ProtoMessage() {} + +func (x *ValidatorMessage_EmbeddedMessage) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto2_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorMessage_EmbeddedMessage.ProtoReflect.Descriptor instead. +func (*ValidatorMessage_EmbeddedMessage) Descriptor() ([]byte, []int) { + return file_test_validator_proto2_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *ValidatorMessage_EmbeddedMessage) GetIdentifier() string { + if x != nil && x.Identifier != nil { + return *x.Identifier + } + return "" +} + +func (x *ValidatorMessage_EmbeddedMessage) GetSomeValue() int64 { + if x != nil && x.SomeValue != nil { + return *x.SomeValue + } + return 0 +} + +var File_test_validator_proto2_proto protoreflect.FileDescriptor + +var file_test_validator_proto2_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, + 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa8, 0x0f, 0x0a, 0x10, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x42, 0x0e, 0xe2, + 0xdf, 0x1f, 0x0a, 0x0a, 0x08, 0x5e, 0x2e, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, 0x09, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x12, 0x2c, 0x0a, 0x09, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x4f, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0e, 0xe2, 0xdf, 0x1f, + 0x0a, 0x0a, 0x08, 0x5e, 0x2e, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, 0x09, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x74, 0x12, 0x39, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x4e, 0x6f, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x02, 0x28, 0x09, 0x42, 0x11, + 0xe2, 0xdf, 0x1f, 0x0d, 0x0a, 0x0b, 0x5e, 0x5b, 0x5e, 0x22, 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, + 0x24, 0x52, 0x0e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x51, 0x75, 0x6f, 0x74, 0x65, + 0x73, 0x12, 0x61, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x65, 0x73, 0x63, + 0x61, 0x70, 0x65, 0x64, 0x18, 0x04, 0x20, 0x02, 0x28, 0x09, 0x42, 0x37, 0xe2, 0xdf, 0x1f, 0x33, + 0x0a, 0x31, 0x5b, 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5c, 0x70, 0x7b, 0x4e, 0x7d, 0x5d, 0x28, 0x7b, + 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5c, 0x70, 0x7b, 0x4e, 0x7d, 0x5f, 0x2d, 0x20, 0x5d, 0x7b, 0x30, + 0x2c, 0x32, 0x38, 0x7d, 0x5b, 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5c, 0x70, 0x7b, 0x4e, 0x7d, 0x5d, + 0x29, 0x3f, 0x2e, 0x52, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x65, 0x73, 0x63, + 0x61, 0x70, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x06, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x18, 0x05, + 0x20, 0x02, 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x0a, 0x52, 0x06, 0x49, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x12, 0x1e, 0x0a, 0x06, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x0a, 0x52, 0x06, 0x49, 0x6e, + 0x74, 0x52, 0x65, 0x70, 0x12, 0x51, 0x0a, 0x0b, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, + 0x52, 0x65, 0x71, 0x18, 0x07, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x65, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x65, 0x64, 0x52, 0x65, 0x71, 0x12, 0x51, 0x0a, 0x0b, 0x65, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x52, 0x65, 0x70, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x6d, + 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x65, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x65, 0x70, 0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x05, 0x42, 0x17, 0xe2, 0xdf, 0x1f, 0x13, 0x10, 0x0a, 0x2a, 0x0f, 0x4d, 0x79, 0x20, 0x43, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x0e, 0x43, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x74, 0x12, 0x51, 0x0a, 0x13, 0x53, + 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x18, 0x0a, 0x20, 0x02, 0x28, 0x01, 0x42, 0x1f, 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, + 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, 0x13, 0x53, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x12, 0x51, + 0x0a, 0x13, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x52, 0x65, 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x01, 0x42, 0x1f, 0xe2, 0xdf, 0x1f, + 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, + 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, 0x13, 0x53, 0x74, + 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, + 0x70, 0x12, 0x4f, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x71, 0x18, 0x0c, 0x20, 0x02, 0x28, 0x02, 0x42, 0x1f, 0xe2, + 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, 0xcc, + 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, 0x12, + 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, + 0x65, 0x71, 0x12, 0x4f, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x02, 0x42, 0x1f, + 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, + 0x12, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, + 0x52, 0x65, 0x70, 0x12, 0x3c, 0x0a, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, + 0x65, 0x52, 0x65, 0x71, 0x18, 0x0e, 0x20, 0x02, 0x28, 0x01, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, + 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x3f, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe8, 0x3f, 0x52, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, + 0x71, 0x12, 0x3c, 0x0a, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, + 0x65, 0x70, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x01, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, 0x49, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x3f, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3f, + 0x52, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x12, + 0x3a, 0x0a, 0x0c, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x71, 0x18, + 0x10, 0x20, 0x02, 0x28, 0x02, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, 0x49, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0x3f, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3f, 0x52, 0x0c, 0x53, + 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x71, 0x12, 0x3a, 0x0a, 0x0c, 0x53, + 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x18, 0x11, 0x20, 0x03, 0x28, + 0x02, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x3f, + 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3f, 0x52, 0x0c, 0x53, 0x6f, 0x6d, 0x65, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x12, 0x36, 0x0a, 0x12, 0x53, 0x6f, 0x6d, 0x65, 0x4e, + 0x6f, 0x6e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x12, 0x20, + 0x02, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x12, 0x53, 0x6f, 0x6d, + 0x65, 0x4e, 0x6f, 0x6e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, + 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x13, 0x20, 0x03, 0x28, 0x05, 0x52, 0x10, 0x52, 0x65, 0x70, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x08, 0x52, + 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x14, 0x20, 0x03, 0x28, 0x05, 0x42, 0x08, 0xe2, + 0xdf, 0x1f, 0x04, 0x60, 0x02, 0x68, 0x05, 0x52, 0x08, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, + 0x74, 0x52, 0x65, 0x71, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, + 0x70, 0x02, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x74, + 0x52, 0x65, 0x71, 0x12, 0x30, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x47, 0x74, 0x52, 0x65, 0x71, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, + 0x1f, 0x02, 0x78, 0x0c, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x47, 0x74, 0x52, 0x65, 0x71, 0x12, 0x31, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x45, 0x71, 0x52, 0x65, 0x71, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xe2, 0xdf, 0x1f, 0x03, 0x80, 0x01, 0x0a, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x45, 0x71, 0x52, 0x65, 0x71, 0x12, 0x2e, 0x0a, 0x0e, 0x53, 0x6f, 0x6d, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x4c, 0x74, 0x52, 0x65, 0x71, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x70, 0x05, 0x52, 0x0e, 0x53, 0x6f, 0x6d, 0x65, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x4c, 0x74, 0x52, 0x65, 0x71, 0x12, 0x2e, 0x0a, 0x0e, 0x53, 0x6f, 0x6d, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x47, 0x74, 0x52, 0x65, 0x71, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x78, 0x14, 0x52, 0x0e, 0x53, 0x6f, 0x6d, 0x65, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x47, 0x74, 0x52, 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x0e, 0x53, 0x6f, 0x6d, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x45, 0x71, 0x52, 0x65, 0x71, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0c, + 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x80, 0x01, 0x0c, 0x52, 0x0e, 0x53, 0x6f, 0x6d, 0x65, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x45, 0x71, 0x52, 0x65, 0x71, 0x12, 0x21, 0x0a, 0x07, 0x55, 0x55, 0x49, + 0x44, 0x41, 0x6e, 0x79, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, + 0x90, 0x01, 0x00, 0x52, 0x07, 0x55, 0x55, 0x49, 0x44, 0x41, 0x6e, 0x79, 0x12, 0x2d, 0x0a, 0x0d, + 0x55, 0x55, 0x49, 0x44, 0x34, 0x4e, 0x6f, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x1c, 0x20, + 0x02, 0x28, 0x09, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x90, 0x01, 0x04, 0x52, 0x0d, 0x55, 0x55, + 0x49, 0x44, 0x34, 0x4e, 0x6f, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x08, 0x73, + 0x6f, 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x18, 0x1d, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x19, 0x2e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x6e, + 0x75, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x88, 0x01, + 0x01, 0x52, 0x08, 0x73, 0x6f, 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x61, 0x0a, 0x10, 0x73, + 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x18, + 0x1e, 0x20, 0x02, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, + 0x6e, 0x75, 0x6d, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x88, 0x01, 0x01, 0x52, 0x10, 0x73, 0x6f, + 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x1a, 0x6d, + 0x0a, 0x0f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x32, 0x0a, 0x0a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x12, 0xe2, 0xdf, 0x1f, 0x0e, 0x0a, 0x0c, 0x5e, 0x5b, 0x61, + 0x2d, 0x7a, 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, 0x0a, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x09, 0x53, 0x6f, 0x6d, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x02, 0x28, 0x03, 0x42, 0x08, 0xe2, 0xdf, 0x1f, 0x04, 0x10, 0x00, + 0x18, 0x64, 0x52, 0x09, 0x53, 0x6f, 0x6d, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x21, 0x0a, + 0x0c, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x08, 0x0a, + 0x04, 0x7a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x6f, 0x6e, 0x65, 0x10, 0x01, + 0x2a, 0x23, 0x0a, 0x0a, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x12, 0x0a, + 0x0a, 0x06, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x62, 0x65, + 0x74, 0x61, 0x32, 0x10, 0x01, +} + +var ( + file_test_validator_proto2_proto_rawDescOnce sync.Once + file_test_validator_proto2_proto_rawDescData = file_test_validator_proto2_proto_rawDesc +) + +func file_test_validator_proto2_proto_rawDescGZIP() []byte { + file_test_validator_proto2_proto_rawDescOnce.Do(func() { + file_test_validator_proto2_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_validator_proto2_proto_rawDescData) + }) + return file_test_validator_proto2_proto_rawDescData +} + +var file_test_validator_proto2_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_test_validator_proto2_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_test_validator_proto2_proto_goTypes = []interface{}{ + (EnumProto2)(0), // 0: validatortest.EnumProto2 + (ValidatorMessage_EmbeddedEnum)(0), // 1: validatortest.ValidatorMessage.EmbeddedEnum + (*ValidatorMessage)(nil), // 2: validatortest.ValidatorMessage + (*ValidatorMessage_EmbeddedMessage)(nil), // 3: validatortest.ValidatorMessage.EmbeddedMessage +} +var file_test_validator_proto2_proto_depIdxs = []int32{ + 3, // 0: validatortest.ValidatorMessage.embeddedReq:type_name -> validatortest.ValidatorMessage.EmbeddedMessage + 3, // 1: validatortest.ValidatorMessage.embeddedRep:type_name -> validatortest.ValidatorMessage.EmbeddedMessage + 0, // 2: validatortest.ValidatorMessage.someEnum:type_name -> validatortest.EnumProto2 + 1, // 3: validatortest.ValidatorMessage.someEmbeddedEnum:type_name -> validatortest.ValidatorMessage.EmbeddedEnum + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name +} + +func init() { file_test_validator_proto2_proto_init() } +func file_test_validator_proto2_proto_init() { + if File_test_validator_proto2_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_validator_proto2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_validator_proto2_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorMessage_EmbeddedMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_validator_proto2_proto_rawDesc, + NumEnums: 2, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_validator_proto2_proto_goTypes, + DependencyIndexes: file_test_validator_proto2_proto_depIdxs, + EnumInfos: file_test_validator_proto2_proto_enumTypes, + MessageInfos: file_test_validator_proto2_proto_msgTypes, + }.Build() + File_test_validator_proto2_proto = out.File + file_test_validator_proto2_proto_rawDesc = nil + file_test_validator_proto2_proto_goTypes = nil + file_test_validator_proto2_proto_depIdxs = nil +} diff --git a/test/validator_proto2.proto b/test/validator_proto2.proto index 7f56035..fe06169 100644 --- a/test/validator_proto2.proto +++ b/test/validator_proto2.proto @@ -4,96 +4,100 @@ syntax = "proto2"; package validatortest; -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; -import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/mwitkow/go-proto-validators/validators.proto"; // Top-level enum type definition. enum EnumProto2 { - alpha2 = 0; - beta2 = 1; + alpha2 = 0; + beta2 = 1; } message ValidatorMessage { - // Embedded message test structure. - message EmbeddedMessage { - optional string Identifier = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; - required int64 SomeValue = 2 [(validator.field) = {int_gt: 0, int_lt: 100}]; - } - - // Embedded enum type definition. - enum EmbeddedEnum { - zero = 0; - one = 1; - } - - // 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 EmbeddedMessage embeddedReq = 10; - required EmbeddedMessage embeddedNonNull = 11 [(gogoproto.nullable) = false]; - repeated EmbeddedMessage embeddedRep = 12; - repeated EmbeddedMessage 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}]; - - optional string UUIDAny = 42 [(validator.field) = {uuid_ver: 0}]; - required string UUID4NotEmpty = 43 [(validator.field) = {uuid_ver: 4, string_not_empty: true}]; - - // Enum tests. - required EnumProto2 someEnum = 44 [(validator.field) = {is_in_enum: true}]; - required EmbeddedEnum someEmbeddedEnum = 45 [(validator.field) = {is_in_enum: true}]; - - // gogo embedded tests. - required EmbeddedMessage someGogoEmbedded = 46 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (gogoproto.jsontag) = ",inline"]; + // Embedded message test structure. + message EmbeddedMessage { + optional string Identifier = 1 + [ (validator.field) = {regex : "^[a-z]{2,5}$"} ]; + required int64 SomeValue = 2 + [ (validator.field) = {int_gt : 0, int_lt : 100} ]; + } + + // Embedded enum type definition. + enum EmbeddedEnum { + zero = 0; + one = 1; + } + + // String regex constraint tests. + required string StringReq = 1 [ (validator.field) = {regex : "^.{2,5}$"} ]; + optional string StringOpt = 2 [ (validator.field) = {regex : "^.{2,5}$"} ]; + required string StringNoQuotes = 3 + [ (validator.field) = {regex : "^[^\"]{2,5}$"} ]; + required string StringUnescaped = 4 [ (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 = 5 [ (validator.field) = {int_gt : 10} ]; + repeated uint32 IntRep = 6 [ (validator.field) = {int_gt : 10} ]; + + // Embedded message recursive constraint tests. + required EmbeddedMessage embeddedReq = 7; + repeated EmbeddedMessage embeddedRep = 8; + + // Custom error tests. + optional int32 CustomErrorInt = 9 + [ (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 = 10 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + repeated double StrictSomeDoubleRep = 11 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + required float StrictSomeFloatReq = 12 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + repeated float StrictSomeFloatRep = 13 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + + // Non-strict floating-point inequality constraint tests. + required double SomeDoubleReq = 14 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + repeated double SomeDoubleRep = 15 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + required float SomeFloatReq = 16 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + repeated float SomeFloatRep = 17 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + + // String not-empty constraint tests. + required string SomeNonEmptyString = 18 + [ (validator.field) = {string_not_empty : true} ]; + + // Repeated base-type without constraint tests. + repeated int32 RepeatedBaseType = 19; + + // Repeated element count constraint tests. + repeated int32 Repeated = 20 + [ (validator.field) = {repeated_count_min : 2, repeated_count_max : 5} ]; + + optional string SomeStringLtReq = 21 [ (validator.field) = {length_gt : 2} ]; + optional string SomeStringGtReq = 22 [ (validator.field) = {length_lt : 12} ]; + optional string SomeStringEqReq = 23 [ (validator.field) = {length_eq : 10} ]; + optional bytes SomeBytesLtReq = 24 [ (validator.field) = {length_gt : 5} ]; + optional bytes SomeBytesGtReq = 25 [ (validator.field) = {length_lt : 20} ]; + optional bytes SomeBytesEqReq = 26 [ (validator.field) = {length_eq : 12} ]; + + optional string UUIDAny = 27 [ (validator.field) = {uuid_ver : 0} ]; + required string UUID4NotEmpty = 28 [ (validator.field) = {uuid_ver : 4} ]; + + // Enum tests. + required EnumProto2 someEnum = 29 [ (validator.field) = {is_in_enum : true} ]; + required EmbeddedEnum someEmbeddedEnum = 30 + [ (validator.field) = {is_in_enum : true} ]; } diff --git a/test/validator_proto2.validator.pb.go b/test/validator_proto2.validator.pb.go new file mode 100644 index 0000000..f702e50 --- /dev/null +++ b/test/validator_proto2.validator.pb.go @@ -0,0 +1,218 @@ +// Code generated by protoc-gen-govalidators. DO NOT EDIT. + +package validatortest + +import ( + errors "errors" + fmt "fmt" + go_proto_validators "github.com/mwitkow/go-proto-validators" + regexp "regexp" +) + +var ValidatorMessage_EmbeddedMessageIdentifierRE = regexp.MustCompile(`^[a-z]{2,5}$`) + +func (m *ValidatorMessage_EmbeddedMessage) Validate() error { + if m.Identifier != nil { + if !ValidatorMessage_EmbeddedMessageIdentifierRE.MatchString(string(m.GetIdentifier())) { + return go_proto_validators.FieldError("Identifier", errors.New(`Identifier should match regular expression "^[a-z]{2,5}$"`)) + } + } + + if m.GetSomeValue() <= 0 { + return go_proto_validators.FieldError("SomeValue", errors.New("SomeValue is not greater than 0")) + } + if m.GetSomeValue() >= 100 { + return go_proto_validators.FieldError("SomeValue", errors.New("SomeValue is not smaller than 100")) + } + + return nil +} + +var ValidatorMessageStringReqRE = regexp.MustCompile(`^.{2,5}$`) +var ValidatorMessageStringOptRE = regexp.MustCompile(`^.{2,5}$`) +var ValidatorMessageStringNoQuotesRE = regexp.MustCompile(`^[^"]{2,5}$`) +var ValidatorMessageStringUnescapedRE = regexp.MustCompile(`[\p{L}\p{N}]({\p{L}\p{N}_- ]{0,28}[\p{L}\p{N}])?.`) +var ValidatorMessageUUIDAnyRE = regexp.MustCompile(`^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$`) +var ValidatorMessageUUID4NotEmptyRE = regexp.MustCompile(`^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$`) + +func (m *ValidatorMessage) Validate() error { + if !ValidatorMessageStringReqRE.MatchString(string(m.GetStringReq())) { + return go_proto_validators.FieldError("StringReq", errors.New(`StringReq should match regular expression "^.{2,5}$"`)) + } + + if m.StringOpt != nil { + if !ValidatorMessageStringOptRE.MatchString(string(m.GetStringOpt())) { + return go_proto_validators.FieldError("StringOpt", errors.New(`StringOpt should match regular expression "^.{2,5}$"`)) + } + } + + if !ValidatorMessageStringNoQuotesRE.MatchString(string(m.GetStringNoQuotes())) { + return go_proto_validators.FieldError("StringNoQuotes", errors.New(`StringNoQuotes should match regular expression "^[^\"]{2,5}$"`)) + } + + if !ValidatorMessageStringUnescapedRE.MatchString(string(m.GetStringUnescaped())) { + return go_proto_validators.FieldError("StringUnescaped", errors.New(`StringUnescaped should match regular expression "[\\p{L}\\p{N}]({\\p{L}\\p{N}_- ]{0,28}[\\p{L}\\p{N}])?."`)) + } + + if m.GetIntReq() <= 10 { + return go_proto_validators.FieldError("IntReq", errors.New("IntReq is not greater than 10")) + } + + for _, item := range m.GetIntRep() { + if item <= 10 { + return go_proto_validators.FieldError("IntRep", errors.New("IntRep is not greater than 10")) + } + } + + if m.GetEmbeddedReq() != nil { + if err := go_proto_validators.CallValidatorIfExists(m.GetEmbeddedReq()); err != nil { + return go_proto_validators.FieldError("EmbeddedReq", err) + } + } + + for _, item := range m.GetEmbeddedRep() { + if item != nil { + if err := go_proto_validators.CallValidatorIfExists(item); err != nil { + return go_proto_validators.FieldError("EmbeddedRep", err) + } + } + } + + if m.CustomErrorInt != nil { + if m.GetCustomErrorInt() <= 10 { + return go_proto_validators.FieldError("CustomErrorInt", errors.New("My Custom Error")) + } + } + + if m.GetStrictSomeDoubleReq() <= 0.3 { + return go_proto_validators.FieldError("StrictSomeDoubleReq", errors.New("StrictSomeDoubleReq is not greater than 0.3")) + } + if m.GetStrictSomeDoubleReq() >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeDoubleReq", errors.New("StrictSomeDoubleReq is not smaller than 0.7000000000000001")) + } + + for _, item := range m.GetStrictSomeDoubleRep() { + if item <= 0.3 { + return go_proto_validators.FieldError("StrictSomeDoubleRep", errors.New("StrictSomeDoubleRep is not greater than 0.3")) + } + if item >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeDoubleRep", errors.New("StrictSomeDoubleRep is not smaller than 0.7000000000000001")) + } + } + + if m.GetStrictSomeFloatReq() <= 0.3 { + return go_proto_validators.FieldError("StrictSomeFloatReq", errors.New("StrictSomeFloatReq is not greater than 0.3")) + } + if m.GetStrictSomeFloatReq() >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeFloatReq", errors.New("StrictSomeFloatReq is not smaller than 0.7000000000000001")) + } + + for _, item := range m.GetStrictSomeFloatRep() { + if item <= 0.3 { + return go_proto_validators.FieldError("StrictSomeFloatRep", errors.New("StrictSomeFloatRep is not greater than 0.3")) + } + if item >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeFloatRep", errors.New("StrictSomeFloatRep is not smaller than 0.7000000000000001")) + } + } + + if m.GetSomeDoubleReq() < 0.25 { + return go_proto_validators.FieldError("SomeDoubleReq", errors.New("SomeDoubleReq is not greater than or equal to 0.25")) + } + if m.GetSomeDoubleReq() > 0.75 { + return go_proto_validators.FieldError("SomeDoubleReq", errors.New("SomeDoubleReq is not smaller than or equal to 0.75")) + } + + for _, item := range m.GetSomeDoubleRep() { + if item < 0.25 { + return go_proto_validators.FieldError("SomeDoubleRep", errors.New("SomeDoubleRep is not greater than or equal to 0.25")) + } + if item > 0.75 { + return go_proto_validators.FieldError("SomeDoubleRep", errors.New("SomeDoubleRep is not smaller than or equal to 0.75")) + } + } + + if m.GetSomeFloatReq() < 0.25 { + return go_proto_validators.FieldError("SomeFloatReq", errors.New("SomeFloatReq is not greater than or equal to 0.25")) + } + if m.GetSomeFloatReq() > 0.75 { + return go_proto_validators.FieldError("SomeFloatReq", errors.New("SomeFloatReq is not smaller than or equal to 0.75")) + } + + for _, item := range m.GetSomeFloatRep() { + if item < 0.25 { + return go_proto_validators.FieldError("SomeFloatRep", errors.New("SomeFloatRep is not greater than or equal to 0.25")) + } + if item > 0.75 { + return go_proto_validators.FieldError("SomeFloatRep", errors.New("SomeFloatRep is not smaller than or equal to 0.75")) + } + } + + if string(m.GetSomeNonEmptyString()) == "" { + return go_proto_validators.FieldError("SomeNonEmptyString", errors.New("SomeNonEmptyString should not be empty")) + } + + if len(m.GetRepeated()) > 5 { + return go_proto_validators.FieldError("Repeated", fmt.Errorf("Repeated has %d elements whereas a maximum of 5 is allowed", len(m.GetRepeated()))) + } + + if len(m.GetRepeated()) < 2 { + return go_proto_validators.FieldError("Repeated", fmt.Errorf("Repeated has %d elements whereas a minimum of 2 is required", len(m.GetRepeated()))) + } + + if m.SomeStringLtReq != nil { + if len(m.GetSomeStringLtReq()) <= 2 { + return go_proto_validators.FieldError("SomeStringLtReq", errors.New("SomeStringLtReq should have a length greater than 2")) + } + } + + if m.SomeStringGtReq != nil { + if len(m.GetSomeStringGtReq()) >= 12 { + return go_proto_validators.FieldError("SomeStringGtReq", errors.New("SomeStringGtReq should have a length smaller than 12")) + } + } + + if m.SomeStringEqReq != nil { + if len(m.GetSomeStringEqReq()) != 10 { + return go_proto_validators.FieldError("SomeStringEqReq", errors.New("SomeStringEqReq should be of length 10")) + } + } + + if m.SomeBytesLtReq != nil { + if len(m.GetSomeBytesLtReq()) <= 5 { + return go_proto_validators.FieldError("SomeBytesLtReq", errors.New("SomeBytesLtReq should have a length greater than 5")) + } + } + + if m.SomeBytesGtReq != nil { + if len(m.GetSomeBytesGtReq()) >= 20 { + return go_proto_validators.FieldError("SomeBytesGtReq", errors.New("SomeBytesGtReq should have a length smaller than 20")) + } + } + + if m.SomeBytesEqReq != nil { + if len(m.GetSomeBytesEqReq()) != 12 { + return go_proto_validators.FieldError("SomeBytesEqReq", errors.New("SomeBytesEqReq should be of length 12")) + } + } + + if m.UUIDAny != nil { + if !ValidatorMessageUUIDAnyRE.MatchString(string(m.GetUUIDAny())) { + return go_proto_validators.FieldError("UUIDAny", errors.New("UUIDAny should match regular expression '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[0][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$'")) + } + } + + if !ValidatorMessageUUID4NotEmptyRE.MatchString(string(m.GetUUID4NotEmpty())) { + return go_proto_validators.FieldError("UUID4NotEmpty", errors.New("UUID4NotEmpty should match regular expression '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$'")) + } + + if _, ok := EnumProto2_name[int32(m.GetSomeEnum())]; !ok { + return go_proto_validators.FieldError("SomeEnum", errors.New("someEnum should correspond to a valid enum value")) + } + + if _, ok := ValidatorMessage_EmbeddedEnum_name[int32(m.GetSomeEmbeddedEnum())]; !ok { + return go_proto_validators.FieldError("SomeEmbeddedEnum", errors.New("someEmbeddedEnum should correspond to a valid enum value")) + } + + return nil +} diff --git a/test/validator_proto3.pb.go b/test/validator_proto3.pb.go new file mode 100644 index 0000000..42da7a9 --- /dev/null +++ b/test/validator_proto3.pb.go @@ -0,0 +1,720 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: test/validator_proto3.proto + +package validatortest + +import ( + proto "github.com/golang/protobuf/proto" + _ "github.com/mwitkow/go-proto-validators" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type EnumProto3 int32 + +const ( + EnumProto3_alpha3 EnumProto3 = 0 + EnumProto3_beta3 EnumProto3 = 1 +) + +// Enum value maps for EnumProto3. +var ( + EnumProto3_name = map[int32]string{ + 0: "alpha3", + 1: "beta3", + } + EnumProto3_value = map[string]int32{ + "alpha3": 0, + "beta3": 1, + } +) + +func (x EnumProto3) Enum() *EnumProto3 { + p := new(EnumProto3) + *p = x + return p +} + +func (x EnumProto3) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (EnumProto3) Descriptor() protoreflect.EnumDescriptor { + return file_test_validator_proto3_proto_enumTypes[0].Descriptor() +} + +func (EnumProto3) Type() protoreflect.EnumType { + return &file_test_validator_proto3_proto_enumTypes[0] +} + +func (x EnumProto3) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use EnumProto3.Descriptor instead. +func (EnumProto3) EnumDescriptor() ([]byte, []int) { + return file_test_validator_proto3_proto_rawDescGZIP(), []int{0} +} + +type ValidatorMessage3_EmbeddedEnum int32 + +const ( + ValidatorMessage3_zero ValidatorMessage3_EmbeddedEnum = 0 + ValidatorMessage3_one ValidatorMessage3_EmbeddedEnum = 1 +) + +// Enum value maps for ValidatorMessage3_EmbeddedEnum. +var ( + ValidatorMessage3_EmbeddedEnum_name = map[int32]string{ + 0: "zero", + 1: "one", + } + ValidatorMessage3_EmbeddedEnum_value = map[string]int32{ + "zero": 0, + "one": 1, + } +) + +func (x ValidatorMessage3_EmbeddedEnum) Enum() *ValidatorMessage3_EmbeddedEnum { + p := new(ValidatorMessage3_EmbeddedEnum) + *p = x + return p +} + +func (x ValidatorMessage3_EmbeddedEnum) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ValidatorMessage3_EmbeddedEnum) Descriptor() protoreflect.EnumDescriptor { + return file_test_validator_proto3_proto_enumTypes[1].Descriptor() +} + +func (ValidatorMessage3_EmbeddedEnum) Type() protoreflect.EnumType { + return &file_test_validator_proto3_proto_enumTypes[1] +} + +func (x ValidatorMessage3_EmbeddedEnum) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ValidatorMessage3_EmbeddedEnum.Descriptor instead. +func (ValidatorMessage3_EmbeddedEnum) EnumDescriptor() ([]byte, []int) { + return file_test_validator_proto3_proto_rawDescGZIP(), []int{0, 0} +} + +type ValidatorMessage3 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SomeString string `protobuf:"bytes,1,opt,name=SomeString,proto3" json:"SomeString,omitempty"` + SomeStringRep []string `protobuf:"bytes,2,rep,name=SomeStringRep,proto3" json:"SomeStringRep,omitempty"` + SomeStringNoQuotes string `protobuf:"bytes,3,opt,name=SomeStringNoQuotes,proto3" json:"SomeStringNoQuotes,omitempty"` + SomeStringUnescaped string `protobuf:"bytes,4,opt,name=SomeStringUnescaped,proto3" json:"SomeStringUnescaped,omitempty"` + SomeInt uint32 `protobuf:"varint,5,opt,name=SomeInt,proto3" json:"SomeInt,omitempty"` + SomeIntRep []uint32 `protobuf:"varint,6,rep,packed,name=SomeIntRep,proto3" json:"SomeIntRep,omitempty"` + SomeEmbedded *ValidatorMessage3_EmbeddedMessage `protobuf:"bytes,7,opt,name=SomeEmbedded,proto3" json:"SomeEmbedded,omitempty"` + SomeEmbeddedExists *ValidatorMessage3_EmbeddedMessage `protobuf:"bytes,8,opt,name=SomeEmbeddedExists,proto3" json:"SomeEmbeddedExists,omitempty"` + SomeEmbeddedRep []*ValidatorMessage3_EmbeddedMessage `protobuf:"bytes,9,rep,name=SomeEmbeddedRep,proto3" json:"SomeEmbeddedRep,omitempty"` + CustomErrorInt int32 `protobuf:"varint,10,opt,name=CustomErrorInt,proto3" json:"CustomErrorInt,omitempty"` + StrictSomeDouble float64 `protobuf:"fixed64,11,opt,name=StrictSomeDouble,proto3" json:"StrictSomeDouble,omitempty"` + StrictSomeDoubleRep []float64 `protobuf:"fixed64,12,rep,packed,name=StrictSomeDoubleRep,proto3" json:"StrictSomeDoubleRep,omitempty"` + StrictSomeDoubleRepNonNull []float64 `protobuf:"fixed64,13,rep,packed,name=StrictSomeDoubleRepNonNull,proto3" json:"StrictSomeDoubleRepNonNull,omitempty"` + StrictSomeFloat float32 `protobuf:"fixed32,14,opt,name=StrictSomeFloat,proto3" json:"StrictSomeFloat,omitempty"` + StrictSomeFloatRep []float32 `protobuf:"fixed32,15,rep,packed,name=StrictSomeFloatRep,proto3" json:"StrictSomeFloatRep,omitempty"` + StrictSomeFloatRepNonNull []float32 `protobuf:"fixed32,16,rep,packed,name=StrictSomeFloatRepNonNull,proto3" json:"StrictSomeFloatRepNonNull,omitempty"` + SomeDouble float64 `protobuf:"fixed64,17,opt,name=SomeDouble,proto3" json:"SomeDouble,omitempty"` + SomeDoubleRep []float64 `protobuf:"fixed64,18,rep,packed,name=SomeDoubleRep,proto3" json:"SomeDoubleRep,omitempty"` + SomeFloat float32 `protobuf:"fixed32,19,opt,name=SomeFloat,proto3" json:"SomeFloat,omitempty"` + SomeFloatRep []float32 `protobuf:"fixed32,20,rep,packed,name=SomeFloatRep,proto3" json:"SomeFloatRep,omitempty"` + SomeNonEmptyString string `protobuf:"bytes,21,opt,name=SomeNonEmptyString,proto3" json:"SomeNonEmptyString,omitempty"` + RepeatedBaseType []int32 `protobuf:"varint,22,rep,packed,name=RepeatedBaseType,proto3" json:"RepeatedBaseType,omitempty"` + Repeated []int32 `protobuf:"varint,23,rep,packed,name=Repeated,proto3" json:"Repeated,omitempty"` + SomeStringLtReq string `protobuf:"bytes,24,opt,name=SomeStringLtReq,proto3" json:"SomeStringLtReq,omitempty"` + SomeStringGtReq string `protobuf:"bytes,25,opt,name=SomeStringGtReq,proto3" json:"SomeStringGtReq,omitempty"` + SomeStringEqReq string `protobuf:"bytes,26,opt,name=SomeStringEqReq,proto3" json:"SomeStringEqReq,omitempty"` + SomeBytesLtReq []byte `protobuf:"bytes,27,opt,name=SomeBytesLtReq,proto3" json:"SomeBytesLtReq,omitempty"` + SomeBytesGtReq []byte `protobuf:"bytes,28,opt,name=SomeBytesGtReq,proto3" json:"SomeBytesGtReq,omitempty"` + SomeBytesEqReq []byte `protobuf:"bytes,29,opt,name=SomeBytesEqReq,proto3" json:"SomeBytesEqReq,omitempty"` + UUIDAny string `protobuf:"bytes,30,opt,name=UUIDAny,proto3" json:"UUIDAny,omitempty"` + UUID4NotEmpty string `protobuf:"bytes,31,opt,name=UUID4NotEmpty,proto3" json:"UUID4NotEmpty,omitempty"` + SomeEnum EnumProto3 `protobuf:"varint,32,opt,name=someEnum,proto3,enum=validatortest.EnumProto3" json:"someEnum,omitempty"` + SomeEmbeddedEnum ValidatorMessage3_EmbeddedEnum `protobuf:"varint,33,opt,name=someEmbeddedEnum,proto3,enum=validatortest.ValidatorMessage3_EmbeddedEnum" json:"someEmbeddedEnum,omitempty"` +} + +func (x *ValidatorMessage3) Reset() { + *x = ValidatorMessage3{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorMessage3) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorMessage3) ProtoMessage() {} + +func (x *ValidatorMessage3) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorMessage3.ProtoReflect.Descriptor instead. +func (*ValidatorMessage3) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_proto_rawDescGZIP(), []int{0} +} + +func (x *ValidatorMessage3) GetSomeString() string { + if x != nil { + return x.SomeString + } + return "" +} + +func (x *ValidatorMessage3) GetSomeStringRep() []string { + if x != nil { + return x.SomeStringRep + } + return nil +} + +func (x *ValidatorMessage3) GetSomeStringNoQuotes() string { + if x != nil { + return x.SomeStringNoQuotes + } + return "" +} + +func (x *ValidatorMessage3) GetSomeStringUnescaped() string { + if x != nil { + return x.SomeStringUnescaped + } + return "" +} + +func (x *ValidatorMessage3) GetSomeInt() uint32 { + if x != nil { + return x.SomeInt + } + return 0 +} + +func (x *ValidatorMessage3) GetSomeIntRep() []uint32 { + if x != nil { + return x.SomeIntRep + } + return nil +} + +func (x *ValidatorMessage3) GetSomeEmbedded() *ValidatorMessage3_EmbeddedMessage { + if x != nil { + return x.SomeEmbedded + } + return nil +} + +func (x *ValidatorMessage3) GetSomeEmbeddedExists() *ValidatorMessage3_EmbeddedMessage { + if x != nil { + return x.SomeEmbeddedExists + } + return nil +} + +func (x *ValidatorMessage3) GetSomeEmbeddedRep() []*ValidatorMessage3_EmbeddedMessage { + if x != nil { + return x.SomeEmbeddedRep + } + return nil +} + +func (x *ValidatorMessage3) GetCustomErrorInt() int32 { + if x != nil { + return x.CustomErrorInt + } + return 0 +} + +func (x *ValidatorMessage3) GetStrictSomeDouble() float64 { + if x != nil { + return x.StrictSomeDouble + } + return 0 +} + +func (x *ValidatorMessage3) GetStrictSomeDoubleRep() []float64 { + if x != nil { + return x.StrictSomeDoubleRep + } + return nil +} + +func (x *ValidatorMessage3) GetStrictSomeDoubleRepNonNull() []float64 { + if x != nil { + return x.StrictSomeDoubleRepNonNull + } + return nil +} + +func (x *ValidatorMessage3) GetStrictSomeFloat() float32 { + if x != nil { + return x.StrictSomeFloat + } + return 0 +} + +func (x *ValidatorMessage3) GetStrictSomeFloatRep() []float32 { + if x != nil { + return x.StrictSomeFloatRep + } + return nil +} + +func (x *ValidatorMessage3) GetStrictSomeFloatRepNonNull() []float32 { + if x != nil { + return x.StrictSomeFloatRepNonNull + } + return nil +} + +func (x *ValidatorMessage3) GetSomeDouble() float64 { + if x != nil { + return x.SomeDouble + } + return 0 +} + +func (x *ValidatorMessage3) GetSomeDoubleRep() []float64 { + if x != nil { + return x.SomeDoubleRep + } + return nil +} + +func (x *ValidatorMessage3) GetSomeFloat() float32 { + if x != nil { + return x.SomeFloat + } + return 0 +} + +func (x *ValidatorMessage3) GetSomeFloatRep() []float32 { + if x != nil { + return x.SomeFloatRep + } + return nil +} + +func (x *ValidatorMessage3) GetSomeNonEmptyString() string { + if x != nil { + return x.SomeNonEmptyString + } + return "" +} + +func (x *ValidatorMessage3) GetRepeatedBaseType() []int32 { + if x != nil { + return x.RepeatedBaseType + } + return nil +} + +func (x *ValidatorMessage3) GetRepeated() []int32 { + if x != nil { + return x.Repeated + } + return nil +} + +func (x *ValidatorMessage3) GetSomeStringLtReq() string { + if x != nil { + return x.SomeStringLtReq + } + return "" +} + +func (x *ValidatorMessage3) GetSomeStringGtReq() string { + if x != nil { + return x.SomeStringGtReq + } + return "" +} + +func (x *ValidatorMessage3) GetSomeStringEqReq() string { + if x != nil { + return x.SomeStringEqReq + } + return "" +} + +func (x *ValidatorMessage3) GetSomeBytesLtReq() []byte { + if x != nil { + return x.SomeBytesLtReq + } + return nil +} + +func (x *ValidatorMessage3) GetSomeBytesGtReq() []byte { + if x != nil { + return x.SomeBytesGtReq + } + return nil +} + +func (x *ValidatorMessage3) GetSomeBytesEqReq() []byte { + if x != nil { + return x.SomeBytesEqReq + } + return nil +} + +func (x *ValidatorMessage3) GetUUIDAny() string { + if x != nil { + return x.UUIDAny + } + return "" +} + +func (x *ValidatorMessage3) GetUUID4NotEmpty() string { + if x != nil { + return x.UUID4NotEmpty + } + return "" +} + +func (x *ValidatorMessage3) GetSomeEnum() EnumProto3 { + if x != nil { + return x.SomeEnum + } + return EnumProto3_alpha3 +} + +func (x *ValidatorMessage3) GetSomeEmbeddedEnum() ValidatorMessage3_EmbeddedEnum { + if x != nil { + return x.SomeEmbeddedEnum + } + return ValidatorMessage3_zero +} + +type ValidatorMessage3_EmbeddedMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identifier string `protobuf:"bytes,1,opt,name=Identifier,proto3" json:"Identifier,omitempty"` + SomeValue int64 `protobuf:"varint,2,opt,name=SomeValue,proto3" json:"SomeValue,omitempty"` +} + +func (x *ValidatorMessage3_EmbeddedMessage) Reset() { + *x = ValidatorMessage3_EmbeddedMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorMessage3_EmbeddedMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorMessage3_EmbeddedMessage) ProtoMessage() {} + +func (x *ValidatorMessage3_EmbeddedMessage) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorMessage3_EmbeddedMessage.ProtoReflect.Descriptor instead. +func (*ValidatorMessage3_EmbeddedMessage) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *ValidatorMessage3_EmbeddedMessage) GetIdentifier() string { + if x != nil { + return x.Identifier + } + return "" +} + +func (x *ValidatorMessage3_EmbeddedMessage) GetSomeValue() int64 { + if x != nil { + return x.SomeValue + } + return 0 +} + +var File_test_validator_proto3_proto protoreflect.FileDescriptor + +var file_test_validator_proto3_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, + 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xec, 0x11, 0x0a, 0x11, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x33, 0x12, 0x2e, 0x0a, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0e, 0xe2, 0xdf, 0x1f, 0x0a, 0x0a, 0x08, 0x5e, 0x2e, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, + 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x0d, 0x53, + 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x42, 0x0e, 0xe2, 0xdf, 0x1f, 0x0a, 0x0a, 0x08, 0x5e, 0x2e, 0x7b, 0x32, 0x2c, 0x35, + 0x7d, 0x24, 0x52, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x70, 0x12, 0x41, 0x0a, 0x12, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4e, + 0x6f, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0xe2, + 0xdf, 0x1f, 0x0d, 0x0a, 0x0b, 0x5e, 0x5b, 0x5e, 0x22, 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, + 0x52, 0x12, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x51, 0x75, + 0x6f, 0x74, 0x65, 0x73, 0x12, 0x69, 0x0a, 0x13, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x55, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x37, 0xe2, 0xdf, 0x1f, 0x33, 0x0a, 0x31, 0x5b, 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5c, + 0x70, 0x7b, 0x4e, 0x7d, 0x5d, 0x28, 0x7b, 0x5c, 0x70, 0x7b, 0x4c, 0x7d, 0x5c, 0x70, 0x7b, 0x4e, + 0x7d, 0x5f, 0x2d, 0x20, 0x5d, 0x7b, 0x30, 0x2c, 0x32, 0x38, 0x7d, 0x5b, 0x5c, 0x70, 0x7b, 0x4c, + 0x7d, 0x5c, 0x70, 0x7b, 0x4e, 0x7d, 0x5d, 0x29, 0x3f, 0x2e, 0x52, 0x13, 0x53, 0x6f, 0x6d, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x64, 0x12, + 0x20, 0x0a, 0x07, 0x53, 0x6f, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, + 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x0a, 0x52, 0x07, 0x53, 0x6f, 0x6d, 0x65, 0x49, 0x6e, + 0x74, 0x12, 0x26, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x0a, 0x52, 0x0a, 0x53, + 0x6f, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x12, 0x54, 0x0a, 0x0c, 0x53, 0x6f, 0x6d, + 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x33, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x0c, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x12, + 0x68, 0x0a, 0x12, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x33, 0x2e, 0x45, 0x6d, + 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0xe2, + 0xdf, 0x1f, 0x02, 0x20, 0x01, 0x52, 0x12, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x5a, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, + 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x65, 0x70, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x33, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, + 0x65, 0x64, 0x52, 0x65, 0x70, 0x12, 0x3f, 0x0a, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x42, 0x17, 0xe2, + 0xdf, 0x1f, 0x13, 0x18, 0x0a, 0x2a, 0x0f, 0x4d, 0x79, 0x20, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x0e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, + 0x42, 0x1f, 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, + 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, + 0x3f, 0x52, 0x10, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x12, 0x51, 0x0a, 0x13, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, + 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x01, + 0x42, 0x1f, 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, + 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, + 0x3f, 0x52, 0x13, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x12, 0x5f, 0x0a, 0x1a, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x4e, 0x6f, 0x6e, + 0x4e, 0x75, 0x6c, 0x6c, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x01, 0x42, 0x1f, 0xe2, 0xdf, 0x1f, 0x1b, + 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, + 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, 0x1a, 0x53, 0x74, 0x72, + 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, + 0x4e, 0x6f, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, 0x12, 0x49, 0x0a, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x02, + 0x42, 0x1f, 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, + 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, + 0x3f, 0x52, 0x0f, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, + 0x61, 0x74, 0x12, 0x4f, 0x0a, 0x12, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x02, 0x42, 0x1f, + 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, + 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, + 0x12, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, + 0x52, 0x65, 0x70, 0x12, 0x5d, 0x0a, 0x19, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, 0x6f, 0x6d, + 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x4e, 0x6f, 0x6e, 0x4e, 0x75, 0x6c, 0x6c, + 0x18, 0x10, 0x20, 0x03, 0x28, 0x02, 0x42, 0x1f, 0xe2, 0xdf, 0x1f, 0x1b, 0x31, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0xd6, 0x3f, 0x39, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xe4, 0x3f, 0x41, 0x9a, + 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0x3f, 0x52, 0x19, 0x53, 0x74, 0x72, 0x69, 0x63, 0x74, 0x53, + 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x4e, 0x6f, 0x6e, 0x4e, 0x75, + 0x6c, 0x6c, 0x12, 0x36, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x01, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, 0x49, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xd0, 0x3f, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3f, 0x52, 0x0a, + 0x53, 0x6f, 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, 0x3c, 0x0a, 0x0d, 0x53, 0x6f, + 0x6d, 0x65, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x18, 0x12, 0x20, 0x03, 0x28, + 0x01, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x3f, + 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3f, 0x52, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x44, + 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x12, 0x34, 0x0a, 0x09, 0x53, 0x6f, 0x6d, 0x65, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x02, 0x42, 0x16, 0xe2, 0xdf, 0x1f, + 0x12, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x3f, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe8, 0x3f, 0x52, 0x09, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x3a, + 0x0a, 0x0c, 0x53, 0x6f, 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x18, 0x14, + 0x20, 0x03, 0x28, 0x02, 0x42, 0x16, 0xe2, 0xdf, 0x1f, 0x12, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd0, 0x3f, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3f, 0x52, 0x0c, 0x53, 0x6f, + 0x6d, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x65, 0x70, 0x12, 0x36, 0x0a, 0x12, 0x53, 0x6f, + 0x6d, 0x65, 0x4e, 0x6f, 0x6e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, 0x01, 0x52, 0x12, + 0x53, 0x6f, 0x6d, 0x65, 0x4e, 0x6f, 0x6e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x61, + 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x16, 0x20, 0x03, 0x28, 0x05, 0x52, 0x10, 0x52, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, + 0x0a, 0x08, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x17, 0x20, 0x03, 0x28, 0x05, + 0x42, 0x08, 0xe2, 0xdf, 0x1f, 0x04, 0x60, 0x02, 0x68, 0x05, 0x52, 0x08, 0x52, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x4c, 0x74, 0x52, 0x65, 0x71, 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, + 0xdf, 0x1f, 0x02, 0x70, 0x02, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x4c, 0x74, 0x52, 0x65, 0x71, 0x12, 0x30, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x47, 0x74, 0x52, 0x65, 0x71, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x78, 0x0c, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x47, 0x74, 0x52, 0x65, 0x71, 0x12, 0x31, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x71, 0x52, 0x65, 0x71, 0x18, 0x1a, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x80, 0x01, 0x0a, 0x52, 0x0f, 0x53, 0x6f, 0x6d, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x45, 0x71, 0x52, 0x65, 0x71, 0x12, 0x2e, 0x0a, 0x0e, 0x53, + 0x6f, 0x6d, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4c, 0x74, 0x52, 0x65, 0x71, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x0c, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x70, 0x05, 0x52, 0x0e, 0x53, 0x6f, 0x6d, + 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x4c, 0x74, 0x52, 0x65, 0x71, 0x12, 0x2e, 0x0a, 0x0e, 0x53, + 0x6f, 0x6d, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x47, 0x74, 0x52, 0x65, 0x71, 0x18, 0x1c, 0x20, + 0x01, 0x28, 0x0c, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x78, 0x14, 0x52, 0x0e, 0x53, 0x6f, 0x6d, + 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x47, 0x74, 0x52, 0x65, 0x71, 0x12, 0x2f, 0x0a, 0x0e, 0x53, + 0x6f, 0x6d, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x45, 0x71, 0x52, 0x65, 0x71, 0x18, 0x1d, 0x20, + 0x01, 0x28, 0x0c, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x80, 0x01, 0x0c, 0x52, 0x0e, 0x53, 0x6f, + 0x6d, 0x65, 0x42, 0x79, 0x74, 0x65, 0x73, 0x45, 0x71, 0x52, 0x65, 0x71, 0x12, 0x21, 0x0a, 0x07, + 0x55, 0x55, 0x49, 0x44, 0x41, 0x6e, 0x79, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xe2, + 0xdf, 0x1f, 0x03, 0x90, 0x01, 0x00, 0x52, 0x07, 0x55, 0x55, 0x49, 0x44, 0x41, 0x6e, 0x79, 0x12, + 0x2d, 0x0a, 0x0d, 0x55, 0x55, 0x49, 0x44, 0x34, 0x4e, 0x6f, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x18, 0x1f, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x90, 0x01, 0x04, 0x52, + 0x0d, 0x55, 0x55, 0x49, 0x44, 0x34, 0x4e, 0x6f, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, + 0x0a, 0x08, 0x73, 0x6f, 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x19, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x42, 0x07, 0xe2, 0xdf, 0x1f, + 0x03, 0x88, 0x01, 0x01, 0x52, 0x08, 0x73, 0x6f, 0x6d, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x62, + 0x0a, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, 0x6e, + 0x75, 0x6d, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x33, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x45, 0x6e, 0x75, 0x6d, 0x42, 0x07, 0xe2, 0xdf, 0x1f, 0x03, 0x88, 0x01, 0x01, + 0x52, 0x10, 0x73, 0x6f, 0x6d, 0x65, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, 0x6e, + 0x75, 0x6d, 0x1a, 0x6d, 0x0a, 0x0f, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x32, 0x0a, 0x0a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x12, 0xe2, 0xdf, 0x1f, 0x0e, 0x0a, + 0x0c, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, 0x0a, 0x49, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x09, 0x53, 0x6f, 0x6d, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x42, 0x08, 0xe2, 0xdf, + 0x1f, 0x04, 0x10, 0x00, 0x18, 0x64, 0x52, 0x09, 0x53, 0x6f, 0x6d, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x21, 0x0a, 0x0c, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x45, 0x6e, 0x75, + 0x6d, 0x12, 0x08, 0x0a, 0x04, 0x7a, 0x65, 0x72, 0x6f, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x6f, + 0x6e, 0x65, 0x10, 0x01, 0x2a, 0x23, 0x0a, 0x0a, 0x45, 0x6e, 0x75, 0x6d, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x33, 0x12, 0x0a, 0x0a, 0x06, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x33, 0x10, 0x00, 0x12, 0x09, + 0x0a, 0x05, 0x62, 0x65, 0x74, 0x61, 0x33, 0x10, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_test_validator_proto3_proto_rawDescOnce sync.Once + file_test_validator_proto3_proto_rawDescData = file_test_validator_proto3_proto_rawDesc +) + +func file_test_validator_proto3_proto_rawDescGZIP() []byte { + file_test_validator_proto3_proto_rawDescOnce.Do(func() { + file_test_validator_proto3_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_validator_proto3_proto_rawDescData) + }) + return file_test_validator_proto3_proto_rawDescData +} + +var file_test_validator_proto3_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_test_validator_proto3_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_test_validator_proto3_proto_goTypes = []interface{}{ + (EnumProto3)(0), // 0: validatortest.EnumProto3 + (ValidatorMessage3_EmbeddedEnum)(0), // 1: validatortest.ValidatorMessage3.EmbeddedEnum + (*ValidatorMessage3)(nil), // 2: validatortest.ValidatorMessage3 + (*ValidatorMessage3_EmbeddedMessage)(nil), // 3: validatortest.ValidatorMessage3.EmbeddedMessage +} +var file_test_validator_proto3_proto_depIdxs = []int32{ + 3, // 0: validatortest.ValidatorMessage3.SomeEmbedded:type_name -> validatortest.ValidatorMessage3.EmbeddedMessage + 3, // 1: validatortest.ValidatorMessage3.SomeEmbeddedExists:type_name -> validatortest.ValidatorMessage3.EmbeddedMessage + 3, // 2: validatortest.ValidatorMessage3.SomeEmbeddedRep:type_name -> validatortest.ValidatorMessage3.EmbeddedMessage + 0, // 3: validatortest.ValidatorMessage3.someEnum:type_name -> validatortest.EnumProto3 + 1, // 4: validatortest.ValidatorMessage3.someEmbeddedEnum:type_name -> validatortest.ValidatorMessage3.EmbeddedEnum + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_test_validator_proto3_proto_init() } +func file_test_validator_proto3_proto_init() { + if File_test_validator_proto3_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_validator_proto3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorMessage3); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_validator_proto3_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorMessage3_EmbeddedMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_validator_proto3_proto_rawDesc, + NumEnums: 2, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_validator_proto3_proto_goTypes, + DependencyIndexes: file_test_validator_proto3_proto_depIdxs, + EnumInfos: file_test_validator_proto3_proto_enumTypes, + MessageInfos: file_test_validator_proto3_proto_msgTypes, + }.Build() + File_test_validator_proto3_proto = out.File + file_test_validator_proto3_proto_rawDesc = nil + file_test_validator_proto3_proto_goTypes = nil + file_test_validator_proto3_proto_depIdxs = nil +} diff --git a/test/validator_proto3.proto b/test/validator_proto3.proto index 92d8fee..17a005a 100644 --- a/test/validator_proto3.proto +++ b/test/validator_proto3.proto @@ -4,90 +4,107 @@ syntax = "proto3"; package validatortest; -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; -import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/mwitkow/go-proto-validators/validators.proto"; // Top-level enum type definition. enum EnumProto3 { - alpha3 = 0; - beta3 = 1; + alpha3 = 0; + beta3 = 1; } message ValidatorMessage3 { - // Embedded message test structure. - message EmbeddedMessage { - string Identifier = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; - int64 SomeValue = 2 [(validator.field) = {int_gt: 0, int_lt: 100}]; - } - - // Embedded enum type definition. - enum EmbeddedEnum { - zero = 0; - one = 1; - } - - // 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. - EmbeddedMessage someEmbedded = 10; - EmbeddedMessage someEmbeddedNonNullable = 11 [(gogoproto.nullable) = false]; - EmbeddedMessage someEmbeddedExists = 12 [(validator.field) = {msg_exists : true}]; - repeated EmbeddedMessage someEmbeddedRep = 14; - repeated EmbeddedMessage 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}]; - - string UUIDAny = 42 [(validator.field) = {uuid_ver: 0}]; - string UUID4NotEmpty = 43 [(validator.field) = {uuid_ver: 4, string_not_empty: true}]; - - // Enum tests. - EnumProto3 someEnum = 44 [(validator.field) = {is_in_enum: true}]; - EmbeddedEnum someEmbeddedEnum = 45 [(validator.field) = {is_in_enum: true}]; - - EmbeddedMessage someGogoEmbedded = 46 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (gogoproto.jsontag) = ",inline"]; + // Embedded message test structure. + message EmbeddedMessage { + string Identifier = 1 [ (validator.field) = {regex : "^[a-z]{2,5}$"} ]; + int64 SomeValue = 2 [ (validator.field) = {int_gt : 0, int_lt : 100} ]; + } + + // Embedded enum type definition. + enum EmbeddedEnum { + zero = 0; + one = 1; + } + + // 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 = 5 [ (validator.field) = {int_gt : 10} ]; + repeated uint32 SomeIntRep = 6 [ (validator.field) = {int_gt : 10} ]; + + // Embedded message existence and recursive constraint tests. + EmbeddedMessage SomeEmbedded = 7; + EmbeddedMessage SomeEmbeddedExists = 8 + [ (validator.field) = {msg_exists : true} ]; + repeated EmbeddedMessage SomeEmbeddedRep = 9; + + // Custom error tests. + int32 CustomErrorInt = 10 + [ (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 = 11 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + repeated double StrictSomeDoubleRep = 12 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + repeated double StrictSomeDoubleRepNonNull = 13 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + float StrictSomeFloat = 14 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + repeated float StrictSomeFloatRep = 15 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + repeated float StrictSomeFloatRepNonNull = 16 [ + (validator.field) = {float_gt : 0.35, float_lt : 0.65, float_epsilon : 0.05} + ]; + + // Non-strict floating-point inequality constraint tests. + double SomeDouble = 17 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + repeated double SomeDoubleRep = 18 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + float SomeFloat = 19 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + repeated float SomeFloatRep = 20 + [ (validator.field) = {float_gte : 0.25, float_lte : 0.75} ]; + + // String not-empty constraint tests. + string SomeNonEmptyString = 21 + [ (validator.field) = {string_not_empty : true} ]; + + // Repeated base-type without constraint tests. + repeated int32 RepeatedBaseType = 22; + + // Repeated element count constraint tests. + repeated int32 Repeated = 23 + [ (validator.field) = {repeated_count_min : 2, repeated_count_max : 5} ]; + string SomeStringLtReq = 24 [ (validator.field) = {length_gt : 2} ]; + string SomeStringGtReq = 25 [ (validator.field) = {length_lt : 12} ]; + string SomeStringEqReq = 26 [ (validator.field) = {length_eq : 10} ]; + + bytes SomeBytesLtReq = 27 [ (validator.field) = {length_gt : 5} ]; + bytes SomeBytesGtReq = 28 [ (validator.field) = {length_lt : 20} ]; + bytes SomeBytesEqReq = 29 [ (validator.field) = {length_eq : 12} ]; + + string UUIDAny = 30 [ (validator.field) = {uuid_ver : 0} ]; + string UUID4NotEmpty = 31 [ (validator.field) = {uuid_ver : 4} ]; + + // Enum tests. + EnumProto3 someEnum = 32 [ (validator.field) = {is_in_enum : true} ]; + EmbeddedEnum someEmbeddedEnum = 33 + [ (validator.field) = {is_in_enum : true} ]; } diff --git a/test/validator_proto3.validator.pb.go b/test/validator_proto3.validator.pb.go new file mode 100644 index 0000000..bf55ef7 --- /dev/null +++ b/test/validator_proto3.validator.pb.go @@ -0,0 +1,227 @@ +// Code generated by protoc-gen-govalidators. DO NOT EDIT. + +package validatortest + +import ( + errors "errors" + fmt "fmt" + go_proto_validators "github.com/mwitkow/go-proto-validators" + regexp "regexp" +) + +var ValidatorMessage3_EmbeddedMessageIdentifierRE = regexp.MustCompile(`^[a-z]{2,5}$`) + +func (m *ValidatorMessage3_EmbeddedMessage) Validate() error { + if !ValidatorMessage3_EmbeddedMessageIdentifierRE.MatchString(string(m.GetIdentifier())) { + return go_proto_validators.FieldError("Identifier", errors.New(`Identifier should match regular expression "^[a-z]{2,5}$"`)) + } + + if m.GetSomeValue() <= 0 { + return go_proto_validators.FieldError("SomeValue", errors.New("SomeValue is not greater than 0")) + } + if m.GetSomeValue() >= 100 { + return go_proto_validators.FieldError("SomeValue", errors.New("SomeValue is not smaller than 100")) + } + + return nil +} + +var ValidatorMessage3SomeStringRE = regexp.MustCompile(`^.{2,5}$`) +var ValidatorMessage3SomeStringRepRE = regexp.MustCompile(`^.{2,5}$`) +var ValidatorMessage3SomeStringNoQuotesRE = regexp.MustCompile(`^[^"]{2,5}$`) +var ValidatorMessage3SomeStringUnescapedRE = regexp.MustCompile(`[\p{L}\p{N}]({\p{L}\p{N}_- ]{0,28}[\p{L}\p{N}])?.`) +var ValidatorMessage3UUIDAnyRE = regexp.MustCompile(`^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$`) +var ValidatorMessage3UUID4NotEmptyRE = regexp.MustCompile(`^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$`) + +func (m *ValidatorMessage3) Validate() error { + if !ValidatorMessage3SomeStringRE.MatchString(string(m.GetSomeString())) { + return go_proto_validators.FieldError("SomeString", errors.New(`SomeString should match regular expression "^.{2,5}$"`)) + } + + for _, item := range m.GetSomeStringRep() { + if !ValidatorMessage3SomeStringRepRE.MatchString(string(item)) { + return go_proto_validators.FieldError("SomeStringRep", errors.New(`SomeStringRep should match regular expression "^.{2,5}$"`)) + } + } + + if !ValidatorMessage3SomeStringNoQuotesRE.MatchString(string(m.GetSomeStringNoQuotes())) { + return go_proto_validators.FieldError("SomeStringNoQuotes", errors.New(`SomeStringNoQuotes should match regular expression "^[^\"]{2,5}$"`)) + } + + if !ValidatorMessage3SomeStringUnescapedRE.MatchString(string(m.GetSomeStringUnescaped())) { + return go_proto_validators.FieldError("SomeStringUnescaped", errors.New(`SomeStringUnescaped should match regular expression "[\\p{L}\\p{N}]({\\p{L}\\p{N}_- ]{0,28}[\\p{L}\\p{N}])?."`)) + } + + if m.GetSomeInt() <= 10 { + return go_proto_validators.FieldError("SomeInt", errors.New("SomeInt is not greater than 10")) + } + + for _, item := range m.GetSomeIntRep() { + if item <= 10 { + return go_proto_validators.FieldError("SomeIntRep", errors.New("SomeIntRep is not greater than 10")) + } + } + + if m.GetSomeEmbedded() != nil { + if err := go_proto_validators.CallValidatorIfExists(m.GetSomeEmbedded()); err != nil { + return go_proto_validators.FieldError("SomeEmbedded", err) + } + } + + if m.GetSomeEmbeddedExists() != nil { + if err := go_proto_validators.CallValidatorIfExists(m.GetSomeEmbeddedExists()); err != nil { + return go_proto_validators.FieldError("SomeEmbeddedExists", err) + } + } + if m.GetSomeEmbeddedExists() == nil { + return go_proto_validators.FieldError("SomeEmbeddedExists", errors.New("SomeEmbeddedExists should be set")) + } + + for _, item := range m.GetSomeEmbeddedRep() { + if item != nil { + if err := go_proto_validators.CallValidatorIfExists(item); err != nil { + return go_proto_validators.FieldError("SomeEmbeddedRep", err) + } + } + } + + if m.GetCustomErrorInt() >= 10 { + return go_proto_validators.FieldError("CustomErrorInt", errors.New("My Custom Error")) + } + + if m.GetStrictSomeDouble() <= 0.3 { + return go_proto_validators.FieldError("StrictSomeDouble", errors.New("StrictSomeDouble is not greater than 0.3")) + } + if m.GetStrictSomeDouble() >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeDouble", errors.New("StrictSomeDouble is not smaller than 0.7000000000000001")) + } + + for _, item := range m.GetStrictSomeDoubleRep() { + if item <= 0.3 { + return go_proto_validators.FieldError("StrictSomeDoubleRep", errors.New("StrictSomeDoubleRep is not greater than 0.3")) + } + if item >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeDoubleRep", errors.New("StrictSomeDoubleRep is not smaller than 0.7000000000000001")) + } + } + + for _, item := range m.GetStrictSomeDoubleRepNonNull() { + if item <= 0.3 { + return go_proto_validators.FieldError("StrictSomeDoubleRepNonNull", errors.New("StrictSomeDoubleRepNonNull is not greater than 0.3")) + } + if item >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeDoubleRepNonNull", errors.New("StrictSomeDoubleRepNonNull is not smaller than 0.7000000000000001")) + } + } + + if m.GetStrictSomeFloat() <= 0.3 { + return go_proto_validators.FieldError("StrictSomeFloat", errors.New("StrictSomeFloat is not greater than 0.3")) + } + if m.GetStrictSomeFloat() >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeFloat", errors.New("StrictSomeFloat is not smaller than 0.7000000000000001")) + } + + for _, item := range m.GetStrictSomeFloatRep() { + if item <= 0.3 { + return go_proto_validators.FieldError("StrictSomeFloatRep", errors.New("StrictSomeFloatRep is not greater than 0.3")) + } + if item >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeFloatRep", errors.New("StrictSomeFloatRep is not smaller than 0.7000000000000001")) + } + } + + for _, item := range m.GetStrictSomeFloatRepNonNull() { + if item <= 0.3 { + return go_proto_validators.FieldError("StrictSomeFloatRepNonNull", errors.New("StrictSomeFloatRepNonNull is not greater than 0.3")) + } + if item >= 0.7000000000000001 { + return go_proto_validators.FieldError("StrictSomeFloatRepNonNull", errors.New("StrictSomeFloatRepNonNull is not smaller than 0.7000000000000001")) + } + } + + if m.GetSomeDouble() < 0.25 { + return go_proto_validators.FieldError("SomeDouble", errors.New("SomeDouble is not greater than or equal to 0.25")) + } + if m.GetSomeDouble() > 0.75 { + return go_proto_validators.FieldError("SomeDouble", errors.New("SomeDouble is not smaller than or equal to 0.75")) + } + + for _, item := range m.GetSomeDoubleRep() { + if item < 0.25 { + return go_proto_validators.FieldError("SomeDoubleRep", errors.New("SomeDoubleRep is not greater than or equal to 0.25")) + } + if item > 0.75 { + return go_proto_validators.FieldError("SomeDoubleRep", errors.New("SomeDoubleRep is not smaller than or equal to 0.75")) + } + } + + if m.GetSomeFloat() < 0.25 { + return go_proto_validators.FieldError("SomeFloat", errors.New("SomeFloat is not greater than or equal to 0.25")) + } + if m.GetSomeFloat() > 0.75 { + return go_proto_validators.FieldError("SomeFloat", errors.New("SomeFloat is not smaller than or equal to 0.75")) + } + + for _, item := range m.GetSomeFloatRep() { + if item < 0.25 { + return go_proto_validators.FieldError("SomeFloatRep", errors.New("SomeFloatRep is not greater than or equal to 0.25")) + } + if item > 0.75 { + return go_proto_validators.FieldError("SomeFloatRep", errors.New("SomeFloatRep is not smaller than or equal to 0.75")) + } + } + + if string(m.GetSomeNonEmptyString()) == "" { + return go_proto_validators.FieldError("SomeNonEmptyString", errors.New("SomeNonEmptyString should not be empty")) + } + + if len(m.GetRepeated()) > 5 { + return go_proto_validators.FieldError("Repeated", fmt.Errorf("Repeated has %d elements whereas a maximum of 5 is allowed", len(m.GetRepeated()))) + } + + if len(m.GetRepeated()) < 2 { + return go_proto_validators.FieldError("Repeated", fmt.Errorf("Repeated has %d elements whereas a minimum of 2 is required", len(m.GetRepeated()))) + } + + if len(m.GetSomeStringLtReq()) <= 2 { + return go_proto_validators.FieldError("SomeStringLtReq", errors.New("SomeStringLtReq should have a length greater than 2")) + } + + if len(m.GetSomeStringGtReq()) >= 12 { + return go_proto_validators.FieldError("SomeStringGtReq", errors.New("SomeStringGtReq should have a length smaller than 12")) + } + + if len(m.GetSomeStringEqReq()) != 10 { + return go_proto_validators.FieldError("SomeStringEqReq", errors.New("SomeStringEqReq should be of length 10")) + } + + if len(m.GetSomeBytesLtReq()) <= 5 { + return go_proto_validators.FieldError("SomeBytesLtReq", errors.New("SomeBytesLtReq should have a length greater than 5")) + } + + if len(m.GetSomeBytesGtReq()) >= 20 { + return go_proto_validators.FieldError("SomeBytesGtReq", errors.New("SomeBytesGtReq should have a length smaller than 20")) + } + + if len(m.GetSomeBytesEqReq()) != 12 { + return go_proto_validators.FieldError("SomeBytesEqReq", errors.New("SomeBytesEqReq should be of length 12")) + } + + if !ValidatorMessage3UUIDAnyRE.MatchString(string(m.GetUUIDAny())) { + return go_proto_validators.FieldError("UUIDAny", errors.New("UUIDAny should match regular expression '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[0][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$'")) + } + + if !ValidatorMessage3UUID4NotEmptyRE.MatchString(string(m.GetUUID4NotEmpty())) { + return go_proto_validators.FieldError("UUID4NotEmpty", errors.New("UUID4NotEmpty should match regular expression '^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[4][a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$'")) + } + + if _, ok := EnumProto3_name[int32(m.GetSomeEnum())]; !ok { + return go_proto_validators.FieldError("SomeEnum", errors.New("someEnum should correspond to a valid enum value")) + } + + if _, ok := ValidatorMessage3_EmbeddedEnum_name[int32(m.GetSomeEmbeddedEnum())]; !ok { + return go_proto_validators.FieldError("SomeEmbeddedEnum", errors.New("someEmbeddedEnum should correspond to a valid enum value")) + } + + return nil +} diff --git a/test/validator_proto3_map.pb.go b/test/validator_proto3_map.pb.go new file mode 100644 index 0000000..d2075e2 --- /dev/null +++ b/test/validator_proto3_map.pb.go @@ -0,0 +1,337 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: test/validator_proto3_map.proto + +package validatortest + +import ( + proto "github.com/golang/protobuf/proto" + _ "github.com/mwitkow/go-proto-validators" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type ValueType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Something string `protobuf:"bytes,1,opt,name=something,proto3" json:"something,omitempty"` +} + +func (x *ValueType) Reset() { + *x = ValueType{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_map_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValueType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValueType) ProtoMessage() {} + +func (x *ValueType) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_map_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValueType.ProtoReflect.Descriptor instead. +func (*ValueType) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_map_proto_rawDescGZIP(), []int{0} +} + +func (x *ValueType) GetSomething() string { + if x != nil { + return x.Something + } + return "" +} + +type ValidatorMapMessage3 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SomeStringMap map[string]string `protobuf:"bytes,1,rep,name=SomeStringMap,proto3" json:"SomeStringMap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + SomeExtMap map[string]*ValueType `protobuf:"bytes,2,rep,name=SomeExtMap,proto3" json:"SomeExtMap,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + SomeNestedMap map[int32]*ValidatorMapMessage3_NestedType `protobuf:"bytes,3,rep,name=SomeNestedMap,proto3" json:"SomeNestedMap,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ValidatorMapMessage3) Reset() { + *x = ValidatorMapMessage3{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_map_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorMapMessage3) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorMapMessage3) ProtoMessage() {} + +func (x *ValidatorMapMessage3) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_map_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorMapMessage3.ProtoReflect.Descriptor instead. +func (*ValidatorMapMessage3) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_map_proto_rawDescGZIP(), []int{1} +} + +func (x *ValidatorMapMessage3) GetSomeStringMap() map[string]string { + if x != nil { + return x.SomeStringMap + } + return nil +} + +func (x *ValidatorMapMessage3) GetSomeExtMap() map[string]*ValueType { + if x != nil { + return x.SomeExtMap + } + return nil +} + +func (x *ValidatorMapMessage3) GetSomeNestedMap() map[int32]*ValidatorMapMessage3_NestedType { + if x != nil { + return x.SomeNestedMap + } + return nil +} + +type ValidatorMapMessage3_NestedType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Something string `protobuf:"bytes,1,opt,name=something,proto3" json:"something,omitempty"` +} + +func (x *ValidatorMapMessage3_NestedType) Reset() { + *x = ValidatorMapMessage3_NestedType{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_map_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorMapMessage3_NestedType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorMapMessage3_NestedType) ProtoMessage() {} + +func (x *ValidatorMapMessage3_NestedType) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_map_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorMapMessage3_NestedType.ProtoReflect.Descriptor instead. +func (*ValidatorMapMessage3_NestedType) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_map_proto_rawDescGZIP(), []int{1, 1} +} + +func (x *ValidatorMapMessage3_NestedType) GetSomething() string { + if x != nil { + return x.Something + } + return "" +} + +var File_test_validator_proto3_map_proto protoreflect.FileDescriptor + +var file_test_validator_proto3_map_proto_rawDesc = []byte{ + 0x0a, 0x1f, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, 0x6d, 0x61, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x0d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, + 0x1a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x31, 0x0a, 0x09, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, + 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x58, + 0x01, 0x52, 0x09, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x22, 0xfc, 0x04, 0x0a, + 0x14, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x33, 0x12, 0x70, 0x0a, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x33, 0x2e, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x42, 0x12, 0xe2, 0xdf, 0x1f, 0x0e, 0x0a, 0x0c, 0x5e, 0x5b, 0x61, 0x2d, + 0x7a, 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x52, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x70, 0x12, 0x53, 0x0a, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x45, + 0x78, 0x74, 0x4d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x33, + 0x2e, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x78, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x78, 0x74, 0x4d, 0x61, 0x70, 0x12, 0x64, 0x0a, 0x0d, + 0x53, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x70, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x33, 0x2e, 0x53, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x73, + 0x74, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x06, 0xe2, 0xdf, 0x1f, + 0x02, 0x20, 0x01, 0x52, 0x0d, 0x53, 0x6f, 0x6d, 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, + 0x61, 0x70, 0x1a, 0x40, 0x0a, 0x12, 0x53, 0x6f, 0x6d, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x2a, 0x0a, 0x0a, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, + 0x1a, 0x57, 0x0a, 0x0f, 0x53, 0x6f, 0x6d, 0x65, 0x45, 0x78, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x70, 0x0a, 0x12, 0x53, 0x6f, 0x6d, + 0x65, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x44, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2e, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x70, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x33, 0x2e, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_test_validator_proto3_map_proto_rawDescOnce sync.Once + file_test_validator_proto3_map_proto_rawDescData = file_test_validator_proto3_map_proto_rawDesc +) + +func file_test_validator_proto3_map_proto_rawDescGZIP() []byte { + file_test_validator_proto3_map_proto_rawDescOnce.Do(func() { + file_test_validator_proto3_map_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_validator_proto3_map_proto_rawDescData) + }) + return file_test_validator_proto3_map_proto_rawDescData +} + +var file_test_validator_proto3_map_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_test_validator_proto3_map_proto_goTypes = []interface{}{ + (*ValueType)(nil), // 0: validatortest.ValueType + (*ValidatorMapMessage3)(nil), // 1: validatortest.ValidatorMapMessage3 + nil, // 2: validatortest.ValidatorMapMessage3.SomeStringMapEntry + (*ValidatorMapMessage3_NestedType)(nil), // 3: validatortest.ValidatorMapMessage3.NestedType + nil, // 4: validatortest.ValidatorMapMessage3.SomeExtMapEntry + nil, // 5: validatortest.ValidatorMapMessage3.SomeNestedMapEntry +} +var file_test_validator_proto3_map_proto_depIdxs = []int32{ + 2, // 0: validatortest.ValidatorMapMessage3.SomeStringMap:type_name -> validatortest.ValidatorMapMessage3.SomeStringMapEntry + 4, // 1: validatortest.ValidatorMapMessage3.SomeExtMap:type_name -> validatortest.ValidatorMapMessage3.SomeExtMapEntry + 5, // 2: validatortest.ValidatorMapMessage3.SomeNestedMap:type_name -> validatortest.ValidatorMapMessage3.SomeNestedMapEntry + 0, // 3: validatortest.ValidatorMapMessage3.SomeExtMapEntry.value:type_name -> validatortest.ValueType + 3, // 4: validatortest.ValidatorMapMessage3.SomeNestedMapEntry.value:type_name -> validatortest.ValidatorMapMessage3.NestedType + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_test_validator_proto3_map_proto_init() } +func file_test_validator_proto3_map_proto_init() { + if File_test_validator_proto3_map_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_validator_proto3_map_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValueType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_validator_proto3_map_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorMapMessage3); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_validator_proto3_map_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorMapMessage3_NestedType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_validator_proto3_map_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_validator_proto3_map_proto_goTypes, + DependencyIndexes: file_test_validator_proto3_map_proto_depIdxs, + MessageInfos: file_test_validator_proto3_map_proto_msgTypes, + }.Build() + File_test_validator_proto3_map_proto = out.File + file_test_validator_proto3_map_proto_rawDesc = nil + file_test_validator_proto3_map_proto_goTypes = nil + file_test_validator_proto3_map_proto_depIdxs = nil +} diff --git a/test/validator_proto3_map.proto b/test/validator_proto3_map.proto index ad74629..6fd1d0e 100644 --- a/test/validator_proto3_map.proto +++ b/test/validator_proto3_map.proto @@ -4,20 +4,21 @@ syntax = "proto3"; package validatortest; +import "github.com/mwitkow/go-proto-validators/validators.proto"; + message ValueType { - string something = 1 ; + string something = 1 [ (validator.field) = {string_not_empty : true} ]; } -// This needs to be able to compile. Fixes https://github.com/mwitkow/go-proto-validators/issues/1 +// This needs to be able to compile. Fixes +// https://github.com/mwitkow/go-proto-validators/issues/1 message ValidatorMapMessage3 { - map SomeStringMap = 1; + map SomeStringMap = 1 + [ (validator.field) = {regex : "^[a-z]{2,5}$"} ]; - message NestedType { - string something = 1 ; - } + message NestedType { string something = 1; } map SomeExtMap = 2; - map SomeNestedMap = 3; + map SomeNestedMap = 3 + [ (validator.field) = {msg_exists : true} ]; } - - diff --git a/test/validator_proto3_map.validator.pb.go b/test/validator_proto3_map.validator.pb.go new file mode 100644 index 0000000..4fc671a --- /dev/null +++ b/test/validator_proto3_map.validator.pb.go @@ -0,0 +1,52 @@ +// Code generated by protoc-gen-govalidators. DO NOT EDIT. + +package validatortest + +import ( + errors "errors" + go_proto_validators "github.com/mwitkow/go-proto-validators" + regexp "regexp" +) + +func (m *ValueType) Validate() error { + if string(m.GetSomething()) == "" { + return go_proto_validators.FieldError("Something", errors.New("something should not be empty")) + } + + return nil +} + +func (m *ValidatorMapMessage3_NestedType) Validate() error { + return nil +} + +var ValidatorMapMessage3SomeStringMapRE = regexp.MustCompile(`^[a-z]{2,5}$`) + +func (m *ValidatorMapMessage3) Validate() error { + for _, item := range m.GetSomeStringMap() { + if !ValidatorMapMessage3SomeStringMapRE.MatchString(string(item)) { + return go_proto_validators.FieldError("SomeStringMap", errors.New(`SomeStringMap should match regular expression "^[a-z]{2,5}$"`)) + } + } + + for _, item := range m.GetSomeExtMap() { + if item != nil { + if err := go_proto_validators.CallValidatorIfExists(item); err != nil { + return go_proto_validators.FieldError("SomeExtMap", err) + } + } + } + + for _, item := range m.GetSomeNestedMap() { + if item != nil { + if err := go_proto_validators.CallValidatorIfExists(item); err != nil { + return go_proto_validators.FieldError("SomeNestedMap", err) + } + } + if item == nil { + return go_proto_validators.FieldError("SomeNestedMap", errors.New("SomeNestedMap should be set")) + } + } + + return nil +} diff --git a/test/validator_proto3_oneof.pb.go b/test/validator_proto3_oneof.pb.go new file mode 100644 index 0000000..8a080ca --- /dev/null +++ b/test/validator_proto3_oneof.pb.go @@ -0,0 +1,364 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: test/validator_proto3_oneof.proto + +package validatortest + +import ( + proto "github.com/golang/protobuf/proto" + _ "github.com/mwitkow/go-proto-validators" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type ExternalMsg struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identifier string `protobuf:"bytes,1,opt,name=Identifier,proto3" json:"Identifier,omitempty"` + SomeValue int64 `protobuf:"varint,2,opt,name=SomeValue,proto3" json:"SomeValue,omitempty"` +} + +func (x *ExternalMsg) Reset() { + *x = ExternalMsg{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_oneof_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExternalMsg) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalMsg) ProtoMessage() {} + +func (x *ExternalMsg) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_oneof_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalMsg.ProtoReflect.Descriptor instead. +func (*ExternalMsg) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_oneof_proto_rawDescGZIP(), []int{0} +} + +func (x *ExternalMsg) GetIdentifier() string { + if x != nil { + return x.Identifier + } + return "" +} + +func (x *ExternalMsg) GetSomeValue() int64 { + if x != nil { + return x.SomeValue + } + return 0 +} + +type OneOfMessage3 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SomeInt uint32 `protobuf:"varint,1,opt,name=SomeInt,proto3" json:"SomeInt,omitempty"` + // Types that are assignable to Type: + // *OneOfMessage3_OneMsg + // *OneOfMessage3_OneInt + // *OneOfMessage3_TwoInt + Type isOneOfMessage3_Type `protobuf_oneof:"type"` + // Types that are assignable to Something: + // *OneOfMessage3_ThreeInt + // *OneOfMessage3_FourInt + // *OneOfMessage3_FiveRegex + Something isOneOfMessage3_Something `protobuf_oneof:"something"` +} + +func (x *OneOfMessage3) Reset() { + *x = OneOfMessage3{} + if protoimpl.UnsafeEnabled { + mi := &file_test_validator_proto3_oneof_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OneOfMessage3) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OneOfMessage3) ProtoMessage() {} + +func (x *OneOfMessage3) ProtoReflect() protoreflect.Message { + mi := &file_test_validator_proto3_oneof_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OneOfMessage3.ProtoReflect.Descriptor instead. +func (*OneOfMessage3) Descriptor() ([]byte, []int) { + return file_test_validator_proto3_oneof_proto_rawDescGZIP(), []int{1} +} + +func (x *OneOfMessage3) GetSomeInt() uint32 { + if x != nil { + return x.SomeInt + } + return 0 +} + +func (m *OneOfMessage3) GetType() isOneOfMessage3_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *OneOfMessage3) GetOneMsg() *ExternalMsg { + if x, ok := x.GetType().(*OneOfMessage3_OneMsg); ok { + return x.OneMsg + } + return nil +} + +func (x *OneOfMessage3) GetOneInt() uint32 { + if x, ok := x.GetType().(*OneOfMessage3_OneInt); ok { + return x.OneInt + } + return 0 +} + +func (x *OneOfMessage3) GetTwoInt() uint32 { + if x, ok := x.GetType().(*OneOfMessage3_TwoInt); ok { + return x.TwoInt + } + return 0 +} + +func (m *OneOfMessage3) GetSomething() isOneOfMessage3_Something { + if m != nil { + return m.Something + } + return nil +} + +func (x *OneOfMessage3) GetThreeInt() uint32 { + if x, ok := x.GetSomething().(*OneOfMessage3_ThreeInt); ok { + return x.ThreeInt + } + return 0 +} + +func (x *OneOfMessage3) GetFourInt() uint32 { + if x, ok := x.GetSomething().(*OneOfMessage3_FourInt); ok { + return x.FourInt + } + return 0 +} + +func (x *OneOfMessage3) GetFiveRegex() string { + if x, ok := x.GetSomething().(*OneOfMessage3_FiveRegex); ok { + return x.FiveRegex + } + return "" +} + +type isOneOfMessage3_Type interface { + isOneOfMessage3_Type() +} + +type OneOfMessage3_OneMsg struct { + OneMsg *ExternalMsg `protobuf:"bytes,2,opt,name=one_msg,json=oneMsg,proto3,oneof"` +} + +type OneOfMessage3_OneInt struct { + OneInt uint32 `protobuf:"varint,3,opt,name=one_int,json=oneInt,proto3,oneof"` +} + +type OneOfMessage3_TwoInt struct { + TwoInt uint32 `protobuf:"varint,4,opt,name=two_int,json=twoInt,proto3,oneof"` +} + +func (*OneOfMessage3_OneMsg) isOneOfMessage3_Type() {} + +func (*OneOfMessage3_OneInt) isOneOfMessage3_Type() {} + +func (*OneOfMessage3_TwoInt) isOneOfMessage3_Type() {} + +type isOneOfMessage3_Something interface { + isOneOfMessage3_Something() +} + +type OneOfMessage3_ThreeInt struct { + ThreeInt uint32 `protobuf:"varint,5,opt,name=three_int,json=threeInt,proto3,oneof"` +} + +type OneOfMessage3_FourInt struct { + FourInt uint32 `protobuf:"varint,6,opt,name=four_int,json=fourInt,proto3,oneof"` +} + +type OneOfMessage3_FiveRegex struct { + FiveRegex string `protobuf:"bytes,7,opt,name=five_regex,json=fiveRegex,proto3,oneof"` +} + +func (*OneOfMessage3_ThreeInt) isOneOfMessage3_Something() {} + +func (*OneOfMessage3_FourInt) isOneOfMessage3_Something() {} + +func (*OneOfMessage3_FiveRegex) isOneOfMessage3_Something() {} + +var File_test_validator_proto3_oneof_proto protoreflect.FileDescriptor + +var file_test_validator_proto3_oneof_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, + 0x73, 0x74, 0x1a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, + 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x0b, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x73, 0x67, 0x12, 0x32, 0x0a, 0x0a, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x12, + 0xe2, 0xdf, 0x1f, 0x0e, 0x0a, 0x0c, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x5d, 0x7b, 0x32, 0x2c, 0x35, + 0x7d, 0x24, 0x52, 0x0a, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x26, + 0x0a, 0x09, 0x53, 0x6f, 0x6d, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x42, 0x08, 0xe2, 0xdf, 0x1f, 0x04, 0x10, 0x00, 0x18, 0x64, 0x52, 0x09, 0x53, 0x6f, 0x6d, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xcc, 0x02, 0x0a, 0x0d, 0x4f, 0x6e, 0x65, 0x4f, 0x66, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x33, 0x12, 0x20, 0x0a, 0x07, 0x53, 0x6f, 0x6d, 0x65, + 0x49, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, + 0x0a, 0x52, 0x07, 0x53, 0x6f, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x07, 0x6f, 0x6e, + 0x65, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x73, 0x67, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x6e, 0x65, 0x4d, 0x73, + 0x67, 0x12, 0x21, 0x0a, 0x07, 0x6f, 0x6e, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x14, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x6e, + 0x65, 0x49, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x74, 0x77, 0x6f, 0x5f, 0x69, 0x6e, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x64, 0x48, 0x00, 0x52, + 0x06, 0x74, 0x77, 0x6f, 0x49, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x65, + 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, + 0x10, 0x14, 0x48, 0x01, 0x52, 0x08, 0x74, 0x68, 0x72, 0x65, 0x65, 0x49, 0x6e, 0x74, 0x12, 0x23, + 0x0a, 0x08, 0x66, 0x6f, 0x75, 0x72, 0x5f, 0x69, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, + 0x42, 0x06, 0xe2, 0xdf, 0x1f, 0x02, 0x10, 0x64, 0x48, 0x01, 0x52, 0x07, 0x66, 0x6f, 0x75, 0x72, + 0x49, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x0a, 0x66, 0x69, 0x76, 0x65, 0x5f, 0x72, 0x65, 0x67, 0x65, + 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x12, 0xe2, 0xdf, 0x1f, 0x0e, 0x0a, 0x0c, 0x5e, + 0x5b, 0x61, 0x2d, 0x7a, 0x5d, 0x7b, 0x32, 0x2c, 0x35, 0x7d, 0x24, 0x48, 0x01, 0x52, 0x09, 0x66, + 0x69, 0x76, 0x65, 0x52, 0x65, 0x67, 0x65, 0x78, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x42, 0x13, 0x0a, 0x09, 0x73, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x12, 0x06, 0xea, + 0xdf, 0x1f, 0x02, 0x08, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_test_validator_proto3_oneof_proto_rawDescOnce sync.Once + file_test_validator_proto3_oneof_proto_rawDescData = file_test_validator_proto3_oneof_proto_rawDesc +) + +func file_test_validator_proto3_oneof_proto_rawDescGZIP() []byte { + file_test_validator_proto3_oneof_proto_rawDescOnce.Do(func() { + file_test_validator_proto3_oneof_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_validator_proto3_oneof_proto_rawDescData) + }) + return file_test_validator_proto3_oneof_proto_rawDescData +} + +var file_test_validator_proto3_oneof_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_test_validator_proto3_oneof_proto_goTypes = []interface{}{ + (*ExternalMsg)(nil), // 0: validatortest.ExternalMsg + (*OneOfMessage3)(nil), // 1: validatortest.OneOfMessage3 +} +var file_test_validator_proto3_oneof_proto_depIdxs = []int32{ + 0, // 0: validatortest.OneOfMessage3.one_msg:type_name -> validatortest.ExternalMsg + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_test_validator_proto3_oneof_proto_init() } +func file_test_validator_proto3_oneof_proto_init() { + if File_test_validator_proto3_oneof_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_validator_proto3_oneof_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExternalMsg); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_validator_proto3_oneof_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OneOfMessage3); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_test_validator_proto3_oneof_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*OneOfMessage3_OneMsg)(nil), + (*OneOfMessage3_OneInt)(nil), + (*OneOfMessage3_TwoInt)(nil), + (*OneOfMessage3_ThreeInt)(nil), + (*OneOfMessage3_FourInt)(nil), + (*OneOfMessage3_FiveRegex)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_validator_proto3_oneof_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_validator_proto3_oneof_proto_goTypes, + DependencyIndexes: file_test_validator_proto3_oneof_proto_depIdxs, + MessageInfos: file_test_validator_proto3_oneof_proto_msgTypes, + }.Build() + File_test_validator_proto3_oneof_proto = out.File + file_test_validator_proto3_oneof_proto_rawDesc = nil + file_test_validator_proto3_oneof_proto_goTypes = nil + file_test_validator_proto3_oneof_proto_depIdxs = nil +} diff --git a/test/validator_proto3_oneof.proto b/test/validator_proto3_oneof.proto index 8042963..21007c9 100644 --- a/test/validator_proto3_oneof.proto +++ b/test/validator_proto3_oneof.proto @@ -4,26 +4,28 @@ syntax = "proto3"; package validatortest; -import "github.com/mwitkow/go-proto-validators/validator.proto"; +import "github.com/mwitkow/go-proto-validators/validators.proto"; message ExternalMsg { - string Identifier = 1 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; - int64 SomeValue = 2 [(validator.field) = {int_gt: 0, int_lt: 100}]; + 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}]; + 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}]; + uint32 one_int = 3 [ (validator.field) = {int_gt : 20} ]; + uint32 two_int = 4 [ (validator.field) = {int_gt : 100} ]; } oneof something { - option (validator.oneof) = {required: true}; - uint32 three_int = 5 [(validator.field) = {int_gt: 20}]; - uint32 four_int = 6 [(validator.field) = {int_gt: 100}]; - string five_regex = 7 [(validator.field) = {regex: "^[a-z]{2,5}$"}]; + option (validator.oneof) = { + required : true + }; + uint32 three_int = 5 [ (validator.field) = {int_gt : 20} ]; + uint32 four_int = 6 [ (validator.field) = {int_gt : 100} ]; + string five_regex = 7 [ (validator.field) = {regex : "^[a-z]{2,5}$"} ]; } } diff --git a/test/validator_proto3_oneof.validator.pb.go b/test/validator_proto3_oneof.validator.pb.go new file mode 100644 index 0000000..dfaace1 --- /dev/null +++ b/test/validator_proto3_oneof.validator.pb.go @@ -0,0 +1,78 @@ +// Code generated by protoc-gen-govalidators. DO NOT EDIT. + +package validatortest + +import ( + errors "errors" + go_proto_validators "github.com/mwitkow/go-proto-validators" + regexp "regexp" +) + +var ExternalMsgIdentifierRE = regexp.MustCompile(`^[a-z]{2,5}$`) + +func (m *ExternalMsg) Validate() error { + if !ExternalMsgIdentifierRE.MatchString(string(m.GetIdentifier())) { + return go_proto_validators.FieldError("Identifier", errors.New(`Identifier should match regular expression "^[a-z]{2,5}$"`)) + } + + if m.GetSomeValue() <= 0 { + return go_proto_validators.FieldError("SomeValue", errors.New("SomeValue is not greater than 0")) + } + if m.GetSomeValue() >= 100 { + return go_proto_validators.FieldError("SomeValue", errors.New("SomeValue is not smaller than 100")) + } + + return nil +} + +var OneOfMessage3FiveRegexRE = regexp.MustCompile(`^[a-z]{2,5}$`) + +func (m *OneOfMessage3) Validate() error { + if m.GetSomething() == nil { + return go_proto_validators.FieldError("Something", errors.New("one of the fields must be set")) + } + + if m.GetSomeInt() <= 10 { + return go_proto_validators.FieldError("SomeInt", errors.New("SomeInt is not greater than 10")) + } + + if _, ok := m.Type.(*OneOfMessage3_OneMsg); ok { + if m.GetOneMsg() != nil { + if err := go_proto_validators.CallValidatorIfExists(m.GetOneMsg()); err != nil { + return go_proto_validators.FieldError("OneMsg", err) + } + } + } + + if _, ok := m.Type.(*OneOfMessage3_OneInt); ok { + if m.GetOneInt() <= 20 { + return go_proto_validators.FieldError("OneInt", errors.New("one_int is not greater than 20")) + } + } + + if _, ok := m.Type.(*OneOfMessage3_TwoInt); ok { + if m.GetTwoInt() <= 100 { + return go_proto_validators.FieldError("TwoInt", errors.New("two_int is not greater than 100")) + } + } + + if _, ok := m.Something.(*OneOfMessage3_ThreeInt); ok { + if m.GetThreeInt() <= 20 { + return go_proto_validators.FieldError("ThreeInt", errors.New("three_int is not greater than 20")) + } + } + + if _, ok := m.Something.(*OneOfMessage3_FourInt); ok { + if m.GetFourInt() <= 100 { + return go_proto_validators.FieldError("FourInt", errors.New("four_int is not greater than 100")) + } + } + + if _, ok := m.Something.(*OneOfMessage3_FiveRegex); ok { + if !OneOfMessage3FiveRegexRE.MatchString(string(m.GetFiveRegex())) { + return go_proto_validators.FieldError("FiveRegex", errors.New(`five_regex should match regular expression "^[a-z]{2,5}$"`)) + } + } + + return nil +} diff --git a/test/golang/validator_test.go b/test/validator_test.go similarity index 55% rename from test/golang/validator_test.go rename to test/validator_test.go index c8a4934..3a577e3 100644 --- a/test/golang/validator_test.go +++ b/test/validator_test.go @@ -4,11 +4,10 @@ package validatortest import ( - fmt "fmt" - "strings" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var ( @@ -36,15 +35,12 @@ func buildProto3(someString string, someInt uint32, identifier string, someValue SomeStringNoQuotes: someString, SomeStringUnescaped: someString, - SomeInt: someInt, - SomeIntRep: []uint32{someInt, 12, 13, 14, 15, 16}, - SomeIntRepNonNull: []uint32{someInt, 102}, + SomeInt: someInt, + SomeIntRep: []uint32{someInt, 12, 13, 14, 15, 16}, - SomeEmbedded: nil, - SomeEmbeddedNonNullable: goodEmbeddedProto3, - SomeEmbeddedExists: goodEmbeddedProto3, - SomeEmbeddedRep: []*ValidatorMessage3_EmbeddedMessage{goodEmbeddedProto3}, - SomeEmbeddedRepNonNullable: []*ValidatorMessage3_EmbeddedMessage{goodEmbeddedProto3}, + SomeEmbedded: nil, + SomeEmbeddedExists: goodEmbeddedProto3, + SomeEmbeddedRep: []*ValidatorMessage3_EmbeddedMessage{goodEmbeddedProto3}, StrictSomeDouble: someDoubleStrict, StrictSomeDoubleRep: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, @@ -53,12 +49,10 @@ func buildProto3(someString string, someInt uint32, identifier string, someValue 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}, + SomeDouble: someDouble, + SomeDoubleRep: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeFloat: someFloat, + SomeFloatRep: []float32{someFloat, 0.5, 0.55, 0.6}, SomeNonEmptyString: nonEmptyString, SomeStringEqReq: someStringLength, @@ -76,8 +70,6 @@ func buildProto3(someString string, someInt uint32, identifier string, someValue SomeEnum: EnumProto3(someEnum), SomeEmbeddedEnum: ValidatorMessage3_EmbeddedEnum(someEmbeddedEnum), - - SomeGogoEmbedded: goodEmbeddedProto3, } goodProto3.Repeated = make([]int32, repeatedCount) @@ -97,41 +89,26 @@ func buildProto2(someString string, someInt uint32, identifier string, } goodProto2 := &ValidatorMessage{ - StringReq: &someString, - StringReqNonNull: &someString, - - StringOpt: nil, - StringOptNonNull: &someString, - + StringReq: &someString, + StringOpt: nil, + StringNoQuotes: &someString, StringUnescaped: &someString, - IntReq: &someInt, - IntReqNonNull: &someInt, - IntRep: []uint32{someInt, 12, 13, 14, 15, 16}, - IntRepNonNull: []uint32{someInt, 12, 13, 14, 15, 16}, + IntReq: &someInt, + IntRep: []uint32{someInt, 12, 13, 14, 15, 16}, - EmbeddedReq: goodEmbeddedProto2, - EmbeddedNonNull: goodEmbeddedProto2, - EmbeddedRep: []*ValidatorMessage_EmbeddedMessage{goodEmbeddedProto2}, - EmbeddedRepNonNullable: []*ValidatorMessage_EmbeddedMessage{goodEmbeddedProto2}, + EmbeddedReq: goodEmbeddedProto2, + EmbeddedRep: []*ValidatorMessage_EmbeddedMessage{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}, + StrictSomeDoubleReq: &someDoubleStrict, + StrictSomeDoubleRep: []float64{someDoubleStrict, 0.5, 0.55, 0.6}, + StrictSomeFloatReq: &someFloatStrict, + StrictSomeFloatRep: []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}, + SomeDoubleReq: &someDouble, + SomeDoubleRep: []float64{someDouble, 0.5, 0.55, 0.6}, + SomeFloatReq: &someFloat, + SomeFloatRep: []float32{someFloat, 0.5, 0.55, 0.6}, SomeNonEmptyString: &nonEmptyString, SomeStringEqReq: &someStringLength, @@ -155,355 +132,308 @@ func buildProto2(someString string, someInt uint32, identifier string, } 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, uuid1, uuid4, 1, 1) - err = goodProto3.Validate() - if err != nil { - t.Fatalf("unexpected fail in validator: %v", err) - } + assert.NoError(t, goodProto3.Validate()) } 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, uuid1, uuid4, 1, 1) - - err = goodProto2.Validate() - if err != nil { - t.Fatalf("unexpected fail in validator: %v", err) - } + assert.NoError(t, goodProto2.Validate()) } func TestStringRegex(t *testing.T) { - tooLong1Proto3 := buildProto3("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if tooLong1Proto3.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, uuid1, uuid4, 0, 0) - if tooLong1Proto2.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, uuid1, uuid4, 0, 0) - if tooLong2Proto3.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, uuid1, uuid4, 0, 0) - if tooLong2Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + tooLongProto3 := buildProto3("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) + assert.Error(t, tooLongProto3.Validate()) + + tooLongProto2 := buildProto2("toolong", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) + assert.Error(t, tooLongProto2.Validate()) + + mismatchProto3 := buildProto3("-%ab", 11, "bad#", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) + assert.Error(t, mismatchProto3.Validate()) + + mismatchProto2 := buildProto2("-%ab", 11, "bad#", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) + assert.Error(t, mismatchProto2.Validate()) } func TestIntLowerBounds(t *testing.T) { lowerThan10Proto3 := buildProto3("-%ab", 9, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan10Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan10Proto3.Validate()) + lowerThan10Proto2 := buildProto2("-%ab", 9, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan10Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan10Proto2.Validate()) + lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", -1, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan0Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan0Proto3.Validate()) + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", -1, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan0Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan0Proto2.Validate()) } func TestIntUpperBounds(t *testing.T) { greaterThan100Proto3 := buildProto3("-%ab", 11, "abba", 101, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan100Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, greaterThan100Proto3.Validate()) + greaterThan100Proto2 := buildProto2("-%ab", 11, "abba", 101, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan100Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, greaterThan100Proto2.Validate()) } func TestDoubleStrictLowerBounds(t *testing.T) { lowerThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.3, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan035EpsilonProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan035EpsilonProto3.Validate()) + lowerThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.3, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan035EpsilonProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan035EpsilonProto2.Validate()) + greaterThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.300000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan035EpsilonProto3.Validate() != nil { - t.Fatalf("unexpected fail in validator") - } + assert.NoError(t, greaterThan035EpsilonProto3.Validate()) + greaterThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.300000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan035EpsilonProto2.Validate() != nil { - t.Fatalf("unexpected fail in validator") - } + assert.NoError(t, greaterThan035EpsilonProto2.Validate()) } func TestDoubleStrictUpperBounds(t *testing.T) { greaterThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.70000000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan065EpsilonProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, greaterThan065EpsilonProto3.Validate()) + greaterThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.70000000001, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan065EpsilonProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, greaterThan065EpsilonProto2.Validate()) + lowerThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.6999999999, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan065EpsilonProto3.Validate() != nil { - t.Fatalf("unexpected fail in validator") - } + assert.NoError(t, lowerThan065EpsilonProto3.Validate()) + lowerThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.6999999999, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan065EpsilonProto2.Validate() != nil { - t.Fatalf("unexpected fail in validator") - } + assert.NoError(t, lowerThan065EpsilonProto2.Validate()) } func TestFloatStrictLowerBounds(t *testing.T) { lowerThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.2999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan035EpsilonProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan035EpsilonProto3.Validate()) + lowerThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.2999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan035EpsilonProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan035EpsilonProto2.Validate()) + greaterThan035EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.3000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := greaterThan035EpsilonProto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, greaterThan035EpsilonProto3.Validate()) + greaterThan035EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.3000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := greaterThan035EpsilonProto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, greaterThan035EpsilonProto2.Validate()) } func TestFloatStrictUpperBounds(t *testing.T) { greaterThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.7000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan065EpsilonProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, greaterThan065EpsilonProto3.Validate()) + greaterThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.7000001, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if greaterThan065EpsilonProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, greaterThan065EpsilonProto2.Validate()) + lowerThan065EpsilonProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.6999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := lowerThan065EpsilonProto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, lowerThan065EpsilonProto3.Validate()) + lowerThan065EpsilonProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.6999999, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := lowerThan065EpsilonProto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, lowerThan065EpsilonProto2.Validate()) } func TestDoubleNonStrictLowerBounds(t *testing.T) { lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.2499999, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan0Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan0Proto3.Validate()) + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.2499999, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan0Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan0Proto2.Validate()) + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.25, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto3.Validate()) + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.25, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto2.Validate()) } func TestDoubleNonStrictUpperBounds(t *testing.T) { higherThan1Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75111111, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if higherThan1Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, higherThan1Proto3.Validate()) + higherThan1Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75111111, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if higherThan1Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, higherThan1Proto2.Validate()) + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto3.Validate()) + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.75, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto2.Validate()) } func TestFloatNonStrictLowerBounds(t *testing.T) { lowerThan0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.2499999, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan0Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan0Proto3.Validate()) + lowerThan0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.2499999, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if lowerThan0Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, lowerThan0Proto2.Validate()) + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.25, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto3.Validate()) + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.25, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto2.Validate()) } func TestFloatNonStrictUpperBounds(t *testing.T) { higherThan1Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75111111, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if higherThan1Proto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, higherThan1Proto3.Validate()) + higherThan1Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75111111, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if higherThan1Proto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, higherThan1Proto2.Validate()) + equalTo0Proto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto3.Validate()) + equalTo0Proto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.75, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := equalTo0Proto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, equalTo0Proto2.Validate()) } func TestStringNonEmpty(t *testing.T) { emptyStringProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if emptyStringProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, emptyStringProto3.Validate()) + emptyStringProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if emptyStringProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, emptyStringProto2.Validate()) + nonEmptyStringProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := nonEmptyStringProto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, nonEmptyStringProto3.Validate()) + nonEmptyStringProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := nonEmptyStringProto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, nonEmptyStringProto2.Validate()) } func TestRepeatedEltsCount(t *testing.T) { notEnoughEltsProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 1, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if notEnoughEltsProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, notEnoughEltsProto3.Validate()) + notEnoughEltsProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 1, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if notEnoughEltsProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, notEnoughEltsProto2.Validate()) + tooManyEltsProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 14, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if tooManyEltsProto3.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, tooManyEltsProto3.Validate()) + tooManyEltsProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 14, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if tooManyEltsProto2.Validate() == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, tooManyEltsProto2.Validate()) + validEltsCountProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := validEltsCountProto3.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, validEltsCountProto3.Validate()) + validEltsCountProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) - if err := validEltsCountProto2.Validate(); err != nil { - t.Fatalf("unexpected fail in validator %v", err) - } + assert.NoError(t, validEltsCountProto2.Validate()) } func TestMsgExist(t *testing.T) { someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) someProto3.SomeEmbedded = nil - if err := someProto3.Validate(); err != nil { - t.Fatalf("validate shouldn't fail on missing SomeEmbedded, not annotated") - } + assert.NoError(t, someProto3.Validate()) + 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) - } + err := someProto3.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid field SomeEmbeddedExists:") } func TestStringLengthValidator(t *testing.T) { - StringLengthErrorProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "abc456", stableBytes, uuid1, uuid4, 0, 0) - 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, uuid1, uuid4, 0, 0) - if err := StringLengthSuccess.Validate(); err != nil { - t.Fatalf("validate shouldn't fail on equal length") - } + stringLengthErrorProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "abc456", stableBytes, uuid1, uuid4, 0, 0) + assert.Error(t, stringLengthErrorProto3.Validate()) + + stringLengthSuccess := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) + assert.NoError(t, stringLengthSuccess.Validate()) } func TestBytesLengthValidator(t *testing.T) { - StringLengthErrorProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "abc456", []byte("anc"), uuid1, uuid4, 0, 0) - 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, uuid1, uuid4, 0, 0) - if err := StringLengthSuccess.Validate(); err != nil { - t.Fatalf("validate shouldn't fail on equal length") - } + stringLengthErrorProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "abc456", []byte("anc"), uuid1, uuid4, 0, 0) + assert.Error(t, stringLengthErrorProto3.Validate()) + + stringLengthSuccess := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) + assert.NoError(t, stringLengthSuccess.Validate()) } func TestValueIsInEnum(t *testing.T) { outOfTopLevelEnumProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 2, 0) - if err := outOfTopLevelEnumProto3.Validate(); err == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, outOfTopLevelEnumProto3.Validate()) + outOfTopLevelEnumProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 2, 0) - if err := outOfTopLevelEnumProto2.Validate(); err == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, outOfTopLevelEnumProto2.Validate()) + outOfEmbeddedEnumProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 2) - if err := outOfEmbeddedEnumProto3.Validate(); err == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, outOfEmbeddedEnumProto3.Validate()) + outOfEmbeddedEnumProto2 := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 2) - if err := outOfEmbeddedEnumProto2.Validate(); err == nil { - t.Fatalf("expected fail in validator, but it didn't happen") - } + assert.Error(t, outOfEmbeddedEnumProto2.Validate()) } func TestNestedError3(t *testing.T) { someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) 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) - } + err := someProto3.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid field SomeEmbeddedExists.SomeValue:") } func TestCustomError_Proto3(t *testing.T) { someProto3 := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, uuid4, 0, 0) 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()) - } + err := someProto3.Validate() + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid field CustomErrorInt: My Custom Error") } func TestMapAlwaysPassesUntilFixedProperly(t *testing.T) { example := &ValidatorMapMessage3{} - if err := example.Validate(); err != nil { - t.Fatalf("map validators should always pass") + assert.NoError(t, example.Validate()) +} + +func TestMapPrimitiveTypeValuesAreValidates(t *testing.T) { + mapError := &ValidatorMapMessage3{ + SomeStringMap: map[string]string{ + "foo": "toolong", + }, + } + assert.Error(t, mapError.Validate()) + + mapSucces := &ValidatorMapMessage3{ + SomeStringMap: map[string]string{ + "foo": "abba", + }, } + assert.NoError(t, mapSucces.Validate()) +} + +func TestMapNestedStructsAreValidated(t *testing.T) { + mapError1 := &ValidatorMapMessage3{ + SomeExtMap: map[string]*ValueType{ + "foo": {Something: "foo"}, + "bar": {Something: ""}, + }, + } + assert.Error(t, mapError1.Validate()) + + mapError2 := &ValidatorMapMessage3{ + SomeNestedMap: map[int32]*ValidatorMapMessage3_NestedType{ + 0: nil, + }, + } + assert.Error(t, mapError2.Validate()) + + mapSucces1 := &ValidatorMapMessage3{ + SomeExtMap: map[string]*ValueType{ + "foo": {Something: "foo"}, + "bar": {Something: "bar"}, + }, + } + assert.NoError(t, mapSucces1.Validate()) + + mapSucces := &ValidatorMapMessage3{ + SomeNestedMap: map[int32]*ValidatorMapMessage3_NestedType{ + 0: {}, + }, + } + assert.NoError(t, mapSucces.Validate()) } func TestOneOf_Required(t *testing.T) { @@ -511,8 +441,8 @@ func TestOneOf_Required(t *testing.T) { SomeInt: 30, } err := example.Validate() - assert.Error(t, err, "oneof.required should fail if none of the oneof fields are set") - assert.Contains(t, err.Error(), "Something", "error must err on the Something field") + require.Error(t, err, "oneof.required should fail if none of the oneof fields are set") + assert.Contains(t, err.Error(), "invalid field Something:") } func TestOneOf_NestedMessage(t *testing.T) { @@ -529,7 +459,7 @@ func TestOneOf_NestedMessage(t *testing.T) { }, } err := example.Validate() - assert.Error(t, err, "nested message in oneof should fail validation on ExternalMsg") + require.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") } @@ -547,7 +477,7 @@ func TestOneOf_NestedInt(t *testing.T) { }, } err := example.Validate() - assert.Error(t, err, "nested message in oneof should fail validation on ThreeInt") + require.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") } @@ -576,7 +506,7 @@ func TestOneOf_Regex(t *testing.T) { }, } err := example.Validate() - assert.Error(t, err, "regex applied to oneof field should fail validation on FiveRegex") + require.Error(t, err, "regex applied to oneof field should fail validation on FiveRegex") assert.Contains(t, err.Error(), "FiveRegex", "error must err on the FiveRegex") example = &OneOfMessage3{ @@ -590,51 +520,54 @@ func TestOneOf_Regex(t *testing.T) { } func TestUUID4Validation(t *testing.T) { - testcases := []struct { + testcases := map[string]struct { uuid string fail bool }{ - { + "UUID1": { uuid: uuid1, fail: true, }, - { + "UUID4": { uuid: uuid4, fail: false, }, - { + "EmptyField": { uuid: "", fail: true, }, - { + "NonUUID1": { uuid: "66bb25e2-2e0d", fail: true, }, - { + "NonUUID2": { uuid: "1234abcd", fail: true, }, } - for _, tc := range testcases { - t.Run(fmt.Sprintf("proto2 uuid '%s'", tc.uuid), func(t *testing.T) { - msg := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, tc.uuid, 0, 0) - - err := msg.Validate() - failed := err != nil - if tc.fail != failed { - t.Errorf("Expected validation failure: %t, but got %t, err: %v", tc.fail, failed, err) - } - }) - - t.Run(fmt.Sprintf("proto3 uuid '%s'", tc.uuid), func(t *testing.T) { - msg := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, tc.uuid, 0, 0) - - err := msg.Validate() - failed := err != nil - if tc.fail != failed { - t.Errorf("Expected validation failure: %t, but got %t, err: %v", tc.fail, failed, err) - } + for name := range testcases { + tc := testcases[name] + t.Run(name, func(t *testing.T) { + t.Run("Proto2", func(t *testing.T) { + msg := buildProto2("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, tc.uuid, 0, 0) + + if tc.fail { + assert.Error(t, msg.Validate()) + } else { + assert.NoError(t, msg.Validate()) + } + }) + + t.Run("Proto3", func(t *testing.T) { + msg := buildProto3("-%ab", 11, "abba", 99, 0.5, 0.5, 0.5, 0.5, "x", 4, "1234567890", stableBytes, uuid1, tc.uuid, 0, 0) + + if tc.fail { + assert.Error(t, msg.Validate()) + } else { + assert.NoError(t, msg.Validate()) + } + }) }) } } diff --git a/validator.pb.go b/validator.pb.go deleted file mode 100644 index b2befcf..0000000 --- a/validator.pb.go +++ /dev/null @@ -1,326 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: validator.proto - -package validator - -import ( - fmt "fmt" - proto "github.com/gogo/protobuf/proto" - descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" - math "math" -) - -// 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"` - // Requires that the value is in the enum. - IsInEnum *bool `protobuf:"varint,17,opt,name=is_in_enum,json=isInEnum" json:"is_in_enum,omitempty"` - // Ensures that a string value is in UUID format. - // uuid_ver specifies the valid UUID versions. Valid values are: 0-5. - // If uuid_ver is 0 all UUID versions are accepted. - UuidVer *int32 `protobuf:"varint,18,opt,name=uuid_ver,json=uuidVer" json:"uuid_ver,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `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 fileDescriptor_bf1c6ec7c0d80dd5, []int{0} -} -func (m *FieldValidator) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_FieldValidator.Unmarshal(m, b) -} -func (m *FieldValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_FieldValidator.Marshal(b, m, deterministic) -} -func (m *FieldValidator) XXX_Merge(src proto.Message) { - xxx_messageInfo_FieldValidator.Merge(m, src) -} -func (m *FieldValidator) XXX_Size() int { - return xxx_messageInfo_FieldValidator.Size(m) -} -func (m *FieldValidator) XXX_DiscardUnknown() { - xxx_messageInfo_FieldValidator.DiscardUnknown(m) -} - -var xxx_messageInfo_FieldValidator proto.InternalMessageInfo - -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 -} - -func (m *FieldValidator) GetIsInEnum() bool { - if m != nil && m.IsInEnum != nil { - return *m.IsInEnum - } - return false -} - -func (m *FieldValidator) GetUuidVer() int32 { - if m != nil && m.UuidVer != nil { - return *m.UuidVer - } - return 0 -} - -type OneofValidator struct { - // Require that one of the oneof fields is set. - Required *bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *OneofValidator) Reset() { *m = OneofValidator{} } -func (m *OneofValidator) String() string { return proto.CompactTextString(m) } -func (*OneofValidator) ProtoMessage() {} -func (*OneofValidator) Descriptor() ([]byte, []int) { - return fileDescriptor_bf1c6ec7c0d80dd5, []int{1} -} -func (m *OneofValidator) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_OneofValidator.Unmarshal(m, b) -} -func (m *OneofValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_OneofValidator.Marshal(b, m, deterministic) -} -func (m *OneofValidator) XXX_Merge(src proto.Message) { - xxx_messageInfo_OneofValidator.Merge(m, src) -} -func (m *OneofValidator) XXX_Size() int { - return xxx_messageInfo_OneofValidator.Size(m) -} -func (m *OneofValidator) XXX_DiscardUnknown() { - xxx_messageInfo_OneofValidator.DiscardUnknown(m) -} - -var xxx_messageInfo_OneofValidator proto.InternalMessageInfo - -func (m *OneofValidator) GetRequired() bool { - if m != nil && m.Required != nil { - return *m.Required - } - return false -} - -var E_Field = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.FieldOptions)(nil), - ExtensionType: (*FieldValidator)(nil), - Field: 65020, - Name: "validator.field", - Tag: "bytes,65020,opt,name=field", - Filename: "validator.proto", -} - -var E_Oneof = &proto.ExtensionDesc{ - ExtendedType: (*descriptor.OneofOptions)(nil), - ExtensionType: (*OneofValidator)(nil), - Field: 65021, - Name: "validator.oneof", - Tag: "bytes,65021,opt,name=oneof", - Filename: "validator.proto", -} - -func init() { - proto.RegisterType((*FieldValidator)(nil), "validator.FieldValidator") - proto.RegisterType((*OneofValidator)(nil), "validator.OneofValidator") - proto.RegisterExtension(E_Field) - proto.RegisterExtension(E_Oneof) -} - -func init() { proto.RegisterFile("validator.proto", fileDescriptor_bf1c6ec7c0d80dd5) } - -var fileDescriptor_bf1c6ec7c0d80dd5 = []byte{ - // 472 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0x41, 0x6f, 0xd4, 0x30, - 0x10, 0x85, 0x15, 0xda, 0xb4, 0x89, 0xb7, 0xdd, 0x2e, 0x16, 0x48, 0x6e, 0xa1, 0x22, 0x2a, 0x97, - 0x1c, 0xaa, 0x54, 0xe2, 0xc8, 0x11, 0x14, 0x56, 0x48, 0x0b, 0x45, 0x39, 0xf4, 0xc0, 0xc5, 0x0a, - 0xcd, 0x6c, 0x6a, 0xc9, 0xb1, 0xb3, 0xf6, 0xa4, 0x5a, 0x7e, 0x1d, 0x3f, 0x0c, 0x90, 0x90, 0x1d, - 0xb2, 0x49, 0xa5, 0x3d, 0xce, 0xfb, 0x26, 0x6f, 0xc6, 0xa3, 0x17, 0x72, 0xf6, 0x58, 0x4a, 0x51, - 0x95, 0xa8, 0x4d, 0xd6, 0x1a, 0x8d, 0x9a, 0xc6, 0x3b, 0xe1, 0x22, 0xa9, 0xb5, 0xae, 0x25, 0xdc, - 0x78, 0xf0, 0xa3, 0x5b, 0xdf, 0x54, 0x60, 0xef, 0x8d, 0x68, 0x77, 0xcd, 0x57, 0xbf, 0x0e, 0xc9, - 0xfc, 0x93, 0x00, 0x59, 0xdd, 0x0d, 0x1f, 0xd1, 0x17, 0x24, 0x34, 0x50, 0xc3, 0x96, 0x05, 0x49, - 0x90, 0xc6, 0x45, 0x5f, 0xd0, 0x97, 0xe4, 0x48, 0x28, 0xe4, 0x35, 0xb2, 0x67, 0x49, 0x90, 0x1e, - 0x14, 0xa1, 0x50, 0xb8, 0xc4, 0x41, 0x96, 0xc8, 0x0e, 0x76, 0xf2, 0x0a, 0xe9, 0x25, 0x21, 0x8d, - 0xad, 0x39, 0x6c, 0x85, 0x45, 0xcb, 0x0e, 0x93, 0x20, 0x8d, 0x8a, 0xb8, 0xb1, 0x75, 0xee, 0x05, - 0xfa, 0x86, 0xcc, 0x1e, 0xba, 0xa6, 0x54, 0x1c, 0x8c, 0xd1, 0x86, 0x85, 0x7e, 0x10, 0xf1, 0x52, - 0xee, 0x14, 0x7a, 0x4e, 0xa2, 0xb5, 0xd4, 0xa5, 0x9f, 0x77, 0x94, 0x04, 0x69, 0x50, 0x1c, 0xfb, - 0x7a, 0x89, 0x23, 0x92, 0xc8, 0x8e, 0x27, 0x68, 0x85, 0xf4, 0x2d, 0x39, 0xed, 0x11, 0xb4, 0x56, - 0x48, 0xad, 0x58, 0xe4, 0xf9, 0x89, 0x17, 0xf3, 0x5e, 0xa3, 0xaf, 0x48, 0x3c, 0x58, 0x03, 0x8b, - 0x7d, 0x43, 0xf4, 0xdf, 0x1b, 0x46, 0x28, 0x11, 0x18, 0x99, 0xc0, 0x15, 0x02, 0x4d, 0xc9, 0xc2, - 0xa2, 0x11, 0xaa, 0xe6, 0x4a, 0x23, 0x87, 0xa6, 0xc5, 0x9f, 0x6c, 0xe6, 0x9f, 0x36, 0xef, 0xf5, - 0xaf, 0x1a, 0x73, 0xa7, 0xd2, 0x6b, 0x42, 0x0d, 0xb4, 0x50, 0x22, 0x54, 0xfc, 0x5e, 0x77, 0x0a, - 0x79, 0x23, 0x14, 0x3b, 0xf1, 0x17, 0x5a, 0x0c, 0xe4, 0xa3, 0x03, 0x5f, 0x84, 0xda, 0xd7, 0x5d, - 0x6e, 0xd9, 0xe9, 0xbe, 0xee, 0x72, 0xeb, 0x56, 0x94, 0xa0, 0x6a, 0x7c, 0x70, 0xb7, 0x99, 0xfb, - 0xa6, 0xa8, 0x17, 0x96, 0x38, 0x81, 0x12, 0xd9, 0xd9, 0x14, 0xae, 0xa6, 0x10, 0x36, 0x6c, 0x31, - 0x85, 0xf9, 0x86, 0xbe, 0x26, 0x44, 0x58, 0x2e, 0x14, 0x07, 0xd5, 0x35, 0xec, 0xb9, 0x7f, 0x56, - 0x24, 0xec, 0x67, 0x95, 0xab, 0xae, 0x71, 0x47, 0xef, 0x3a, 0x51, 0xf1, 0x47, 0x30, 0x8c, 0x26, - 0x41, 0x1a, 0x16, 0xc7, 0xae, 0xbe, 0x03, 0x73, 0x75, 0x4d, 0xe6, 0xb7, 0x0a, 0xf4, 0x7a, 0x0c, - 0xd0, 0x05, 0x89, 0x0c, 0x6c, 0x3a, 0x61, 0xa0, 0xf2, 0x19, 0x8a, 0x8a, 0x5d, 0xfd, 0xfe, 0x1b, - 0x09, 0xd7, 0x2e, 0x6e, 0xf4, 0x32, 0xeb, 0xb3, 0x99, 0x0d, 0xd9, 0xcc, 0x7c, 0x0c, 0x6f, 0x5b, - 0x14, 0x5a, 0x59, 0xf6, 0xe7, 0xb7, 0xcb, 0xd3, 0xec, 0xdd, 0x79, 0x36, 0xc6, 0xfb, 0x69, 0x4e, - 0x8b, 0xde, 0xc8, 0x39, 0x6a, 0x37, 0x7f, 0x8f, 0xa3, 0xdf, 0x6b, 0x70, 0xfc, 0xbb, 0xc7, 0xf1, - 0xe9, 0xe2, 0x45, 0x6f, 0xf4, 0x61, 0xf6, 0x7d, 0xfc, 0x85, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, - 0x05, 0x20, 0x26, 0x13, 0x5f, 0x03, 0x00, 0x00, -} diff --git a/validator.proto b/validator.proto deleted file mode 100644 index 8b15acf..0000000 --- a/validator.proto +++ /dev/null @@ -1,80 +0,0 @@ -// 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 = "github.com/mwitkow/go-proto-validators;validator"; - -// TODO(mwitkow): Email protobuf-global-extension-registry@google.com to get an extension ID. - -extend google.protobuf.FieldOptions { - optional FieldValidator field = 65020; -} - -extend google.protobuf.OneofOptions { - optional OneofValidator oneof = 65021; -} - -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 length strictly equal to this value. - optional int64 length_eq = 16; - // Requires that the value is in the enum. - optional bool is_in_enum = 17; - // Ensures that a string value is in UUID format. - // uuid_ver specifies the valid UUID versions. Valid values are: 0-5. - // If uuid_ver is 0 all UUID versions are accepted. - optional int32 uuid_ver = 18; -} - -message OneofValidator { - // Require that one of the oneof fields is set. - optional bool required = 1; -} diff --git a/validator/validator.pb.go b/validator/validator.pb.go new file mode 100644 index 0000000..6f61dd4 --- /dev/null +++ b/validator/validator.pb.go @@ -0,0 +1,90 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: validator.proto + +package validator + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + math "math" +) + +// 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.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type FieldValidator struct { + CustomRegex *string `protobuf:"bytes,1,opt,name=customRegex" json:"customRegex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `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 fileDescriptor_bf1c6ec7c0d80dd5, []int{0} +} +func (m *FieldValidator) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FieldValidator.Unmarshal(m, b) +} +func (m *FieldValidator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FieldValidator.Marshal(b, m, deterministic) +} +func (m *FieldValidator) XXX_Merge(src proto.Message) { + xxx_messageInfo_FieldValidator.Merge(m, src) +} +func (m *FieldValidator) XXX_Size() int { + return xxx_messageInfo_FieldValidator.Size(m) +} +func (m *FieldValidator) XXX_DiscardUnknown() { + xxx_messageInfo_FieldValidator.DiscardUnknown(m) +} + +var xxx_messageInfo_FieldValidator proto.InternalMessageInfo + +func (m *FieldValidator) GetCustomRegex() string { + if m != nil && m.CustomRegex != nil { + return *m.CustomRegex + } + return "" +} + +var E_Field = &proto.ExtensionDesc{ + ExtendedType: (*descriptorpb.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", fileDescriptor_bf1c6ec7c0d80dd5) } + +var fileDescriptor_bf1c6ec7c0d80dd5 = []byte{ + // 157 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0x4b, 0xcc, 0xc9, + 0x4c, 0x49, 0x2c, 0xc9, 0x2f, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0x0b, 0x48, + 0x29, 0xa4, 0xe7, 0xe7, 0xa7, 0xe7, 0xa4, 0xea, 0x83, 0x25, 0x92, 0x4a, 0xd3, 0xf4, 0x53, 0x52, + 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0xe0, 0x8a, 0x95, 0x8c, 0xb8, 0xf8, 0xdc, 0x32, 0x53, 0x73, 0x52, + 0xc2, 0x60, 0x7a, 0x84, 0x14, 0xb8, 0xb8, 0x93, 0x4b, 0x8b, 0x4b, 0xf2, 0x73, 0x83, 0x52, 0xd3, + 0x53, 0x2b, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, 0x90, 0x85, 0xac, 0x02, 0xb8, 0x58, 0xd3, + 0x40, 0x7a, 0x84, 0x64, 0xf5, 0x20, 0xe6, 0xeb, 0xc1, 0xcc, 0xd7, 0x03, 0x9b, 0xe5, 0x5f, 0x50, + 0x92, 0x99, 0x9f, 0x57, 0x2c, 0xf1, 0xe7, 0x37, 0xb3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0xa4, 0x1e, + 0xc2, 0x89, 0xa8, 0x96, 0x05, 0x41, 0x0c, 0x72, 0xe2, 0x8d, 0xe2, 0xd6, 0xd3, 0x87, 0x2b, 0x02, + 0x04, 0x00, 0x00, 0xff, 0xff, 0x21, 0x51, 0x9e, 0x6b, 0xd3, 0x00, 0x00, 0x00, +} diff --git a/validator/validator.validator.pb.go b/validator/validator.validator.pb.go new file mode 100644 index 0000000..78a8dec --- /dev/null +++ b/validator/validator.validator.pb.go @@ -0,0 +1,20 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: validator.proto + +package validator + +import ( + fmt "fmt" + math "math" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/protobuf/types/descriptorpb" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +func (this *FieldValidator) Validate() error { + return nil +} diff --git a/validators.pb.go b/validators.pb.go new file mode 100644 index 0000000..a8ae578 --- /dev/null +++ b/validators.pb.go @@ -0,0 +1,435 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.12.3 +// source: github.com/mwitkow/go-proto-validators/validators.proto + +package validator + +import ( + proto "github.com/golang/protobuf/proto" + descriptor "github.com/golang/protobuf/protoc-gen-go/descriptor" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type FieldValidator struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Regex *string `protobuf:"bytes,1,opt,name=regex" json:"regex,omitempty"` + IntGt *int64 `protobuf:"varint,2,opt,name=int_gt,json=intGt" json:"int_gt,omitempty"` + IntLt *int64 `protobuf:"varint,3,opt,name=int_lt,json=intLt" json:"int_lt,omitempty"` + MsgExists *bool `protobuf:"varint,4,opt,name=msg_exists,json=msgExists" json:"msg_exists,omitempty"` + HumanError *string `protobuf:"bytes,5,opt,name=human_error,json=humanError" json:"human_error,omitempty"` + FloatGt *float64 `protobuf:"fixed64,6,opt,name=float_gt,json=floatGt" json:"float_gt,omitempty"` + FloatLt *float64 `protobuf:"fixed64,7,opt,name=float_lt,json=floatLt" json:"float_lt,omitempty"` + FloatEpsilon *float64 `protobuf:"fixed64,8,opt,name=float_epsilon,json=floatEpsilon" json:"float_epsilon,omitempty"` + FloatGte *float64 `protobuf:"fixed64,9,opt,name=float_gte,json=floatGte" json:"float_gte,omitempty"` + FloatLte *float64 `protobuf:"fixed64,10,opt,name=float_lte,json=floatLte" json:"float_lte,omitempty"` + StringNotEmpty *bool `protobuf:"varint,11,opt,name=string_not_empty,json=stringNotEmpty" json:"string_not_empty,omitempty"` + RepeatedCountMin *int64 `protobuf:"varint,12,opt,name=repeated_count_min,json=repeatedCountMin" json:"repeated_count_min,omitempty"` + RepeatedCountMax *int64 `protobuf:"varint,13,opt,name=repeated_count_max,json=repeatedCountMax" json:"repeated_count_max,omitempty"` + LengthGt *int64 `protobuf:"varint,14,opt,name=length_gt,json=lengthGt" json:"length_gt,omitempty"` + LengthLt *int64 `protobuf:"varint,15,opt,name=length_lt,json=lengthLt" json:"length_lt,omitempty"` + LengthEq *int64 `protobuf:"varint,16,opt,name=length_eq,json=lengthEq" json:"length_eq,omitempty"` + IsInEnum *bool `protobuf:"varint,17,opt,name=is_in_enum,json=isInEnum" json:"is_in_enum,omitempty"` + UuidVer *int32 `protobuf:"varint,18,opt,name=uuid_ver,json=uuidVer" json:"uuid_ver,omitempty"` +} + +func (x *FieldValidator) Reset() { + *x = FieldValidator{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FieldValidator) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FieldValidator) ProtoMessage() {} + +func (x *FieldValidator) ProtoReflect() protoreflect.Message { + mi := &file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FieldValidator.ProtoReflect.Descriptor instead. +func (*FieldValidator) Descriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescGZIP(), []int{0} +} + +func (x *FieldValidator) GetRegex() string { + if x != nil && x.Regex != nil { + return *x.Regex + } + return "" +} + +func (x *FieldValidator) GetIntGt() int64 { + if x != nil && x.IntGt != nil { + return *x.IntGt + } + return 0 +} + +func (x *FieldValidator) GetIntLt() int64 { + if x != nil && x.IntLt != nil { + return *x.IntLt + } + return 0 +} + +func (x *FieldValidator) GetMsgExists() bool { + if x != nil && x.MsgExists != nil { + return *x.MsgExists + } + return false +} + +func (x *FieldValidator) GetHumanError() string { + if x != nil && x.HumanError != nil { + return *x.HumanError + } + return "" +} + +func (x *FieldValidator) GetFloatGt() float64 { + if x != nil && x.FloatGt != nil { + return *x.FloatGt + } + return 0 +} + +func (x *FieldValidator) GetFloatLt() float64 { + if x != nil && x.FloatLt != nil { + return *x.FloatLt + } + return 0 +} + +func (x *FieldValidator) GetFloatEpsilon() float64 { + if x != nil && x.FloatEpsilon != nil { + return *x.FloatEpsilon + } + return 0 +} + +func (x *FieldValidator) GetFloatGte() float64 { + if x != nil && x.FloatGte != nil { + return *x.FloatGte + } + return 0 +} + +func (x *FieldValidator) GetFloatLte() float64 { + if x != nil && x.FloatLte != nil { + return *x.FloatLte + } + return 0 +} + +func (x *FieldValidator) GetStringNotEmpty() bool { + if x != nil && x.StringNotEmpty != nil { + return *x.StringNotEmpty + } + return false +} + +func (x *FieldValidator) GetRepeatedCountMin() int64 { + if x != nil && x.RepeatedCountMin != nil { + return *x.RepeatedCountMin + } + return 0 +} + +func (x *FieldValidator) GetRepeatedCountMax() int64 { + if x != nil && x.RepeatedCountMax != nil { + return *x.RepeatedCountMax + } + return 0 +} + +func (x *FieldValidator) GetLengthGt() int64 { + if x != nil && x.LengthGt != nil { + return *x.LengthGt + } + return 0 +} + +func (x *FieldValidator) GetLengthLt() int64 { + if x != nil && x.LengthLt != nil { + return *x.LengthLt + } + return 0 +} + +func (x *FieldValidator) GetLengthEq() int64 { + if x != nil && x.LengthEq != nil { + return *x.LengthEq + } + return 0 +} + +func (x *FieldValidator) GetIsInEnum() bool { + if x != nil && x.IsInEnum != nil { + return *x.IsInEnum + } + return false +} + +func (x *FieldValidator) GetUuidVer() int32 { + if x != nil && x.UuidVer != nil { + return *x.UuidVer + } + return 0 +} + +type OneofValidator struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Required *bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` +} + +func (x *OneofValidator) Reset() { + *x = OneofValidator{} + if protoimpl.UnsafeEnabled { + mi := &file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OneofValidator) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OneofValidator) ProtoMessage() {} + +func (x *OneofValidator) ProtoReflect() protoreflect.Message { + mi := &file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OneofValidator.ProtoReflect.Descriptor instead. +func (*OneofValidator) Descriptor() ([]byte, []int) { + return file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescGZIP(), []int{1} +} + +func (x *OneofValidator) GetRequired() bool { + if x != nil && x.Required != nil { + return *x.Required + } + return false +} + +var file_github_com_mwitkow_go_proto_validators_validators_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptor.FieldOptions)(nil), + ExtensionType: (*FieldValidator)(nil), + Field: 65020, + Name: "validator.field", + Tag: "bytes,65020,opt,name=field", + Filename: "github.com/mwitkow/go-proto-validators/validators.proto", + }, + { + ExtendedType: (*descriptor.OneofOptions)(nil), + ExtensionType: (*OneofValidator)(nil), + Field: 65021, + Name: "validator.oneof", + Tag: "bytes,65021,opt,name=oneof", + Filename: "github.com/mwitkow/go-proto-validators/validators.proto", + }, +} + +// Extension fields to descriptor.FieldOptions. +var ( + // optional validator.FieldValidator field = 65020; + E_Field = &file_github_com_mwitkow_go_proto_validators_validators_proto_extTypes[0] +) + +// Extension fields to descriptor.OneofOptions. +var ( + // optional validator.OneofValidator oneof = 65021; + E_Oneof = &file_github_com_mwitkow_go_proto_validators_validators_proto_extTypes[1] +) + +var File_github_com_mwitkow_go_proto_validators_validators_proto protoreflect.FileDescriptor + +var file_github_com_mwitkow_go_proto_validators_validators_proto_rawDesc = []byte{ + 0x0a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, + 0x74, 0x6b, 0x6f, 0x77, 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x04, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, + 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, + 0x15, 0x0a, 0x06, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x05, 0x69, 0x6e, 0x74, 0x47, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x69, 0x6e, 0x74, 0x5f, 0x6c, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x69, 0x6e, 0x74, 0x4c, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x6d, 0x73, 0x67, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x6d, 0x73, 0x67, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, + 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x68, 0x75, 0x6d, 0x61, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, + 0x08, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x67, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x07, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x47, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x5f, 0x6c, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x4c, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x65, 0x70, 0x73, + 0x69, 0x6c, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0c, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x45, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x5f, 0x67, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x47, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x6c, + 0x74, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x4c, + 0x74, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x6f, 0x74, + 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x74, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x12, + 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6d, + 0x69, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6d, 0x61, 0x78, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x78, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x5f, 0x67, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x47, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, + 0x6c, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x4c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5f, 0x65, 0x71, 0x18, + 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x45, 0x71, 0x12, + 0x1c, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x49, 0x6e, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x19, 0x0a, + 0x08, 0x75, 0x75, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x07, 0x75, 0x75, 0x69, 0x64, 0x56, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x0e, 0x4f, 0x6e, 0x65, 0x6f, + 0x66, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x50, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, + 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xfc, + 0xfb, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x3a, 0x50, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, + 0x66, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xfd, 0xfb, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x52, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x77, 0x69, 0x74, 0x6b, 0x6f, 0x77, + 0x2f, 0x67, 0x6f, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x6f, 0x72, 0x73, 0x3b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, +} + +var ( + file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescOnce sync.Once + file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescData = file_github_com_mwitkow_go_proto_validators_validators_proto_rawDesc +) + +func file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescGZIP() []byte { + file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescOnce.Do(func() { + file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescData) + }) + return file_github_com_mwitkow_go_proto_validators_validators_proto_rawDescData +} + +var file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_github_com_mwitkow_go_proto_validators_validators_proto_goTypes = []interface{}{ + (*FieldValidator)(nil), // 0: validator.FieldValidator + (*OneofValidator)(nil), // 1: validator.OneofValidator + (*descriptor.FieldOptions)(nil), // 2: google.protobuf.FieldOptions + (*descriptor.OneofOptions)(nil), // 3: google.protobuf.OneofOptions +} +var file_github_com_mwitkow_go_proto_validators_validators_proto_depIdxs = []int32{ + 2, // 0: validator.field:extendee -> google.protobuf.FieldOptions + 3, // 1: validator.oneof:extendee -> google.protobuf.OneofOptions + 0, // 2: validator.field:type_name -> validator.FieldValidator + 1, // 3: validator.oneof:type_name -> validator.OneofValidator + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 2, // [2:4] is the sub-list for extension type_name + 0, // [0:2] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_mwitkow_go_proto_validators_validators_proto_init() } +func file_github_com_mwitkow_go_proto_validators_validators_proto_init() { + if File_github_com_mwitkow_go_proto_validators_validators_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FieldValidator); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OneofValidator); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_mwitkow_go_proto_validators_validators_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 2, + NumServices: 0, + }, + GoTypes: file_github_com_mwitkow_go_proto_validators_validators_proto_goTypes, + DependencyIndexes: file_github_com_mwitkow_go_proto_validators_validators_proto_depIdxs, + MessageInfos: file_github_com_mwitkow_go_proto_validators_validators_proto_msgTypes, + ExtensionInfos: file_github_com_mwitkow_go_proto_validators_validators_proto_extTypes, + }.Build() + File_github_com_mwitkow_go_proto_validators_validators_proto = out.File + file_github_com_mwitkow_go_proto_validators_validators_proto_rawDesc = nil + file_github_com_mwitkow_go_proto_validators_validators_proto_goTypes = nil + file_github_com_mwitkow_go_proto_validators_validators_proto_depIdxs = nil +} diff --git a/validators.proto b/validators.proto new file mode 100644 index 0000000..201b1f1 --- /dev/null +++ b/validators.proto @@ -0,0 +1,84 @@ +// 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; + //optional bool alphaNumeric = 65020; +} +/* +extend google.protobuf.OneofOptions { + optional OneofValidator oneof = 65021; +}*/ + +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 length strictly equal to this value. +// optional int64 length_eq = 16; +// // Requires that the value is in the enum. +// optional bool is_in_enum = 17; +// // Ensures that a string value is in UUID format. +// // uuid_ver specifies the valid UUID versions. Valid values are: 0-5. +// // If uuid_ver is 0 all UUID versions are accepted. +// optional int32 uuid_ver = 18; + + optional string customRegex = 1; +} + +/*message OneofValidator { + // Require that one of the oneof fields is set. + optional bool required = 1; +}*/