├── .gitignore ├── Makefile ├── README.md ├── go.mod ├── go.sum ├── main.go ├── main_test.go ├── templates ├── hugo-markdown.tmpl └── markdown.tmpl ├── testdata └── example1 │ ├── booking.md │ ├── booking.proto │ ├── field_presence.md │ ├── field_presence.proto │ ├── vehicle.md │ └── vehicle.proto ├── thirdparty ├── generate.go └── github.com │ ├── envoyproxy │ └── protoc-gen-validate │ │ └── validate │ │ └── validate.proto │ ├── mwitkow │ └── go-proto-validators │ │ └── validator.proto │ └── pseudomuto │ └── protokit │ └── fixtures │ └── extend.proto └── tmp └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | tmp 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test 2 | test: tmp/googleapis 3 | go install 4 | protoc \ 5 | -I thirdparty \ 6 | -I tmp/googleapis \ 7 | -I testdata \ 8 | --apidocs_out=testdata/ \ 9 | --apidocs_opt=paths=source_relative \ 10 | testdata/example1/*.proto 11 | 12 | .PHONY: install 13 | install: 14 | go install 15 | 16 | tmp/googleapis: 17 | rm -rf tmp/googleapis tmp/protocolbuffers 18 | git clone --depth 1 https://github.com/googleapis/googleapis tmp/googleapis 19 | rm -rf tmp/googleapis/.git 20 | git clone --depth 1 https://github.com/protocolbuffers/protobuf tmp/protocolbuffers 21 | cp -r tmp/protocolbuffers/src/* tmp/googleapis/ 22 | rm -rf tmp/protocolbuffers 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # protoc-gen-apidocs 2 | 3 | `protoc-gen-apidocs` is a very simple and customizable protoc generator that translates .proto files into clean and readable markdown format. 4 | 5 | This is achieved by levearging the fantastic 6 | [protogen](https://pkg.go.dev/google.golang.org/protobuf/compiler/protogen) library and Go's 7 | built-in templating capabilties. 8 | 9 | ## Example Output 10 | 11 | **Vehicle.proto example** 12 | 13 | This example shows a variety of protobuf features including extensions and nested messages. 14 | 15 | * [Output markdown](./testdata/example1/vehicle.md) 16 | * [Source proto](./testdata/example1/vehicle.proto) 17 | 18 | 19 | **Booking.proto example** 20 | 21 | This example is relatively simple but shows streaming rpc endpoints properly handled. 22 | 23 | * [Output markdown](./testdata/example1/booking.md) 24 | * [Source proto](./testdata/example1/booking.proto) 25 | 26 | 27 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/tmc/protoc-gen-apidocs 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/Masterminds/sprig v2.22.0+incompatible 7 | google.golang.org/protobuf v1.33.0 8 | ) 9 | 10 | require ( 11 | github.com/Masterminds/goutils v1.1.1 // indirect 12 | github.com/Masterminds/semver v1.5.0 // indirect 13 | github.com/golang/protobuf v1.5.4 // indirect 14 | github.com/google/uuid v1.4.0 // indirect 15 | github.com/huandu/xstrings v1.3.2 // indirect 16 | github.com/imdario/mergo v0.3.12 // indirect 17 | github.com/lyft/protoc-gen-star v0.6.0 // indirect 18 | github.com/mitchellh/copystructure v1.2.0 // indirect 19 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 20 | github.com/spf13/afero v1.11.0 // indirect 21 | golang.org/x/crypto v0.16.0 // indirect 22 | golang.org/x/text v0.14.0 // indirect 23 | ) 24 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= 2 | github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= 3 | github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= 4 | github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= 5 | github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= 6 | github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= 7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 9 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 10 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 11 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 12 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 13 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 14 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 15 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 16 | github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= 17 | github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 18 | github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= 19 | github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 20 | github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= 21 | github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 22 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 23 | github.com/lyft/protoc-gen-star v0.6.0 h1:xOpFu4vwmIoUeUrRuAtdCrZZymT/6AkW/bsUWA506Fo= 24 | github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= 25 | github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= 26 | github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= 27 | github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= 28 | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 29 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 30 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 31 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 32 | github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= 33 | github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= 34 | github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= 35 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 36 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 37 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 38 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 39 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 40 | golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= 41 | golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 42 | golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= 43 | golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 44 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 45 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 46 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 47 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 48 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 49 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 50 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 51 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 52 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 53 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 54 | google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= 55 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 56 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 57 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 58 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 59 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 60 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 61 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 62 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 63 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 64 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "embed" 5 | "flag" 6 | "fmt" 7 | htmltemplate "html/template" 8 | "io/fs" 9 | "os" 10 | "path/filepath" 11 | "regexp" 12 | "strings" 13 | "text/template" 14 | 15 | "github.com/Masterminds/sprig" 16 | "google.golang.org/protobuf/compiler/protogen" 17 | "google.golang.org/protobuf/reflect/protoreflect" 18 | "google.golang.org/protobuf/types/pluginpb" 19 | ) 20 | 21 | func main() { 22 | var flags flag.FlagSet 23 | format := flags.String("format", "markdown", "Format to use") 24 | templates := flags.String("templates", "", "Custom templates directory to use") 25 | trimPrefix := flags.String("trimprefix", "", "If supplied, this prefix will be removed from generated file paths.") 26 | 27 | opts := &protogen.Options{ 28 | ParamFunc: flags.Set, 29 | } 30 | opts.Run(func(gen *protogen.Plugin) error { 31 | gen.SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL) 32 | genOpts := GenOpts{ 33 | Format: *format, 34 | TemplateDir: *templates, 35 | TrimPrefix: *trimPrefix, 36 | } 37 | for _, f := range gen.Files { 38 | if !f.Generate { 39 | continue 40 | } 41 | if err := genOpts.generateFile(gen, f); err != nil { 42 | return err 43 | } 44 | } 45 | return nil 46 | }) 47 | } 48 | 49 | // GenOpts hold options for generation. 50 | type GenOpts struct { 51 | Format string 52 | TemplateDir string 53 | TrimPrefix string 54 | } 55 | 56 | var formatFileSuffixes = map[string]string{ 57 | "markdown": "md", 58 | "hugo-markdown": "md", 59 | } 60 | 61 | // generateFile generates a _ascii.pb.go file containing gRPC service definitions. 62 | func (o *GenOpts) generateFile(gen *protogen.Plugin, file *protogen.File) error { 63 | suffix, ok := formatFileSuffixes[o.Format] 64 | if !ok { 65 | suffix = o.Format 66 | } 67 | filename := file.GeneratedFilenamePrefix + "." + suffix 68 | filename = strings.TrimPrefix(filename, o.TrimPrefix) 69 | g := gen.NewGeneratedFile(filename, file.GoImportPath) 70 | if err := o.renderTemplate(file, g); err != nil { 71 | return fmt.Errorf("issue generating %v: %w", filename, err) 72 | } 73 | return nil 74 | } 75 | 76 | func (o *GenOpts) relPath(t1, t2 protoreflect.Descriptor) string { 77 | path := "" 78 | cpf := filepath.Base(fmt.Sprint(t1.ParentFile().Path())) 79 | rpf := filepath.Base(fmt.Sprint(t2.ParentFile().Path())) 80 | if cpf != rpf { 81 | path, _ = filepath.Rel(cpf, rpf) 82 | path = strings.TrimSuffix(path, filepath.Ext(path)) 83 | path = strings.TrimPrefix(path, ".") 84 | path = fmt.Sprintf("%s.%s", path, formatFileSuffixes[o.Format]) 85 | } 86 | return path 87 | } 88 | 89 | func longName(d protoreflect.Descriptor) string { 90 | p := d.Parent() 91 | if p != nil && p.Parent() != nil { 92 | return fmt.Sprintf("%v.%v", p.Name(), d.Name()) 93 | } 94 | return fmt.Sprint(d.Name()) 95 | } 96 | 97 | func anchor(str interface{}) string { 98 | return specialCharsPattern.ReplaceAllString(strings.ReplaceAll(fmt.Sprint(str), "/", "_"), "-") 99 | } 100 | 101 | func (o *GenOpts) templateFuncMap() template.FuncMap { 102 | return map[string]interface{}{ 103 | "anchor": anchor, 104 | "long_name": longName, 105 | "field_type": func(f *protogen.Field) string { 106 | if f.Message != nil { 107 | return longName(f.Message.Desc) 108 | } 109 | if f.Enum != nil { 110 | return longName(f.Enum.Desc) 111 | } 112 | return fmt.Sprint(f.Desc.Kind()) 113 | }, 114 | "full_field_type": func(f *protogen.Field) string { 115 | if f.Message != nil { 116 | return fmt.Sprint(f.Message.Desc.FullName()) 117 | } 118 | if f.Enum != nil { 119 | return fmt.Sprint(f.Enum.Desc.FullName()) 120 | } 121 | return fmt.Sprint(f.Desc.Kind()) 122 | }, 123 | "is_primitive": func(f *protogen.Field) bool { 124 | // TODO: consider oneof, enum, ... 125 | k := f.Desc.Kind() 126 | nonPrim := k == protoreflect.EnumKind || k == protoreflect.MessageKind || k == protoreflect.GroupKind 127 | return !nonPrim 128 | }, 129 | "message_type": func(f *protogen.Message) string { 130 | if f == nil { 131 | return "(none)" 132 | } 133 | return fmt.Sprint(f.Desc.Name()) 134 | }, 135 | "full_message_type": func(f *protogen.Message) string { 136 | return fmt.Sprint(f.Desc.FullName()) 137 | }, 138 | "is_google_type": func(f *protogen.Field) bool { 139 | if f.Message != nil { 140 | return strings.HasPrefix(string(f.Message.Desc.FullName()), "google.") 141 | } 142 | if f.Enum != nil { 143 | return strings.HasPrefix(string(f.Enum.Desc.FullName()), "google.") 144 | } 145 | return false 146 | }, 147 | "type_link": func(f *protogen.Field) string { 148 | var t1, t2 protoreflect.Descriptor 149 | t1 = f.Desc 150 | if f.Message != nil { 151 | t2 = f.Message.Desc 152 | } 153 | if f.Enum != nil { 154 | t2 = f.Enum.Desc 155 | } 156 | if strings.HasPrefix(string(t2.FullName()), "google.") { 157 | return string(t2.FullName()) 158 | } 159 | fn := o.relPath(t1, t2) 160 | typ := anchor(fmt.Sprint(t2.FullName())) 161 | return fmt.Sprintf(`%s#%s`, fn, typ) 162 | }, 163 | "hugo_type_link": func(f *protogen.Field) string { 164 | // exclude google types: 165 | 166 | if f.Message != nil { 167 | if strings.HasPrefix(string(f.Message.Desc.FullName()), "google.") { 168 | return string(f.Message.Desc.FullName()) 169 | } 170 | fn := fmt.Sprint(f.Message.Desc.ParentFile().Path()) 171 | fn = filepath.Base(fn) 172 | fn = strings.TrimSuffix(fn, filepath.Ext(fn)) 173 | typ := anchor(fmt.Sprint(f.Message.Desc.FullName())) 174 | return fmt.Sprintf(`{{< relref "%s#%s" >}}`, fn, typ) 175 | } 176 | if f.Enum != nil { 177 | fn := fmt.Sprint(f.Enum.Desc.ParentFile().Path()) 178 | fn = filepath.Base(fn) 179 | fn = strings.TrimSuffix(fn, filepath.Ext(fn)) 180 | typ := anchor(fmt.Sprint(f.Enum.Desc.FullName())) 181 | return fmt.Sprintf(`{{< relref "%s#%s" >}}`, fn, typ) 182 | } 183 | return fmt.Sprintf(`#%s`, anchor(f.Desc.FullName())) 184 | }, 185 | "description": func(s interface{}) string { 186 | val := strings.TrimLeft(fmt.Sprint(s), "*/\n ") 187 | if strings.HasPrefix(val, "@exclude") { 188 | return "" 189 | } 190 | commentRe := regexp.MustCompile("\n// ?") 191 | return commentRe.ReplaceAllString(val, "\n") 192 | }, 193 | "p": pFilter, 194 | "para": paraFilter, 195 | "nobr": nobrFilter, 196 | } 197 | } 198 | 199 | //go:embed templates/* 200 | var defaultTemplates embed.FS 201 | 202 | func (o *GenOpts) getTemplateFS() (fs.FS, error) { 203 | if o.TemplateDir == "" { 204 | return fs.Sub(defaultTemplates, "templates") 205 | } 206 | tFS := os.DirFS(o.TemplateDir) 207 | return fs.Sub(tFS, o.TemplateDir) 208 | } 209 | 210 | func (o *GenOpts) renderTemplate(file *protogen.File, g *protogen.GeneratedFile) error { 211 | tFS, err := o.getTemplateFS() 212 | if err != nil { 213 | return err 214 | } 215 | t := template.New("file.tmpl").Funcs(o.templateFuncMap()).Funcs(sprig.TxtFuncMap()) 216 | t, err = t.ParseFS(tFS, fmt.Sprintf("%v.tmpl", o.Format)) 217 | if err != nil { 218 | return err 219 | } 220 | return t.ExecuteTemplate(g, "output", file) 221 | } 222 | 223 | // Template Helpers 224 | 225 | var ( 226 | paraPattern = regexp.MustCompile(`(\n|\r|\r\n)\s*`) 227 | spacePattern = regexp.MustCompile("( )+") 228 | multiNewlinePattern = regexp.MustCompile(`(\r\n|\r|\n){2,}`) 229 | specialCharsPattern = regexp.MustCompile(`[^a-zA-Z0-9_-]`) 230 | ) 231 | 232 | func pFilter(content string) htmltemplate.HTML { 233 | paragraphs := paraPattern.Split(content, -1) 234 | return htmltemplate.HTML(fmt.Sprintf("
%s
", strings.Join(paragraphs, "")))
235 | }
236 |
237 | func paraFilter(content string) string {
238 | paragraphs := paraPattern.Split(content, -1)
239 | return fmt.Sprintf(" |
128 | {{range .Fields}}{{template "field" .}}{{end}}
129 | {{end}}
130 |
131 | {{/***************************************************************
132 | Enum template
133 | ***************************************************************/}}
134 | {{define "enum" }}
135 |
136 |
137 | ### {{.Desc | long_name}}
138 | {{.Comments.Leading | description}}
139 | {{.Comments.Trailing | description}}
140 |
141 | | Name | Number | Description |
142 | | ---- | ------ | ----------- |
143 | {{range .Values -}}
144 | | {{.Desc.Name}} | {{.Desc.Number}} | {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr}} |
145 | {{end}}
146 | {{end}}
147 |
--------------------------------------------------------------------------------
/templates/markdown.tmpl:
--------------------------------------------------------------------------------
1 | {{/***************************************************************
2 | Markdown template for protoc-gen-apidocs
3 |
4 | This template is rendered once per incoming .proto file and
5 | defines the resulting output documentation.
6 |
7 | This file is organized into blocks via the go template "define"
8 | function and they are executed with the "template" function.
9 | ***************************************************************/}}
10 |
11 | {{/***************************************************************
12 | Main output block
13 | ***************************************************************/}}
14 | {{define "output" -}}
15 |
16 | ---
17 | title: {{ .Desc.Package }}
18 | description: API Specification for the {{ .Desc.Package }} package.
19 | ---
20 |
21 |
22 |
23 |
24 | {{range .Services}}
25 | {{template "service" .}}
26 | {{end}}
27 |
28 |
29 | {{ range .Messages }}
30 | {{template "message" .}}
31 | {{end}}
32 |
33 |
34 | {{range .Enums}}
35 | {{template "enum" .}}
36 | {{end}}
37 |
38 |
39 | {{if .Extensions}}
40 |
41 |
42 | ### Extensions
43 | | Extension | Type | Extension Point | Number | Description |
44 | | --------- | ---- | ---- | ------ | ----------- |
45 | {{range .Extensions -}}
46 | | {{.Desc.Name}} | {{.Desc.FullName}} | {{ .Extendee | message_type }} | {{.Desc.Number}} | {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr}} |
47 | {{end}}
48 | {{end}}
49 |
50 | {{end}}
51 |
52 |
53 | {{/***************************************************************
54 | Service template
55 | ***************************************************************/}}
56 | {{define "service"}}
57 |
58 |
59 | ### {{.Desc.Name}}
60 |
61 | {{.Comments.Leading | description}}
62 | {{.Comments.Trailing | description}}
63 |
64 | | Method Name | Request Type | Response Type | Description |
65 | | ----------- | ------------ | ------------- | ------------|
66 | {{range .Methods -}}
67 | | {{.Desc.Name}} | [{{ .Input | message_type }}](#{{ .Input | full_message_type | anchor }}) | [{{ .Output | message_type }}](#{{ .Output | full_message_type | anchor }}){{if .Desc.IsStreamingServer}} stream{{end}} | {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr}} |
68 | {{end}}
69 | {{end}}
70 |
71 |
72 |
73 | {{/***************************************************************
74 | Message template
75 | ***************************************************************/}}
76 | {{define "message"}}
77 |
78 |
79 | ### {{.Desc.Name}}
80 |
81 | {{.Comments.Leading | description}}
82 | {{.Comments.Trailing | description}}
83 |
84 | {{if .Fields}}
85 | | Field | Type | Description |
86 | | ----- | ---- | ----------- |
87 | {{range .Fields}}{{ if (not .Desc.ContainingOneof) }}{{template "field" .}}{{end}}{{end}}
88 | {{- end -}}
89 |
90 | {{range .Oneofs}}{{ if .Desc.IsSynthetic }}{{template "field" (index .Fields 0) }}{{else}}{{template "oneof" .}}{{end}}{{end}}
91 |
92 | {{if .Extensions}}
93 | | Extension | Type | Base | Number | Description |
94 | | --------- | ---- | ---- | ------ | ----------- |
95 | {{range .Extensions -}}
96 | | {{.Desc.Name}} | {{.Desc | long_name}} | {{.Parent | message_type}} | {{.Desc.Number}} | {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr}} |
97 | {{end}}
98 | {{end}}
99 |
100 | {{ range .Messages }}
101 | {{template "message" .}}
102 | {{end}}
103 |
104 | {{range .Enums}}
105 | {{template "enum" .}}
106 | {{end}}
107 |
108 | {{end}}
109 |
110 | {{/***************************************************************
111 | Field template
112 | ***************************************************************/}}
113 | {{define "field" -}}
114 | | {{.Desc.Name }}{{ if .Desc.IsList }}[]{{ end }}{{ if .Desc.HasOptionalKeyword }} (optional){{ end }} |
115 | {{- if (or (is_primitive .) (is_google_type .)) -}}
116 | {{ field_type . }}
117 | {{- else -}}
118 | [{{ .| field_type }}]({{ type_link . }})
119 | {{- end -}}
120 | | {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr }} |
121 | {{end}}
122 |
123 | {{/***************************************************************
124 | Oneof template
125 | This is kind of gross since GFM doesn't support colspan.
126 | ***************************************************************/}}
127 | {{define "oneof" -}}
128 | |Union field `{{ .Desc.Name }}`. {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr }} `{{ .Desc.Name }}` can be only one of the following: |
129 | {{range .Fields}}{{template "field" .}}{{end}}
130 | {{end}}
131 |
132 | {{/***************************************************************
133 | Enum template
134 | ***************************************************************/}}
135 | {{define "enum" }}
136 |
137 |
138 | ### {{.Desc | long_name}}
139 | {{.Comments.Leading | description}}
140 | {{.Comments.Trailing | description}}
141 |
142 | | Name | Number | Description |
143 | | ---- | ------ | ----------- |
144 | {{range .Values -}}
145 | | {{.Desc.Name}} | {{.Desc.Number}} | {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr}} |
146 | {{end}}
147 | {{end}}
148 |
--------------------------------------------------------------------------------
/testdata/example1/booking.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: com.example.booking
3 | description: API Specification for the com.example.booking package.
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ### BookingService
14 |
15 | Service for handling vehicle bookings.
16 |
17 |
18 |
19 | | Method Name | Request Type | Response Type | Description |
20 | | ----------- | ------------ | ------------- | ------------|
21 | | BookVehicle | [Booking](#com-example-booking-Booking) | [BookingStatus](#com-example-booking-BookingStatus) | Used to book a vehicle. Pass in a Booking and a BookingStatus will be returned. |
22 | | BookingUpdates | [BookingStatusID](#com-example-booking-BookingStatusID) | [BookingStatus](#com-example-booking-BookingStatus) stream | Used to subscribe to updates of the BookingStatus. |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | ### BookingStatusID
33 |
34 | Represents the booking status ID.
35 |
36 |
37 |
38 |
39 | | Field | Type | Description |
40 | | ----- | ---- | ----------- |
41 | | id |int32| Unique booking status ID. |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | ### BookingStatus
56 |
57 | Represents the status of a vehicle booking.
58 |
59 |
60 |
61 |
62 | | Field | Type | Description |
63 | | ----- | ---- | ----------- |
64 | | id |int32| Unique booking status ID. |
65 | | description |string| Booking status description. E.g. "Active". |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | ### Booking
80 |
81 | Represents the booking of a vehicle.
82 |
83 | Vehicles are quite fun. But drive carefully!
84 |
85 |
86 |
87 |
88 | | Field | Type | Description |
89 | | ----- | ---- | ----------- |
90 | | vehicle_id |int32| ID of booked vehicle. |
91 | | customer_id |int32| Customer that booked the vehicle. |
92 | | status |[BookingStatus](#com-example-booking-BookingStatus)| Status of the booking. |
93 | | confirmation_sent |bool| Has booking confirmation been sent? |
94 | | payment_received |bool| Has payment been received? |
95 | | color_preference |string| Color preference of the customer. |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | ### EmptyBookingMessage
110 |
111 | An empty message for testing
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/testdata/example1/booking.proto:
--------------------------------------------------------------------------------
1 | /**
2 | * Booking related messages.
3 | *
4 | * This file is really just an example. The data model is completely
5 | * fictional.
6 | */
7 | syntax = "proto3";
8 |
9 | option go_package = "example.com/booking";
10 |
11 | package com.example.booking;
12 |
13 | /**
14 | * Represents the booking status ID.
15 | */
16 | message BookingStatusID {
17 | int32 id = 1; /// Unique booking status ID.
18 | }
19 |
20 | /**
21 | * Represents the status of a vehicle booking.
22 | */
23 | message BookingStatus {
24 | int32 id = 1; /// Unique booking status ID.
25 | string description = 2; /// Booking status description. E.g. "Active".
26 | }
27 |
28 | /**
29 | * Represents the booking of a vehicle.
30 | *
31 | * Vehicles are quite fun. But drive carefully!
32 | */
33 | message Booking {
34 | int32 vehicle_id = 1; /// ID of booked vehicle.
35 | int32 customer_id = 2; /// Customer that booked the vehicle.
36 | BookingStatus status = 3; /// Status of the booking.
37 |
38 | /** Has booking confirmation been sent? */
39 | bool confirmation_sent = 4;
40 |
41 | /** Has payment been received? */
42 | bool payment_received = 5;
43 |
44 | string color_preference = 6 [deprecated=true]; // Color preference of the customer.
45 | }
46 |
47 | // An empty message for testing
48 | message EmptyBookingMessage {
49 | }
50 |
51 | /**
52 | * Service for handling vehicle bookings.
53 | */
54 | service BookingService {
55 | /// Used to book a vehicle. Pass in a Booking and a BookingStatus will be returned.
56 | rpc BookVehicle (Booking) returns (BookingStatus) {}
57 |
58 | /// Used to subscribe to updates of the BookingStatus.
59 | rpc BookingUpdates (BookingStatusID) returns (stream BookingStatus);
60 | }
61 |
--------------------------------------------------------------------------------
/testdata/example1/field_presence.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: com.example.proto3
3 | description: API Specification for the com.example.proto3 package.
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ### MyMessage
17 |
18 |
19 |
20 |
21 |
22 | | Field | Type | Description |
23 | | ----- | ---- | ----------- |
24 | | not_tracked |int32| |
25 | | tracked (optional) |int32| Explicit presence |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ### AnotherMessage
40 |
41 |
42 |
43 |
44 |
45 | | Field | Type | Description |
46 | | ----- | ---- | ----------- |
47 | | id |int32| |
48 | |Union field `{{ .Desc.Name }}`. {{ .Comments.Leading | description | nobr}} {{ .Comments.Trailing | description | nobr }} `{{ .Desc.Name }}` can be only one of the following: |
49 | | my_message |[MyMessage](#com-example-proto3-MyMessage)| |
50 | | my_string |string| |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/testdata/example1/field_presence.proto:
--------------------------------------------------------------------------------
1 | // Encoding and show field presence.
2 | syntax = "proto3";
3 |
4 | package com.example.proto3;
5 |
6 | option go_package = "example.com/vehicleproto3";
7 |
8 | message MyMessage {
9 | int32 not_tracked = 1;
10 | // Explicit presence
11 | optional int32 tracked = 2;
12 | }
13 |
14 | message AnotherMessage {
15 | int32 id = 1;
16 | oneof payload {
17 | MyMessage my_message = 2;
18 | string my_string = 3;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/testdata/example1/vehicle.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: com.example
3 | description: API Specification for the com.example package.
4 | ---
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ### Manufacturer
17 |
18 | Represents a manufacturer of cars.
19 |
20 |
21 |
22 |
23 | | Field | Type | Description |
24 | | ----- | ---- | ----------- |
25 | | id |int32| The unique manufacturer ID. |
26 | | code |string| A manufacturer code, e.g. "DKL4P". |
27 | | details (optional) |string| Manufacturer details (minimum orders et.c.). |
28 | | category (optional) |[Manufacturer.Category](#com-example-Manufacturer-Category)| Manufacturer category. |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ### Manufacturer.Category
40 | Manufacturer category. A manufacturer may be either inhouse or external.
41 |
42 |
43 |
44 | | Name | Number | Description |
45 | | ---- | ------ | ----------- |
46 | | CATEGORY_INHOUSE | 0 | The manufacturer is inhouse. |
47 | | CATEGORY_EXTERNAL | 1 | The manufacturer is external. |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | ### Model
58 |
59 | Represents a vehicle model.
60 |
61 |
62 |
63 |
64 | | Field | Type | Description |
65 | | ----- | ---- | ----------- |
66 | | id |string| The unique model ID. |
67 | | model_code |string| The car model code, e.g. "PZ003". |
68 | | model_name |string| The car model name, e.g. "Z3". |
69 | | daily_hire_rate_dollars |sint32| Dollars per day. |
70 | | daily_hire_rate_cents |sint32| Cents per day. |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | ### Vehicle
85 |
86 | Represents a vehicle that can be hired.
87 |
88 |
89 |
90 |
91 | | Field | Type | Description |
92 | | ----- | ---- | ----------- |
93 | | id |int32| Unique vehicle ID. |
94 | | model |[Model](#com-example-Model)| Vehicle model. |
95 | | reg_number |string| Vehicle registration number. |
96 | | mileage (optional) |sint32| Current vehicle mileage, if known. |
97 | | category (optional) |[Vehicle.Category](#com-example-Vehicle-Category)| Vehicle category. |
98 | | daily_hire_rate_dollars (optional) |sint32| Dollars per day. |
99 | | daily_hire_rate_cents (optional) |sint32| Cents per day. |
100 |
101 |
102 |
103 | | Extension | Type | Base | Number | Description |
104 | | --------- | ---- | ---- | ------ | ----------- |
105 | | series | Vehicle.series | Vehicle | 100 | Vehicle model series. |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | ### Category
114 |
115 | Represents a vehicle category. E.g. "Sedan" or "Truck".
116 |
117 |
118 |
119 |
120 | | Field | Type | Description |
121 | | ----- | ---- | ----------- |
122 | | code |string| Category code. E.g. "S". |
123 | | description |string| Category name. E.g. "Sedan". |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | ### Coolness
146 |
147 |
148 |
149 | | Name | Number | Description |
150 | | ---- | ------ | ----------- |
151 | | COOLNESS_UNSPECIFIED | 0 | The coolness is unknown. |
152 | | COOLNESS_MAX | 1 | The coolness is maximum. |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 | ### Extensions
162 | | Extension | Type | Extension Point | Number | Description |
163 | | --------- | ---- | ---- | ------ | ----------- |
164 | | country | com.example.country | Manufacturer | 100 | Manufacturer country. |
165 |
166 |
167 |
168 |
--------------------------------------------------------------------------------
/testdata/example1/vehicle.proto:
--------------------------------------------------------------------------------
1 | /** Messages describing manufacturers / vehicles. */
2 | syntax = "proto2";
3 |
4 | package com.example;
5 |
6 | option go_package = "example.com/vehicle";
7 |
8 | enum Coolness {
9 | COOLNESS_UNSPECIFIED = 0; /** The coolness is unknown. */
10 | COOLNESS_MAX = 1; /** The coolness is maximum. */
11 | }
12 |
13 | /**
14 | * Represents a manufacturer of cars.
15 | */
16 | message Manufacturer {
17 | /**
18 | * Manufacturer category. A manufacturer may be either inhouse or external.
19 | */
20 | enum Category {
21 | CATEGORY_INHOUSE = 0; /** The manufacturer is inhouse. */
22 | CATEGORY_EXTERNAL = 1; /** The manufacturer is external. */
23 | }
24 |
25 | required int32 id = 1; /** The unique manufacturer ID. */
26 | required string code = 2; /** A manufacturer code, e.g. "DKL4P". */
27 | optional string details = 3; /** Manufacturer details (minimum orders et.c.). */
28 |
29 | /** Manufacturer category. */
30 | optional Category category = 4 [default = CATEGORY_EXTERNAL];
31 |
32 | extensions 100 to max;
33 | }
34 |
35 | // File-level extensions can also be documented:
36 |
37 | extend Manufacturer {
38 | /** Manufacturer country. */
39 | optional string country = 100 [default = "China"];
40 | }
41 |
42 | /**
43 | * Represents a vehicle model.
44 | */
45 | message Model {
46 | required string id = 1; /** The unique model ID. */
47 | required string model_code = 2; /** The car model code, e.g. "PZ003". */
48 | required string model_name = 3; /** The car model name, e.g. "Z3". */
49 |
50 | required sint32 daily_hire_rate_dollars = 4; /// Dollars per day.
51 | required sint32 daily_hire_rate_cents = 5; /// Cents per day.
52 |
53 | extensions 100 to max;
54 | }
55 |
56 | /**
57 | * Represents a vehicle that can be hired.
58 | */
59 | message Vehicle {
60 | /**
61 | * Represents a vehicle category. E.g. "Sedan" or "Truck".
62 | */
63 | message Category {
64 | required string code = 1; /// Category code. E.g. "S".
65 | required string description = 2; /// Category name. E.g. "Sedan".
66 | }
67 |
68 | required int32 id = 1; /** Unique vehicle ID. */
69 | required Model model = 2; /** Vehicle model. */
70 | required string reg_number = 3; /** Vehicle registration number. */
71 | optional sint32 mileage = 4; /** Current vehicle mileage, if known. */
72 | optional Category category = 5; /** Vehicle category. */
73 |
74 | // Doc comments for fields can come before or
75 | // after the field definition. And just like
76 | // comments for messages / enums, they can be
77 | // multi-paragraph:
78 |
79 | /**
80 | * Dollars per day.
81 | */
82 | optional sint32 daily_hire_rate_dollars = 6 [default = 50];
83 |
84 | /**
85 | * Cents per day.
86 | */
87 | optional sint32 daily_hire_rate_cents = 7;
88 |
89 | // Nested extensions can also be documented:
90 |
91 | extend Model {
92 | /** Vehicle model series. */
93 | optional string series = 100;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/thirdparty/generate.go:
--------------------------------------------------------------------------------
1 | package thirdparty
2 |
3 | //go:generate mkdir -p github.com/envoyproxy/protoc-gen-validate/validate
4 | //go:generate curl -fsSL https://github.com/envoyproxy/protoc-gen-validate/raw/main/validate/validate.proto -o github.com/envoyproxy/protoc-gen-validate/validate/validate.proto
5 |
6 | //go:generate mkdir -p github.com/mwitkow/go-proto-validators
7 | //go:generate curl -fsSL https://github.com/mwitkow/go-proto-validators/raw/master/validator.proto -o github.com/mwitkow/go-proto-validators/validator.proto
8 |
9 | //go:generate mkdir -p github.com/pseudomuto/protokit/fixtures
10 | //go:generate curl -fsSL https://github.com/pseudomuto/protokit/raw/master/fixtures/extend.proto -o github.com/pseudomuto/protokit/fixtures/extend.proto
11 |
--------------------------------------------------------------------------------
/thirdparty/github.com/envoyproxy/protoc-gen-validate/validate/validate.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | package validate;
3 |
4 | option go_package = "github.com/envoyproxy/protoc-gen-validate/validate";
5 | option java_package = "io.envoyproxy.pgv.validate";
6 |
7 | import "google/protobuf/descriptor.proto";
8 | import "google/protobuf/duration.proto";
9 | import "google/protobuf/timestamp.proto";
10 |
11 | // Validation rules applied at the message level
12 | extend google.protobuf.MessageOptions {
13 | // Disabled nullifies any validation rules for this message, including any
14 | // message fields associated with it that do support validation.
15 | optional bool disabled = 1071;
16 | // Ignore skips generation of validation methods for this message.
17 | optional bool ignored = 1072;
18 | }
19 |
20 | // Validation rules applied at the oneof level
21 | extend google.protobuf.OneofOptions {
22 | // Required ensures that exactly one the field options in a oneof is set;
23 | // validation fails if no fields in the oneof are set.
24 | optional bool required = 1071;
25 | }
26 |
27 | // Validation rules applied at the field level
28 | extend google.protobuf.FieldOptions {
29 | // Rules specify the validations to be performed on this field. By default,
30 | // no validation is performed against a field.
31 | optional FieldRules rules = 1071;
32 | }
33 |
34 | // FieldRules encapsulates the rules for each type of field. Depending on the
35 | // field, the correct set should be used to ensure proper validations.
36 | message FieldRules {
37 | optional MessageRules message = 17;
38 | oneof type {
39 | // Scalar Field Types
40 | FloatRules float = 1;
41 | DoubleRules double = 2;
42 | Int32Rules int32 = 3;
43 | Int64Rules int64 = 4;
44 | UInt32Rules uint32 = 5;
45 | UInt64Rules uint64 = 6;
46 | SInt32Rules sint32 = 7;
47 | SInt64Rules sint64 = 8;
48 | Fixed32Rules fixed32 = 9;
49 | Fixed64Rules fixed64 = 10;
50 | SFixed32Rules sfixed32 = 11;
51 | SFixed64Rules sfixed64 = 12;
52 | BoolRules bool = 13;
53 | StringRules string = 14;
54 | BytesRules bytes = 15;
55 |
56 | // Complex Field Types
57 | EnumRules enum = 16;
58 | RepeatedRules repeated = 18;
59 | MapRules map = 19;
60 |
61 | // Well-Known Field Types
62 | AnyRules any = 20;
63 | DurationRules duration = 21;
64 | TimestampRules timestamp = 22;
65 | }
66 | }
67 |
68 | // FloatRules describes the constraints applied to `float` values
69 | message FloatRules {
70 | // Const specifies that this field must be exactly the specified value
71 | optional float const = 1;
72 |
73 | // Lt specifies that this field must be less than the specified value,
74 | // exclusive
75 | optional float lt = 2;
76 |
77 | // Lte specifies that this field must be less than or equal to the
78 | // specified value, inclusive
79 | optional float lte = 3;
80 |
81 | // Gt specifies that this field must be greater than the specified value,
82 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
83 | // range is reversed.
84 | optional float gt = 4;
85 |
86 | // Gte specifies that this field must be greater than or equal to the
87 | // specified value, inclusive. If the value of Gte is larger than a
88 | // specified Lt or Lte, the range is reversed.
89 | optional float gte = 5;
90 |
91 | // In specifies that this field must be equal to one of the specified
92 | // values
93 | repeated float in = 6;
94 |
95 | // NotIn specifies that this field cannot be equal to one of the specified
96 | // values
97 | repeated float not_in = 7;
98 |
99 | // IgnoreEmpty specifies that the validation rules of this field should be
100 | // evaluated only if the field is not empty
101 | optional bool ignore_empty = 8;
102 | }
103 |
104 | // DoubleRules describes the constraints applied to `double` values
105 | message DoubleRules {
106 | // Const specifies that this field must be exactly the specified value
107 | optional double const = 1;
108 |
109 | // Lt specifies that this field must be less than the specified value,
110 | // exclusive
111 | optional double lt = 2;
112 |
113 | // Lte specifies that this field must be less than or equal to the
114 | // specified value, inclusive
115 | optional double lte = 3;
116 |
117 | // Gt specifies that this field must be greater than the specified value,
118 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
119 | // range is reversed.
120 | optional double gt = 4;
121 |
122 | // Gte specifies that this field must be greater than or equal to the
123 | // specified value, inclusive. If the value of Gte is larger than a
124 | // specified Lt or Lte, the range is reversed.
125 | optional double gte = 5;
126 |
127 | // In specifies that this field must be equal to one of the specified
128 | // values
129 | repeated double in = 6;
130 |
131 | // NotIn specifies that this field cannot be equal to one of the specified
132 | // values
133 | repeated double not_in = 7;
134 |
135 | // IgnoreEmpty specifies that the validation rules of this field should be
136 | // evaluated only if the field is not empty
137 | optional bool ignore_empty = 8;
138 | }
139 |
140 | // Int32Rules describes the constraints applied to `int32` values
141 | message Int32Rules {
142 | // Const specifies that this field must be exactly the specified value
143 | optional int32 const = 1;
144 |
145 | // Lt specifies that this field must be less than the specified value,
146 | // exclusive
147 | optional int32 lt = 2;
148 |
149 | // Lte specifies that this field must be less than or equal to the
150 | // specified value, inclusive
151 | optional int32 lte = 3;
152 |
153 | // Gt specifies that this field must be greater than the specified value,
154 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
155 | // range is reversed.
156 | optional int32 gt = 4;
157 |
158 | // Gte specifies that this field must be greater than or equal to the
159 | // specified value, inclusive. If the value of Gte is larger than a
160 | // specified Lt or Lte, the range is reversed.
161 | optional int32 gte = 5;
162 |
163 | // In specifies that this field must be equal to one of the specified
164 | // values
165 | repeated int32 in = 6;
166 |
167 | // NotIn specifies that this field cannot be equal to one of the specified
168 | // values
169 | repeated int32 not_in = 7;
170 |
171 | // IgnoreEmpty specifies that the validation rules of this field should be
172 | // evaluated only if the field is not empty
173 | optional bool ignore_empty = 8;
174 | }
175 |
176 | // Int64Rules describes the constraints applied to `int64` values
177 | message Int64Rules {
178 | // Const specifies that this field must be exactly the specified value
179 | optional int64 const = 1;
180 |
181 | // Lt specifies that this field must be less than the specified value,
182 | // exclusive
183 | optional int64 lt = 2;
184 |
185 | // Lte specifies that this field must be less than or equal to the
186 | // specified value, inclusive
187 | optional int64 lte = 3;
188 |
189 | // Gt specifies that this field must be greater than the specified value,
190 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
191 | // range is reversed.
192 | optional int64 gt = 4;
193 |
194 | // Gte specifies that this field must be greater than or equal to the
195 | // specified value, inclusive. If the value of Gte is larger than a
196 | // specified Lt or Lte, the range is reversed.
197 | optional int64 gte = 5;
198 |
199 | // In specifies that this field must be equal to one of the specified
200 | // values
201 | repeated int64 in = 6;
202 |
203 | // NotIn specifies that this field cannot be equal to one of the specified
204 | // values
205 | repeated int64 not_in = 7;
206 |
207 | // IgnoreEmpty specifies that the validation rules of this field should be
208 | // evaluated only if the field is not empty
209 | optional bool ignore_empty = 8;
210 | }
211 |
212 | // UInt32Rules describes the constraints applied to `uint32` values
213 | message UInt32Rules {
214 | // Const specifies that this field must be exactly the specified value
215 | optional uint32 const = 1;
216 |
217 | // Lt specifies that this field must be less than the specified value,
218 | // exclusive
219 | optional uint32 lt = 2;
220 |
221 | // Lte specifies that this field must be less than or equal to the
222 | // specified value, inclusive
223 | optional uint32 lte = 3;
224 |
225 | // Gt specifies that this field must be greater than the specified value,
226 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
227 | // range is reversed.
228 | optional uint32 gt = 4;
229 |
230 | // Gte specifies that this field must be greater than or equal to the
231 | // specified value, inclusive. If the value of Gte is larger than a
232 | // specified Lt or Lte, the range is reversed.
233 | optional uint32 gte = 5;
234 |
235 | // In specifies that this field must be equal to one of the specified
236 | // values
237 | repeated uint32 in = 6;
238 |
239 | // NotIn specifies that this field cannot be equal to one of the specified
240 | // values
241 | repeated uint32 not_in = 7;
242 |
243 | // IgnoreEmpty specifies that the validation rules of this field should be
244 | // evaluated only if the field is not empty
245 | optional bool ignore_empty = 8;
246 | }
247 |
248 | // UInt64Rules describes the constraints applied to `uint64` values
249 | message UInt64Rules {
250 | // Const specifies that this field must be exactly the specified value
251 | optional uint64 const = 1;
252 |
253 | // Lt specifies that this field must be less than the specified value,
254 | // exclusive
255 | optional uint64 lt = 2;
256 |
257 | // Lte specifies that this field must be less than or equal to the
258 | // specified value, inclusive
259 | optional uint64 lte = 3;
260 |
261 | // Gt specifies that this field must be greater than the specified value,
262 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
263 | // range is reversed.
264 | optional uint64 gt = 4;
265 |
266 | // Gte specifies that this field must be greater than or equal to the
267 | // specified value, inclusive. If the value of Gte is larger than a
268 | // specified Lt or Lte, the range is reversed.
269 | optional uint64 gte = 5;
270 |
271 | // In specifies that this field must be equal to one of the specified
272 | // values
273 | repeated uint64 in = 6;
274 |
275 | // NotIn specifies that this field cannot be equal to one of the specified
276 | // values
277 | repeated uint64 not_in = 7;
278 |
279 | // IgnoreEmpty specifies that the validation rules of this field should be
280 | // evaluated only if the field is not empty
281 | optional bool ignore_empty = 8;
282 | }
283 |
284 | // SInt32Rules describes the constraints applied to `sint32` values
285 | message SInt32Rules {
286 | // Const specifies that this field must be exactly the specified value
287 | optional sint32 const = 1;
288 |
289 | // Lt specifies that this field must be less than the specified value,
290 | // exclusive
291 | optional sint32 lt = 2;
292 |
293 | // Lte specifies that this field must be less than or equal to the
294 | // specified value, inclusive
295 | optional sint32 lte = 3;
296 |
297 | // Gt specifies that this field must be greater than the specified value,
298 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
299 | // range is reversed.
300 | optional sint32 gt = 4;
301 |
302 | // Gte specifies that this field must be greater than or equal to the
303 | // specified value, inclusive. If the value of Gte is larger than a
304 | // specified Lt or Lte, the range is reversed.
305 | optional sint32 gte = 5;
306 |
307 | // In specifies that this field must be equal to one of the specified
308 | // values
309 | repeated sint32 in = 6;
310 |
311 | // NotIn specifies that this field cannot be equal to one of the specified
312 | // values
313 | repeated sint32 not_in = 7;
314 |
315 | // IgnoreEmpty specifies that the validation rules of this field should be
316 | // evaluated only if the field is not empty
317 | optional bool ignore_empty = 8;
318 | }
319 |
320 | // SInt64Rules describes the constraints applied to `sint64` values
321 | message SInt64Rules {
322 | // Const specifies that this field must be exactly the specified value
323 | optional sint64 const = 1;
324 |
325 | // Lt specifies that this field must be less than the specified value,
326 | // exclusive
327 | optional sint64 lt = 2;
328 |
329 | // Lte specifies that this field must be less than or equal to the
330 | // specified value, inclusive
331 | optional sint64 lte = 3;
332 |
333 | // Gt specifies that this field must be greater than the specified value,
334 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
335 | // range is reversed.
336 | optional sint64 gt = 4;
337 |
338 | // Gte specifies that this field must be greater than or equal to the
339 | // specified value, inclusive. If the value of Gte is larger than a
340 | // specified Lt or Lte, the range is reversed.
341 | optional sint64 gte = 5;
342 |
343 | // In specifies that this field must be equal to one of the specified
344 | // values
345 | repeated sint64 in = 6;
346 |
347 | // NotIn specifies that this field cannot be equal to one of the specified
348 | // values
349 | repeated sint64 not_in = 7;
350 |
351 | // IgnoreEmpty specifies that the validation rules of this field should be
352 | // evaluated only if the field is not empty
353 | optional bool ignore_empty = 8;
354 | }
355 |
356 | // Fixed32Rules describes the constraints applied to `fixed32` values
357 | message Fixed32Rules {
358 | // Const specifies that this field must be exactly the specified value
359 | optional fixed32 const = 1;
360 |
361 | // Lt specifies that this field must be less than the specified value,
362 | // exclusive
363 | optional fixed32 lt = 2;
364 |
365 | // Lte specifies that this field must be less than or equal to the
366 | // specified value, inclusive
367 | optional fixed32 lte = 3;
368 |
369 | // Gt specifies that this field must be greater than the specified value,
370 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
371 | // range is reversed.
372 | optional fixed32 gt = 4;
373 |
374 | // Gte specifies that this field must be greater than or equal to the
375 | // specified value, inclusive. If the value of Gte is larger than a
376 | // specified Lt or Lte, the range is reversed.
377 | optional fixed32 gte = 5;
378 |
379 | // In specifies that this field must be equal to one of the specified
380 | // values
381 | repeated fixed32 in = 6;
382 |
383 | // NotIn specifies that this field cannot be equal to one of the specified
384 | // values
385 | repeated fixed32 not_in = 7;
386 |
387 | // IgnoreEmpty specifies that the validation rules of this field should be
388 | // evaluated only if the field is not empty
389 | optional bool ignore_empty = 8;
390 | }
391 |
392 | // Fixed64Rules describes the constraints applied to `fixed64` values
393 | message Fixed64Rules {
394 | // Const specifies that this field must be exactly the specified value
395 | optional fixed64 const = 1;
396 |
397 | // Lt specifies that this field must be less than the specified value,
398 | // exclusive
399 | optional fixed64 lt = 2;
400 |
401 | // Lte specifies that this field must be less than or equal to the
402 | // specified value, inclusive
403 | optional fixed64 lte = 3;
404 |
405 | // Gt specifies that this field must be greater than the specified value,
406 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
407 | // range is reversed.
408 | optional fixed64 gt = 4;
409 |
410 | // Gte specifies that this field must be greater than or equal to the
411 | // specified value, inclusive. If the value of Gte is larger than a
412 | // specified Lt or Lte, the range is reversed.
413 | optional fixed64 gte = 5;
414 |
415 | // In specifies that this field must be equal to one of the specified
416 | // values
417 | repeated fixed64 in = 6;
418 |
419 | // NotIn specifies that this field cannot be equal to one of the specified
420 | // values
421 | repeated fixed64 not_in = 7;
422 |
423 | // IgnoreEmpty specifies that the validation rules of this field should be
424 | // evaluated only if the field is not empty
425 | optional bool ignore_empty = 8;
426 | }
427 |
428 | // SFixed32Rules describes the constraints applied to `sfixed32` values
429 | message SFixed32Rules {
430 | // Const specifies that this field must be exactly the specified value
431 | optional sfixed32 const = 1;
432 |
433 | // Lt specifies that this field must be less than the specified value,
434 | // exclusive
435 | optional sfixed32 lt = 2;
436 |
437 | // Lte specifies that this field must be less than or equal to the
438 | // specified value, inclusive
439 | optional sfixed32 lte = 3;
440 |
441 | // Gt specifies that this field must be greater than the specified value,
442 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
443 | // range is reversed.
444 | optional sfixed32 gt = 4;
445 |
446 | // Gte specifies that this field must be greater than or equal to the
447 | // specified value, inclusive. If the value of Gte is larger than a
448 | // specified Lt or Lte, the range is reversed.
449 | optional sfixed32 gte = 5;
450 |
451 | // In specifies that this field must be equal to one of the specified
452 | // values
453 | repeated sfixed32 in = 6;
454 |
455 | // NotIn specifies that this field cannot be equal to one of the specified
456 | // values
457 | repeated sfixed32 not_in = 7;
458 |
459 | // IgnoreEmpty specifies that the validation rules of this field should be
460 | // evaluated only if the field is not empty
461 | optional bool ignore_empty = 8;
462 | }
463 |
464 | // SFixed64Rules describes the constraints applied to `sfixed64` values
465 | message SFixed64Rules {
466 | // Const specifies that this field must be exactly the specified value
467 | optional sfixed64 const = 1;
468 |
469 | // Lt specifies that this field must be less than the specified value,
470 | // exclusive
471 | optional sfixed64 lt = 2;
472 |
473 | // Lte specifies that this field must be less than or equal to the
474 | // specified value, inclusive
475 | optional sfixed64 lte = 3;
476 |
477 | // Gt specifies that this field must be greater than the specified value,
478 | // exclusive. If the value of Gt is larger than a specified Lt or Lte, the
479 | // range is reversed.
480 | optional sfixed64 gt = 4;
481 |
482 | // Gte specifies that this field must be greater than or equal to the
483 | // specified value, inclusive. If the value of Gte is larger than a
484 | // specified Lt or Lte, the range is reversed.
485 | optional sfixed64 gte = 5;
486 |
487 | // In specifies that this field must be equal to one of the specified
488 | // values
489 | repeated sfixed64 in = 6;
490 |
491 | // NotIn specifies that this field cannot be equal to one of the specified
492 | // values
493 | repeated sfixed64 not_in = 7;
494 |
495 | // IgnoreEmpty specifies that the validation rules of this field should be
496 | // evaluated only if the field is not empty
497 | optional bool ignore_empty = 8;
498 | }
499 |
500 | // BoolRules describes the constraints applied to `bool` values
501 | message BoolRules {
502 | // Const specifies that this field must be exactly the specified value
503 | optional bool const = 1;
504 | }
505 |
506 | // StringRules describe the constraints applied to `string` values
507 | message StringRules {
508 | // Const specifies that this field must be exactly the specified value
509 | optional string const = 1;
510 |
511 | // Len specifies that this field must be the specified number of
512 | // characters (Unicode code points). Note that the number of
513 | // characters may differ from the number of bytes in the string.
514 | optional uint64 len = 19;
515 |
516 | // MinLen specifies that this field must be the specified number of
517 | // characters (Unicode code points) at a minimum. Note that the number of
518 | // characters may differ from the number of bytes in the string.
519 | optional uint64 min_len = 2;
520 |
521 | // MaxLen specifies that this field must be the specified number of
522 | // characters (Unicode code points) at a maximum. Note that the number of
523 | // characters may differ from the number of bytes in the string.
524 | optional uint64 max_len = 3;
525 |
526 | // LenBytes specifies that this field must be the specified number of bytes
527 | optional uint64 len_bytes = 20;
528 |
529 | // MinBytes specifies that this field must be the specified number of bytes
530 | // at a minimum
531 | optional uint64 min_bytes = 4;
532 |
533 | // MaxBytes specifies that this field must be the specified number of bytes
534 | // at a maximum
535 | optional uint64 max_bytes = 5;
536 |
537 | // Pattern specifes that this field must match against the specified
538 | // regular expression (RE2 syntax). The included expression should elide
539 | // any delimiters.
540 | optional string pattern = 6;
541 |
542 | // Prefix specifies that this field must have the specified substring at
543 | // the beginning of the string.
544 | optional string prefix = 7;
545 |
546 | // Suffix specifies that this field must have the specified substring at
547 | // the end of the string.
548 | optional string suffix = 8;
549 |
550 | // Contains specifies that this field must have the specified substring
551 | // anywhere in the string.
552 | optional string contains = 9;
553 |
554 | // NotContains specifies that this field cannot have the specified substring
555 | // anywhere in the string.
556 | optional string not_contains = 23;
557 |
558 | // In specifies that this field must be equal to one of the specified
559 | // values
560 | repeated string in = 10;
561 |
562 | // NotIn specifies that this field cannot be equal to one of the specified
563 | // values
564 | repeated string not_in = 11;
565 |
566 | // WellKnown rules provide advanced constraints against common string
567 | // patterns
568 | oneof well_known {
569 | // Email specifies that the field must be a valid email address as
570 | // defined by RFC 5322
571 | bool email = 12;
572 |
573 | // Hostname specifies that the field must be a valid hostname as
574 | // defined by RFC 1034. This constraint does not support
575 | // internationalized domain names (IDNs).
576 | bool hostname = 13;
577 |
578 | // Ip specifies that the field must be a valid IP (v4 or v6) address.
579 | // Valid IPv6 addresses should not include surrounding square brackets.
580 | bool ip = 14;
581 |
582 | // Ipv4 specifies that the field must be a valid IPv4 address.
583 | bool ipv4 = 15;
584 |
585 | // Ipv6 specifies that the field must be a valid IPv6 address. Valid
586 | // IPv6 addresses should not include surrounding square brackets.
587 | bool ipv6 = 16;
588 |
589 | // Uri specifies that the field must be a valid, absolute URI as defined
590 | // by RFC 3986
591 | bool uri = 17;
592 |
593 | // UriRef specifies that the field must be a valid URI as defined by RFC
594 | // 3986 and may be relative or absolute.
595 | bool uri_ref = 18;
596 |
597 | // Address specifies that the field must be either a valid hostname as
598 | // defined by RFC 1034 (which does not support internationalized domain
599 | // names or IDNs), or it can be a valid IP (v4 or v6).
600 | bool address = 21;
601 |
602 | // Uuid specifies that the field must be a valid UUID as defined by
603 | // RFC 4122
604 | bool uuid = 22;
605 |
606 | // WellKnownRegex specifies a common well known pattern defined as a regex.
607 | KnownRegex well_known_regex = 24;
608 | }
609 |
610 | // This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable
611 | // strict header validation.
612 | // By default, this is true, and HTTP header validations are RFC-compliant.
613 | // Setting to false will enable a looser validations that only disallows
614 | // \r\n\0 characters, which can be used to bypass header matching rules.
615 | optional bool strict = 25 [default = true];
616 |
617 | // IgnoreEmpty specifies that the validation rules of this field should be
618 | // evaluated only if the field is not empty
619 | optional bool ignore_empty = 26;
620 | }
621 |
622 | // WellKnownRegex contain some well-known patterns.
623 | enum KnownRegex {
624 | UNKNOWN = 0;
625 |
626 | // HTTP header name as defined by RFC 7230.
627 | HTTP_HEADER_NAME = 1;
628 |
629 | // HTTP header value as defined by RFC 7230.
630 | HTTP_HEADER_VALUE = 2;
631 | }
632 |
633 | // BytesRules describe the constraints applied to `bytes` values
634 | message BytesRules {
635 | // Const specifies that this field must be exactly the specified value
636 | optional bytes const = 1;
637 |
638 | // Len specifies that this field must be the specified number of bytes
639 | optional uint64 len = 13;
640 |
641 | // MinLen specifies that this field must be the specified number of bytes
642 | // at a minimum
643 | optional uint64 min_len = 2;
644 |
645 | // MaxLen specifies that this field must be the specified number of bytes
646 | // at a maximum
647 | optional uint64 max_len = 3;
648 |
649 | // Pattern specifes that this field must match against the specified
650 | // regular expression (RE2 syntax). The included expression should elide
651 | // any delimiters.
652 | optional string pattern = 4;
653 |
654 | // Prefix specifies that this field must have the specified bytes at the
655 | // beginning of the string.
656 | optional bytes prefix = 5;
657 |
658 | // Suffix specifies that this field must have the specified bytes at the
659 | // end of the string.
660 | optional bytes suffix = 6;
661 |
662 | // Contains specifies that this field must have the specified bytes
663 | // anywhere in the string.
664 | optional bytes contains = 7;
665 |
666 | // In specifies that this field must be equal to one of the specified
667 | // values
668 | repeated bytes in = 8;
669 |
670 | // NotIn specifies that this field cannot be equal to one of the specified
671 | // values
672 | repeated bytes not_in = 9;
673 |
674 | // WellKnown rules provide advanced constraints against common byte
675 | // patterns
676 | oneof well_known {
677 | // Ip specifies that the field must be a valid IP (v4 or v6) address in
678 | // byte format
679 | bool ip = 10;
680 |
681 | // Ipv4 specifies that the field must be a valid IPv4 address in byte
682 | // format
683 | bool ipv4 = 11;
684 |
685 | // Ipv6 specifies that the field must be a valid IPv6 address in byte
686 | // format
687 | bool ipv6 = 12;
688 | }
689 |
690 | // IgnoreEmpty specifies that the validation rules of this field should be
691 | // evaluated only if the field is not empty
692 | optional bool ignore_empty = 14;
693 | }
694 |
695 | // EnumRules describe the constraints applied to enum values
696 | message EnumRules {
697 | // Const specifies that this field must be exactly the specified value
698 | optional int32 const = 1;
699 |
700 | // DefinedOnly specifies that this field must be only one of the defined
701 | // values for this enum, failing on any undefined value.
702 | optional bool defined_only = 2;
703 |
704 | // In specifies that this field must be equal to one of the specified
705 | // values
706 | repeated int32 in = 3;
707 |
708 | // NotIn specifies that this field cannot be equal to one of the specified
709 | // values
710 | repeated int32 not_in = 4;
711 | }
712 |
713 | // MessageRules describe the constraints applied to embedded message values.
714 | // For message-type fields, validation is performed recursively.
715 | message MessageRules {
716 | // Skip specifies that the validation rules of this field should not be
717 | // evaluated
718 | optional bool skip = 1;
719 |
720 | // Required specifies that this field must be set
721 | optional bool required = 2;
722 | }
723 |
724 | // RepeatedRules describe the constraints applied to `repeated` values
725 | message RepeatedRules {
726 | // MinItems specifies that this field must have the specified number of
727 | // items at a minimum
728 | optional uint64 min_items = 1;
729 |
730 | // MaxItems specifies that this field must have the specified number of
731 | // items at a maximum
732 | optional uint64 max_items = 2;
733 |
734 | // Unique specifies that all elements in this field must be unique. This
735 | // contraint is only applicable to scalar and enum types (messages are not
736 | // supported).
737 | optional bool unique = 3;
738 |
739 | // Items specifies the contraints to be applied to each item in the field.
740 | // Repeated message fields will still execute validation against each item
741 | // unless skip is specified here.
742 | optional FieldRules items = 4;
743 |
744 | // IgnoreEmpty specifies that the validation rules of this field should be
745 | // evaluated only if the field is not empty
746 | optional bool ignore_empty = 5;
747 | }
748 |
749 | // MapRules describe the constraints applied to `map` values
750 | message MapRules {
751 | // MinPairs specifies that this field must have the specified number of
752 | // KVs at a minimum
753 | optional uint64 min_pairs = 1;
754 |
755 | // MaxPairs specifies that this field must have the specified number of
756 | // KVs at a maximum
757 | optional uint64 max_pairs = 2;
758 |
759 | // NoSparse specifies values in this field cannot be unset. This only
760 | // applies to map's with message value types.
761 | optional bool no_sparse = 3;
762 |
763 | // Keys specifies the constraints to be applied to each key in the field.
764 | optional FieldRules keys = 4;
765 |
766 | // Values specifies the constraints to be applied to the value of each key
767 | // in the field. Message values will still have their validations evaluated
768 | // unless skip is specified here.
769 | optional FieldRules values = 5;
770 |
771 | // IgnoreEmpty specifies that the validation rules of this field should be
772 | // evaluated only if the field is not empty
773 | optional bool ignore_empty = 6;
774 | }
775 |
776 | // AnyRules describe constraints applied exclusively to the
777 | // `google.protobuf.Any` well-known type
778 | message AnyRules {
779 | // Required specifies that this field must be set
780 | optional bool required = 1;
781 |
782 | // In specifies that this field's `type_url` must be equal to one of the
783 | // specified values.
784 | repeated string in = 2;
785 |
786 | // NotIn specifies that this field's `type_url` must not be equal to any of
787 | // the specified values.
788 | repeated string not_in = 3;
789 | }
790 |
791 | // DurationRules describe the constraints applied exclusively to the
792 | // `google.protobuf.Duration` well-known type
793 | message DurationRules {
794 | // Required specifies that this field must be set
795 | optional bool required = 1;
796 |
797 | // Const specifies that this field must be exactly the specified value
798 | optional google.protobuf.Duration const = 2;
799 |
800 | // Lt specifies that this field must be less than the specified value,
801 | // exclusive
802 | optional google.protobuf.Duration lt = 3;
803 |
804 | // Lt specifies that this field must be less than the specified value,
805 | // inclusive
806 | optional google.protobuf.Duration lte = 4;
807 |
808 | // Gt specifies that this field must be greater than the specified value,
809 | // exclusive
810 | optional google.protobuf.Duration gt = 5;
811 |
812 | // Gte specifies that this field must be greater than the specified value,
813 | // inclusive
814 | optional google.protobuf.Duration gte = 6;
815 |
816 | // In specifies that this field must be equal to one of the specified
817 | // values
818 | repeated google.protobuf.Duration in = 7;
819 |
820 | // NotIn specifies that this field cannot be equal to one of the specified
821 | // values
822 | repeated google.protobuf.Duration not_in = 8;
823 | }
824 |
825 | // TimestampRules describe the constraints applied exclusively to the
826 | // `google.protobuf.Timestamp` well-known type
827 | message TimestampRules {
828 | // Required specifies that this field must be set
829 | optional bool required = 1;
830 |
831 | // Const specifies that this field must be exactly the specified value
832 | optional google.protobuf.Timestamp const = 2;
833 |
834 | // Lt specifies that this field must be less than the specified value,
835 | // exclusive
836 | optional google.protobuf.Timestamp lt = 3;
837 |
838 | // Lte specifies that this field must be less than the specified value,
839 | // inclusive
840 | optional google.protobuf.Timestamp lte = 4;
841 |
842 | // Gt specifies that this field must be greater than the specified value,
843 | // exclusive
844 | optional google.protobuf.Timestamp gt = 5;
845 |
846 | // Gte specifies that this field must be greater than the specified value,
847 | // inclusive
848 | optional google.protobuf.Timestamp gte = 6;
849 |
850 | // LtNow specifies that this must be less than the current time. LtNow
851 | // can only be used with the Within rule.
852 | optional bool lt_now = 7;
853 |
854 | // GtNow specifies that this must be greater than the current time. GtNow
855 | // can only be used with the Within rule.
856 | optional bool gt_now = 8;
857 |
858 | // Within specifies that this field must be within this duration of the
859 | // current time. This constraint can be used alone or with the LtNow and
860 | // GtNow rules.
861 | optional google.protobuf.Duration within = 9;
862 | }
863 |
--------------------------------------------------------------------------------
/thirdparty/github.com/mwitkow/go-proto-validators/validator.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2016 Michal Witkowski. All Rights Reserved.
2 | // See LICENSE for licensing terms.
3 |
4 | // Protocol Buffers extensions for defining auto-generateable validators for messages.
5 |
6 | // TODO(mwitkow): Add example.
7 |
8 |
9 | syntax = "proto2";
10 | package validator;
11 |
12 | import "google/protobuf/descriptor.proto";
13 |
14 | option go_package = "github.com/mwitkow/go-proto-validators;validator";
15 |
16 | // TODO(mwitkow): Email protobuf-global-extension-registry@google.com to get an extension ID.
17 |
18 | extend google.protobuf.FieldOptions {
19 | optional FieldValidator field = 65020;
20 | }
21 |
22 | extend google.protobuf.OneofOptions {
23 | optional OneofValidator oneof = 65021;
24 | }
25 |
26 | message FieldValidator {
27 | // Uses a Golang RE2-syntax regex to match the field contents.
28 | optional string regex = 1;
29 | // Field value of integer strictly greater than this value.
30 | optional int64 int_gt = 2;
31 | // Field value of integer strictly smaller than this value.
32 | optional int64 int_lt = 3;
33 | // Used for nested message types, requires that the message type exists.
34 | optional bool msg_exists = 4;
35 | // Human error specifies a user-customizable error that is visible to the user.
36 | optional string human_error = 5;
37 | // Field value of double strictly greater than this value.
38 | // Note that this value can only take on a valid floating point
39 | // value. Use together with float_epsilon if you need something more specific.
40 | optional double float_gt = 6;
41 | // Field value of double strictly smaller than this value.
42 | // Note that this value can only take on a valid floating point
43 | // value. Use together with float_epsilon if you need something more specific.
44 | optional double float_lt = 7;
45 | // Field value of double describing the epsilon within which
46 | // any comparison should be considered to be true. For example,
47 | // when using float_gt = 0.35, using a float_epsilon of 0.05
48 | // would mean that any value above 0.30 is acceptable. It can be
49 | // thought of as a {float_value_condition} +- {float_epsilon}.
50 | // If unset, no correction for floating point inaccuracies in
51 | // comparisons will be attempted.
52 | optional double float_epsilon = 8;
53 | // Floating-point value compared to which the field content should be greater or equal.
54 | optional double float_gte = 9;
55 | // Floating-point value compared to which the field content should be smaller or equal.
56 | optional double float_lte = 10;
57 | // Used for string fields, requires the string to be not empty (i.e different from "").
58 | optional bool string_not_empty = 11;
59 | // Repeated field with at least this number of elements.
60 | optional int64 repeated_count_min = 12;
61 | // Repeated field with at most this number of elements.
62 | optional int64 repeated_count_max = 13;
63 | // Field value of length greater than this value.
64 | optional int64 length_gt = 14;
65 | // Field value of length smaller than this value.
66 | optional int64 length_lt = 15;
67 | // Field value of length strictly equal to this value.
68 | optional int64 length_eq = 16;
69 | // Requires that the value is in the enum.
70 | optional bool is_in_enum = 17;
71 | // Ensures that a string value is in UUID format.
72 | // uuid_ver specifies the valid UUID versions. Valid values are: 0-5.
73 | // If uuid_ver is 0 all UUID versions are accepted.
74 | optional int32 uuid_ver = 18;
75 | }
76 |
77 | message OneofValidator {
78 | // Require that one of the oneof fields is set.
79 | optional bool required = 1;
80 | }
81 |
--------------------------------------------------------------------------------
/thirdparty/github.com/pseudomuto/protokit/fixtures/extend.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 |
3 | import "google/protobuf/descriptor.proto";
4 |
5 | package com.pseudomuto.protokit.v1;
6 |
7 | /**
8 | * Extension of protobuf file options.
9 | */
10 | extend google.protobuf.FileOptions {
11 | optional bool extend_file = 20000;
12 | }
13 |
14 | /**
15 | * Extension of protobuf service options.
16 | */
17 | extend google.protobuf.ServiceOptions {
18 | optional bool extend_service = 20000;
19 | }
20 |
21 | /**
22 | * Extension of protobuf method options.
23 | */
24 | extend google.protobuf.MethodOptions {
25 | optional bool extend_method = 20000;
26 | }
27 |
28 | /**
29 | * Extension of protobuf enum options.
30 | */
31 | extend google.protobuf.EnumOptions {
32 | optional bool extend_enum = 20000;
33 | }
34 |
35 | /**
36 | * Extension of protobuf enum value options.
37 | */
38 | extend google.protobuf.EnumValueOptions {
39 | optional bool extend_enum_value = 20000;
40 | }
41 |
42 | /**
43 | * Extension of protobuf message options.
44 | */
45 | extend google.protobuf.MessageOptions {
46 | optional bool extend_message = 20000;
47 | }
48 |
49 | /**
50 | * Extension of protobuf field options.
51 | */
52 | extend google.protobuf.FieldOptions {
53 | optional bool extend_field = 20000;
54 | }
55 |
--------------------------------------------------------------------------------
/tmp/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tmc/protoc-gen-apidocs/b7fcc7fd042d1152fbd933b3d3acdc4be50b5f4e/tmp/.gitkeep
--------------------------------------------------------------------------------
Union field `payload`. `payload` can be only one of the following: