CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/go-protoc-gen-validate

Protoc plugin to generate polyglot message validators for protocol buffers

Pending
Overview
Eval results
Files

validation-rules.mddocs/

Validation Rules Schema

The validation rules schema defines comprehensive validation constraints for all protocol buffer field types through protocol buffer extensions. These rules are applied as field options in proto files and processed by the plugin to generate validation code.

Protocol Buffer Extensions

Message-Level Extensions

extend google.protobuf.MessageOptions {
  optional bool disabled = 1071;
  optional bool ignored = 1072;
}

disabled: Nullifies all validation rules for the message and its fields ignored: Skips generation of validation methods entirely for the message

Usage:

message Example {
  option (validate.disabled) = true;
  // validation rules are ignored
}

Oneof Extensions

extend google.protobuf.OneofOptions {
  optional bool required = 1071;
}

required: Ensures exactly one field in the oneof is set

Usage:

oneof choice {
  option (validate.required) = true;
  string option_a = 1;
  int32 option_b = 2;
}

Field Extensions

extend google.protobuf.FieldOptions {
  optional FieldRules rules = 1071;
}

rules: Main validation rules container for field-level constraints

Core Rule Types

Field Rules Container

message FieldRules {
  optional MessageRules message = 17;
  oneof type {
    FloatRules    float    = 1;
    DoubleRules   double   = 2;
    Int32Rules    int32    = 3;
    Int64Rules    int64    = 4;
    UInt32Rules   uint32   = 5;
    UInt64Rules   uint64   = 6;
    SInt32Rules   sint32   = 7;
    SInt64Rules   sint64   = 8;
    Fixed32Rules  fixed32  = 9;
    Fixed64Rules  fixed64  = 10;
    SFixed32Rules sfixed32 = 11;
    SFixed64Rules sfixed64 = 12;
    BoolRules     bool     = 13;
    StringRules   string   = 14;
    BytesRules    bytes    = 15;
    EnumRules     enum     = 16;
    RepeatedRules repeated = 18;
    MapRules      map      = 19;
    AnyRules      any      = 20;
    DurationRules duration = 21;
    TimestampRules timestamp = 22;
  }
}

Main container for all validation rules. Contains message-level rules and a oneof for type-specific rules.

Numeric Validation Rules

All numeric types share the same rule structure for consistency:

message FloatRules {
  optional float const = 1;
  optional float lt = 2;
  optional float lte = 3;
  optional float gt = 4;
  optional float gte = 5;
  repeated float in = 6;
  repeated float not_in = 7;
  optional bool ignore_empty = 8;
}

const: Field must equal exact value lt: Field must be less than value (exclusive) lte: Field must be less than or equal to value (inclusive) gt: Field must be greater than value (exclusive) gte: Field must be greater than or equal to value (inclusive) in: Field must be one of the specified values not_in: Field cannot be any of the specified values ignore_empty: Skip validation if field is empty/default

Usage examples:

float price = 1 [(validate.rules).float = {gt: 0, lte: 1000}];
int32 count = 2 [(validate.rules).int32 = {in: [1, 5, 10, 25]}];
uint64 id = 3 [(validate.rules).uint64 = {ignore_empty: true, gt: 999}];

String Validation Rules

message StringRules {
  optional string const = 1;
  optional uint64 len = 19;
  optional uint64 min_len = 2;
  optional uint64 max_len = 3;
  optional uint64 min_bytes = 4;
  optional uint64 max_bytes = 5;
  optional string pattern = 6;
  optional string prefix = 7;
  optional string suffix = 8;
  optional string contains = 9;
  optional string not_contains = 23;
  repeated string in = 10;
  repeated string not_in = 11;
  optional bool email = 12;
  optional bool hostname = 13;
  optional bool ip = 14;
  optional bool ipv4 = 15;
  optional bool ipv6 = 16;
  optional bool uri = 17;
  optional bool uri_ref = 18;
  optional bool address = 21;
  optional bool uuid = 22;
  optional KnownRegex well_known_regex = 24;
  optional bool strict = 25;
  optional bool ignore_empty = 26;
}

const: Exact string match len: Exact character length (Unicode code points) min_len/max_len: Minimum/maximum character length min_bytes/max_bytes: Minimum/maximum byte length pattern: RE2-compliant regular expression match prefix/suffix: Required prefix/suffix contains/not_contains: Required/forbidden substring in/not_in: Allowed/disallowed string values email: RFC 5322 email format validation hostname: RFC 1034 hostname format validation ip: IP address format (v4 or v6) ipv4/ipv6: Specific IP version format uri: RFC 3986 absolute URI format uri_ref: URI reference format (absolute or relative) address: Valid address (IP or hostname) uuid: RFC 4122 UUID format well_known_regex: Predefined regex patterns strict: Strict format validation mode ignore_empty: Skip validation if empty

Usage examples:

string email = 1 [(validate.rules).string.email = true];
string name = 2 [(validate.rules).string = {min_len: 1, max_len: 100}];
string token = 3 [(validate.rules).string.uuid = true];

Bytes Validation Rules

message BytesRules {
  optional bytes const = 1;
  optional uint64 len = 13;
  optional uint64 min_len = 2;
  optional uint64 max_len = 3;
  optional string pattern = 4;
  optional bytes prefix = 5;
  optional bytes suffix = 6;
  optional bytes contains = 7;
  repeated bytes in = 8;
  repeated bytes not_in = 9;
  optional bool ip = 10;
  optional bool ipv4 = 11;
  optional bool ipv6 = 12;
  optional bool ignore_empty = 14;
}

Similar to StringRules but for byte sequences: const: Exact byte sequence match len: Exact byte length min_len/max_len: Minimum/maximum byte length pattern: RE2 regex pattern for byte content prefix/suffix/contains: Required byte subsequences in/not_in: Allowed/disallowed byte values ip/ipv4/ipv6: IP address in byte format ignore_empty: Skip validation if empty

Boolean Validation Rules

message BoolRules {
  optional bool const = 1;
}

const: Exact boolean value required

Enum Validation Rules

message EnumRules {
  optional int32 const = 1;
  optional bool defined_only = 2;
  repeated int32 in = 3;
  repeated int32 not_in = 4;
}

const: Exact enum value (numeric) defined_only: Must be a defined enum value in/not_in: Allowed/disallowed enum values

Message Validation Rules

message MessageRules {
  optional bool skip = 1;
  optional bool required = 2;
}

skip: Skip validation of message fields required: Message field must be set (not null)

Repeated Field Validation Rules

message RepeatedRules {
  optional uint64 min_items = 1;
  optional uint64 max_items = 2;
  optional bool unique = 3;
  optional FieldRules items = 4;
  optional bool ignore_empty = 5;
}

min_items/max_items: Minimum/maximum number of items unique: All items must be unique (not supported for messages) items: Validation rules applied to each item ignore_empty: Skip validation if empty

Map Validation Rules

message MapRules {
  optional uint64 min_pairs = 1;
  optional uint64 max_pairs = 2;
  optional bool no_sparse = 3;
  optional FieldRules keys = 4;
  optional FieldRules values = 5;
  optional bool ignore_empty = 6;
}

min_pairs/max_pairs: Minimum/maximum key-value pairs no_sparse: Disallow unset message values keys: Validation rules for map keys values: Validation rules for map values ignore_empty: Skip validation if empty

Well-Known Types Rules

Any Rules

message AnyRules {
  optional bool required = 1;
  repeated string in = 2;
  repeated string not_in = 3;
}

required: Any field must be set in/not_in: Allowed/disallowed type URLs

Duration Rules

message DurationRules {
  optional bool required = 1;
  optional google.protobuf.Duration const = 2;
  optional google.protobuf.Duration lt = 3;
  optional google.protobuf.Duration lte = 4;
  optional google.protobuf.Duration gt = 5;
  optional google.protobuf.Duration gte = 6;
  repeated google.protobuf.Duration in = 7;
  repeated google.protobuf.Duration not_in = 8;
}

required: Duration field must be set const: Exact duration value lt/lte/gt/gte: Duration comparison constraints in/not_in: Allowed/disallowed duration values

Timestamp Rules

message TimestampRules {
  optional bool required = 1;
  optional google.protobuf.Timestamp const = 2;
  optional google.protobuf.Timestamp lt = 3;
  optional google.protobuf.Timestamp lte = 4;
  optional google.protobuf.Timestamp gt = 5;
  optional google.protobuf.Timestamp gte = 6;
  optional bool lt_now = 7;
  optional bool gt_now = 8;
  optional google.protobuf.Duration within = 9;
  repeated google.protobuf.Timestamp in = 10;
  repeated google.protobuf.Timestamp not_in = 11;
}

required: Timestamp field must be set const: Exact timestamp value lt/lte/gt/gte: Timestamp comparison constraints lt_now/gt_now: Comparison relative to current time within: Must be within duration of current time in/not_in: Allowed/disallowed timestamp values

Known Regex Patterns

enum KnownRegex {
  UNKNOWN = 0;
  HTTP_HEADER_NAME = 1;
  HTTP_HEADER_VALUE = 2;
}

Predefined regex patterns for common validation needs: HTTP_HEADER_NAME: RFC 7230 HTTP header name format (^:?[0-9a-zA-Z!#$%&'*+-.^_|~\x60]+$)
HTTP_HEADER_VALUE: RFC 7230 HTTP header value format (^[^\u0000-\u0008\u000A-\u001F\u007F]*$) HEADER_STRING: Non-strict header validation (^[^\u0000\u000A\u000D]*$)

Install with Tessl CLI

npx tessl i tessl/go-protoc-gen-validate

docs

code-generation.md

core-plugin.md

generated-code.md

index.md

runtime-libraries.md

validation-rules.md

tile.json