{"id":19674738,"url":"https://github.com/cloudwego/protoc-gen-validator","last_synced_at":"2025-04-29T02:30:24.751Z","repository":{"id":65661768,"uuid":"563740480","full_name":"cloudwego/protoc-gen-validator","owner":"cloudwego","description":"A protoc plugin that can generate go structure validate functions.","archived":false,"fork":false,"pushed_at":"2024-05-27T03:08:52.000Z","size":112,"stargazers_count":18,"open_issues_count":1,"forks_count":4,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-05T12:33:11.455Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudwego.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-09T08:30:41.000Z","updated_at":"2025-02-15T06:49:40.000Z","dependencies_parsed_at":"2024-06-19T17:40:52.721Z","dependency_job_id":"af88e724-90fc-4ec3-b7d1-4a7095be03e0","html_url":"https://github.com/cloudwego/protoc-gen-validator","commit_stats":{"total_commits":1,"total_committers":1,"mean_commits":1.0,"dds":0.0,"last_synced_commit":"87b9691d699334d6b2427d0f28e42d4595275750"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":"cloudwego/.github","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fprotoc-gen-validator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fprotoc-gen-validator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fprotoc-gen-validator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fprotoc-gen-validator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudwego","download_url":"https://codeload.github.com/cloudwego/protoc-gen-validator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251420861,"owners_count":21586693,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T17:19:36.911Z","updated_at":"2025-04-29T02:30:24.304Z","avatar_url":"https://github.com/cloudwego.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# protoc-gen-validator\n`protoc-gen-validator` is a protoc plugin that can generate go structure validate functions.\u003cbr\u003e\n`protoc-gen-validator` will generate the `Validate() error` method for the corresponding message.\u003cbr\u003e\n## Example:\n```\nmessage Example {\n  // The value of 'Int64Const' must be equal to '123'\n  int64 Int64Const = 1 [(api.vt).const=\"123\"];\n  \n  // The value of 'DoubleLe' must be less than '123.45'\n  optional double DoubleLe = 2 [(api.vt).le=\"123.45\"];\n  \n  // The value of 'BoolConst' must be 'true'\n  optional bool BoolConst = 3 [(api.vt).const=\"true\"];\n  \n  // The maximum length of 'StringMaxSize' is '12'\n  optional string StringMaxSize = 4 [(api.vt).max_size=\"12\"];\n  \n  // The prefix of 'bytesPrefix' must be 'validator'\n  optional bytes bytesPrefix = 5 [(api.vt).prefix=\"validator\"];\n  \n  // Each element of 'ListElem' must be a 'validator'\n  repeated string ListElem = 6 [(api.vt).elem.const=\"validator\"];\n  \n  // 'MapKeyValue' The value of all keys must be '123'\n  // 'MapKeyValue' The value of all keys must be greater than '100'\n  // 'MapKeyValue' All values of value must be 'validator'\n  // 'MapKeyValue' All values must be prefixed with 'validator'\n  map\u003cint32, string\u003e MapKeyValue = 7 [(api.vt).key.const=\"123\", (api.vt).key.gt=\"100\", (api.vt).value.const=\"validator\", (api.vt).value.prefix=\"validator\"];\n  \n  optional int64 Func1 = 8 [(api.vt).gt = \"@add($Int64Const, 1000)\"]; // Use the built-in function 'add' to get the constraint value\n}\n```\nThe method of generation is as follows:\n```\nfunc (m *Example) Validate() error {\n\tif m.GetInt64Const() != int64(123) {\n\t\treturn fmt.Errorf(\"field Int64Const not match const value, current value: %v\", m.GetInt64Const())\n\t}\n\tif m.GetDoubleLe() \u003e float64(123.45) {\n\t\treturn fmt.Errorf(\"field DoubleLe le rule failed, current value: %v\", m.GetDoubleLe())\n\t}\n\tif m.GetBoolConst() != true {\n\t\treturn fmt.Errorf(\"field BoolConst const rule failed, current value: %v\", m.GetBoolConst())\n\t}\n\tif len(m.GetStringMaxSize()) \u003e int(12) {\n\t\treturn fmt.Errorf(\"field StringMaxSize max_len rule failed, current value: %d\", len(m.GetStringMaxSize()))\n\t}\n\t_src := []byte(\"validator\")\n\tif !bytes.HasPrefix(m.GetBytesPrefix(), _src) {\n\t\treturn fmt.Errorf(\"field bytesPrefix prefix rule failed, current value: %v\", m.GetBytesPrefix())\n\t}\n\tfor i := 0; i \u003c len(m.GetListElem()); i++ {\n\t\t_elem := m.GetListElem()[i]\n\t\t_src1 := \"validator\"\n\t\tif _elem != _src1 {\n\t\t\treturn fmt.Errorf(\"field _elem not match const value, current value: %v\", _elem)\n\t\t}\n\t}\n\tfor k := range m.GetMapKeyValue() {\n\t\tif k != int32(123) {\n\t\t\treturn fmt.Errorf(\"field k not match const value, current value: %v\", k)\n\t\t}\n\t\tif k \u003c= int32(100) {\n\t\t\treturn fmt.Errorf(\"field k gt rule failed, current value: %v\", k)\n\t\t}\n\t}\n\tfor _, v := range m.GetMapKeyValue() {\n\t\t_src2 := \"validator\"\n\t\tif v != _src2 {\n\t\t\treturn fmt.Errorf(\"field v not match const value, current value: %v\", v)\n\t\t}\n\t\t_src3 := \"validator\"\n\t\tif !strings.HasPrefix(v, _src3) {\n\t\t\treturn fmt.Errorf(\"field v prefix rule failed, current value: %v\", v)\n\t\t}\n\t}\n\t_src4 := m.GetInt64Const() + int64(1000)\n\tif m.GetFunc1() \u003c= int64(_src4) {\n\t\treturn fmt.Errorf(\"field Func1 gt rule failed, current value: %v\", m.GetFunc1())\n\t}\n\treturn nil\n}\n```\n# Usage\n## Dependency\n* [protoc](https://developers.google.com/protocol-buffers/docs/downloads) located under `$PATH`\n* [protoc-gen-go](https://github.com/protocolbuffers/protobuf-go) located under `$PATH`/`$GOPATH`\n* `protoc-gen-validator` located under `$PATH`/`$GOPATH`\n* Support `proto2`/`proto3` syntax, `proto3` syntax is recommended\n## Installation\n`go install github.com/cloudwego/protoc-gen-validator@latest`\n## Parameters\n* version: Print `protoc-gen-validator` version\n* recurse: Recursively generate validate functions for dependent proto files\n* func: Specify the path of the custom validation function\n## Examples\nThe validate function(example_validate.pb.go) is generated at the same location as in [protoc-gen-go](https://github.com/protocolbuffers/protobuf-go).\n```\ncd example\n\nprotoc \\\n  -I . \\\n  --go_out=. \\\n  --validator_out=. \\\n  example.proto\n```\nBy default, `example_validate.pb.go` is generated in the same path as `option go_package`. \nYou can generate it to the location you want with the `paths=source_relative:. ` parameter to generate it to the location you want\n```\ncd example\n\nprotoc \\\n  -I . \\\n  --go_out=. \\\n  --go_opt=source_relative \\\n  --validator_out=. \\\n  --validator_opt=source_relative \\\n  example.proto\n```\nIf you want to specify `go module`, you need the prefix of `go module` to be consistent with `option go_package`, e.g.\n```\n// option go_package=\"example.com/validator/example\";\ncd example\n\nprotoc \\\n  -I . \\\n  --go_out=. \\\n  --go_opt=module=example.com/validator \\\n  --validator_out=. \\\n  --validator_opt=module=example.com/validator \\\n  example.proto\n```\n## Usage with hz\n- Use adaptations for hz\n```\n// with no go module\nhz new -I={$INCLUDEPATH} \\ \n       -idl={$IDLPATH} \\\n       -protoc-plugins=validator:hz=true:.\n// with go module\nhz new -I={$INCLUDEPATH} \\ \n       -idl={$IDLPATH} \\\n       -protoc-plugins=validator:hz=true,go_mod={$GOMODULE}:.\n       -mod={$GOMODULE}\n```\n- Use a specific go_package\n```\n// option go_package={$GOMODULE}/{$MODELDIR}/x/y/z\n// {$MODELDIR} defaults to \"biz/model\" \nhz new -I={$INCLUDEPATH} \\ \n       -idl={$IDLPATH} \\\n       -protoc-plugins=validator:module={$GOMODULE},recurse=true:. \\ \n       -mod={$GOMODULE}\n```\n# API Annotation\nIn order to use the constraint rules correctly, the file \"[api.proto](https://github.com/cloudwego/protoc-gen-validator/blob/main/parser/api/api.proto)\" needs to be introduced when writing the 'proto' file\n\n# Constraint rules\n\u003e Currently, 'protoc-gen-validator' only supports the basic data types of protobuf, some [WKTs](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf) types, such as Any, Oneofs, etc., will be supported later.\u003cbr\u003e\n\u003e The annotation \"vt\" is an abbreviation for \"validate\".\n### Numeric\n\u003e All numeric types (`float`, `double`, `int32`, `int64`, `uint32`, `uint64`, `sint32`, `sint64`, `fixed32`, `fixed64`, `sfixed32`, `sfixed64`) share the same constraint rules.\n* const: The value of the field must be a specific value\n```\nint32 Int32Const = 1 [(api.vt).const=\"123\"];\n```\n* lt/le/gt/ge: denote respectively: \u003c, \u003c=, \u003e, \u003e=\n```\noptional double DoubleLe = 2 [(api.vt).le=\"123.54\"];\n```\n* in/not_in: The value of the field must be/not be one of some specific values\n```\n// Since the 'in' constraint is a list, it is written slightly differently here\noptional fixed32 Fix32In = 3 [(api.vt)={in: [\"123\",\"456\",\"789\"]}];\n```\n* not_nil: If the field is a pointer, then the pointer cannot be nil\n```\noptional int64 I64NotNil = 4 [(api.vt).not_nil=\"true\"];\n```\n\n### Bool\n* const: The value of the field must be a specific value (true/false)\n```\noptional bool BoolConst = 1 [(api.vt).const=\"true\"];\n```\n* not_nil: If the field is a pointer, then the pointer cannot be nil\n```\noptional bool BoolNotNil = 2 [(api.vt).not_nil=\"true\"];\n```\n\n### String/Bytes\n* const: The value of the field must be a specific value\n```\noptional string StringConst = 1 [(api.vt).const=\"validator\"];\noptional bytes bytesConst = 2 [(api.vt).const=\"validator\"];\n```\n* pattern: Regular Match\n```\noptional string StringPattern = 3 [(api.vt).pattern=\"[0-9A-Za-z]+\"];\noptional bytes bytesPattern = 4 [(api.vt).pattern=\"[0-9A-Za-z]+\"];\n```\n* min_size/max_size: Minimum/maximum length\n```\noptional string StringMinSize = 5 [(api.vt).min_size=\"12\"];\noptional bytes bytesMaxSize = 6 [(api.vt).max_size=\"12\"];\n```\n* prefix/suffix/contains/not_contains: prefix/suffix/contains/not_contains\n```\noptional string StringPrefix = 7 [(api.vt).prefix=\"validator\"];\noptional string StringSuffix = 8 [(api.vt).suffix=\"validator\"];\noptional bytes bytesContain = 9 [(api.vt).contains=\"validator\"];\noptional bytes bytesNotContain = 10 [(api.vt).not_contains=\"validator\"];\n```\n* in/not_in: The value of the field must be/not be one of some specific values\n```\n// Since the 'in' constraint is a list, it is written slightly differently here\noptional string StringIn = 11 [(api.vt)={in:[\"123\",\"456\",\"789\"]}];\noptional bytes bytesNotIn = 12 [(api.vt)={not_in:[\"123\",\"456\",\"789\"]}];\n```\n* not_nil: If the field is a pointer, then the pointer cannot be nil\n```\noptional string StringNotNil = 13 [(api.vt).not_nil=\"true\"];\n```\n\n### Enum\n```\nenum EnumType {\n  TWEET = 0;\n  RETWEET = 1;\n}\n```\n* const: The value of the field must be a specific value\n```\noptional EnumType Enum1 = 1 [(api.vt).const=\"EnumType.TWEET\"];\n```\n* defined_only: The value of the field must be the value defined by the enum\n```\noptional EnumType Enum2 = 2 [(api.vt).defined_only=\"true\"];\n```\n* not_nil: If the field is a pointer, then the pointer cannot be nil\n```\noptional EnumType Enum3 = 3 [(api.vt).not_nil=\"true\"];\n```\n\n### Repeated\n* min_size/max_size: Minimum/maximum number of elements\n```\nrepeated string ListMinSize = 1 [(api.vt).min_size=\"12\"];\n```\n* elem: Constraints on elements within a list\n```\nrepeated string ListBaseElem = 2 [(api.vt).elem.const=\"validator\"];\n```\n\n### Map\n* min_size/max_size: Minimum/maximum number of elements\n```\nmap\u003cint32, string\u003e MapISMinSize = 1 [(api.vt).min_size=\"10\", (api.vt).max_size=\"30\"];\n```\n* key: For the constraints on the key in the map\n```\nmap\u003cint32, string\u003e MapKey = 2 [(api.vt).key.const=\"123\", (api.vt).key.gt=\"12\"];\n```\n* value: For the constraints on the value in the map\n```\nmap\u003cint32, string\u003e MapValue = 3 [(api.vt).value.const=\"validator\", (api.vt).value.prefix=\"validator\"];\n```\n* no_sparse: If the value of a map is a pointer, then the pointer cannot be nil\n```\nmap\u003cint32, MsgType\u003e MapNoSparse = 4 [(api.vt).no_sparse=\"true\"];\n```\n\n### Message Field\n* skip: Skip validating for this structure\n```\noptional MapValidate MsgField = 1 [(api.vt).skip=\"true\"];\n```\n### Message Level Rule\n* msg_vt.assert: The result of the expression specified by 'assert' should be \"true\", in the perspective of the message to validate\n```\nmessage StructValidate {\n  option (api.msg_vt).assert = \"@equal($MsgValidate,1)\";\n  optional int64 MsgValidate = 1;\n}\n```\n\n### Cross-field references\n* Cross-field references: You can use the value of another field as the constraint value, with the scope of the current structure\n```\noptional double DoubleLe = 1;\noptional double Reference = 2 [(api.vt).le=\"$DoubleLe\"];\n```\n\n### Built-in functions\n`protoc-gen-validator` provide a set of built-in functions for validating\n\n| function name | arguments                                             | results                                                | remarks                                 |\n| ------------- | ----------------------------------------------------- | ------------------------------------------------------ | --------------------------------------- |\n| len           | 1: container filed                                    | 1: length of container (integer)                       | just like `len` of go                   |\n| sprintf       | 1: format string \u003cbr /\u003e 2+: arguments matching format | 1: formatted string (string)                           | just like `fmt.Sprintf` of go           |\n| now_unix_nano | none                                                  | 1: nano seconds (int64)                                | just like `time.Now().UnixNano()` of go |\n| equal         | 1, 2: comparable values                               | 1: whether two arguments is equal (bool)               | just like `==` of go                    |\n| mod           | 1, 2: integer                                         | 1: remainder of $1 / $2 (integer)                      | just like `%` of go                     |\n| add           | 1, 2: both are numeric or string                      | 1: sum of two arguments (integer or float64 or string) | just like `+` of go                     |\n\n### Custom validation functions\n`protoc-gen-validator` provides a way to expand the validate function\nNow you can use parameter `func` to customize your validation function. Like below:\n```\ncd example\n\nprotoc \\\n  -I . \\\n  --go_out=. \\\n  --validator_out=. \\\n  --validator_opt=func=my_func=path_to_template.txt \\\n  example.proto\n```\n`my_func` is the function name, `path_to_template.txt` is the path to template file which should be a go template.\nAvailable template variables:\n\n| variable name | meaning                               | type                                                             |\n| ------------- | ------------------------------------- | ---------------------------------------------------------------- |\n| Source        | variable name that rule will refer to | string                                                           |\n| Function      | data of current function              | *\"github.com/cloudwego/protoc-gen-validator/parser\".ToolFunction |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudwego%2Fprotoc-gen-validator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudwego%2Fprotoc-gen-validator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudwego%2Fprotoc-gen-validator/lists"}