├── .github └── workflows │ └── go.yml ├── COMPILE-PROTOS.sh ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── compiler ├── README.md ├── context.go ├── error.go ├── extensions.go ├── helpers.go ├── main.go └── reader.go ├── discovery ├── README.md ├── discovery.go ├── discovery.pb.go ├── discovery.proto ├── document.go └── list.go ├── extensions ├── README.md ├── extension.pb.go ├── extension.proto └── extensions.go ├── go.mod ├── go.sum ├── jsonschema ├── README.md ├── base.go ├── display.go ├── generate-base.go ├── models.go ├── operations.go ├── reader.go ├── schema.json └── writer.go ├── openapiv2 ├── OpenAPIv2.go ├── OpenAPIv2.pb.go ├── OpenAPIv2.proto ├── README.md ├── document.go └── openapi-2.0.json ├── openapiv3 ├── OpenAPIv3.go ├── OpenAPIv3.pb.go ├── OpenAPIv3.proto ├── README.md ├── annotations.pb.go ├── annotations.proto └── document.go └── third_party └── google ├── api └── httpbody.proto └── protobuf ├── any.proto ├── api.proto ├── compiler └── plugin.proto ├── descriptor.proto ├── duration.proto ├── empty.proto ├── field_mask.proto ├── source_context.proto ├── struct.proto ├── timestamp.proto ├── type.proto └── wrappers.proto /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | 12 | build: 13 | name: Build 14 | runs-on: ubuntu-22.04 15 | steps: 16 | 17 | - name: Set up Go 1.x 18 | uses: actions/setup-go@v2 19 | with: 20 | go-version: ^1.13 21 | 22 | - name: Check out code into the Go module directory 23 | uses: actions/checkout@v2 24 | 25 | # Disable protoc download until we have proper validation in place 26 | # - name: Get protoc 27 | # run: | 28 | # sudo curl -L https://github.com/protocolbuffers/protobuf/releases/download/v3.15.0/protoc-3.15.0-linux-x86_64.zip > /tmp/protoc.zip 29 | # sudo unzip /tmp/protoc.zip -d /usr/local 30 | # sudo chown -R $USER /usr/local 31 | 32 | - name: Get dependencies 33 | run: go get -v -t -d ./... 34 | 35 | - name: Build 36 | run: make all 37 | 38 | - name: Test 39 | run: go test ./... -v 40 | -------------------------------------------------------------------------------- /COMPILE-PROTOS.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2016 Google LLC. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | go install google.golang.org/protobuf/cmd/protoc-gen-go 19 | 20 | protoc -I . -I ./third_party --go_out=. --go_opt=paths=source_relative openapiv2/*.proto 21 | protoc -I . -I ./third_party --go_out=. --go_opt=paths=source_relative openapiv3/*.proto 22 | protoc -I . -I ./third_party --go_out=. --go_opt=paths=source_relative discovery/*.proto 23 | protoc -I . -I ./third_party --go_out=. --go_opt=paths=source_relative extensions/*.proto 24 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement (CLA). You (or your employer) retain the copyright to your 10 | contribution; this simply gives us permission to use and redistribute your 11 | contributions as part of the project. Head over to 12 | to see your current agreements on file or 13 | to sign a new one. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted one 16 | (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | ## Code Reviews 20 | 21 | All submissions, including submissions by project members, require review. We 22 | use GitHub pull requests for this purpose. Consult 23 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 24 | information on using pull requests. 25 | 26 | ## Community Guidelines 27 | 28 | This project follows 29 | [Google's Open Source Community Guidelines](https://opensource.google/conduct/). 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | 204 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | go generate ./... 3 | go get ./... 4 | go install ./... 5 | 6 | test: 7 | # since some tests call separately-built binaries, clear the cache to ensure all get run 8 | go clean -testcache 9 | go test ./... -v 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⨁ gnostic-models 2 | 3 | This repository contains Protocol Buffer models and associated libraries 4 | for working with API description formats supported by 5 | [gnostic](https://github.com/google/gnostic). It exists to provide a 6 | lightweight distribution of these models with minimal dependencies. 7 | For more information, please see the 8 | [gnostic](https://github.com/google/gnostic) repository. 9 | 10 | ## Versions 11 | 12 | Versions of this repository will be tagged with the **gnostic** version used 13 | to create them, e.g. "v0.7.0" will correspond to "v0.7.0" of **gnostic**. 14 | 15 | ## Disclaimer 16 | 17 | Feedback and contributions are welcome! Until there is a 1.0 release, please 18 | consider this prerelease software and work in progress. To ensure stable 19 | builds, we request that dependent projects always refer to tagged releases of 20 | **gnostic**. 21 | 22 | ## Copyright 23 | 24 | Copyright 2017-2024, Google LLC. 25 | 26 | ## License 27 | 28 | Released under the Apache 2.0 license. 29 | -------------------------------------------------------------------------------- /compiler/README.md: -------------------------------------------------------------------------------- 1 | # Compiler support code 2 | 3 | This directory contains compiler support code used by Gnostic and Gnostic 4 | extensions. 5 | -------------------------------------------------------------------------------- /compiler/context.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compiler 16 | 17 | import ( 18 | yaml "gopkg.in/yaml.v3" 19 | ) 20 | 21 | // Context contains state of the compiler as it traverses a document. 22 | type Context struct { 23 | Parent *Context 24 | Name string 25 | Node *yaml.Node 26 | ExtensionHandlers *[]ExtensionHandler 27 | } 28 | 29 | // NewContextWithExtensions returns a new object representing the compiler state 30 | func NewContextWithExtensions(name string, node *yaml.Node, parent *Context, extensionHandlers *[]ExtensionHandler) *Context { 31 | return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: extensionHandlers} 32 | } 33 | 34 | // NewContext returns a new object representing the compiler state 35 | func NewContext(name string, node *yaml.Node, parent *Context) *Context { 36 | if parent != nil { 37 | return &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers} 38 | } 39 | return &Context{Name: name, Parent: parent, ExtensionHandlers: nil} 40 | } 41 | 42 | // Description returns a text description of the compiler state 43 | func (context *Context) Description() string { 44 | name := context.Name 45 | if context.Parent != nil { 46 | name = context.Parent.Description() + "." + name 47 | } 48 | return name 49 | } 50 | -------------------------------------------------------------------------------- /compiler/error.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compiler 16 | 17 | import "fmt" 18 | 19 | // Error represents compiler errors and their location in the document. 20 | type Error struct { 21 | Context *Context 22 | Message string 23 | } 24 | 25 | // NewError creates an Error. 26 | func NewError(context *Context, message string) *Error { 27 | return &Error{Context: context, Message: message} 28 | } 29 | 30 | func (err *Error) locationDescription() string { 31 | if err.Context.Node != nil { 32 | return fmt.Sprintf("[%d,%d] %s", err.Context.Node.Line, err.Context.Node.Column, err.Context.Description()) 33 | } 34 | return err.Context.Description() 35 | } 36 | 37 | // Error returns the string value of an Error. 38 | func (err *Error) Error() string { 39 | if err.Context == nil { 40 | return err.Message 41 | } 42 | return err.locationDescription() + " " + err.Message 43 | } 44 | 45 | // ErrorGroup is a container for groups of Error values. 46 | type ErrorGroup struct { 47 | Errors []error 48 | } 49 | 50 | // NewErrorGroupOrNil returns a new ErrorGroup for a slice of errors or nil if the slice is empty. 51 | func NewErrorGroupOrNil(errors []error) error { 52 | if len(errors) == 0 { 53 | return nil 54 | } else if len(errors) == 1 { 55 | return errors[0] 56 | } else { 57 | return &ErrorGroup{Errors: errors} 58 | } 59 | } 60 | 61 | func (group *ErrorGroup) Error() string { 62 | result := "" 63 | for i, err := range group.Errors { 64 | if i > 0 { 65 | result += "\n" 66 | } 67 | result += err.Error() 68 | } 69 | return result 70 | } 71 | -------------------------------------------------------------------------------- /compiler/extensions.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compiler 16 | 17 | import ( 18 | "bytes" 19 | "fmt" 20 | "os/exec" 21 | "strings" 22 | 23 | "google.golang.org/protobuf/proto" 24 | "google.golang.org/protobuf/types/known/anypb" 25 | yaml "gopkg.in/yaml.v3" 26 | 27 | extensions "github.com/google/gnostic-models/extensions" 28 | ) 29 | 30 | // ExtensionHandler describes a binary that is called by the compiler to handle specification extensions. 31 | type ExtensionHandler struct { 32 | Name string 33 | } 34 | 35 | // CallExtension calls a binary extension handler. 36 | func CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *anypb.Any, err error) { 37 | if context == nil || context.ExtensionHandlers == nil { 38 | return false, nil, nil 39 | } 40 | handled = false 41 | for _, handler := range *(context.ExtensionHandlers) { 42 | response, err = handler.handle(in, extensionName) 43 | if response == nil { 44 | continue 45 | } else { 46 | handled = true 47 | break 48 | } 49 | } 50 | return handled, response, err 51 | } 52 | 53 | func (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*anypb.Any, error) { 54 | if extensionHandlers.Name != "" { 55 | yamlData, _ := yaml.Marshal(in) 56 | request := &extensions.ExtensionHandlerRequest{ 57 | CompilerVersion: &extensions.Version{ 58 | Major: 0, 59 | Minor: 1, 60 | Patch: 0, 61 | }, 62 | Wrapper: &extensions.Wrapper{ 63 | Version: "unknown", // TODO: set this to the type/version of spec being parsed. 64 | Yaml: string(yamlData), 65 | ExtensionName: extensionName, 66 | }, 67 | } 68 | requestBytes, _ := proto.Marshal(request) 69 | cmd := exec.Command(extensionHandlers.Name) 70 | cmd.Stdin = bytes.NewReader(requestBytes) 71 | output, err := cmd.Output() 72 | if err != nil { 73 | return nil, err 74 | } 75 | response := &extensions.ExtensionHandlerResponse{} 76 | err = proto.Unmarshal(output, response) 77 | if err != nil || !response.Handled { 78 | return nil, err 79 | } 80 | if len(response.Errors) != 0 { 81 | return nil, fmt.Errorf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Errors, ",")) 82 | } 83 | return response.Value, nil 84 | } 85 | return nil, nil 86 | } 87 | -------------------------------------------------------------------------------- /compiler/helpers.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compiler 16 | 17 | import ( 18 | "fmt" 19 | "regexp" 20 | "sort" 21 | "strconv" 22 | 23 | "gopkg.in/yaml.v3" 24 | 25 | "github.com/google/gnostic-models/jsonschema" 26 | ) 27 | 28 | // compiler helper functions, usually called from generated code 29 | 30 | // UnpackMap gets a *yaml.Node if possible. 31 | func UnpackMap(in *yaml.Node) (*yaml.Node, bool) { 32 | if in == nil { 33 | return nil, false 34 | } 35 | return in, true 36 | } 37 | 38 | // SortedKeysForMap returns the sorted keys of a yamlv2.MapSlice. 39 | func SortedKeysForMap(m *yaml.Node) []string { 40 | keys := make([]string, 0) 41 | if m.Kind == yaml.MappingNode { 42 | for i := 0; i < len(m.Content); i += 2 { 43 | keys = append(keys, m.Content[i].Value) 44 | } 45 | } 46 | sort.Strings(keys) 47 | return keys 48 | } 49 | 50 | // MapHasKey returns true if a yamlv2.MapSlice contains a specified key. 51 | func MapHasKey(m *yaml.Node, key string) bool { 52 | if m == nil { 53 | return false 54 | } 55 | if m.Kind == yaml.MappingNode { 56 | for i := 0; i < len(m.Content); i += 2 { 57 | itemKey := m.Content[i].Value 58 | if key == itemKey { 59 | return true 60 | } 61 | } 62 | } 63 | return false 64 | } 65 | 66 | // MapValueForKey gets the value of a map value for a specified key. 67 | func MapValueForKey(m *yaml.Node, key string) *yaml.Node { 68 | if m == nil { 69 | return nil 70 | } 71 | if m.Kind == yaml.MappingNode { 72 | for i := 0; i < len(m.Content); i += 2 { 73 | itemKey := m.Content[i].Value 74 | if key == itemKey { 75 | return m.Content[i+1] 76 | } 77 | } 78 | } 79 | return nil 80 | } 81 | 82 | // ConvertInterfaceArrayToStringArray converts an array of interfaces to an array of strings, if possible. 83 | func ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string { 84 | stringArray := make([]string, 0) 85 | for _, item := range interfaceArray { 86 | v, ok := item.(string) 87 | if ok { 88 | stringArray = append(stringArray, v) 89 | } 90 | } 91 | return stringArray 92 | } 93 | 94 | // SequenceNodeForNode returns a node if it is a SequenceNode. 95 | func SequenceNodeForNode(node *yaml.Node) (*yaml.Node, bool) { 96 | if node.Kind != yaml.SequenceNode { 97 | return nil, false 98 | } 99 | return node, true 100 | } 101 | 102 | // BoolForScalarNode returns the bool value of a node. 103 | func BoolForScalarNode(node *yaml.Node) (bool, bool) { 104 | if node == nil { 105 | return false, false 106 | } 107 | if node.Kind == yaml.DocumentNode { 108 | return BoolForScalarNode(node.Content[0]) 109 | } 110 | if node.Kind != yaml.ScalarNode { 111 | return false, false 112 | } 113 | if node.Tag != "!!bool" { 114 | return false, false 115 | } 116 | v, err := strconv.ParseBool(node.Value) 117 | if err != nil { 118 | return false, false 119 | } 120 | return v, true 121 | } 122 | 123 | // IntForScalarNode returns the integer value of a node. 124 | func IntForScalarNode(node *yaml.Node) (int64, bool) { 125 | if node == nil { 126 | return 0, false 127 | } 128 | if node.Kind == yaml.DocumentNode { 129 | return IntForScalarNode(node.Content[0]) 130 | } 131 | if node.Kind != yaml.ScalarNode { 132 | return 0, false 133 | } 134 | if node.Tag != "!!int" { 135 | return 0, false 136 | } 137 | v, err := strconv.ParseInt(node.Value, 10, 64) 138 | if err != nil { 139 | return 0, false 140 | } 141 | return v, true 142 | } 143 | 144 | // FloatForScalarNode returns the float value of a node. 145 | func FloatForScalarNode(node *yaml.Node) (float64, bool) { 146 | if node == nil { 147 | return 0.0, false 148 | } 149 | if node.Kind == yaml.DocumentNode { 150 | return FloatForScalarNode(node.Content[0]) 151 | } 152 | if node.Kind != yaml.ScalarNode { 153 | return 0.0, false 154 | } 155 | if (node.Tag != "!!int") && (node.Tag != "!!float") { 156 | return 0.0, false 157 | } 158 | v, err := strconv.ParseFloat(node.Value, 64) 159 | if err != nil { 160 | return 0.0, false 161 | } 162 | return v, true 163 | } 164 | 165 | // StringForScalarNode returns the string value of a node. 166 | func StringForScalarNode(node *yaml.Node) (string, bool) { 167 | if node == nil { 168 | return "", false 169 | } 170 | if node.Kind == yaml.DocumentNode { 171 | return StringForScalarNode(node.Content[0]) 172 | } 173 | switch node.Kind { 174 | case yaml.ScalarNode: 175 | switch node.Tag { 176 | case "!!int": 177 | return node.Value, true 178 | case "!!str": 179 | return node.Value, true 180 | case "!!timestamp": 181 | return node.Value, true 182 | case "!!null": 183 | return "", true 184 | default: 185 | return "", false 186 | } 187 | default: 188 | return "", false 189 | } 190 | } 191 | 192 | // StringArrayForSequenceNode converts a sequence node to an array of strings, if possible. 193 | func StringArrayForSequenceNode(node *yaml.Node) []string { 194 | stringArray := make([]string, 0) 195 | for _, item := range node.Content { 196 | v, ok := StringForScalarNode(item) 197 | if ok { 198 | stringArray = append(stringArray, v) 199 | } 200 | } 201 | return stringArray 202 | } 203 | 204 | // MissingKeysInMap identifies which keys from a list of required keys are not in a map. 205 | func MissingKeysInMap(m *yaml.Node, requiredKeys []string) []string { 206 | missingKeys := make([]string, 0) 207 | for _, k := range requiredKeys { 208 | if !MapHasKey(m, k) { 209 | missingKeys = append(missingKeys, k) 210 | } 211 | } 212 | return missingKeys 213 | } 214 | 215 | // InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns. 216 | func InvalidKeysInMap(m *yaml.Node, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string { 217 | invalidKeys := make([]string, 0) 218 | if m == nil || m.Kind != yaml.MappingNode { 219 | return invalidKeys 220 | } 221 | for i := 0; i < len(m.Content); i += 2 { 222 | key := m.Content[i].Value 223 | found := false 224 | // does the key match an allowed key? 225 | for _, allowedKey := range allowedKeys { 226 | if key == allowedKey { 227 | found = true 228 | break 229 | } 230 | } 231 | if !found { 232 | // does the key match an allowed pattern? 233 | for _, allowedPattern := range allowedPatterns { 234 | if allowedPattern.MatchString(key) { 235 | found = true 236 | break 237 | } 238 | } 239 | if !found { 240 | invalidKeys = append(invalidKeys, key) 241 | } 242 | } 243 | } 244 | return invalidKeys 245 | } 246 | 247 | // NewNullNode creates a new Null node. 248 | func NewNullNode() *yaml.Node { 249 | node := &yaml.Node{ 250 | Kind: yaml.ScalarNode, 251 | Tag: "!!null", 252 | } 253 | return node 254 | } 255 | 256 | // NewMappingNode creates a new Mapping node. 257 | func NewMappingNode() *yaml.Node { 258 | return &yaml.Node{ 259 | Kind: yaml.MappingNode, 260 | Content: make([]*yaml.Node, 0), 261 | } 262 | } 263 | 264 | // NewSequenceNode creates a new Sequence node. 265 | func NewSequenceNode() *yaml.Node { 266 | node := &yaml.Node{ 267 | Kind: yaml.SequenceNode, 268 | Content: make([]*yaml.Node, 0), 269 | } 270 | return node 271 | } 272 | 273 | // NewScalarNodeForString creates a new node to hold a string. 274 | func NewScalarNodeForString(s string) *yaml.Node { 275 | return &yaml.Node{ 276 | Kind: yaml.ScalarNode, 277 | Tag: "!!str", 278 | Value: s, 279 | } 280 | } 281 | 282 | // NewSequenceNodeForStringArray creates a new node to hold an array of strings. 283 | func NewSequenceNodeForStringArray(strings []string) *yaml.Node { 284 | node := &yaml.Node{ 285 | Kind: yaml.SequenceNode, 286 | Content: make([]*yaml.Node, 0), 287 | } 288 | for _, s := range strings { 289 | node.Content = append(node.Content, NewScalarNodeForString(s)) 290 | } 291 | return node 292 | } 293 | 294 | // NewScalarNodeForBool creates a new node to hold a bool. 295 | func NewScalarNodeForBool(b bool) *yaml.Node { 296 | return &yaml.Node{ 297 | Kind: yaml.ScalarNode, 298 | Tag: "!!bool", 299 | Value: fmt.Sprintf("%t", b), 300 | } 301 | } 302 | 303 | // NewScalarNodeForFloat creates a new node to hold a float. 304 | func NewScalarNodeForFloat(f float64) *yaml.Node { 305 | return &yaml.Node{ 306 | Kind: yaml.ScalarNode, 307 | Tag: "!!float", 308 | Value: fmt.Sprintf("%g", f), 309 | } 310 | } 311 | 312 | // NewScalarNodeForInt creates a new node to hold an integer. 313 | func NewScalarNodeForInt(i int64) *yaml.Node { 314 | return &yaml.Node{ 315 | Kind: yaml.ScalarNode, 316 | Tag: "!!int", 317 | Value: fmt.Sprintf("%d", i), 318 | } 319 | } 320 | 321 | // PluralProperties returns the string "properties" pluralized. 322 | func PluralProperties(count int) string { 323 | if count == 1 { 324 | return "property" 325 | } 326 | return "properties" 327 | } 328 | 329 | // StringArrayContainsValue returns true if a string array contains a specified value. 330 | func StringArrayContainsValue(array []string, value string) bool { 331 | for _, item := range array { 332 | if item == value { 333 | return true 334 | } 335 | } 336 | return false 337 | } 338 | 339 | // StringArrayContainsValues returns true if a string array contains all of a list of specified values. 340 | func StringArrayContainsValues(array []string, values []string) bool { 341 | for _, value := range values { 342 | if !StringArrayContainsValue(array, value) { 343 | return false 344 | } 345 | } 346 | return true 347 | } 348 | 349 | // StringValue returns the string value of an item. 350 | func StringValue(item interface{}) (value string, ok bool) { 351 | value, ok = item.(string) 352 | if ok { 353 | return value, ok 354 | } 355 | intValue, ok := item.(int) 356 | if ok { 357 | return strconv.Itoa(intValue), true 358 | } 359 | return "", false 360 | } 361 | 362 | // Description returns a human-readable represention of an item. 363 | func Description(item interface{}) string { 364 | value, ok := item.(*yaml.Node) 365 | if ok { 366 | return jsonschema.Render(value) 367 | } 368 | return fmt.Sprintf("%+v", item) 369 | } 370 | 371 | // Display returns a description of a node for use in error messages. 372 | func Display(node *yaml.Node) string { 373 | switch node.Kind { 374 | case yaml.ScalarNode: 375 | switch node.Tag { 376 | case "!!str": 377 | return fmt.Sprintf("%s (string)", node.Value) 378 | } 379 | } 380 | return fmt.Sprintf("%+v (%T)", node, node) 381 | } 382 | 383 | // Marshal creates a yaml version of a structure in our preferred style 384 | func Marshal(in *yaml.Node) []byte { 385 | clearStyle(in) 386 | //bytes, _ := yaml.Marshal(&yaml.Node{Kind: yaml.DocumentNode, Content: []*yaml.Node{in}}) 387 | bytes, _ := yaml.Marshal(in) 388 | 389 | return bytes 390 | } 391 | 392 | func clearStyle(node *yaml.Node) { 393 | node.Style = 0 394 | for _, c := range node.Content { 395 | clearStyle(c) 396 | } 397 | } 398 | -------------------------------------------------------------------------------- /compiler/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package compiler provides support functions to generated compiler code. 16 | package compiler 17 | -------------------------------------------------------------------------------- /compiler/reader.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package compiler 16 | 17 | import ( 18 | "fmt" 19 | "io/ioutil" 20 | "log" 21 | "net/http" 22 | "net/url" 23 | "path/filepath" 24 | "strings" 25 | "sync" 26 | 27 | yaml "gopkg.in/yaml.v3" 28 | ) 29 | 30 | var verboseReader = false 31 | 32 | var fileCache map[string][]byte 33 | var infoCache map[string]*yaml.Node 34 | 35 | var fileCacheEnable = true 36 | var infoCacheEnable = true 37 | 38 | // These locks are used to synchronize accesses to the fileCache and infoCache 39 | // maps (above). They are global state and can throw thread-related errors 40 | // when modified from separate goroutines. The general strategy is to protect 41 | // all public functions in this file with mutex Lock() calls. As a result, to 42 | // avoid deadlock, these public functions should not call other public 43 | // functions, so some public functions have private equivalents. 44 | // In the future, we might consider replacing the maps with sync.Map and 45 | // eliminating these mutexes. 46 | var fileCacheMutex sync.Mutex 47 | var infoCacheMutex sync.Mutex 48 | 49 | func initializeFileCache() { 50 | if fileCache == nil { 51 | fileCache = make(map[string][]byte, 0) 52 | } 53 | } 54 | 55 | func initializeInfoCache() { 56 | if infoCache == nil { 57 | infoCache = make(map[string]*yaml.Node, 0) 58 | } 59 | } 60 | 61 | // EnableFileCache turns on file caching. 62 | func EnableFileCache() { 63 | fileCacheMutex.Lock() 64 | defer fileCacheMutex.Unlock() 65 | fileCacheEnable = true 66 | } 67 | 68 | // EnableInfoCache turns on parsed info caching. 69 | func EnableInfoCache() { 70 | infoCacheMutex.Lock() 71 | defer infoCacheMutex.Unlock() 72 | infoCacheEnable = true 73 | } 74 | 75 | // DisableFileCache turns off file caching. 76 | func DisableFileCache() { 77 | fileCacheMutex.Lock() 78 | defer fileCacheMutex.Unlock() 79 | fileCacheEnable = false 80 | } 81 | 82 | // DisableInfoCache turns off parsed info caching. 83 | func DisableInfoCache() { 84 | infoCacheMutex.Lock() 85 | defer infoCacheMutex.Unlock() 86 | infoCacheEnable = false 87 | } 88 | 89 | // RemoveFromFileCache removes an entry from the file cache. 90 | func RemoveFromFileCache(fileurl string) { 91 | fileCacheMutex.Lock() 92 | defer fileCacheMutex.Unlock() 93 | if !fileCacheEnable { 94 | return 95 | } 96 | initializeFileCache() 97 | delete(fileCache, fileurl) 98 | } 99 | 100 | // RemoveFromInfoCache removes an entry from the info cache. 101 | func RemoveFromInfoCache(filename string) { 102 | infoCacheMutex.Lock() 103 | defer infoCacheMutex.Unlock() 104 | if !infoCacheEnable { 105 | return 106 | } 107 | initializeInfoCache() 108 | delete(infoCache, filename) 109 | } 110 | 111 | // GetInfoCache returns the info cache map. 112 | func GetInfoCache() map[string]*yaml.Node { 113 | infoCacheMutex.Lock() 114 | defer infoCacheMutex.Unlock() 115 | if infoCache == nil { 116 | initializeInfoCache() 117 | } 118 | return infoCache 119 | } 120 | 121 | // ClearFileCache clears the file cache. 122 | func ClearFileCache() { 123 | fileCacheMutex.Lock() 124 | defer fileCacheMutex.Unlock() 125 | fileCache = make(map[string][]byte, 0) 126 | } 127 | 128 | // ClearInfoCache clears the info cache. 129 | func ClearInfoCache() { 130 | infoCacheMutex.Lock() 131 | defer infoCacheMutex.Unlock() 132 | infoCache = make(map[string]*yaml.Node) 133 | } 134 | 135 | // ClearCaches clears all caches. 136 | func ClearCaches() { 137 | ClearFileCache() 138 | ClearInfoCache() 139 | } 140 | 141 | // FetchFile gets a specified file from the local filesystem or a remote location. 142 | func FetchFile(fileurl string) ([]byte, error) { 143 | fileCacheMutex.Lock() 144 | defer fileCacheMutex.Unlock() 145 | return fetchFile(fileurl) 146 | } 147 | 148 | func fetchFile(fileurl string) ([]byte, error) { 149 | var bytes []byte 150 | initializeFileCache() 151 | if fileCacheEnable { 152 | bytes, ok := fileCache[fileurl] 153 | if ok { 154 | if verboseReader { 155 | log.Printf("Cache hit %s", fileurl) 156 | } 157 | return bytes, nil 158 | } 159 | if verboseReader { 160 | log.Printf("Fetching %s", fileurl) 161 | } 162 | } 163 | response, err := http.Get(fileurl) 164 | if err != nil { 165 | return nil, err 166 | } 167 | defer response.Body.Close() 168 | if response.StatusCode != 200 { 169 | return nil, fmt.Errorf("Error downloading %s: %s", fileurl, response.Status) 170 | } 171 | bytes, err = ioutil.ReadAll(response.Body) 172 | if fileCacheEnable && err == nil { 173 | fileCache[fileurl] = bytes 174 | } 175 | return bytes, err 176 | } 177 | 178 | // ReadBytesForFile reads the bytes of a file. 179 | func ReadBytesForFile(filename string) ([]byte, error) { 180 | fileCacheMutex.Lock() 181 | defer fileCacheMutex.Unlock() 182 | return readBytesForFile(filename) 183 | } 184 | 185 | func readBytesForFile(filename string) ([]byte, error) { 186 | // is the filename a url? 187 | fileurl, _ := url.Parse(filename) 188 | if fileurl.Scheme != "" { 189 | // yes, fetch it 190 | bytes, err := fetchFile(filename) 191 | if err != nil { 192 | return nil, err 193 | } 194 | return bytes, nil 195 | } 196 | // no, it's a local filename 197 | bytes, err := ioutil.ReadFile(filename) 198 | if err != nil { 199 | return nil, err 200 | } 201 | return bytes, nil 202 | } 203 | 204 | // ReadInfoFromBytes unmarshals a file as a *yaml.Node. 205 | func ReadInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) { 206 | infoCacheMutex.Lock() 207 | defer infoCacheMutex.Unlock() 208 | return readInfoFromBytes(filename, bytes) 209 | } 210 | 211 | func readInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) { 212 | initializeInfoCache() 213 | if infoCacheEnable { 214 | cachedInfo, ok := infoCache[filename] 215 | if ok { 216 | if verboseReader { 217 | log.Printf("Cache hit info for file %s", filename) 218 | } 219 | return cachedInfo, nil 220 | } 221 | if verboseReader { 222 | log.Printf("Reading info for file %s", filename) 223 | } 224 | } 225 | var info yaml.Node 226 | err := yaml.Unmarshal(bytes, &info) 227 | if err != nil { 228 | return nil, err 229 | } 230 | if infoCacheEnable && len(filename) > 0 { 231 | infoCache[filename] = &info 232 | } 233 | return &info, nil 234 | } 235 | 236 | // ReadInfoForRef reads a file and return the fragment needed to resolve a $ref. 237 | func ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) { 238 | fileCacheMutex.Lock() 239 | defer fileCacheMutex.Unlock() 240 | infoCacheMutex.Lock() 241 | defer infoCacheMutex.Unlock() 242 | initializeInfoCache() 243 | if infoCacheEnable { 244 | info, ok := infoCache[ref] 245 | if ok { 246 | if verboseReader { 247 | log.Printf("Cache hit for ref %s#%s", basefile, ref) 248 | } 249 | return info, nil 250 | } 251 | if verboseReader { 252 | log.Printf("Reading info for ref %s#%s", basefile, ref) 253 | } 254 | } 255 | basedir, _ := filepath.Split(basefile) 256 | parts := strings.Split(ref, "#") 257 | var filename string 258 | if parts[0] != "" { 259 | filename = parts[0] 260 | if _, err := url.ParseRequestURI(parts[0]); err != nil { 261 | // It is not an URL, so the file is local 262 | filename = basedir + parts[0] 263 | } 264 | } else { 265 | filename = basefile 266 | } 267 | bytes, err := readBytesForFile(filename) 268 | if err != nil { 269 | return nil, err 270 | } 271 | info, err := readInfoFromBytes(filename, bytes) 272 | if info != nil && info.Kind == yaml.DocumentNode { 273 | info = info.Content[0] 274 | } 275 | if err != nil { 276 | log.Printf("File error: %v\n", err) 277 | } else { 278 | if info == nil { 279 | return nil, NewError(nil, fmt.Sprintf("could not resolve %s", ref)) 280 | } 281 | if len(parts) > 1 { 282 | path := strings.Split(parts[1], "/") 283 | for i, key := range path { 284 | if i > 0 { 285 | m := info 286 | if true { 287 | found := false 288 | for i := 0; i < len(m.Content); i += 2 { 289 | if m.Content[i].Value == key { 290 | info = m.Content[i+1] 291 | found = true 292 | } 293 | } 294 | if !found { 295 | infoCache[ref] = nil 296 | return nil, NewError(nil, fmt.Sprintf("could not resolve %s", ref)) 297 | } 298 | } 299 | } 300 | } 301 | } 302 | } 303 | if infoCacheEnable { 304 | infoCache[ref] = info 305 | } 306 | return info, nil 307 | } 308 | -------------------------------------------------------------------------------- /discovery/README.md: -------------------------------------------------------------------------------- 1 | # API Discovery Format 2 | 3 | This directory contains a Protocol Buffer-language model and related code for 4 | supporting Google's API Discovery Format. 5 | 6 | Gnostic applications and plugins can use Discovery.proto to generate Protocol 7 | Buffer support code for their preferred languages. 8 | 9 | Discovery.go is used by Gnostic to read JSON and YAML Discovery descriptions 10 | into the Protocol Buffer-based datastructures generated from Discovery.proto. 11 | 12 | Discovery.proto and Discovery.go are generated by the Gnostic compiler 13 | generator, and Discovery.pb.go is generated by protoc, the Protocol Buffer 14 | compiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin. 15 | -------------------------------------------------------------------------------- /discovery/discovery.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // THIS FILE IS AUTOMATICALLY GENERATED. 16 | 17 | syntax = "proto3"; 18 | 19 | package discovery.v1; 20 | 21 | import "google/protobuf/any.proto"; 22 | 23 | // This option lets the proto compiler generate Java code inside the package 24 | // name (see below) instead of inside an outer class. It creates a simpler 25 | // developer experience by reducing one-level of name nesting and be 26 | // consistent with most programming languages that don't support outer classes. 27 | option java_multiple_files = true; 28 | 29 | // The Java outer classname should be the filename in UpperCamelCase. This 30 | // class is only used to hold proto descriptor, so developers don't need to 31 | // work with it directly. 32 | option java_outer_classname = "OpenAPIProto"; 33 | 34 | // The Java package name must be proto package name with proper prefix. 35 | option java_package = "org.discovery_v1"; 36 | 37 | // A reasonable prefix for the Objective-C symbols generated from the package. 38 | // It should at a minimum be 3 characters long, all uppercase, and convention 39 | // is to use an abbreviation of the package name. Something short, but 40 | // hopefully unique enough to not conflict with things that may come along in 41 | // the future. 'GPB' is reserved for the protocol buffer implementation itself. 42 | option objc_class_prefix = "OAS"; 43 | 44 | // The Go package name. 45 | option go_package = "./discovery;discovery_v1"; 46 | 47 | message Annotations { 48 | repeated string required = 1; 49 | } 50 | 51 | message Any { 52 | google.protobuf.Any value = 1; 53 | string yaml = 2; 54 | } 55 | 56 | message Auth { 57 | Oauth2 oauth2 = 1; 58 | } 59 | 60 | message Document { 61 | string kind = 1; 62 | string discovery_version = 2; 63 | string id = 3; 64 | string name = 4; 65 | string version = 5; 66 | string revision = 6; 67 | string title = 7; 68 | string description = 8; 69 | Icons icons = 9; 70 | string documentation_link = 10; 71 | repeated string labels = 11; 72 | string protocol = 12; 73 | string base_url = 13; 74 | string base_path = 14; 75 | string root_url = 15; 76 | string service_path = 16; 77 | string batch_path = 17; 78 | Parameters parameters = 18; 79 | Auth auth = 19; 80 | repeated string features = 20; 81 | Schemas schemas = 21; 82 | Methods methods = 22; 83 | Resources resources = 23; 84 | string etag = 24; 85 | string owner_domain = 25; 86 | string owner_name = 26; 87 | bool version_module = 27; 88 | string canonical_name = 28; 89 | bool fully_encode_reserved_expansion = 29; 90 | string package_path = 30; 91 | string mtls_root_url = 31; 92 | } 93 | 94 | // Icons that represent the API. 95 | message Icons { 96 | string x16 = 1; 97 | string x32 = 2; 98 | } 99 | 100 | message MediaUpload { 101 | repeated string accept = 1; 102 | string max_size = 2; 103 | Protocols protocols = 3; 104 | bool supports_subscription = 4; 105 | } 106 | 107 | message Method { 108 | string id = 1; 109 | string path = 2; 110 | string http_method = 3; 111 | string description = 4; 112 | Parameters parameters = 5; 113 | repeated string parameter_order = 6; 114 | Request request = 7; 115 | Response response = 8; 116 | repeated string scopes = 9; 117 | bool supports_media_download = 10; 118 | bool supports_media_upload = 11; 119 | bool use_media_download_service = 12; 120 | MediaUpload media_upload = 13; 121 | bool supports_subscription = 14; 122 | string flat_path = 15; 123 | bool etag_required = 16; 124 | string streaming_type = 17; 125 | } 126 | 127 | message Methods { 128 | repeated NamedMethod additional_properties = 1; 129 | } 130 | 131 | // Automatically-generated message used to represent maps of Method as ordered (name,value) pairs. 132 | message NamedMethod { 133 | // Map key 134 | string name = 1; 135 | // Mapped value 136 | Method value = 2; 137 | } 138 | 139 | // Automatically-generated message used to represent maps of Parameter as ordered (name,value) pairs. 140 | message NamedParameter { 141 | // Map key 142 | string name = 1; 143 | // Mapped value 144 | Parameter value = 2; 145 | } 146 | 147 | // Automatically-generated message used to represent maps of Resource as ordered (name,value) pairs. 148 | message NamedResource { 149 | // Map key 150 | string name = 1; 151 | // Mapped value 152 | Resource value = 2; 153 | } 154 | 155 | // Automatically-generated message used to represent maps of Schema as ordered (name,value) pairs. 156 | message NamedSchema { 157 | // Map key 158 | string name = 1; 159 | // Mapped value 160 | Schema value = 2; 161 | } 162 | 163 | // Automatically-generated message used to represent maps of Scope as ordered (name,value) pairs. 164 | message NamedScope { 165 | // Map key 166 | string name = 1; 167 | // Mapped value 168 | Scope value = 2; 169 | } 170 | 171 | message Oauth2 { 172 | Scopes scopes = 1; 173 | } 174 | 175 | message Parameter { 176 | string id = 1; 177 | string type = 2; 178 | string _ref = 3; 179 | string description = 4; 180 | string default = 5; 181 | bool required = 6; 182 | string format = 7; 183 | string pattern = 8; 184 | string minimum = 9; 185 | string maximum = 10; 186 | repeated string enum = 11; 187 | repeated string enum_descriptions = 12; 188 | bool repeated = 13; 189 | string location = 14; 190 | Schemas properties = 15; 191 | Schema additional_properties = 16; 192 | Schema items = 17; 193 | Annotations annotations = 18; 194 | } 195 | 196 | message Parameters { 197 | repeated NamedParameter additional_properties = 1; 198 | } 199 | 200 | message Protocols { 201 | Simple simple = 1; 202 | Resumable resumable = 2; 203 | } 204 | 205 | message Request { 206 | string _ref = 1; 207 | string parameter_name = 2; 208 | } 209 | 210 | message Resource { 211 | Methods methods = 1; 212 | Resources resources = 2; 213 | } 214 | 215 | message Resources { 216 | repeated NamedResource additional_properties = 1; 217 | } 218 | 219 | message Response { 220 | string _ref = 1; 221 | } 222 | 223 | message Resumable { 224 | bool multipart = 1; 225 | string path = 2; 226 | } 227 | 228 | message Schema { 229 | string id = 1; 230 | string type = 2; 231 | string description = 3; 232 | string default = 4; 233 | bool required = 5; 234 | string format = 6; 235 | string pattern = 7; 236 | string minimum = 8; 237 | string maximum = 9; 238 | repeated string enum = 10; 239 | repeated string enum_descriptions = 11; 240 | bool repeated = 12; 241 | string location = 13; 242 | Schemas properties = 14; 243 | Schema additional_properties = 15; 244 | Schema items = 16; 245 | string _ref = 17; 246 | Annotations annotations = 18; 247 | bool read_only = 19; 248 | } 249 | 250 | message Schemas { 251 | repeated NamedSchema additional_properties = 1; 252 | } 253 | 254 | message Scope { 255 | string description = 1; 256 | } 257 | 258 | message Scopes { 259 | repeated NamedScope additional_properties = 1; 260 | } 261 | 262 | message Simple { 263 | bool multipart = 1; 264 | string path = 2; 265 | } 266 | 267 | message StringArray { 268 | repeated string value = 1; 269 | } 270 | 271 | -------------------------------------------------------------------------------- /discovery/document.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package discovery_v1 16 | 17 | import ( 18 | "github.com/google/gnostic-models/compiler" 19 | ) 20 | 21 | // FetchDocumentBytes downloads the bytes of a discovery document from a URL. 22 | func FetchDocumentBytes(documentURL string) ([]byte, error) { 23 | return compiler.FetchFile(documentURL) 24 | } 25 | 26 | // ParseDocument reads a Discovery description from a YAML/JSON representation. 27 | func ParseDocument(b []byte) (*Document, error) { 28 | info, err := compiler.ReadInfoFromBytes("", b) 29 | if err != nil { 30 | return nil, err 31 | } 32 | root := info.Content[0] 33 | return NewDocument(root, compiler.NewContext("$root", root, nil)) 34 | } 35 | -------------------------------------------------------------------------------- /discovery/list.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package discovery_v1 16 | 17 | import ( 18 | "encoding/json" 19 | "errors" 20 | "strings" 21 | 22 | "github.com/google/gnostic-models/compiler" 23 | ) 24 | 25 | // APIsListServiceURL is the URL for the Google APIs Discovery Service 26 | const APIsListServiceURL = "https://www.googleapis.com/discovery/v1/apis" 27 | 28 | // A List represents the results of a call to the apis/list API. 29 | // https://developers.google.com/discovery/v1/reference/apis/list 30 | type List struct { 31 | Kind string `json:"kind"` 32 | DiscoveryVersion string `json:"discoveryVersion"` 33 | APIs []*API `json:"items"` 34 | } 35 | 36 | func FetchListBytes() ([]byte, error) { 37 | return compiler.FetchFile(APIsListServiceURL) 38 | } 39 | 40 | // Read the list of APIs from the apis/list service. 41 | func FetchList() (*List, error) { 42 | bytes, err := FetchListBytes() 43 | if err != nil { 44 | return nil, err 45 | } 46 | return ParseList(bytes) 47 | } 48 | 49 | // ParseList unmarshals the bytes into a Document. 50 | func ParseList(bytes []byte) (*List, error) { 51 | var listResponse List 52 | err := json.Unmarshal(bytes, &listResponse) 53 | return &listResponse, err 54 | } 55 | 56 | // An API represents an API description returned by the apis/list API. 57 | type API struct { 58 | Kind string `json:"kind"` 59 | ID string `json:"id"` 60 | Name string `json:"name"` 61 | Version string `json:"version"` 62 | Title string `json:"title"` 63 | Description string `json:"description"` 64 | DiscoveryRestURL string `json:"discoveryRestUrl"` 65 | DiscoveryLink string `json:"discoveryLink"` 66 | Icons map[string]string `json:"icons"` 67 | DocumentationLink string `json:"documentationLink"` 68 | Labels []string `json:"labels"` 69 | Preferred bool `json:"preferred"` 70 | } 71 | 72 | // APIWithNameAndVersion returns the API with a specified name and version. 73 | // If version is the empty string, the API name must be unique. 74 | func (a *List) APIWithNameAndVersion(name string, version string) (*API, error) { 75 | var api *API // the API to return 76 | versions := make([]string, 0) // the matching version names 77 | // Scan the list for matching APIs and versions. 78 | for _, item := range a.APIs { 79 | if item.Name == name { 80 | if version == "" || version == item.Version { 81 | api = item 82 | versions = append(versions, item.Version) 83 | } 84 | } 85 | } 86 | switch { 87 | case len(versions) == 0: 88 | return nil, errors.New(name + " was not found.") 89 | case len(versions) > 1: 90 | return nil, errors.New(name + " has multiple versions: " + strings.Join(versions, ", ")) 91 | default: 92 | return api, nil 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /extensions/README.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | **Extension Support is experimental.** 4 | 5 | This directory contains support code for building Gnostic extensio handlers and 6 | associated examples. 7 | 8 | Extension handlers can be used to compile vendor or specification extensions 9 | into protocol buffer structures. 10 | 11 | Like plugins, extension handlers are built as separate executables. Extension 12 | bodies are written to extension handlers as serialized 13 | ExtensionHandlerRequests. 14 | -------------------------------------------------------------------------------- /extensions/extension.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package gnostic.extension.v1; 18 | 19 | import "google/protobuf/any.proto"; 20 | 21 | // This option lets the proto compiler generate Java code inside the package 22 | // name (see below) instead of inside an outer class. It creates a simpler 23 | // developer experience by reducing one-level of name nesting and be 24 | // consistent with most programming languages that don't support outer classes. 25 | option java_multiple_files = true; 26 | 27 | // The Java outer classname should be the filename in UpperCamelCase. This 28 | // class is only used to hold proto descriptor, so developers don't need to 29 | // work with it directly. 30 | option java_outer_classname = "GnosticExtension"; 31 | 32 | // The Java package name must be proto package name with proper prefix. 33 | option java_package = "org.gnostic.v1"; 34 | 35 | // A reasonable prefix for the Objective-C symbols generated from the package. 36 | // It should at a minimum be 3 characters long, all uppercase, and convention 37 | // is to use an abbreviation of the package name. Something short, but 38 | // hopefully unique enough to not conflict with things that may come along in 39 | // the future. 'GPB' is reserved for the protocol buffer implementation itself. 40 | // 41 | // "Gnostic Extension" 42 | option objc_class_prefix = "GNX"; 43 | 44 | // The Go package name. 45 | option go_package = "./extensions;gnostic_extension_v1"; 46 | 47 | // The version number of Gnostic. 48 | message Version { 49 | int32 major = 1; 50 | int32 minor = 2; 51 | int32 patch = 3; 52 | // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should 53 | // be empty for mainline stable releases. 54 | string suffix = 4; 55 | } 56 | 57 | // An encoded Request is written to the ExtensionHandler's stdin. 58 | message ExtensionHandlerRequest { 59 | 60 | // The extension to process. 61 | Wrapper wrapper = 1; 62 | 63 | // The version number of Gnostic. 64 | Version compiler_version = 2; 65 | } 66 | 67 | // The extensions writes an encoded ExtensionHandlerResponse to stdout. 68 | message ExtensionHandlerResponse { 69 | 70 | // true if the extension is handled by the extension handler; false otherwise 71 | bool handled = 1; 72 | 73 | // Error message(s). If non-empty, the extension handling failed. 74 | // The extension handler process should exit with status code zero 75 | // even if it reports an error in this way. 76 | // 77 | // This should be used to indicate errors which prevent the extension from 78 | // operating as intended. Errors which indicate a problem in gnostic 79 | // itself -- such as the input Document being unparseable -- should be 80 | // reported by writing a message to stderr and exiting with a non-zero 81 | // status code. 82 | repeated string errors = 2; 83 | 84 | // text output 85 | google.protobuf.Any value = 3; 86 | } 87 | 88 | message Wrapper { 89 | // version of the OpenAPI specification in which this extension was written. 90 | string version = 1; 91 | 92 | // Name of the extension. 93 | string extension_name = 2; 94 | 95 | // YAML-formatted extension value. 96 | string yaml = 3; 97 | } 98 | -------------------------------------------------------------------------------- /extensions/extensions.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package gnostic_extension_v1 16 | 17 | import ( 18 | "io/ioutil" 19 | "log" 20 | "os" 21 | 22 | "google.golang.org/protobuf/proto" 23 | "google.golang.org/protobuf/types/known/anypb" 24 | ) 25 | 26 | type extensionHandler func(name string, yamlInput string) (bool, proto.Message, error) 27 | 28 | // Main implements the main program of an extension handler. 29 | func Main(handler extensionHandler) { 30 | // unpack the request 31 | data, err := ioutil.ReadAll(os.Stdin) 32 | if err != nil { 33 | log.Println("File error:", err.Error()) 34 | os.Exit(1) 35 | } 36 | if len(data) == 0 { 37 | log.Println("No input data.") 38 | os.Exit(1) 39 | } 40 | request := &ExtensionHandlerRequest{} 41 | err = proto.Unmarshal(data, request) 42 | if err != nil { 43 | log.Println("Input error:", err.Error()) 44 | os.Exit(1) 45 | } 46 | // call the handler 47 | handled, output, err := handler(request.Wrapper.ExtensionName, request.Wrapper.Yaml) 48 | // respond with the output of the handler 49 | response := &ExtensionHandlerResponse{ 50 | Handled: false, // default assumption 51 | Errors: make([]string, 0), 52 | } 53 | if err != nil { 54 | response.Errors = append(response.Errors, err.Error()) 55 | } else if handled { 56 | response.Handled = true 57 | response.Value, err = anypb.New(output) 58 | if err != nil { 59 | response.Errors = append(response.Errors, err.Error()) 60 | } 61 | } 62 | responseBytes, _ := proto.Marshal(response) 63 | os.Stdout.Write(responseBytes) 64 | } 65 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/google/gnostic-models 2 | 3 | go 1.21 4 | 5 | require ( 6 | google.golang.org/protobuf v1.35.1 7 | gopkg.in/yaml.v3 v3.0.1 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 2 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 3 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 4 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 5 | google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= 6 | google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 7 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 9 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 10 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 11 | -------------------------------------------------------------------------------- /jsonschema/README.md: -------------------------------------------------------------------------------- 1 | # jsonschema 2 | 3 | This directory contains code for reading, writing, and manipulating JSON 4 | schemas. 5 | -------------------------------------------------------------------------------- /jsonschema/base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // THIS FILE IS AUTOMATICALLY GENERATED. 16 | 17 | package jsonschema 18 | 19 | import ( 20 | "encoding/base64" 21 | ) 22 | 23 | func baseSchemaBytes() ([]byte, error){ 24 | return base64.StdEncoding.DecodeString( 25 | `ewogICAgImlkIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIyIsCiAgICAi 26 | JHNjaGVtYSI6ICJodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMiLAogICAgImRl 27 | c2NyaXB0aW9uIjogIkNvcmUgc2NoZW1hIG1ldGEtc2NoZW1hIiwKICAgICJkZWZpbml0aW9ucyI6IHsK 28 | ICAgICAgICAic2NoZW1hQXJyYXkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAg 29 | ICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjIiB9CiAg 30 | ICAgICAgfSwKICAgICAgICAicG9zaXRpdmVJbnRlZ2VyIjogewogICAgICAgICAgICAidHlwZSI6ICJp 31 | bnRlZ2VyIiwKICAgICAgICAgICAgIm1pbmltdW0iOiAwCiAgICAgICAgfSwKICAgICAgICAicG9zaXRp 32 | dmVJbnRlZ2VyRGVmYXVsdDAiOiB7CiAgICAgICAgICAgICJhbGxPZiI6IFsgeyAiJHJlZiI6ICIjL2Rl 33 | ZmluaXRpb25zL3Bvc2l0aXZlSW50ZWdlciIgfSwgeyAiZGVmYXVsdCI6IDAgfSBdCiAgICAgICAgfSwK 34 | ICAgICAgICAic2ltcGxlVHlwZXMiOiB7CiAgICAgICAgICAgICJlbnVtIjogWyAiYXJyYXkiLCAiYm9v 35 | bGVhbiIsICJpbnRlZ2VyIiwgIm51bGwiLCAibnVtYmVyIiwgIm9iamVjdCIsICJzdHJpbmciIF0KICAg 36 | ICAgICB9LAogICAgICAgICJzdHJpbmdBcnJheSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiYXJyYXki 37 | LAogICAgICAgICAgICAiaXRlbXMiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgIm1p 38 | bkl0ZW1zIjogMSwKICAgICAgICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0KICAgIH0s 39 | CiAgICAidHlwZSI6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImlkIjogewog 40 | ICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAg 41 | ICAgICB9LAogICAgICAgICIkc2NoZW1hIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAog 42 | ICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICB9LAogICAgICAgICJ0aXRsZSI6IHsKICAg 43 | ICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImRlc2NyaXB0aW9uIjog 44 | ewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgfSwKICAgICAgICAiZGVmYXVsdCI6 45 | IHt9LAogICAgICAgICJtdWx0aXBsZU9mIjogewogICAgICAgICAgICAidHlwZSI6ICJudW1iZXIiLAog 46 | ICAgICAgICAgICAibWluaW11bSI6IDAsCiAgICAgICAgICAgICJleGNsdXNpdmVNaW5pbXVtIjogdHJ1 47 | ZQogICAgICAgIH0sCiAgICAgICAgIm1heGltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJl 48 | ciIKICAgICAgICB9LAogICAgICAgICJleGNsdXNpdmVNYXhpbXVtIjogewogICAgICAgICAgICAidHlw 49 | ZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAg 50 | ICAgIm1pbmltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJlciIKICAgICAgICB9LAogICAg 51 | ICAgICJleGNsdXNpdmVNaW5pbXVtIjogewogICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAg 52 | ICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgIm1heExlbmd0aCI6IHsg 53 | IiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pbkxlbmd0 54 | aCI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAg 55 | ICAgICAicGF0dGVybiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAg 56 | ImZvcm1hdCI6ICJyZWdleCIKICAgICAgICB9LAogICAgICAgICJhZGRpdGlvbmFsSXRlbXMiOiB7CiAg 57 | ICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgInR5cGUiOiAiYm9vbGVhbiIgfSwK 58 | ICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAi 59 | ZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICJhbnlP 60 | ZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgICAgIHsgIiRy 61 | ZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIgfQogICAgICAgICAgICBdLAogICAgICAgICAg 62 | ICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAibWF4SXRlbXMiOiB7ICIkcmVmIjogIiMv 63 | ZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyIiB9LAogICAgICAgICJtaW5JdGVtcyI6IHsgIiRyZWYi 64 | OiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAgICAgICAidW5pcXVl 65 | SXRlbXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAiZGVmYXVs 66 | dCI6IGZhbHNlCiAgICAgICAgfSwKICAgICAgICAibWF4UHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIy9k 67 | ZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pblByb3BlcnRpZXMiOiB7ICIk 68 | cmVmIjogIiMvZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyRGVmYXVsdDAiIH0sCiAgICAgICAgInJl 69 | cXVpcmVkIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3N0cmluZ0FycmF5IiB9LAogICAgICAgICJh 70 | ZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAg 71 | ICAgeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjIiB9CiAg 72 | ICAgICAgICAgIF0sCiAgICAgICAgICAgICJkZWZhdWx0Ijoge30KICAgICAgICB9LAogICAgICAgICJk 73 | ZWZpbml0aW9ucyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImFk 74 | ZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9LAogICAgICAgICAgICAiZGVmYXVsdCI6 75 | IHt9CiAgICAgICAgfSwKICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAi 76 | b2JqZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9 77 | LAogICAgICAgICAgICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAicGF0dGVyblByb3Bl 78 | cnRpZXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJhZGRpdGlv 79 | bmFsUHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgImRlZmF1bHQiOiB7fQog 80 | ICAgICAgIH0sCiAgICAgICAgImRlcGVuZGVuY2llcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2Jq 81 | ZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAg 82 | ImFueU9mIjogWwogICAgICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAg 83 | ICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc3RyaW5nQXJyYXkiIH0KICAgICAgICAgICAg 84 | ICAgIF0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImVudW0iOiB7CiAgICAgICAgICAg 85 | ICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgInVu 86 | aXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICJh 87 | bnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zaW1wbGVUeXBl 88 | cyIgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIs 89 | CiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NpbXBs 90 | ZVR5cGVzIiB9LAogICAgICAgICAgICAgICAgICAgICJtaW5JdGVtcyI6IDEsCiAgICAgICAgICAgICAg 91 | ICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAg 92 | ICAgICAgfSwKICAgICAgICAiYWxsT2YiOiB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc2NoZW1hQXJy 93 | YXkiIH0sCiAgICAgICAgImFueU9mIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NjaGVtYUFycmF5 94 | IiB9LAogICAgICAgICJvbmVPZiI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIg 95 | fSwKICAgICAgICAibm90IjogeyAiJHJlZiI6ICIjIiB9CiAgICB9LAogICAgImRlcGVuZGVuY2llcyI6 96 | IHsKICAgICAgICAiZXhjbHVzaXZlTWF4aW11bSI6IFsgIm1heGltdW0iIF0sCiAgICAgICAgImV4Y2x1 97 | c2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)} 98 | -------------------------------------------------------------------------------- /jsonschema/display.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jsonschema 16 | 17 | import ( 18 | "fmt" 19 | "strings" 20 | ) 21 | 22 | // 23 | // DISPLAY 24 | // The following methods display Schemas. 25 | // 26 | 27 | // Description returns a string representation of a string or string array. 28 | func (s *StringOrStringArray) Description() string { 29 | if s.String != nil { 30 | return *s.String 31 | } 32 | if s.StringArray != nil { 33 | return strings.Join(*s.StringArray, ", ") 34 | } 35 | return "" 36 | } 37 | 38 | // Returns a string representation of a Schema. 39 | func (schema *Schema) String() string { 40 | return schema.describeSchema("") 41 | } 42 | 43 | // Helper: Returns a string representation of a Schema indented by a specified string. 44 | func (schema *Schema) describeSchema(indent string) string { 45 | result := "" 46 | if schema.Schema != nil { 47 | result += indent + "$schema: " + *(schema.Schema) + "\n" 48 | } 49 | if schema.ID != nil { 50 | result += indent + "id: " + *(schema.ID) + "\n" 51 | } 52 | if schema.MultipleOf != nil { 53 | result += indent + fmt.Sprintf("multipleOf: %+v\n", *(schema.MultipleOf)) 54 | } 55 | if schema.Maximum != nil { 56 | result += indent + fmt.Sprintf("maximum: %+v\n", *(schema.Maximum)) 57 | } 58 | if schema.ExclusiveMaximum != nil { 59 | result += indent + fmt.Sprintf("exclusiveMaximum: %+v\n", *(schema.ExclusiveMaximum)) 60 | } 61 | if schema.Minimum != nil { 62 | result += indent + fmt.Sprintf("minimum: %+v\n", *(schema.Minimum)) 63 | } 64 | if schema.ExclusiveMinimum != nil { 65 | result += indent + fmt.Sprintf("exclusiveMinimum: %+v\n", *(schema.ExclusiveMinimum)) 66 | } 67 | if schema.MaxLength != nil { 68 | result += indent + fmt.Sprintf("maxLength: %+v\n", *(schema.MaxLength)) 69 | } 70 | if schema.MinLength != nil { 71 | result += indent + fmt.Sprintf("minLength: %+v\n", *(schema.MinLength)) 72 | } 73 | if schema.Pattern != nil { 74 | result += indent + fmt.Sprintf("pattern: %+v\n", *(schema.Pattern)) 75 | } 76 | if schema.AdditionalItems != nil { 77 | s := schema.AdditionalItems.Schema 78 | if s != nil { 79 | result += indent + "additionalItems:\n" 80 | result += s.describeSchema(indent + " ") 81 | } else { 82 | b := *(schema.AdditionalItems.Boolean) 83 | result += indent + fmt.Sprintf("additionalItems: %+v\n", b) 84 | } 85 | } 86 | if schema.Items != nil { 87 | result += indent + "items:\n" 88 | items := schema.Items 89 | if items.SchemaArray != nil { 90 | for i, s := range *(items.SchemaArray) { 91 | result += indent + " " + fmt.Sprintf("%d", i) + ":\n" 92 | result += s.describeSchema(indent + " " + " ") 93 | } 94 | } else if items.Schema != nil { 95 | result += items.Schema.describeSchema(indent + " " + " ") 96 | } 97 | } 98 | if schema.MaxItems != nil { 99 | result += indent + fmt.Sprintf("maxItems: %+v\n", *(schema.MaxItems)) 100 | } 101 | if schema.MinItems != nil { 102 | result += indent + fmt.Sprintf("minItems: %+v\n", *(schema.MinItems)) 103 | } 104 | if schema.UniqueItems != nil { 105 | result += indent + fmt.Sprintf("uniqueItems: %+v\n", *(schema.UniqueItems)) 106 | } 107 | if schema.MaxProperties != nil { 108 | result += indent + fmt.Sprintf("maxProperties: %+v\n", *(schema.MaxProperties)) 109 | } 110 | if schema.MinProperties != nil { 111 | result += indent + fmt.Sprintf("minProperties: %+v\n", *(schema.MinProperties)) 112 | } 113 | if schema.Required != nil { 114 | result += indent + fmt.Sprintf("required: %+v\n", *(schema.Required)) 115 | } 116 | if schema.AdditionalProperties != nil { 117 | s := schema.AdditionalProperties.Schema 118 | if s != nil { 119 | result += indent + "additionalProperties:\n" 120 | result += s.describeSchema(indent + " ") 121 | } else { 122 | b := *(schema.AdditionalProperties.Boolean) 123 | result += indent + fmt.Sprintf("additionalProperties: %+v\n", b) 124 | } 125 | } 126 | if schema.Properties != nil { 127 | result += indent + "properties:\n" 128 | for _, pair := range *(schema.Properties) { 129 | name := pair.Name 130 | s := pair.Value 131 | result += indent + " " + name + ":\n" 132 | result += s.describeSchema(indent + " " + " ") 133 | } 134 | } 135 | if schema.PatternProperties != nil { 136 | result += indent + "patternProperties:\n" 137 | for _, pair := range *(schema.PatternProperties) { 138 | name := pair.Name 139 | s := pair.Value 140 | result += indent + " " + name + ":\n" 141 | result += s.describeSchema(indent + " " + " ") 142 | } 143 | } 144 | if schema.Dependencies != nil { 145 | result += indent + "dependencies:\n" 146 | for _, pair := range *(schema.Dependencies) { 147 | name := pair.Name 148 | schemaOrStringArray := pair.Value 149 | s := schemaOrStringArray.Schema 150 | if s != nil { 151 | result += indent + " " + name + ":\n" 152 | result += s.describeSchema(indent + " " + " ") 153 | } else { 154 | a := schemaOrStringArray.StringArray 155 | if a != nil { 156 | result += indent + " " + name + ":\n" 157 | for _, s2 := range *a { 158 | result += indent + " " + " " + s2 + "\n" 159 | } 160 | } 161 | } 162 | 163 | } 164 | } 165 | if schema.Enumeration != nil { 166 | result += indent + "enumeration:\n" 167 | for _, value := range *(schema.Enumeration) { 168 | if value.String != nil { 169 | result += indent + " " + fmt.Sprintf("%+v\n", *value.String) 170 | } else { 171 | result += indent + " " + fmt.Sprintf("%+v\n", *value.Bool) 172 | } 173 | } 174 | } 175 | if schema.Type != nil { 176 | result += indent + fmt.Sprintf("type: %+v\n", schema.Type.Description()) 177 | } 178 | if schema.AllOf != nil { 179 | result += indent + "allOf:\n" 180 | for _, s := range *(schema.AllOf) { 181 | result += s.describeSchema(indent + " ") 182 | result += indent + "-\n" 183 | } 184 | } 185 | if schema.AnyOf != nil { 186 | result += indent + "anyOf:\n" 187 | for _, s := range *(schema.AnyOf) { 188 | result += s.describeSchema(indent + " ") 189 | result += indent + "-\n" 190 | } 191 | } 192 | if schema.OneOf != nil { 193 | result += indent + "oneOf:\n" 194 | for _, s := range *(schema.OneOf) { 195 | result += s.describeSchema(indent + " ") 196 | result += indent + "-\n" 197 | } 198 | } 199 | if schema.Not != nil { 200 | result += indent + "not:\n" 201 | result += schema.Not.describeSchema(indent + " ") 202 | } 203 | if schema.Definitions != nil { 204 | result += indent + "definitions:\n" 205 | for _, pair := range *(schema.Definitions) { 206 | name := pair.Name 207 | s := pair.Value 208 | result += indent + " " + name + ":\n" 209 | result += s.describeSchema(indent + " " + " ") 210 | } 211 | } 212 | if schema.Title != nil { 213 | result += indent + "title: " + *(schema.Title) + "\n" 214 | } 215 | if schema.Description != nil { 216 | result += indent + "description: " + *(schema.Description) + "\n" 217 | } 218 | if schema.Default != nil { 219 | result += indent + "default:\n" 220 | result += indent + fmt.Sprintf(" %+v\n", *(schema.Default)) 221 | } 222 | if schema.Format != nil { 223 | result += indent + "format: " + *(schema.Format) + "\n" 224 | } 225 | if schema.Ref != nil { 226 | result += indent + "$ref: " + *(schema.Ref) + "\n" 227 | } 228 | return result 229 | } 230 | -------------------------------------------------------------------------------- /jsonschema/generate-base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build ignore 16 | 17 | package main 18 | 19 | import ( 20 | "encoding/base64" 21 | "io/ioutil" 22 | "os" 23 | ) 24 | 25 | func check(err error) { 26 | if err != nil { 27 | panic(err) 28 | } 29 | } 30 | 31 | func write(f *os.File, s string) { 32 | _, err := f.WriteString(s) 33 | check(err) 34 | } 35 | 36 | func main() { 37 | f, err := os.Create("base.go") 38 | check(err) 39 | 40 | defer f.Close() 41 | 42 | write(f, ` 43 | // THIS FILE IS AUTOMATICALLY GENERATED. 44 | 45 | package jsonschema 46 | 47 | import ( 48 | "encoding/base64" 49 | ) 50 | 51 | func baseSchemaBytes() ([]byte, error){ 52 | return base64.StdEncoding.DecodeString( 53 | `) 54 | write(f, "`") 55 | 56 | b, err := ioutil.ReadFile("schema.json") 57 | check(err) 58 | 59 | s := base64.StdEncoding.EncodeToString(b) 60 | limit := len(s) 61 | width := 80 62 | for i := 0; i < limit; i += width { 63 | if i > 0 { 64 | write(f, "\n") 65 | } 66 | j := i + width 67 | if j > limit { 68 | j = limit 69 | } 70 | write(f, s[i:j]) 71 | } 72 | write(f, "`)}") 73 | } 74 | -------------------------------------------------------------------------------- /jsonschema/models.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Package jsonschema supports the reading, writing, and manipulation 16 | // of JSON Schemas. 17 | package jsonschema 18 | 19 | import "gopkg.in/yaml.v3" 20 | 21 | // The Schema struct models a JSON Schema and, because schemas are 22 | // defined hierarchically, contains many references to itself. 23 | // All fields are pointers and are nil if the associated values 24 | // are not specified. 25 | type Schema struct { 26 | Schema *string // $schema 27 | ID *string // id keyword used for $ref resolution scope 28 | Ref *string // $ref, i.e. JSON Pointers 29 | 30 | // http://json-schema.org/latest/json-schema-validation.html 31 | // 5.1. Validation keywords for numeric instances (number and integer) 32 | MultipleOf *SchemaNumber 33 | Maximum *SchemaNumber 34 | ExclusiveMaximum *bool 35 | Minimum *SchemaNumber 36 | ExclusiveMinimum *bool 37 | 38 | // 5.2. Validation keywords for strings 39 | MaxLength *int64 40 | MinLength *int64 41 | Pattern *string 42 | 43 | // 5.3. Validation keywords for arrays 44 | AdditionalItems *SchemaOrBoolean 45 | Items *SchemaOrSchemaArray 46 | MaxItems *int64 47 | MinItems *int64 48 | UniqueItems *bool 49 | 50 | // 5.4. Validation keywords for objects 51 | MaxProperties *int64 52 | MinProperties *int64 53 | Required *[]string 54 | AdditionalProperties *SchemaOrBoolean 55 | Properties *[]*NamedSchema 56 | PatternProperties *[]*NamedSchema 57 | Dependencies *[]*NamedSchemaOrStringArray 58 | 59 | // 5.5. Validation keywords for any instance type 60 | Enumeration *[]SchemaEnumValue 61 | Type *StringOrStringArray 62 | AllOf *[]*Schema 63 | AnyOf *[]*Schema 64 | OneOf *[]*Schema 65 | Not *Schema 66 | Definitions *[]*NamedSchema 67 | 68 | // 6. Metadata keywords 69 | Title *string 70 | Description *string 71 | Default *yaml.Node 72 | 73 | // 7. Semantic validation with "format" 74 | Format *string 75 | } 76 | 77 | // These helper structs represent "combination" types that generally can 78 | // have values of one type or another. All are used to represent parts 79 | // of Schemas. 80 | 81 | // SchemaNumber represents a value that can be either an Integer or a Float. 82 | type SchemaNumber struct { 83 | Integer *int64 84 | Float *float64 85 | } 86 | 87 | // NewSchemaNumberWithInteger creates and returns a new object 88 | func NewSchemaNumberWithInteger(i int64) *SchemaNumber { 89 | result := &SchemaNumber{} 90 | result.Integer = &i 91 | return result 92 | } 93 | 94 | // NewSchemaNumberWithFloat creates and returns a new object 95 | func NewSchemaNumberWithFloat(f float64) *SchemaNumber { 96 | result := &SchemaNumber{} 97 | result.Float = &f 98 | return result 99 | } 100 | 101 | // SchemaOrBoolean represents a value that can be either a Schema or a Boolean. 102 | type SchemaOrBoolean struct { 103 | Schema *Schema 104 | Boolean *bool 105 | } 106 | 107 | // NewSchemaOrBooleanWithSchema creates and returns a new object 108 | func NewSchemaOrBooleanWithSchema(s *Schema) *SchemaOrBoolean { 109 | result := &SchemaOrBoolean{} 110 | result.Schema = s 111 | return result 112 | } 113 | 114 | // NewSchemaOrBooleanWithBoolean creates and returns a new object 115 | func NewSchemaOrBooleanWithBoolean(b bool) *SchemaOrBoolean { 116 | result := &SchemaOrBoolean{} 117 | result.Boolean = &b 118 | return result 119 | } 120 | 121 | // StringOrStringArray represents a value that can be either 122 | // a String or an Array of Strings. 123 | type StringOrStringArray struct { 124 | String *string 125 | StringArray *[]string 126 | } 127 | 128 | // NewStringOrStringArrayWithString creates and returns a new object 129 | func NewStringOrStringArrayWithString(s string) *StringOrStringArray { 130 | result := &StringOrStringArray{} 131 | result.String = &s 132 | return result 133 | } 134 | 135 | // NewStringOrStringArrayWithStringArray creates and returns a new object 136 | func NewStringOrStringArrayWithStringArray(a []string) *StringOrStringArray { 137 | result := &StringOrStringArray{} 138 | result.StringArray = &a 139 | return result 140 | } 141 | 142 | // SchemaOrStringArray represents a value that can be either 143 | // a Schema or an Array of Strings. 144 | type SchemaOrStringArray struct { 145 | Schema *Schema 146 | StringArray *[]string 147 | } 148 | 149 | // SchemaOrSchemaArray represents a value that can be either 150 | // a Schema or an Array of Schemas. 151 | type SchemaOrSchemaArray struct { 152 | Schema *Schema 153 | SchemaArray *[]*Schema 154 | } 155 | 156 | // NewSchemaOrSchemaArrayWithSchema creates and returns a new object 157 | func NewSchemaOrSchemaArrayWithSchema(s *Schema) *SchemaOrSchemaArray { 158 | result := &SchemaOrSchemaArray{} 159 | result.Schema = s 160 | return result 161 | } 162 | 163 | // NewSchemaOrSchemaArrayWithSchemaArray creates and returns a new object 164 | func NewSchemaOrSchemaArrayWithSchemaArray(a []*Schema) *SchemaOrSchemaArray { 165 | result := &SchemaOrSchemaArray{} 166 | result.SchemaArray = &a 167 | return result 168 | } 169 | 170 | // SchemaEnumValue represents a value that can be part of an 171 | // enumeration in a Schema. 172 | type SchemaEnumValue struct { 173 | String *string 174 | Bool *bool 175 | } 176 | 177 | // NamedSchema is a name-value pair that is used to emulate maps 178 | // with ordered keys. 179 | type NamedSchema struct { 180 | Name string 181 | Value *Schema 182 | } 183 | 184 | // NewNamedSchema creates and returns a new object 185 | func NewNamedSchema(name string, value *Schema) *NamedSchema { 186 | return &NamedSchema{Name: name, Value: value} 187 | } 188 | 189 | // NamedSchemaOrStringArray is a name-value pair that is used 190 | // to emulate maps with ordered keys. 191 | type NamedSchemaOrStringArray struct { 192 | Name string 193 | Value *SchemaOrStringArray 194 | } 195 | 196 | // Access named subschemas by name 197 | 198 | func namedSchemaArrayElementWithName(array *[]*NamedSchema, name string) *Schema { 199 | if array == nil { 200 | return nil 201 | } 202 | for _, pair := range *array { 203 | if pair.Name == name { 204 | return pair.Value 205 | } 206 | } 207 | return nil 208 | } 209 | 210 | // PropertyWithName returns the selected element. 211 | func (s *Schema) PropertyWithName(name string) *Schema { 212 | return namedSchemaArrayElementWithName(s.Properties, name) 213 | } 214 | 215 | // PatternPropertyWithName returns the selected element. 216 | func (s *Schema) PatternPropertyWithName(name string) *Schema { 217 | return namedSchemaArrayElementWithName(s.PatternProperties, name) 218 | } 219 | 220 | // DefinitionWithName returns the selected element. 221 | func (s *Schema) DefinitionWithName(name string) *Schema { 222 | return namedSchemaArrayElementWithName(s.Definitions, name) 223 | } 224 | 225 | // AddProperty adds a named property. 226 | func (s *Schema) AddProperty(name string, property *Schema) { 227 | *s.Properties = append(*s.Properties, NewNamedSchema(name, property)) 228 | } 229 | -------------------------------------------------------------------------------- /jsonschema/operations.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jsonschema 16 | 17 | import ( 18 | "fmt" 19 | "log" 20 | "strings" 21 | ) 22 | 23 | // 24 | // OPERATIONS 25 | // The following methods perform operations on Schemas. 26 | // 27 | 28 | // IsEmpty returns true if no members of the Schema are specified. 29 | func (schema *Schema) IsEmpty() bool { 30 | return (schema.Schema == nil) && 31 | (schema.ID == nil) && 32 | (schema.MultipleOf == nil) && 33 | (schema.Maximum == nil) && 34 | (schema.ExclusiveMaximum == nil) && 35 | (schema.Minimum == nil) && 36 | (schema.ExclusiveMinimum == nil) && 37 | (schema.MaxLength == nil) && 38 | (schema.MinLength == nil) && 39 | (schema.Pattern == nil) && 40 | (schema.AdditionalItems == nil) && 41 | (schema.Items == nil) && 42 | (schema.MaxItems == nil) && 43 | (schema.MinItems == nil) && 44 | (schema.UniqueItems == nil) && 45 | (schema.MaxProperties == nil) && 46 | (schema.MinProperties == nil) && 47 | (schema.Required == nil) && 48 | (schema.AdditionalProperties == nil) && 49 | (schema.Properties == nil) && 50 | (schema.PatternProperties == nil) && 51 | (schema.Dependencies == nil) && 52 | (schema.Enumeration == nil) && 53 | (schema.Type == nil) && 54 | (schema.AllOf == nil) && 55 | (schema.AnyOf == nil) && 56 | (schema.OneOf == nil) && 57 | (schema.Not == nil) && 58 | (schema.Definitions == nil) && 59 | (schema.Title == nil) && 60 | (schema.Description == nil) && 61 | (schema.Default == nil) && 62 | (schema.Format == nil) && 63 | (schema.Ref == nil) 64 | } 65 | 66 | // IsEqual returns true if two schemas are equal. 67 | func (schema *Schema) IsEqual(schema2 *Schema) bool { 68 | return schema.String() == schema2.String() 69 | } 70 | 71 | // SchemaOperation represents a function that can be applied to a Schema. 72 | type SchemaOperation func(schema *Schema, context string) 73 | 74 | // Applies a specified function to a Schema and all of the Schemas that it contains. 75 | func (schema *Schema) applyToSchemas(operation SchemaOperation, context string) { 76 | 77 | if schema.AdditionalItems != nil { 78 | s := schema.AdditionalItems.Schema 79 | if s != nil { 80 | s.applyToSchemas(operation, "AdditionalItems") 81 | } 82 | } 83 | 84 | if schema.Items != nil { 85 | if schema.Items.SchemaArray != nil { 86 | for _, s := range *(schema.Items.SchemaArray) { 87 | s.applyToSchemas(operation, "Items.SchemaArray") 88 | } 89 | } else if schema.Items.Schema != nil { 90 | schema.Items.Schema.applyToSchemas(operation, "Items.Schema") 91 | } 92 | } 93 | 94 | if schema.AdditionalProperties != nil { 95 | s := schema.AdditionalProperties.Schema 96 | if s != nil { 97 | s.applyToSchemas(operation, "AdditionalProperties") 98 | } 99 | } 100 | 101 | if schema.Properties != nil { 102 | for _, pair := range *(schema.Properties) { 103 | s := pair.Value 104 | s.applyToSchemas(operation, "Properties") 105 | } 106 | } 107 | if schema.PatternProperties != nil { 108 | for _, pair := range *(schema.PatternProperties) { 109 | s := pair.Value 110 | s.applyToSchemas(operation, "PatternProperties") 111 | } 112 | } 113 | 114 | if schema.Dependencies != nil { 115 | for _, pair := range *(schema.Dependencies) { 116 | schemaOrStringArray := pair.Value 117 | s := schemaOrStringArray.Schema 118 | if s != nil { 119 | s.applyToSchemas(operation, "Dependencies") 120 | } 121 | } 122 | } 123 | 124 | if schema.AllOf != nil { 125 | for _, s := range *(schema.AllOf) { 126 | s.applyToSchemas(operation, "AllOf") 127 | } 128 | } 129 | if schema.AnyOf != nil { 130 | for _, s := range *(schema.AnyOf) { 131 | s.applyToSchemas(operation, "AnyOf") 132 | } 133 | } 134 | if schema.OneOf != nil { 135 | for _, s := range *(schema.OneOf) { 136 | s.applyToSchemas(operation, "OneOf") 137 | } 138 | } 139 | if schema.Not != nil { 140 | schema.Not.applyToSchemas(operation, "Not") 141 | } 142 | 143 | if schema.Definitions != nil { 144 | for _, pair := range *(schema.Definitions) { 145 | s := pair.Value 146 | s.applyToSchemas(operation, "Definitions") 147 | } 148 | } 149 | 150 | operation(schema, context) 151 | } 152 | 153 | // CopyProperties copies all non-nil properties from the source Schema to the schema Schema. 154 | func (schema *Schema) CopyProperties(source *Schema) { 155 | if source.Schema != nil { 156 | schema.Schema = source.Schema 157 | } 158 | if source.ID != nil { 159 | schema.ID = source.ID 160 | } 161 | if source.MultipleOf != nil { 162 | schema.MultipleOf = source.MultipleOf 163 | } 164 | if source.Maximum != nil { 165 | schema.Maximum = source.Maximum 166 | } 167 | if source.ExclusiveMaximum != nil { 168 | schema.ExclusiveMaximum = source.ExclusiveMaximum 169 | } 170 | if source.Minimum != nil { 171 | schema.Minimum = source.Minimum 172 | } 173 | if source.ExclusiveMinimum != nil { 174 | schema.ExclusiveMinimum = source.ExclusiveMinimum 175 | } 176 | if source.MaxLength != nil { 177 | schema.MaxLength = source.MaxLength 178 | } 179 | if source.MinLength != nil { 180 | schema.MinLength = source.MinLength 181 | } 182 | if source.Pattern != nil { 183 | schema.Pattern = source.Pattern 184 | } 185 | if source.AdditionalItems != nil { 186 | schema.AdditionalItems = source.AdditionalItems 187 | } 188 | if source.Items != nil { 189 | schema.Items = source.Items 190 | } 191 | if source.MaxItems != nil { 192 | schema.MaxItems = source.MaxItems 193 | } 194 | if source.MinItems != nil { 195 | schema.MinItems = source.MinItems 196 | } 197 | if source.UniqueItems != nil { 198 | schema.UniqueItems = source.UniqueItems 199 | } 200 | if source.MaxProperties != nil { 201 | schema.MaxProperties = source.MaxProperties 202 | } 203 | if source.MinProperties != nil { 204 | schema.MinProperties = source.MinProperties 205 | } 206 | if source.Required != nil { 207 | schema.Required = source.Required 208 | } 209 | if source.AdditionalProperties != nil { 210 | schema.AdditionalProperties = source.AdditionalProperties 211 | } 212 | if source.Properties != nil { 213 | schema.Properties = source.Properties 214 | } 215 | if source.PatternProperties != nil { 216 | schema.PatternProperties = source.PatternProperties 217 | } 218 | if source.Dependencies != nil { 219 | schema.Dependencies = source.Dependencies 220 | } 221 | if source.Enumeration != nil { 222 | schema.Enumeration = source.Enumeration 223 | } 224 | if source.Type != nil { 225 | schema.Type = source.Type 226 | } 227 | if source.AllOf != nil { 228 | schema.AllOf = source.AllOf 229 | } 230 | if source.AnyOf != nil { 231 | schema.AnyOf = source.AnyOf 232 | } 233 | if source.OneOf != nil { 234 | schema.OneOf = source.OneOf 235 | } 236 | if source.Not != nil { 237 | schema.Not = source.Not 238 | } 239 | if source.Definitions != nil { 240 | schema.Definitions = source.Definitions 241 | } 242 | if source.Title != nil { 243 | schema.Title = source.Title 244 | } 245 | if source.Description != nil { 246 | schema.Description = source.Description 247 | } 248 | if source.Default != nil { 249 | schema.Default = source.Default 250 | } 251 | if source.Format != nil { 252 | schema.Format = source.Format 253 | } 254 | if source.Ref != nil { 255 | schema.Ref = source.Ref 256 | } 257 | } 258 | 259 | // TypeIs returns true if the Type of a Schema includes the specified type 260 | func (schema *Schema) TypeIs(typeName string) bool { 261 | if schema.Type != nil { 262 | // the schema Type is either a string or an array of strings 263 | if schema.Type.String != nil { 264 | return (*(schema.Type.String) == typeName) 265 | } else if schema.Type.StringArray != nil { 266 | for _, n := range *(schema.Type.StringArray) { 267 | if n == typeName { 268 | return true 269 | } 270 | } 271 | } 272 | } 273 | return false 274 | } 275 | 276 | // ResolveRefs resolves "$ref" elements in a Schema and its children. 277 | // But if a reference refers to an object type, is inside a oneOf, or contains a oneOf, 278 | // the reference is kept and we expect downstream tools to separately model these 279 | // referenced schemas. 280 | func (schema *Schema) ResolveRefs() { 281 | rootSchema := schema 282 | count := 1 283 | for count > 0 { 284 | count = 0 285 | schema.applyToSchemas( 286 | func(schema *Schema, context string) { 287 | if schema.Ref != nil { 288 | resolvedRef, err := rootSchema.resolveJSONPointer(*(schema.Ref)) 289 | if err != nil { 290 | log.Printf("%+v", err) 291 | } else if resolvedRef.TypeIs("object") { 292 | // don't substitute for objects, we'll model the referenced schema with a class 293 | } else if context == "OneOf" { 294 | // don't substitute for references inside oneOf declarations 295 | } else if resolvedRef.OneOf != nil { 296 | // don't substitute for references that contain oneOf declarations 297 | } else if resolvedRef.AdditionalProperties != nil { 298 | // don't substitute for references that look like objects 299 | } else { 300 | schema.Ref = nil 301 | schema.CopyProperties(resolvedRef) 302 | count++ 303 | } 304 | } 305 | }, "") 306 | } 307 | } 308 | 309 | // resolveJSONPointer resolves JSON pointers. 310 | // This current implementation is very crude and custom for OpenAPI 2.0 schemas. 311 | // It panics for any pointer that it is unable to resolve. 312 | func (schema *Schema) resolveJSONPointer(ref string) (result *Schema, err error) { 313 | parts := strings.Split(ref, "#") 314 | if len(parts) == 2 { 315 | documentName := parts[0] + "#" 316 | if documentName == "#" && schema.ID != nil { 317 | documentName = *(schema.ID) 318 | } 319 | path := parts[1] 320 | document := schemas[documentName] 321 | pathParts := strings.Split(path, "/") 322 | 323 | // we currently do a very limited (hard-coded) resolution of certain paths and log errors for missed cases 324 | if len(pathParts) == 1 { 325 | return document, nil 326 | } else if len(pathParts) == 3 { 327 | switch pathParts[1] { 328 | case "definitions": 329 | dictionary := document.Definitions 330 | for _, pair := range *dictionary { 331 | if pair.Name == pathParts[2] { 332 | result = pair.Value 333 | } 334 | } 335 | case "properties": 336 | dictionary := document.Properties 337 | for _, pair := range *dictionary { 338 | if pair.Name == pathParts[2] { 339 | result = pair.Value 340 | } 341 | } 342 | default: 343 | break 344 | } 345 | } 346 | } 347 | if result == nil { 348 | return nil, fmt.Errorf("unresolved pointer: %+v", ref) 349 | } 350 | return result, nil 351 | } 352 | 353 | // ResolveAllOfs replaces "allOf" elements by merging their properties into the parent Schema. 354 | func (schema *Schema) ResolveAllOfs() { 355 | schema.applyToSchemas( 356 | func(schema *Schema, context string) { 357 | if schema.AllOf != nil { 358 | for _, allOf := range *(schema.AllOf) { 359 | schema.CopyProperties(allOf) 360 | } 361 | schema.AllOf = nil 362 | } 363 | }, "resolveAllOfs") 364 | } 365 | 366 | // ResolveAnyOfs replaces all "anyOf" elements with "oneOf". 367 | func (schema *Schema) ResolveAnyOfs() { 368 | schema.applyToSchemas( 369 | func(schema *Schema, context string) { 370 | if schema.AnyOf != nil { 371 | schema.OneOf = schema.AnyOf 372 | schema.AnyOf = nil 373 | } 374 | }, "resolveAnyOfs") 375 | } 376 | 377 | // return a pointer to a copy of a passed-in string 378 | func stringptr(input string) (output *string) { 379 | return &input 380 | } 381 | 382 | // CopyOfficialSchemaProperty copies a named property from the official JSON Schema definition 383 | func (schema *Schema) CopyOfficialSchemaProperty(name string) { 384 | *schema.Properties = append(*schema.Properties, 385 | NewNamedSchema(name, 386 | &Schema{Ref: stringptr("http://json-schema.org/draft-04/schema#/properties/" + name)})) 387 | } 388 | 389 | // CopyOfficialSchemaProperties copies named properties from the official JSON Schema definition 390 | func (schema *Schema) CopyOfficialSchemaProperties(names []string) { 391 | for _, name := range names { 392 | schema.CopyOfficialSchemaProperty(name) 393 | } 394 | } 395 | -------------------------------------------------------------------------------- /jsonschema/reader.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | //go:generate go run generate-base.go 16 | 17 | package jsonschema 18 | 19 | import ( 20 | "fmt" 21 | "io/ioutil" 22 | "strconv" 23 | 24 | "gopkg.in/yaml.v3" 25 | ) 26 | 27 | // This is a global map of all known Schemas. 28 | // It is initialized when the first Schema is created and inserted. 29 | var schemas map[string]*Schema 30 | 31 | // NewBaseSchema builds a schema object from an embedded json representation. 32 | func NewBaseSchema() (schema *Schema, err error) { 33 | b, err := baseSchemaBytes() 34 | if err != nil { 35 | return nil, err 36 | } 37 | var node yaml.Node 38 | err = yaml.Unmarshal(b, &node) 39 | if err != nil { 40 | return nil, err 41 | } 42 | return NewSchemaFromObject(&node), nil 43 | } 44 | 45 | // NewSchemaFromFile reads a schema from a file. 46 | // Currently this assumes that schemas are stored in the source distribution of this project. 47 | func NewSchemaFromFile(filename string) (schema *Schema, err error) { 48 | file, err := ioutil.ReadFile(filename) 49 | if err != nil { 50 | return nil, err 51 | } 52 | var node yaml.Node 53 | err = yaml.Unmarshal(file, &node) 54 | if err != nil { 55 | return nil, err 56 | } 57 | return NewSchemaFromObject(&node), nil 58 | } 59 | 60 | // NewSchemaFromObject constructs a schema from a parsed JSON object. 61 | // Due to the complexity of the schema representation, this is a 62 | // custom reader and not the standard Go JSON reader (encoding/json). 63 | func NewSchemaFromObject(jsonData *yaml.Node) *Schema { 64 | switch jsonData.Kind { 65 | case yaml.DocumentNode: 66 | return NewSchemaFromObject(jsonData.Content[0]) 67 | case yaml.MappingNode: 68 | schema := &Schema{} 69 | 70 | for i := 0; i < len(jsonData.Content); i += 2 { 71 | k := jsonData.Content[i].Value 72 | v := jsonData.Content[i+1] 73 | 74 | switch k { 75 | case "$schema": 76 | schema.Schema = schema.stringValue(v) 77 | case "id": 78 | schema.ID = schema.stringValue(v) 79 | 80 | case "multipleOf": 81 | schema.MultipleOf = schema.numberValue(v) 82 | case "maximum": 83 | schema.Maximum = schema.numberValue(v) 84 | case "exclusiveMaximum": 85 | schema.ExclusiveMaximum = schema.boolValue(v) 86 | case "minimum": 87 | schema.Minimum = schema.numberValue(v) 88 | case "exclusiveMinimum": 89 | schema.ExclusiveMinimum = schema.boolValue(v) 90 | 91 | case "maxLength": 92 | schema.MaxLength = schema.intValue(v) 93 | case "minLength": 94 | schema.MinLength = schema.intValue(v) 95 | case "pattern": 96 | schema.Pattern = schema.stringValue(v) 97 | 98 | case "additionalItems": 99 | schema.AdditionalItems = schema.schemaOrBooleanValue(v) 100 | case "items": 101 | schema.Items = schema.schemaOrSchemaArrayValue(v) 102 | case "maxItems": 103 | schema.MaxItems = schema.intValue(v) 104 | case "minItems": 105 | schema.MinItems = schema.intValue(v) 106 | case "uniqueItems": 107 | schema.UniqueItems = schema.boolValue(v) 108 | 109 | case "maxProperties": 110 | schema.MaxProperties = schema.intValue(v) 111 | case "minProperties": 112 | schema.MinProperties = schema.intValue(v) 113 | case "required": 114 | schema.Required = schema.arrayOfStringsValue(v) 115 | case "additionalProperties": 116 | schema.AdditionalProperties = schema.schemaOrBooleanValue(v) 117 | case "properties": 118 | schema.Properties = schema.mapOfSchemasValue(v) 119 | case "patternProperties": 120 | schema.PatternProperties = schema.mapOfSchemasValue(v) 121 | case "dependencies": 122 | schema.Dependencies = schema.mapOfSchemasOrStringArraysValue(v) 123 | 124 | case "enum": 125 | schema.Enumeration = schema.arrayOfEnumValuesValue(v) 126 | 127 | case "type": 128 | schema.Type = schema.stringOrStringArrayValue(v) 129 | case "allOf": 130 | schema.AllOf = schema.arrayOfSchemasValue(v) 131 | case "anyOf": 132 | schema.AnyOf = schema.arrayOfSchemasValue(v) 133 | case "oneOf": 134 | schema.OneOf = schema.arrayOfSchemasValue(v) 135 | case "not": 136 | schema.Not = NewSchemaFromObject(v) 137 | case "definitions": 138 | schema.Definitions = schema.mapOfSchemasValue(v) 139 | 140 | case "title": 141 | schema.Title = schema.stringValue(v) 142 | case "description": 143 | schema.Description = schema.stringValue(v) 144 | 145 | case "default": 146 | schema.Default = v 147 | 148 | case "format": 149 | schema.Format = schema.stringValue(v) 150 | case "$ref": 151 | schema.Ref = schema.stringValue(v) 152 | default: 153 | fmt.Printf("UNSUPPORTED (%s)\n", k) 154 | } 155 | } 156 | 157 | // insert schema in global map 158 | if schema.ID != nil { 159 | if schemas == nil { 160 | schemas = make(map[string]*Schema, 0) 161 | } 162 | schemas[*(schema.ID)] = schema 163 | } 164 | return schema 165 | 166 | default: 167 | fmt.Printf("schemaValue: unexpected node %+v\n", jsonData) 168 | return nil 169 | } 170 | 171 | return nil 172 | } 173 | 174 | // 175 | // BUILDERS 176 | // The following methods build elements of Schemas from interface{} values. 177 | // Each returns nil if it is unable to build the desired element. 178 | // 179 | 180 | // Gets the string value of an interface{} value if possible. 181 | func (schema *Schema) stringValue(v *yaml.Node) *string { 182 | switch v.Kind { 183 | case yaml.ScalarNode: 184 | return &v.Value 185 | default: 186 | fmt.Printf("stringValue: unexpected node %+v\n", v) 187 | } 188 | return nil 189 | } 190 | 191 | // Gets the numeric value of an interface{} value if possible. 192 | func (schema *Schema) numberValue(v *yaml.Node) *SchemaNumber { 193 | number := &SchemaNumber{} 194 | switch v.Kind { 195 | case yaml.ScalarNode: 196 | switch v.Tag { 197 | case "!!float": 198 | v2, _ := strconv.ParseFloat(v.Value, 64) 199 | number.Float = &v2 200 | return number 201 | case "!!int": 202 | v2, _ := strconv.ParseInt(v.Value, 10, 64) 203 | number.Integer = &v2 204 | return number 205 | default: 206 | fmt.Printf("stringValue: unexpected node %+v\n", v) 207 | } 208 | default: 209 | fmt.Printf("stringValue: unexpected node %+v\n", v) 210 | } 211 | return nil 212 | } 213 | 214 | // Gets the integer value of an interface{} value if possible. 215 | func (schema *Schema) intValue(v *yaml.Node) *int64 { 216 | switch v.Kind { 217 | case yaml.ScalarNode: 218 | switch v.Tag { 219 | case "!!float": 220 | v2, _ := strconv.ParseFloat(v.Value, 64) 221 | v3 := int64(v2) 222 | return &v3 223 | case "!!int": 224 | v2, _ := strconv.ParseInt(v.Value, 10, 64) 225 | return &v2 226 | default: 227 | fmt.Printf("intValue: unexpected node %+v\n", v) 228 | } 229 | default: 230 | fmt.Printf("intValue: unexpected node %+v\n", v) 231 | } 232 | return nil 233 | } 234 | 235 | // Gets the bool value of an interface{} value if possible. 236 | func (schema *Schema) boolValue(v *yaml.Node) *bool { 237 | switch v.Kind { 238 | case yaml.ScalarNode: 239 | switch v.Tag { 240 | case "!!bool": 241 | v2, _ := strconv.ParseBool(v.Value) 242 | return &v2 243 | default: 244 | fmt.Printf("boolValue: unexpected node %+v\n", v) 245 | } 246 | default: 247 | fmt.Printf("boolValue: unexpected node %+v\n", v) 248 | } 249 | return nil 250 | } 251 | 252 | // Gets a map of Schemas from an interface{} value if possible. 253 | func (schema *Schema) mapOfSchemasValue(v *yaml.Node) *[]*NamedSchema { 254 | switch v.Kind { 255 | case yaml.MappingNode: 256 | m := make([]*NamedSchema, 0) 257 | for i := 0; i < len(v.Content); i += 2 { 258 | k2 := v.Content[i].Value 259 | v2 := v.Content[i+1] 260 | pair := &NamedSchema{Name: k2, Value: NewSchemaFromObject(v2)} 261 | m = append(m, pair) 262 | } 263 | return &m 264 | default: 265 | fmt.Printf("mapOfSchemasValue: unexpected node %+v\n", v) 266 | } 267 | return nil 268 | } 269 | 270 | // Gets an array of Schemas from an interface{} value if possible. 271 | func (schema *Schema) arrayOfSchemasValue(v *yaml.Node) *[]*Schema { 272 | switch v.Kind { 273 | case yaml.SequenceNode: 274 | m := make([]*Schema, 0) 275 | for _, v2 := range v.Content { 276 | switch v2.Kind { 277 | case yaml.MappingNode: 278 | s := NewSchemaFromObject(v2) 279 | m = append(m, s) 280 | default: 281 | fmt.Printf("arrayOfSchemasValue: unexpected node %+v\n", v2) 282 | } 283 | } 284 | return &m 285 | case yaml.MappingNode: 286 | m := make([]*Schema, 0) 287 | s := NewSchemaFromObject(v) 288 | m = append(m, s) 289 | return &m 290 | default: 291 | fmt.Printf("arrayOfSchemasValue: unexpected node %+v\n", v) 292 | } 293 | return nil 294 | } 295 | 296 | // Gets a Schema or an array of Schemas from an interface{} value if possible. 297 | func (schema *Schema) schemaOrSchemaArrayValue(v *yaml.Node) *SchemaOrSchemaArray { 298 | switch v.Kind { 299 | case yaml.SequenceNode: 300 | m := make([]*Schema, 0) 301 | for _, v2 := range v.Content { 302 | switch v2.Kind { 303 | case yaml.MappingNode: 304 | s := NewSchemaFromObject(v2) 305 | m = append(m, s) 306 | default: 307 | fmt.Printf("schemaOrSchemaArrayValue: unexpected node %+v\n", v2) 308 | } 309 | } 310 | return &SchemaOrSchemaArray{SchemaArray: &m} 311 | case yaml.MappingNode: 312 | s := NewSchemaFromObject(v) 313 | return &SchemaOrSchemaArray{Schema: s} 314 | default: 315 | fmt.Printf("schemaOrSchemaArrayValue: unexpected node %+v\n", v) 316 | } 317 | return nil 318 | } 319 | 320 | // Gets an array of strings from an interface{} value if possible. 321 | func (schema *Schema) arrayOfStringsValue(v *yaml.Node) *[]string { 322 | switch v.Kind { 323 | case yaml.ScalarNode: 324 | a := []string{v.Value} 325 | return &a 326 | case yaml.SequenceNode: 327 | a := make([]string, 0) 328 | for _, v2 := range v.Content { 329 | switch v2.Kind { 330 | case yaml.ScalarNode: 331 | a = append(a, v2.Value) 332 | default: 333 | fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v2) 334 | } 335 | } 336 | return &a 337 | default: 338 | fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v) 339 | } 340 | return nil 341 | } 342 | 343 | // Gets a string or an array of strings from an interface{} value if possible. 344 | func (schema *Schema) stringOrStringArrayValue(v *yaml.Node) *StringOrStringArray { 345 | switch v.Kind { 346 | case yaml.ScalarNode: 347 | s := &StringOrStringArray{} 348 | s.String = &v.Value 349 | return s 350 | case yaml.SequenceNode: 351 | a := make([]string, 0) 352 | for _, v2 := range v.Content { 353 | switch v2.Kind { 354 | case yaml.ScalarNode: 355 | a = append(a, v2.Value) 356 | default: 357 | fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v2) 358 | } 359 | } 360 | s := &StringOrStringArray{} 361 | s.StringArray = &a 362 | return s 363 | default: 364 | fmt.Printf("arrayOfStringsValue: unexpected node %+v\n", v) 365 | } 366 | return nil 367 | } 368 | 369 | // Gets an array of enum values from an interface{} value if possible. 370 | func (schema *Schema) arrayOfEnumValuesValue(v *yaml.Node) *[]SchemaEnumValue { 371 | a := make([]SchemaEnumValue, 0) 372 | switch v.Kind { 373 | case yaml.SequenceNode: 374 | for _, v2 := range v.Content { 375 | switch v2.Kind { 376 | case yaml.ScalarNode: 377 | switch v2.Tag { 378 | case "!!str": 379 | a = append(a, SchemaEnumValue{String: &v2.Value}) 380 | case "!!bool": 381 | v3, _ := strconv.ParseBool(v2.Value) 382 | a = append(a, SchemaEnumValue{Bool: &v3}) 383 | default: 384 | fmt.Printf("arrayOfEnumValuesValue: unexpected type %s\n", v2.Tag) 385 | } 386 | default: 387 | fmt.Printf("arrayOfEnumValuesValue: unexpected node %+v\n", v2) 388 | } 389 | } 390 | default: 391 | fmt.Printf("arrayOfEnumValuesValue: unexpected node %+v\n", v) 392 | } 393 | return &a 394 | } 395 | 396 | // Gets a map of schemas or string arrays from an interface{} value if possible. 397 | func (schema *Schema) mapOfSchemasOrStringArraysValue(v *yaml.Node) *[]*NamedSchemaOrStringArray { 398 | m := make([]*NamedSchemaOrStringArray, 0) 399 | switch v.Kind { 400 | case yaml.MappingNode: 401 | for i := 0; i < len(v.Content); i += 2 { 402 | k2 := v.Content[i].Value 403 | v2 := v.Content[i+1] 404 | switch v2.Kind { 405 | case yaml.SequenceNode: 406 | a := make([]string, 0) 407 | for _, v3 := range v2.Content { 408 | switch v3.Kind { 409 | case yaml.ScalarNode: 410 | a = append(a, v3.Value) 411 | default: 412 | fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v3) 413 | } 414 | } 415 | s := &SchemaOrStringArray{} 416 | s.StringArray = &a 417 | pair := &NamedSchemaOrStringArray{Name: k2, Value: s} 418 | m = append(m, pair) 419 | default: 420 | fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v2) 421 | } 422 | } 423 | default: 424 | fmt.Printf("mapOfSchemasOrStringArraysValue: unexpected node %+v\n", v) 425 | } 426 | return &m 427 | } 428 | 429 | // Gets a schema or a boolean value from an interface{} value if possible. 430 | func (schema *Schema) schemaOrBooleanValue(v *yaml.Node) *SchemaOrBoolean { 431 | schemaOrBoolean := &SchemaOrBoolean{} 432 | switch v.Kind { 433 | case yaml.ScalarNode: 434 | v2, _ := strconv.ParseBool(v.Value) 435 | schemaOrBoolean.Boolean = &v2 436 | case yaml.MappingNode: 437 | schemaOrBoolean.Schema = NewSchemaFromObject(v) 438 | default: 439 | fmt.Printf("schemaOrBooleanValue: unexpected node %+v\n", v) 440 | } 441 | return schemaOrBoolean 442 | } 443 | -------------------------------------------------------------------------------- /jsonschema/schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "http://json-schema.org/draft-04/schema#", 3 | "$schema": "http://json-schema.org/draft-04/schema#", 4 | "description": "Core schema meta-schema", 5 | "definitions": { 6 | "schemaArray": { 7 | "type": "array", 8 | "minItems": 1, 9 | "items": { "$ref": "#" } 10 | }, 11 | "positiveInteger": { 12 | "type": "integer", 13 | "minimum": 0 14 | }, 15 | "positiveIntegerDefault0": { 16 | "allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ] 17 | }, 18 | "simpleTypes": { 19 | "enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ] 20 | }, 21 | "stringArray": { 22 | "type": "array", 23 | "items": { "type": "string" }, 24 | "minItems": 1, 25 | "uniqueItems": true 26 | } 27 | }, 28 | "type": "object", 29 | "properties": { 30 | "id": { 31 | "type": "string", 32 | "format": "uri" 33 | }, 34 | "$schema": { 35 | "type": "string", 36 | "format": "uri" 37 | }, 38 | "title": { 39 | "type": "string" 40 | }, 41 | "description": { 42 | "type": "string" 43 | }, 44 | "default": {}, 45 | "multipleOf": { 46 | "type": "number", 47 | "minimum": 0, 48 | "exclusiveMinimum": true 49 | }, 50 | "maximum": { 51 | "type": "number" 52 | }, 53 | "exclusiveMaximum": { 54 | "type": "boolean", 55 | "default": false 56 | }, 57 | "minimum": { 58 | "type": "number" 59 | }, 60 | "exclusiveMinimum": { 61 | "type": "boolean", 62 | "default": false 63 | }, 64 | "maxLength": { "$ref": "#/definitions/positiveInteger" }, 65 | "minLength": { "$ref": "#/definitions/positiveIntegerDefault0" }, 66 | "pattern": { 67 | "type": "string", 68 | "format": "regex" 69 | }, 70 | "additionalItems": { 71 | "anyOf": [ 72 | { "type": "boolean" }, 73 | { "$ref": "#" } 74 | ], 75 | "default": {} 76 | }, 77 | "items": { 78 | "anyOf": [ 79 | { "$ref": "#" }, 80 | { "$ref": "#/definitions/schemaArray" } 81 | ], 82 | "default": {} 83 | }, 84 | "maxItems": { "$ref": "#/definitions/positiveInteger" }, 85 | "minItems": { "$ref": "#/definitions/positiveIntegerDefault0" }, 86 | "uniqueItems": { 87 | "type": "boolean", 88 | "default": false 89 | }, 90 | "maxProperties": { "$ref": "#/definitions/positiveInteger" }, 91 | "minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" }, 92 | "required": { "$ref": "#/definitions/stringArray" }, 93 | "additionalProperties": { 94 | "anyOf": [ 95 | { "type": "boolean" }, 96 | { "$ref": "#" } 97 | ], 98 | "default": {} 99 | }, 100 | "definitions": { 101 | "type": "object", 102 | "additionalProperties": { "$ref": "#" }, 103 | "default": {} 104 | }, 105 | "properties": { 106 | "type": "object", 107 | "additionalProperties": { "$ref": "#" }, 108 | "default": {} 109 | }, 110 | "patternProperties": { 111 | "type": "object", 112 | "additionalProperties": { "$ref": "#" }, 113 | "default": {} 114 | }, 115 | "dependencies": { 116 | "type": "object", 117 | "additionalProperties": { 118 | "anyOf": [ 119 | { "$ref": "#" }, 120 | { "$ref": "#/definitions/stringArray" } 121 | ] 122 | } 123 | }, 124 | "enum": { 125 | "type": "array", 126 | "minItems": 1, 127 | "uniqueItems": true 128 | }, 129 | "type": { 130 | "anyOf": [ 131 | { "$ref": "#/definitions/simpleTypes" }, 132 | { 133 | "type": "array", 134 | "items": { "$ref": "#/definitions/simpleTypes" }, 135 | "minItems": 1, 136 | "uniqueItems": true 137 | } 138 | ] 139 | }, 140 | "allOf": { "$ref": "#/definitions/schemaArray" }, 141 | "anyOf": { "$ref": "#/definitions/schemaArray" }, 142 | "oneOf": { "$ref": "#/definitions/schemaArray" }, 143 | "not": { "$ref": "#" } 144 | }, 145 | "dependencies": { 146 | "exclusiveMaximum": [ "maximum" ], 147 | "exclusiveMinimum": [ "minimum" ] 148 | }, 149 | "default": {} 150 | } 151 | -------------------------------------------------------------------------------- /jsonschema/writer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package jsonschema 16 | 17 | import ( 18 | "fmt" 19 | 20 | "gopkg.in/yaml.v3" 21 | ) 22 | 23 | const indentation = " " 24 | 25 | func renderMappingNode(node *yaml.Node, indent string) (result string) { 26 | result = "{\n" 27 | innerIndent := indent + indentation 28 | for i := 0; i < len(node.Content); i += 2 { 29 | // first print the key 30 | key := node.Content[i].Value 31 | result += fmt.Sprintf("%s\"%+v\": ", innerIndent, key) 32 | // then the value 33 | value := node.Content[i+1] 34 | switch value.Kind { 35 | case yaml.ScalarNode: 36 | result += "\"" + value.Value + "\"" 37 | case yaml.MappingNode: 38 | result += renderMappingNode(value, innerIndent) 39 | case yaml.SequenceNode: 40 | result += renderSequenceNode(value, innerIndent) 41 | default: 42 | result += fmt.Sprintf("???MapItem(Key:%+v, Value:%T)", value, value) 43 | } 44 | if i < len(node.Content)-2 { 45 | result += "," 46 | } 47 | result += "\n" 48 | } 49 | 50 | result += indent + "}" 51 | return result 52 | } 53 | 54 | func renderSequenceNode(node *yaml.Node, indent string) (result string) { 55 | result = "[\n" 56 | innerIndent := indent + indentation 57 | for i := 0; i < len(node.Content); i++ { 58 | item := node.Content[i] 59 | switch item.Kind { 60 | case yaml.ScalarNode: 61 | result += innerIndent + "\"" + item.Value + "\"" 62 | case yaml.MappingNode: 63 | result += innerIndent + renderMappingNode(item, innerIndent) + "" 64 | default: 65 | result += innerIndent + fmt.Sprintf("???ArrayItem(%+v)", item) 66 | } 67 | if i < len(node.Content)-1 { 68 | result += "," 69 | } 70 | result += "\n" 71 | } 72 | result += indent + "]" 73 | return result 74 | } 75 | 76 | func renderStringArray(array []string, indent string) (result string) { 77 | result = "[\n" 78 | innerIndent := indent + indentation 79 | for i, item := range array { 80 | result += innerIndent + "\"" + item + "\"" 81 | if i < len(array)-1 { 82 | result += "," 83 | } 84 | result += "\n" 85 | } 86 | result += indent + "]" 87 | return result 88 | } 89 | 90 | // Render renders a yaml.Node as JSON 91 | func Render(node *yaml.Node) string { 92 | if node.Kind == yaml.DocumentNode { 93 | if len(node.Content) == 1 { 94 | return Render(node.Content[0]) 95 | } 96 | } else if node.Kind == yaml.MappingNode { 97 | return renderMappingNode(node, "") + "\n" 98 | } else if node.Kind == yaml.SequenceNode { 99 | return renderSequenceNode(node, "") + "\n" 100 | } 101 | return "" 102 | } 103 | 104 | func (object *SchemaNumber) nodeValue() *yaml.Node { 105 | if object.Integer != nil { 106 | return nodeForInt64(*object.Integer) 107 | } else if object.Float != nil { 108 | return nodeForFloat64(*object.Float) 109 | } else { 110 | return nil 111 | } 112 | } 113 | 114 | func (object *SchemaOrBoolean) nodeValue() *yaml.Node { 115 | if object.Schema != nil { 116 | return object.Schema.nodeValue() 117 | } else if object.Boolean != nil { 118 | return nodeForBoolean(*object.Boolean) 119 | } else { 120 | return nil 121 | } 122 | } 123 | 124 | func nodeForStringArray(array []string) *yaml.Node { 125 | content := make([]*yaml.Node, 0) 126 | for _, item := range array { 127 | content = append(content, nodeForString(item)) 128 | } 129 | return nodeForSequence(content) 130 | } 131 | 132 | func nodeForSchemaArray(array []*Schema) *yaml.Node { 133 | content := make([]*yaml.Node, 0) 134 | for _, item := range array { 135 | content = append(content, item.nodeValue()) 136 | } 137 | return nodeForSequence(content) 138 | } 139 | 140 | func (object *StringOrStringArray) nodeValue() *yaml.Node { 141 | if object.String != nil { 142 | return nodeForString(*object.String) 143 | } else if object.StringArray != nil { 144 | return nodeForStringArray(*(object.StringArray)) 145 | } else { 146 | return nil 147 | } 148 | } 149 | 150 | func (object *SchemaOrStringArray) nodeValue() *yaml.Node { 151 | if object.Schema != nil { 152 | return object.Schema.nodeValue() 153 | } else if object.StringArray != nil { 154 | return nodeForStringArray(*(object.StringArray)) 155 | } else { 156 | return nil 157 | } 158 | } 159 | 160 | func (object *SchemaOrSchemaArray) nodeValue() *yaml.Node { 161 | if object.Schema != nil { 162 | return object.Schema.nodeValue() 163 | } else if object.SchemaArray != nil { 164 | return nodeForSchemaArray(*(object.SchemaArray)) 165 | } else { 166 | return nil 167 | } 168 | } 169 | 170 | func (object *SchemaEnumValue) nodeValue() *yaml.Node { 171 | if object.String != nil { 172 | return nodeForString(*object.String) 173 | } else if object.Bool != nil { 174 | return nodeForBoolean(*object.Bool) 175 | } else { 176 | return nil 177 | } 178 | } 179 | 180 | func nodeForNamedSchemaArray(array *[]*NamedSchema) *yaml.Node { 181 | content := make([]*yaml.Node, 0) 182 | for _, pair := range *(array) { 183 | content = appendPair(content, pair.Name, pair.Value.nodeValue()) 184 | } 185 | return nodeForMapping(content) 186 | } 187 | 188 | func nodeForNamedSchemaOrStringArray(array *[]*NamedSchemaOrStringArray) *yaml.Node { 189 | content := make([]*yaml.Node, 0) 190 | for _, pair := range *(array) { 191 | content = appendPair(content, pair.Name, pair.Value.nodeValue()) 192 | } 193 | return nodeForMapping(content) 194 | } 195 | 196 | func nodeForSchemaEnumArray(array *[]SchemaEnumValue) *yaml.Node { 197 | content := make([]*yaml.Node, 0) 198 | for _, item := range *array { 199 | content = append(content, item.nodeValue()) 200 | } 201 | return nodeForSequence(content) 202 | } 203 | 204 | func nodeForMapping(content []*yaml.Node) *yaml.Node { 205 | return &yaml.Node{ 206 | Kind: yaml.MappingNode, 207 | Content: content, 208 | } 209 | } 210 | 211 | func nodeForSequence(content []*yaml.Node) *yaml.Node { 212 | return &yaml.Node{ 213 | Kind: yaml.SequenceNode, 214 | Content: content, 215 | } 216 | } 217 | 218 | func nodeForString(value string) *yaml.Node { 219 | return &yaml.Node{ 220 | Kind: yaml.ScalarNode, 221 | Tag: "!!str", 222 | Value: value, 223 | } 224 | } 225 | 226 | func nodeForBoolean(value bool) *yaml.Node { 227 | return &yaml.Node{ 228 | Kind: yaml.ScalarNode, 229 | Tag: "!!bool", 230 | Value: fmt.Sprintf("%t", value), 231 | } 232 | } 233 | 234 | func nodeForInt64(value int64) *yaml.Node { 235 | return &yaml.Node{ 236 | Kind: yaml.ScalarNode, 237 | Tag: "!!int", 238 | Value: fmt.Sprintf("%d", value), 239 | } 240 | } 241 | 242 | func nodeForFloat64(value float64) *yaml.Node { 243 | return &yaml.Node{ 244 | Kind: yaml.ScalarNode, 245 | Tag: "!!float", 246 | Value: fmt.Sprintf("%f", value), 247 | } 248 | } 249 | 250 | func appendPair(nodes []*yaml.Node, name string, value *yaml.Node) []*yaml.Node { 251 | nodes = append(nodes, nodeForString(name)) 252 | nodes = append(nodes, value) 253 | return nodes 254 | } 255 | 256 | func (schema *Schema) nodeValue() *yaml.Node { 257 | n := &yaml.Node{Kind: yaml.MappingNode} 258 | content := make([]*yaml.Node, 0) 259 | if schema.Title != nil { 260 | content = appendPair(content, "title", nodeForString(*schema.Title)) 261 | } 262 | if schema.ID != nil { 263 | content = appendPair(content, "id", nodeForString(*schema.ID)) 264 | } 265 | if schema.Schema != nil { 266 | content = appendPair(content, "$schema", nodeForString(*schema.Schema)) 267 | } 268 | if schema.Type != nil { 269 | content = appendPair(content, "type", schema.Type.nodeValue()) 270 | } 271 | if schema.Items != nil { 272 | content = appendPair(content, "items", schema.Items.nodeValue()) 273 | } 274 | if schema.Description != nil { 275 | content = appendPair(content, "description", nodeForString(*schema.Description)) 276 | } 277 | if schema.Required != nil { 278 | content = appendPair(content, "required", nodeForStringArray(*schema.Required)) 279 | } 280 | if schema.AdditionalProperties != nil { 281 | content = appendPair(content, "additionalProperties", schema.AdditionalProperties.nodeValue()) 282 | } 283 | if schema.PatternProperties != nil { 284 | content = appendPair(content, "patternProperties", nodeForNamedSchemaArray(schema.PatternProperties)) 285 | } 286 | if schema.Properties != nil { 287 | content = appendPair(content, "properties", nodeForNamedSchemaArray(schema.Properties)) 288 | } 289 | if schema.Dependencies != nil { 290 | content = appendPair(content, "dependencies", nodeForNamedSchemaOrStringArray(schema.Dependencies)) 291 | } 292 | if schema.Ref != nil { 293 | content = appendPair(content, "$ref", nodeForString(*schema.Ref)) 294 | } 295 | if schema.MultipleOf != nil { 296 | content = appendPair(content, "multipleOf", schema.MultipleOf.nodeValue()) 297 | } 298 | if schema.Maximum != nil { 299 | content = appendPair(content, "maximum", schema.Maximum.nodeValue()) 300 | } 301 | if schema.ExclusiveMaximum != nil { 302 | content = appendPair(content, "exclusiveMaximum", nodeForBoolean(*schema.ExclusiveMaximum)) 303 | } 304 | if schema.Minimum != nil { 305 | content = appendPair(content, "minimum", schema.Minimum.nodeValue()) 306 | } 307 | if schema.ExclusiveMinimum != nil { 308 | content = appendPair(content, "exclusiveMinimum", nodeForBoolean(*schema.ExclusiveMinimum)) 309 | } 310 | if schema.MaxLength != nil { 311 | content = appendPair(content, "maxLength", nodeForInt64(*schema.MaxLength)) 312 | } 313 | if schema.MinLength != nil { 314 | content = appendPair(content, "minLength", nodeForInt64(*schema.MinLength)) 315 | } 316 | if schema.Pattern != nil { 317 | content = appendPair(content, "pattern", nodeForString(*schema.Pattern)) 318 | } 319 | if schema.AdditionalItems != nil { 320 | content = appendPair(content, "additionalItems", schema.AdditionalItems.nodeValue()) 321 | } 322 | if schema.MaxItems != nil { 323 | content = appendPair(content, "maxItems", nodeForInt64(*schema.MaxItems)) 324 | } 325 | if schema.MinItems != nil { 326 | content = appendPair(content, "minItems", nodeForInt64(*schema.MinItems)) 327 | } 328 | if schema.UniqueItems != nil { 329 | content = appendPair(content, "uniqueItems", nodeForBoolean(*schema.UniqueItems)) 330 | } 331 | if schema.MaxProperties != nil { 332 | content = appendPair(content, "maxProperties", nodeForInt64(*schema.MaxProperties)) 333 | } 334 | if schema.MinProperties != nil { 335 | content = appendPair(content, "minProperties", nodeForInt64(*schema.MinProperties)) 336 | } 337 | if schema.Enumeration != nil { 338 | content = appendPair(content, "enum", nodeForSchemaEnumArray(schema.Enumeration)) 339 | } 340 | if schema.AllOf != nil { 341 | content = appendPair(content, "allOf", nodeForSchemaArray(*schema.AllOf)) 342 | } 343 | if schema.AnyOf != nil { 344 | content = appendPair(content, "anyOf", nodeForSchemaArray(*schema.AnyOf)) 345 | } 346 | if schema.OneOf != nil { 347 | content = appendPair(content, "oneOf", nodeForSchemaArray(*schema.OneOf)) 348 | } 349 | if schema.Not != nil { 350 | content = appendPair(content, "not", schema.Not.nodeValue()) 351 | } 352 | if schema.Definitions != nil { 353 | content = appendPair(content, "definitions", nodeForNamedSchemaArray(schema.Definitions)) 354 | } 355 | if schema.Default != nil { 356 | // m = append(m, yaml.MapItem{Key: "default", Value: *schema.Default}) 357 | } 358 | if schema.Format != nil { 359 | content = appendPair(content, "format", nodeForString(*schema.Format)) 360 | } 361 | n.Content = content 362 | return n 363 | } 364 | 365 | // JSONString returns a json representation of a schema. 366 | func (schema *Schema) JSONString() string { 367 | node := schema.nodeValue() 368 | return Render(node) 369 | } 370 | -------------------------------------------------------------------------------- /openapiv2/README.md: -------------------------------------------------------------------------------- 1 | # OpenAPI v2 Protocol Buffer Models 2 | 3 | This directory contains a Protocol Buffer-language model and related code for 4 | supporting OpenAPI v2. 5 | 6 | Gnostic applications and plugins can use OpenAPIv2.proto to generate Protocol 7 | Buffer support code for their preferred languages. 8 | 9 | OpenAPIv2.go is used by Gnostic to read JSON and YAML OpenAPI descriptions into 10 | the Protocol Buffer-based datastructures generated from OpenAPIv2.proto. 11 | 12 | OpenAPIv2.proto and OpenAPIv2.go are generated by the Gnostic compiler 13 | generator, and OpenAPIv2.pb.go is generated by protoc, the Protocol Buffer 14 | compiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin. 15 | -------------------------------------------------------------------------------- /openapiv2/document.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package openapi_v2 16 | 17 | import ( 18 | "gopkg.in/yaml.v3" 19 | 20 | "github.com/google/gnostic-models/compiler" 21 | ) 22 | 23 | // ParseDocument reads an OpenAPI v2 description from a YAML/JSON representation. 24 | func ParseDocument(b []byte) (*Document, error) { 25 | info, err := compiler.ReadInfoFromBytes("", b) 26 | if err != nil { 27 | return nil, err 28 | } 29 | root := info.Content[0] 30 | return NewDocument(root, compiler.NewContextWithExtensions("$root", root, nil, nil)) 31 | } 32 | 33 | // YAMLValue produces a serialized YAML representation of the document. 34 | func (d *Document) YAMLValue(comment string) ([]byte, error) { 35 | rawInfo := d.ToRawInfo() 36 | rawInfo = &yaml.Node{ 37 | Kind: yaml.DocumentNode, 38 | Content: []*yaml.Node{rawInfo}, 39 | HeadComment: comment, 40 | } 41 | return yaml.Marshal(rawInfo) 42 | } 43 | -------------------------------------------------------------------------------- /openapiv3/README.md: -------------------------------------------------------------------------------- 1 | # OpenAPI v3 Protocol Buffer Models 2 | 3 | This directory contains a Protocol Buffer-language model and related code for 4 | supporting OpenAPI v3. 5 | 6 | Gnostic applications and plugins can use OpenAPIv3.proto to generate Protocol 7 | Buffer support code for their preferred languages. 8 | 9 | OpenAPIv3.go is used by Gnostic to read JSON and YAML OpenAPI descriptions into 10 | the Protocol Buffer-based datastructures generated from OpenAPIv3.proto. 11 | 12 | OpenAPIv3.proto and OpenAPIv3.go are generated by the Gnostic compiler 13 | generator, and OpenAPIv3.pb.go is generated by protoc, the Protocol Buffer 14 | compiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin. 15 | 16 | openapi-3.1.json is a JSON schema for OpenAPI 3.1 that is automatically 17 | generated from the OpenAPI 3.1 specification. It is not an official JSON Schema 18 | for OpenAPI. 19 | 20 | The schema-generator directory contains support code which generates 21 | openapi-3.1.json from the OpenAPI 3.1 specification document (Markdown). 22 | -------------------------------------------------------------------------------- /openapiv3/annotations.pb.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Code generated by protoc-gen-go. DO NOT EDIT. 16 | // versions: 17 | // protoc-gen-go v1.35.1 18 | // protoc v4.23.4 19 | // source: openapiv3/annotations.proto 20 | 21 | package openapi_v3 22 | 23 | import ( 24 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 25 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 26 | descriptorpb "google.golang.org/protobuf/types/descriptorpb" 27 | reflect "reflect" 28 | ) 29 | 30 | const ( 31 | // Verify that this generated code is sufficiently up-to-date. 32 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 33 | // Verify that runtime/protoimpl is sufficiently up-to-date. 34 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 35 | ) 36 | 37 | var file_openapiv3_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ 38 | { 39 | ExtendedType: (*descriptorpb.FileOptions)(nil), 40 | ExtensionType: (*Document)(nil), 41 | Field: 1143, 42 | Name: "openapi.v3.document", 43 | Tag: "bytes,1143,opt,name=document", 44 | Filename: "openapiv3/annotations.proto", 45 | }, 46 | { 47 | ExtendedType: (*descriptorpb.MethodOptions)(nil), 48 | ExtensionType: (*Operation)(nil), 49 | Field: 1143, 50 | Name: "openapi.v3.operation", 51 | Tag: "bytes,1143,opt,name=operation", 52 | Filename: "openapiv3/annotations.proto", 53 | }, 54 | { 55 | ExtendedType: (*descriptorpb.MessageOptions)(nil), 56 | ExtensionType: (*Schema)(nil), 57 | Field: 1143, 58 | Name: "openapi.v3.schema", 59 | Tag: "bytes,1143,opt,name=schema", 60 | Filename: "openapiv3/annotations.proto", 61 | }, 62 | { 63 | ExtendedType: (*descriptorpb.FieldOptions)(nil), 64 | ExtensionType: (*Schema)(nil), 65 | Field: 1143, 66 | Name: "openapi.v3.property", 67 | Tag: "bytes,1143,opt,name=property", 68 | Filename: "openapiv3/annotations.proto", 69 | }, 70 | } 71 | 72 | // Extension fields to descriptorpb.FileOptions. 73 | var ( 74 | // optional openapi.v3.Document document = 1143; 75 | E_Document = &file_openapiv3_annotations_proto_extTypes[0] 76 | ) 77 | 78 | // Extension fields to descriptorpb.MethodOptions. 79 | var ( 80 | // optional openapi.v3.Operation operation = 1143; 81 | E_Operation = &file_openapiv3_annotations_proto_extTypes[1] 82 | ) 83 | 84 | // Extension fields to descriptorpb.MessageOptions. 85 | var ( 86 | // optional openapi.v3.Schema schema = 1143; 87 | E_Schema = &file_openapiv3_annotations_proto_extTypes[2] 88 | ) 89 | 90 | // Extension fields to descriptorpb.FieldOptions. 91 | var ( 92 | // optional openapi.v3.Schema property = 1143; 93 | E_Property = &file_openapiv3_annotations_proto_extTypes[3] 94 | ) 95 | 96 | var File_openapiv3_annotations_proto protoreflect.FileDescriptor 97 | 98 | var file_openapiv3_annotations_proto_rawDesc = []byte{ 99 | 0x0a, 0x1b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 100 | 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, 101 | 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 102 | 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 103 | 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x6f, 0x70, 0x65, 104 | 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x76, 0x33, 105 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x4f, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 106 | 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 107 | 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 108 | 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 109 | 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x64, 110 | 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x54, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 111 | 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 112 | 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 113 | 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 114 | 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 115 | 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x4c, 0x0a, 116 | 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 117 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 118 | 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 119 | 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 120 | 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x3a, 0x4e, 0x0a, 0x08, 0x70, 121 | 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 122 | 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 123 | 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xf7, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 124 | 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 125 | 0x61, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x42, 0x42, 0x0a, 0x0e, 0x6f, 126 | 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0x42, 0x10, 0x41, 127 | 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 128 | 0x01, 0x5a, 0x16, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 129 | 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 130 | 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 131 | } 132 | 133 | var file_openapiv3_annotations_proto_goTypes = []any{ 134 | (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions 135 | (*descriptorpb.MethodOptions)(nil), // 1: google.protobuf.MethodOptions 136 | (*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions 137 | (*descriptorpb.FieldOptions)(nil), // 3: google.protobuf.FieldOptions 138 | (*Document)(nil), // 4: openapi.v3.Document 139 | (*Operation)(nil), // 5: openapi.v3.Operation 140 | (*Schema)(nil), // 6: openapi.v3.Schema 141 | } 142 | var file_openapiv3_annotations_proto_depIdxs = []int32{ 143 | 0, // 0: openapi.v3.document:extendee -> google.protobuf.FileOptions 144 | 1, // 1: openapi.v3.operation:extendee -> google.protobuf.MethodOptions 145 | 2, // 2: openapi.v3.schema:extendee -> google.protobuf.MessageOptions 146 | 3, // 3: openapi.v3.property:extendee -> google.protobuf.FieldOptions 147 | 4, // 4: openapi.v3.document:type_name -> openapi.v3.Document 148 | 5, // 5: openapi.v3.operation:type_name -> openapi.v3.Operation 149 | 6, // 6: openapi.v3.schema:type_name -> openapi.v3.Schema 150 | 6, // 7: openapi.v3.property:type_name -> openapi.v3.Schema 151 | 8, // [8:8] is the sub-list for method output_type 152 | 8, // [8:8] is the sub-list for method input_type 153 | 4, // [4:8] is the sub-list for extension type_name 154 | 0, // [0:4] is the sub-list for extension extendee 155 | 0, // [0:0] is the sub-list for field type_name 156 | } 157 | 158 | func init() { file_openapiv3_annotations_proto_init() } 159 | func file_openapiv3_annotations_proto_init() { 160 | if File_openapiv3_annotations_proto != nil { 161 | return 162 | } 163 | file_openapiv3_OpenAPIv3_proto_init() 164 | type x struct{} 165 | out := protoimpl.TypeBuilder{ 166 | File: protoimpl.DescBuilder{ 167 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 168 | RawDescriptor: file_openapiv3_annotations_proto_rawDesc, 169 | NumEnums: 0, 170 | NumMessages: 0, 171 | NumExtensions: 4, 172 | NumServices: 0, 173 | }, 174 | GoTypes: file_openapiv3_annotations_proto_goTypes, 175 | DependencyIndexes: file_openapiv3_annotations_proto_depIdxs, 176 | ExtensionInfos: file_openapiv3_annotations_proto_extTypes, 177 | }.Build() 178 | File_openapiv3_annotations_proto = out.File 179 | file_openapiv3_annotations_proto_rawDesc = nil 180 | file_openapiv3_annotations_proto_goTypes = nil 181 | file_openapiv3_annotations_proto_depIdxs = nil 182 | } 183 | -------------------------------------------------------------------------------- /openapiv3/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package openapi.v3; 18 | 19 | import "google/protobuf/descriptor.proto"; 20 | import "openapiv3/OpenAPIv3.proto"; 21 | 22 | // The Go package name. 23 | option go_package = "./openapiv3;openapi_v3"; 24 | // This option lets the proto compiler generate Java code inside the package 25 | // name (see below) instead of inside an outer class. It creates a simpler 26 | // developer experience by reducing one-level of name nesting and be 27 | // consistent with most programming languages that don't support outer classes. 28 | option java_multiple_files = true; 29 | // The Java outer classname should be the filename in UpperCamelCase. This 30 | // class is only used to hold proto descriptor, so developers don't need to 31 | // work with it directly. 32 | option java_outer_classname = "AnnotationsProto"; 33 | // The Java package name must be proto package name with proper prefix. 34 | option java_package = "org.openapi_v3"; 35 | // A reasonable prefix for the Objective-C symbols generated from the package. 36 | // It should at a minimum be 3 characters long, all uppercase, and convention 37 | // is to use an abbreviation of the package name. Something short, but 38 | // hopefully unique enough to not conflict with things that may come along in 39 | // the future. 'GPB' is reserved for the protocol buffer implementation itself. 40 | option objc_class_prefix = "OAS"; 41 | 42 | extend google.protobuf.FileOptions { 43 | Document document = 1143; 44 | } 45 | 46 | extend google.protobuf.MethodOptions { 47 | Operation operation = 1143; 48 | } 49 | 50 | extend google.protobuf.MessageOptions { 51 | Schema schema = 1143; 52 | } 53 | 54 | extend google.protobuf.FieldOptions { 55 | Schema property = 1143; 56 | } 57 | -------------------------------------------------------------------------------- /openapiv3/document.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package openapi_v3 16 | 17 | import ( 18 | "gopkg.in/yaml.v3" 19 | 20 | "github.com/google/gnostic-models/compiler" 21 | ) 22 | 23 | // ParseDocument reads an OpenAPI v3 description from a YAML/JSON representation. 24 | func ParseDocument(b []byte) (*Document, error) { 25 | info, err := compiler.ReadInfoFromBytes("", b) 26 | if err != nil { 27 | return nil, err 28 | } 29 | root := info.Content[0] 30 | return NewDocument(root, compiler.NewContextWithExtensions("$root", root, nil, nil)) 31 | } 32 | 33 | // YAMLValue produces a serialized YAML representation of the document. 34 | func (d *Document) YAMLValue(comment string) ([]byte, error) { 35 | rawInfo := d.ToRawInfo() 36 | rawInfo = &yaml.Node{ 37 | Kind: yaml.DocumentNode, 38 | Content: []*yaml.Node{rawInfo}, 39 | HeadComment: comment, 40 | } 41 | return yaml.Marshal(rawInfo) 42 | } 43 | -------------------------------------------------------------------------------- /third_party/google/api/httpbody.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/protobuf/any.proto"; 20 | 21 | option cc_enable_arenas = true; 22 | option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "HttpBodyProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | // Message that represents an arbitrary HTTP body. It should only be used for 29 | // payload formats that can't be represented as JSON, such as raw binary or 30 | // an HTML page. 31 | // 32 | // 33 | // This message can be used both in streaming and non-streaming API methods in 34 | // the request as well as the response. 35 | // 36 | // It can be used as a top-level request field, which is convenient if one 37 | // wants to extract parameters from either the URL or HTTP template into the 38 | // request fields and also want access to the raw HTTP body. 39 | // 40 | // Example: 41 | // 42 | // message GetResourceRequest { 43 | // // A unique request id. 44 | // string request_id = 1; 45 | // 46 | // // The raw HTTP body is bound to this field. 47 | // google.api.HttpBody http_body = 2; 48 | // 49 | // } 50 | // 51 | // service ResourceService { 52 | // rpc GetResource(GetResourceRequest) 53 | // returns (google.api.HttpBody); 54 | // rpc UpdateResource(google.api.HttpBody) 55 | // returns (google.protobuf.Empty); 56 | // 57 | // } 58 | // 59 | // Example with streaming methods: 60 | // 61 | // service CaldavService { 62 | // rpc GetCalendar(stream google.api.HttpBody) 63 | // returns (stream google.api.HttpBody); 64 | // rpc UpdateCalendar(stream google.api.HttpBody) 65 | // returns (stream google.api.HttpBody); 66 | // 67 | // } 68 | // 69 | // Use of this type only changes how the request and response bodies are 70 | // handled, all other features will continue to work unchanged. 71 | message HttpBody { 72 | // The HTTP Content-Type header value specifying the content type of the body. 73 | string content_type = 1; 74 | 75 | // The HTTP request/response body as raw binary. 76 | bytes data = 2; 77 | 78 | // Application specific response metadata. Must be set in the first response 79 | // for streaming APIs. 80 | repeated google.protobuf.Any extensions = 3; 81 | } 82 | -------------------------------------------------------------------------------- /third_party/google/protobuf/any.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "google.golang.org/protobuf/types/known/anypb"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "AnyProto"; 39 | option java_multiple_files = true; 40 | option objc_class_prefix = "GPB"; 41 | 42 | // `Any` contains an arbitrary serialized protocol buffer message along with a 43 | // URL that describes the type of the serialized message. 44 | // 45 | // Protobuf library provides support to pack/unpack Any values in the form 46 | // of utility functions or additional generated methods of the Any type. 47 | // 48 | // Example 1: Pack and unpack a message in C++. 49 | // 50 | // Foo foo = ...; 51 | // Any any; 52 | // any.PackFrom(foo); 53 | // ... 54 | // if (any.UnpackTo(&foo)) { 55 | // ... 56 | // } 57 | // 58 | // Example 2: Pack and unpack a message in Java. 59 | // 60 | // Foo foo = ...; 61 | // Any any = Any.pack(foo); 62 | // ... 63 | // if (any.is(Foo.class)) { 64 | // foo = any.unpack(Foo.class); 65 | // } 66 | // 67 | // Example 3: Pack and unpack a message in Python. 68 | // 69 | // foo = Foo(...) 70 | // any = Any() 71 | // any.Pack(foo) 72 | // ... 73 | // if any.Is(Foo.DESCRIPTOR): 74 | // any.Unpack(foo) 75 | // ... 76 | // 77 | // Example 4: Pack and unpack a message in Go 78 | // 79 | // foo := &pb.Foo{...} 80 | // any, err := anypb.New(foo) 81 | // if err != nil { 82 | // ... 83 | // } 84 | // ... 85 | // foo := &pb.Foo{} 86 | // if err := any.UnmarshalTo(foo); err != nil { 87 | // ... 88 | // } 89 | // 90 | // The pack methods provided by protobuf library will by default use 91 | // 'type.googleapis.com/full.type.name' as the type URL and the unpack 92 | // methods only use the fully qualified type name after the last '/' 93 | // in the type URL, for example "foo.bar.com/x/y.z" will yield type 94 | // name "y.z". 95 | // 96 | // 97 | // JSON 98 | // ==== 99 | // The JSON representation of an `Any` value uses the regular 100 | // representation of the deserialized, embedded message, with an 101 | // additional field `@type` which contains the type URL. Example: 102 | // 103 | // package google.profile; 104 | // message Person { 105 | // string first_name = 1; 106 | // string last_name = 2; 107 | // } 108 | // 109 | // { 110 | // "@type": "type.googleapis.com/google.profile.Person", 111 | // "firstName": , 112 | // "lastName": 113 | // } 114 | // 115 | // If the embedded message type is well-known and has a custom JSON 116 | // representation, that representation will be embedded adding a field 117 | // `value` which holds the custom JSON in addition to the `@type` 118 | // field. Example (for message [google.protobuf.Duration][]): 119 | // 120 | // { 121 | // "@type": "type.googleapis.com/google.protobuf.Duration", 122 | // "value": "1.212s" 123 | // } 124 | // 125 | message Any { 126 | // A URL/resource name that uniquely identifies the type of the serialized 127 | // protocol buffer message. This string must contain at least 128 | // one "/" character. The last segment of the URL's path must represent 129 | // the fully qualified name of the type (as in 130 | // `path/google.protobuf.Duration`). The name should be in a canonical form 131 | // (e.g., leading "." is not accepted). 132 | // 133 | // In practice, teams usually precompile into the binary all types that they 134 | // expect it to use in the context of Any. However, for URLs which use the 135 | // scheme `http`, `https`, or no scheme, one can optionally set up a type 136 | // server that maps type URLs to message definitions as follows: 137 | // 138 | // * If no scheme is provided, `https` is assumed. 139 | // * An HTTP GET on the URL must yield a [google.protobuf.Type][] 140 | // value in binary format, or produce an error. 141 | // * Applications are allowed to cache lookup results based on the 142 | // URL, or have them precompiled into a binary to avoid any 143 | // lookup. Therefore, binary compatibility needs to be preserved 144 | // on changes to types. (Use versioned type names to manage 145 | // breaking changes.) 146 | // 147 | // Note: this functionality is not currently available in the official 148 | // protobuf release, and it is not used for type URLs beginning with 149 | // type.googleapis.com. 150 | // 151 | // Schemes other than `http`, `https` (or the empty scheme) might be 152 | // used with implementation specific semantics. 153 | // 154 | string type_url = 1; 155 | 156 | // Must be a valid serialized protocol buffer of the above specified type. 157 | bytes value = 2; 158 | } 159 | -------------------------------------------------------------------------------- /third_party/google/protobuf/api.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | import "google/protobuf/source_context.proto"; 36 | import "google/protobuf/type.proto"; 37 | 38 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 39 | option java_package = "com.google.protobuf"; 40 | option java_outer_classname = "ApiProto"; 41 | option java_multiple_files = true; 42 | option objc_class_prefix = "GPB"; 43 | option go_package = "google.golang.org/protobuf/types/known/apipb"; 44 | 45 | // Api is a light-weight descriptor for an API Interface. 46 | // 47 | // Interfaces are also described as "protocol buffer services" in some contexts, 48 | // such as by the "service" keyword in a .proto file, but they are different 49 | // from API Services, which represent a concrete implementation of an interface 50 | // as opposed to simply a description of methods and bindings. They are also 51 | // sometimes simply referred to as "APIs" in other contexts, such as the name of 52 | // this message itself. See https://cloud.google.com/apis/design/glossary for 53 | // detailed terminology. 54 | message Api { 55 | // The fully qualified name of this interface, including package name 56 | // followed by the interface's simple name. 57 | string name = 1; 58 | 59 | // The methods of this interface, in unspecified order. 60 | repeated Method methods = 2; 61 | 62 | // Any metadata attached to the interface. 63 | repeated Option options = 3; 64 | 65 | // A version string for this interface. If specified, must have the form 66 | // `major-version.minor-version`, as in `1.10`. If the minor version is 67 | // omitted, it defaults to zero. If the entire version field is empty, the 68 | // major version is derived from the package name, as outlined below. If the 69 | // field is not empty, the version in the package name will be verified to be 70 | // consistent with what is provided here. 71 | // 72 | // The versioning schema uses [semantic 73 | // versioning](http://semver.org) where the major version number 74 | // indicates a breaking change and the minor version an additive, 75 | // non-breaking change. Both version numbers are signals to users 76 | // what to expect from different versions, and should be carefully 77 | // chosen based on the product plan. 78 | // 79 | // The major version is also reflected in the package name of the 80 | // interface, which must end in `v`, as in 81 | // `google.feature.v1`. For major versions 0 and 1, the suffix can 82 | // be omitted. Zero major versions must only be used for 83 | // experimental, non-GA interfaces. 84 | // 85 | // 86 | string version = 4; 87 | 88 | // Source context for the protocol buffer service represented by this 89 | // message. 90 | SourceContext source_context = 5; 91 | 92 | // Included interfaces. See [Mixin][]. 93 | repeated Mixin mixins = 6; 94 | 95 | // The source syntax of the service. 96 | Syntax syntax = 7; 97 | } 98 | 99 | // Method represents a method of an API interface. 100 | message Method { 101 | // The simple name of this method. 102 | string name = 1; 103 | 104 | // A URL of the input message type. 105 | string request_type_url = 2; 106 | 107 | // If true, the request is streamed. 108 | bool request_streaming = 3; 109 | 110 | // The URL of the output message type. 111 | string response_type_url = 4; 112 | 113 | // If true, the response is streamed. 114 | bool response_streaming = 5; 115 | 116 | // Any metadata attached to the method. 117 | repeated Option options = 6; 118 | 119 | // The source syntax of this method. 120 | Syntax syntax = 7; 121 | } 122 | 123 | // Declares an API Interface to be included in this interface. The including 124 | // interface must redeclare all the methods from the included interface, but 125 | // documentation and options are inherited as follows: 126 | // 127 | // - If after comment and whitespace stripping, the documentation 128 | // string of the redeclared method is empty, it will be inherited 129 | // from the original method. 130 | // 131 | // - Each annotation belonging to the service config (http, 132 | // visibility) which is not set in the redeclared method will be 133 | // inherited. 134 | // 135 | // - If an http annotation is inherited, the path pattern will be 136 | // modified as follows. Any version prefix will be replaced by the 137 | // version of the including interface plus the [root][] path if 138 | // specified. 139 | // 140 | // Example of a simple mixin: 141 | // 142 | // package google.acl.v1; 143 | // service AccessControl { 144 | // // Get the underlying ACL object. 145 | // rpc GetAcl(GetAclRequest) returns (Acl) { 146 | // option (google.api.http).get = "/v1/{resource=**}:getAcl"; 147 | // } 148 | // } 149 | // 150 | // package google.storage.v2; 151 | // service Storage { 152 | // rpc GetAcl(GetAclRequest) returns (Acl); 153 | // 154 | // // Get a data record. 155 | // rpc GetData(GetDataRequest) returns (Data) { 156 | // option (google.api.http).get = "/v2/{resource=**}"; 157 | // } 158 | // } 159 | // 160 | // Example of a mixin configuration: 161 | // 162 | // apis: 163 | // - name: google.storage.v2.Storage 164 | // mixins: 165 | // - name: google.acl.v1.AccessControl 166 | // 167 | // The mixin construct implies that all methods in `AccessControl` are 168 | // also declared with same name and request/response types in 169 | // `Storage`. A documentation generator or annotation processor will 170 | // see the effective `Storage.GetAcl` method after inheriting 171 | // documentation and annotations as follows: 172 | // 173 | // service Storage { 174 | // // Get the underlying ACL object. 175 | // rpc GetAcl(GetAclRequest) returns (Acl) { 176 | // option (google.api.http).get = "/v2/{resource=**}:getAcl"; 177 | // } 178 | // ... 179 | // } 180 | // 181 | // Note how the version in the path pattern changed from `v1` to `v2`. 182 | // 183 | // If the `root` field in the mixin is specified, it should be a 184 | // relative path under which inherited HTTP paths are placed. Example: 185 | // 186 | // apis: 187 | // - name: google.storage.v2.Storage 188 | // mixins: 189 | // - name: google.acl.v1.AccessControl 190 | // root: acls 191 | // 192 | // This implies the following inherited HTTP annotation: 193 | // 194 | // service Storage { 195 | // // Get the underlying ACL object. 196 | // rpc GetAcl(GetAclRequest) returns (Acl) { 197 | // option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; 198 | // } 199 | // ... 200 | // } 201 | message Mixin { 202 | // The fully qualified name of the interface which is included. 203 | string name = 1; 204 | 205 | // If non-empty specifies a path under which inherited HTTP paths 206 | // are rooted. 207 | string root = 2; 208 | } 209 | -------------------------------------------------------------------------------- /third_party/google/protobuf/compiler/plugin.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // 33 | // WARNING: The plugin interface is currently EXPERIMENTAL and is subject to 34 | // change. 35 | // 36 | // protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is 37 | // just a program that reads a CodeGeneratorRequest from stdin and writes a 38 | // CodeGeneratorResponse to stdout. 39 | // 40 | // Plugins written using C++ can use google/protobuf/compiler/plugin.h instead 41 | // of dealing with the raw protocol defined here. 42 | // 43 | // A plugin executable needs only to be placed somewhere in the path. The 44 | // plugin should be named "protoc-gen-$NAME", and will then be used when the 45 | // flag "--${NAME}_out" is passed to protoc. 46 | 47 | syntax = "proto2"; 48 | 49 | package google.protobuf.compiler; 50 | option java_package = "com.google.protobuf.compiler"; 51 | option java_outer_classname = "PluginProtos"; 52 | 53 | option go_package = "google.golang.org/protobuf/types/pluginpb"; 54 | 55 | import "google/protobuf/descriptor.proto"; 56 | 57 | // The version number of protocol compiler. 58 | message Version { 59 | optional int32 major = 1; 60 | optional int32 minor = 2; 61 | optional int32 patch = 3; 62 | // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should 63 | // be empty for mainline stable releases. 64 | optional string suffix = 4; 65 | } 66 | 67 | // An encoded CodeGeneratorRequest is written to the plugin's stdin. 68 | message CodeGeneratorRequest { 69 | // The .proto files that were explicitly listed on the command-line. The 70 | // code generator should generate code only for these files. Each file's 71 | // descriptor will be included in proto_file, below. 72 | repeated string file_to_generate = 1; 73 | 74 | // The generator parameter passed on the command-line. 75 | optional string parameter = 2; 76 | 77 | // FileDescriptorProtos for all files in files_to_generate and everything 78 | // they import. The files will appear in topological order, so each file 79 | // appears before any file that imports it. 80 | // 81 | // protoc guarantees that all proto_files will be written after 82 | // the fields above, even though this is not technically guaranteed by the 83 | // protobuf wire format. This theoretically could allow a plugin to stream 84 | // in the FileDescriptorProtos and handle them one by one rather than read 85 | // the entire set into memory at once. However, as of this writing, this 86 | // is not similarly optimized on protoc's end -- it will store all fields in 87 | // memory at once before sending them to the plugin. 88 | // 89 | // Type names of fields and extensions in the FileDescriptorProto are always 90 | // fully qualified. 91 | repeated FileDescriptorProto proto_file = 15; 92 | 93 | // The version number of protocol compiler. 94 | optional Version compiler_version = 3; 95 | 96 | } 97 | 98 | // The plugin writes an encoded CodeGeneratorResponse to stdout. 99 | message CodeGeneratorResponse { 100 | // Error message. If non-empty, code generation failed. The plugin process 101 | // should exit with status code zero even if it reports an error in this way. 102 | // 103 | // This should be used to indicate errors in .proto files which prevent the 104 | // code generator from generating correct code. Errors which indicate a 105 | // problem in protoc itself -- such as the input CodeGeneratorRequest being 106 | // unparseable -- should be reported by writing a message to stderr and 107 | // exiting with a non-zero status code. 108 | optional string error = 1; 109 | 110 | // A bitmask of supported features that the code generator supports. 111 | // This is a bitwise "or" of values from the Feature enum. 112 | optional uint64 supported_features = 2; 113 | 114 | // Sync with code_generator.h. 115 | enum Feature { 116 | FEATURE_NONE = 0; 117 | FEATURE_PROTO3_OPTIONAL = 1; 118 | } 119 | 120 | // Represents a single generated file. 121 | message File { 122 | // The file name, relative to the output directory. The name must not 123 | // contain "." or ".." components and must be relative, not be absolute (so, 124 | // the file cannot lie outside the output directory). "/" must be used as 125 | // the path separator, not "\". 126 | // 127 | // If the name is omitted, the content will be appended to the previous 128 | // file. This allows the generator to break large files into small chunks, 129 | // and allows the generated text to be streamed back to protoc so that large 130 | // files need not reside completely in memory at one time. Note that as of 131 | // this writing protoc does not optimize for this -- it will read the entire 132 | // CodeGeneratorResponse before writing files to disk. 133 | optional string name = 1; 134 | 135 | // If non-empty, indicates that the named file should already exist, and the 136 | // content here is to be inserted into that file at a defined insertion 137 | // point. This feature allows a code generator to extend the output 138 | // produced by another code generator. The original generator may provide 139 | // insertion points by placing special annotations in the file that look 140 | // like: 141 | // @@protoc_insertion_point(NAME) 142 | // The annotation can have arbitrary text before and after it on the line, 143 | // which allows it to be placed in a comment. NAME should be replaced with 144 | // an identifier naming the point -- this is what other generators will use 145 | // as the insertion_point. Code inserted at this point will be placed 146 | // immediately above the line containing the insertion point (thus multiple 147 | // insertions to the same point will come out in the order they were added). 148 | // The double-@ is intended to make it unlikely that the generated code 149 | // could contain things that look like insertion points by accident. 150 | // 151 | // For example, the C++ code generator places the following line in the 152 | // .pb.h files that it generates: 153 | // // @@protoc_insertion_point(namespace_scope) 154 | // This line appears within the scope of the file's package namespace, but 155 | // outside of any particular class. Another plugin can then specify the 156 | // insertion_point "namespace_scope" to generate additional classes or 157 | // other declarations that should be placed in this scope. 158 | // 159 | // Note that if the line containing the insertion point begins with 160 | // whitespace, the same whitespace will be added to every line of the 161 | // inserted text. This is useful for languages like Python, where 162 | // indentation matters. In these languages, the insertion point comment 163 | // should be indented the same amount as any inserted code will need to be 164 | // in order to work correctly in that context. 165 | // 166 | // The code generator that generates the initial file and the one which 167 | // inserts into it must both run as part of a single invocation of protoc. 168 | // Code generators are executed in the order in which they appear on the 169 | // command line. 170 | // 171 | // If |insertion_point| is present, |name| must also be present. 172 | optional string insertion_point = 2; 173 | 174 | // The file contents. 175 | optional string content = 15; 176 | 177 | // Information describing the file content being inserted. If an insertion 178 | // point is used, this information will be appropriately offset and inserted 179 | // into the code generation metadata for the generated files. 180 | optional GeneratedCodeInfo generated_code_info = 16; 181 | } 182 | repeated File file = 15; 183 | } 184 | -------------------------------------------------------------------------------- /third_party/google/protobuf/duration.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "google.golang.org/protobuf/types/known/durationpb"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "DurationProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Duration represents a signed, fixed-length span of time represented 44 | // as a count of seconds and fractions of seconds at nanosecond 45 | // resolution. It is independent of any calendar and concepts like "day" 46 | // or "month". It is related to Timestamp in that the difference between 47 | // two Timestamp values is a Duration and it can be added or subtracted 48 | // from a Timestamp. Range is approximately +-10,000 years. 49 | // 50 | // # Examples 51 | // 52 | // Example 1: Compute Duration from two Timestamps in pseudo code. 53 | // 54 | // Timestamp start = ...; 55 | // Timestamp end = ...; 56 | // Duration duration = ...; 57 | // 58 | // duration.seconds = end.seconds - start.seconds; 59 | // duration.nanos = end.nanos - start.nanos; 60 | // 61 | // if (duration.seconds < 0 && duration.nanos > 0) { 62 | // duration.seconds += 1; 63 | // duration.nanos -= 1000000000; 64 | // } else if (duration.seconds > 0 && duration.nanos < 0) { 65 | // duration.seconds -= 1; 66 | // duration.nanos += 1000000000; 67 | // } 68 | // 69 | // Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. 70 | // 71 | // Timestamp start = ...; 72 | // Duration duration = ...; 73 | // Timestamp end = ...; 74 | // 75 | // end.seconds = start.seconds + duration.seconds; 76 | // end.nanos = start.nanos + duration.nanos; 77 | // 78 | // if (end.nanos < 0) { 79 | // end.seconds -= 1; 80 | // end.nanos += 1000000000; 81 | // } else if (end.nanos >= 1000000000) { 82 | // end.seconds += 1; 83 | // end.nanos -= 1000000000; 84 | // } 85 | // 86 | // Example 3: Compute Duration from datetime.timedelta in Python. 87 | // 88 | // td = datetime.timedelta(days=3, minutes=10) 89 | // duration = Duration() 90 | // duration.FromTimedelta(td) 91 | // 92 | // # JSON Mapping 93 | // 94 | // In JSON format, the Duration type is encoded as a string rather than an 95 | // object, where the string ends in the suffix "s" (indicating seconds) and 96 | // is preceded by the number of seconds, with nanoseconds expressed as 97 | // fractional seconds. For example, 3 seconds with 0 nanoseconds should be 98 | // encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should 99 | // be expressed in JSON format as "3.000000001s", and 3 seconds and 1 100 | // microsecond should be expressed in JSON format as "3.000001s". 101 | // 102 | // 103 | message Duration { 104 | // Signed seconds of the span of time. Must be from -315,576,000,000 105 | // to +315,576,000,000 inclusive. Note: these bounds are computed from: 106 | // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years 107 | int64 seconds = 1; 108 | 109 | // Signed fractions of a second at nanosecond resolution of the span 110 | // of time. Durations less than one second are represented with a 0 111 | // `seconds` field and a positive or negative `nanos` field. For durations 112 | // of one second or more, a non-zero value for the `nanos` field must be 113 | // of the same sign as the `seconds` field. Must be from -999,999,999 114 | // to +999,999,999 inclusive. 115 | int32 nanos = 2; 116 | } 117 | -------------------------------------------------------------------------------- /third_party/google/protobuf/empty.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option go_package = "google.golang.org/protobuf/types/known/emptypb"; 37 | option java_package = "com.google.protobuf"; 38 | option java_outer_classname = "EmptyProto"; 39 | option java_multiple_files = true; 40 | option objc_class_prefix = "GPB"; 41 | option cc_enable_arenas = true; 42 | 43 | // A generic empty message that you can re-use to avoid defining duplicated 44 | // empty messages in your APIs. A typical example is to use it as the request 45 | // or the response type of an API method. For instance: 46 | // 47 | // service Foo { 48 | // rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); 49 | // } 50 | // 51 | // The JSON representation for `Empty` is empty JSON object `{}`. 52 | message Empty {} 53 | -------------------------------------------------------------------------------- /third_party/google/protobuf/field_mask.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option java_package = "com.google.protobuf"; 37 | option java_outer_classname = "FieldMaskProto"; 38 | option java_multiple_files = true; 39 | option objc_class_prefix = "GPB"; 40 | option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; 41 | option cc_enable_arenas = true; 42 | 43 | // `FieldMask` represents a set of symbolic field paths, for example: 44 | // 45 | // paths: "f.a" 46 | // paths: "f.b.d" 47 | // 48 | // Here `f` represents a field in some root message, `a` and `b` 49 | // fields in the message found in `f`, and `d` a field found in the 50 | // message in `f.b`. 51 | // 52 | // Field masks are used to specify a subset of fields that should be 53 | // returned by a get operation or modified by an update operation. 54 | // Field masks also have a custom JSON encoding (see below). 55 | // 56 | // # Field Masks in Projections 57 | // 58 | // When used in the context of a projection, a response message or 59 | // sub-message is filtered by the API to only contain those fields as 60 | // specified in the mask. For example, if the mask in the previous 61 | // example is applied to a response message as follows: 62 | // 63 | // f { 64 | // a : 22 65 | // b { 66 | // d : 1 67 | // x : 2 68 | // } 69 | // y : 13 70 | // } 71 | // z: 8 72 | // 73 | // The result will not contain specific values for fields x,y and z 74 | // (their value will be set to the default, and omitted in proto text 75 | // output): 76 | // 77 | // 78 | // f { 79 | // a : 22 80 | // b { 81 | // d : 1 82 | // } 83 | // } 84 | // 85 | // A repeated field is not allowed except at the last position of a 86 | // paths string. 87 | // 88 | // If a FieldMask object is not present in a get operation, the 89 | // operation applies to all fields (as if a FieldMask of all fields 90 | // had been specified). 91 | // 92 | // Note that a field mask does not necessarily apply to the 93 | // top-level response message. In case of a REST get operation, the 94 | // field mask applies directly to the response, but in case of a REST 95 | // list operation, the mask instead applies to each individual message 96 | // in the returned resource list. In case of a REST custom method, 97 | // other definitions may be used. Where the mask applies will be 98 | // clearly documented together with its declaration in the API. In 99 | // any case, the effect on the returned resource/resources is required 100 | // behavior for APIs. 101 | // 102 | // # Field Masks in Update Operations 103 | // 104 | // A field mask in update operations specifies which fields of the 105 | // targeted resource are going to be updated. The API is required 106 | // to only change the values of the fields as specified in the mask 107 | // and leave the others untouched. If a resource is passed in to 108 | // describe the updated values, the API ignores the values of all 109 | // fields not covered by the mask. 110 | // 111 | // If a repeated field is specified for an update operation, new values will 112 | // be appended to the existing repeated field in the target resource. Note that 113 | // a repeated field is only allowed in the last position of a `paths` string. 114 | // 115 | // If a sub-message is specified in the last position of the field mask for an 116 | // update operation, then new value will be merged into the existing sub-message 117 | // in the target resource. 118 | // 119 | // For example, given the target message: 120 | // 121 | // f { 122 | // b { 123 | // d: 1 124 | // x: 2 125 | // } 126 | // c: [1] 127 | // } 128 | // 129 | // And an update message: 130 | // 131 | // f { 132 | // b { 133 | // d: 10 134 | // } 135 | // c: [2] 136 | // } 137 | // 138 | // then if the field mask is: 139 | // 140 | // paths: ["f.b", "f.c"] 141 | // 142 | // then the result will be: 143 | // 144 | // f { 145 | // b { 146 | // d: 10 147 | // x: 2 148 | // } 149 | // c: [1, 2] 150 | // } 151 | // 152 | // An implementation may provide options to override this default behavior for 153 | // repeated and message fields. 154 | // 155 | // In order to reset a field's value to the default, the field must 156 | // be in the mask and set to the default value in the provided resource. 157 | // Hence, in order to reset all fields of a resource, provide a default 158 | // instance of the resource and set all fields in the mask, or do 159 | // not provide a mask as described below. 160 | // 161 | // If a field mask is not present on update, the operation applies to 162 | // all fields (as if a field mask of all fields has been specified). 163 | // Note that in the presence of schema evolution, this may mean that 164 | // fields the client does not know and has therefore not filled into 165 | // the request will be reset to their default. If this is unwanted 166 | // behavior, a specific service may require a client to always specify 167 | // a field mask, producing an error if not. 168 | // 169 | // As with get operations, the location of the resource which 170 | // describes the updated values in the request message depends on the 171 | // operation kind. In any case, the effect of the field mask is 172 | // required to be honored by the API. 173 | // 174 | // ## Considerations for HTTP REST 175 | // 176 | // The HTTP kind of an update operation which uses a field mask must 177 | // be set to PATCH instead of PUT in order to satisfy HTTP semantics 178 | // (PUT must only be used for full updates). 179 | // 180 | // # JSON Encoding of Field Masks 181 | // 182 | // In JSON, a field mask is encoded as a single string where paths are 183 | // separated by a comma. Fields name in each path are converted 184 | // to/from lower-camel naming conventions. 185 | // 186 | // As an example, consider the following message declarations: 187 | // 188 | // message Profile { 189 | // User user = 1; 190 | // Photo photo = 2; 191 | // } 192 | // message User { 193 | // string display_name = 1; 194 | // string address = 2; 195 | // } 196 | // 197 | // In proto a field mask for `Profile` may look as such: 198 | // 199 | // mask { 200 | // paths: "user.display_name" 201 | // paths: "photo" 202 | // } 203 | // 204 | // In JSON, the same mask is represented as below: 205 | // 206 | // { 207 | // mask: "user.displayName,photo" 208 | // } 209 | // 210 | // # Field Masks and Oneof Fields 211 | // 212 | // Field masks treat fields in oneofs just as regular fields. Consider the 213 | // following message: 214 | // 215 | // message SampleMessage { 216 | // oneof test_oneof { 217 | // string name = 4; 218 | // SubMessage sub_message = 9; 219 | // } 220 | // } 221 | // 222 | // The field mask can be: 223 | // 224 | // mask { 225 | // paths: "name" 226 | // } 227 | // 228 | // Or: 229 | // 230 | // mask { 231 | // paths: "sub_message" 232 | // } 233 | // 234 | // Note that oneof type names ("test_oneof" in this case) cannot be used in 235 | // paths. 236 | // 237 | // ## Field Mask Verification 238 | // 239 | // The implementation of any API method which has a FieldMask type field in the 240 | // request should verify the included field paths, and return an 241 | // `INVALID_ARGUMENT` error if any path is unmappable. 242 | message FieldMask { 243 | // The set of field mask paths. 244 | repeated string paths = 1; 245 | } 246 | -------------------------------------------------------------------------------- /third_party/google/protobuf/source_context.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option java_package = "com.google.protobuf"; 37 | option java_outer_classname = "SourceContextProto"; 38 | option java_multiple_files = true; 39 | option objc_class_prefix = "GPB"; 40 | option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; 41 | 42 | // `SourceContext` represents information about the source of a 43 | // protobuf element, like the file in which it is defined. 44 | message SourceContext { 45 | // The path-qualified name of the .proto file that contained the associated 46 | // protobuf element. For example: `"google/protobuf/source_context.proto"`. 47 | string file_name = 1; 48 | } 49 | -------------------------------------------------------------------------------- /third_party/google/protobuf/struct.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "google.golang.org/protobuf/types/known/structpb"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "StructProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // `Struct` represents a structured data value, consisting of fields 44 | // which map to dynamically typed values. In some languages, `Struct` 45 | // might be supported by a native representation. For example, in 46 | // scripting languages like JS a struct is represented as an 47 | // object. The details of that representation are described together 48 | // with the proto support for the language. 49 | // 50 | // The JSON representation for `Struct` is JSON object. 51 | message Struct { 52 | // Unordered map of dynamically typed values. 53 | map fields = 1; 54 | } 55 | 56 | // `Value` represents a dynamically typed value which can be either 57 | // null, a number, a string, a boolean, a recursive struct value, or a 58 | // list of values. A producer of value is expected to set one of that 59 | // variants, absence of any variant indicates an error. 60 | // 61 | // The JSON representation for `Value` is JSON value. 62 | message Value { 63 | // The kind of value. 64 | oneof kind { 65 | // Represents a null value. 66 | NullValue null_value = 1; 67 | // Represents a double value. 68 | double number_value = 2; 69 | // Represents a string value. 70 | string string_value = 3; 71 | // Represents a boolean value. 72 | bool bool_value = 4; 73 | // Represents a structured value. 74 | Struct struct_value = 5; 75 | // Represents a repeated `Value`. 76 | ListValue list_value = 6; 77 | } 78 | } 79 | 80 | // `NullValue` is a singleton enumeration to represent the null value for the 81 | // `Value` type union. 82 | // 83 | // The JSON representation for `NullValue` is JSON `null`. 84 | enum NullValue { 85 | // Null value. 86 | NULL_VALUE = 0; 87 | } 88 | 89 | // `ListValue` is a wrapper around a repeated field of values. 90 | // 91 | // The JSON representation for `ListValue` is JSON array. 92 | message ListValue { 93 | // Repeated field of dynamically typed values. 94 | repeated Value values = 1; 95 | } 96 | -------------------------------------------------------------------------------- /third_party/google/protobuf/timestamp.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 36 | option cc_enable_arenas = true; 37 | option go_package = "google.golang.org/protobuf/types/known/timestamppb"; 38 | option java_package = "com.google.protobuf"; 39 | option java_outer_classname = "TimestampProto"; 40 | option java_multiple_files = true; 41 | option objc_class_prefix = "GPB"; 42 | 43 | // A Timestamp represents a point in time independent of any time zone or local 44 | // calendar, encoded as a count of seconds and fractions of seconds at 45 | // nanosecond resolution. The count is relative to an epoch at UTC midnight on 46 | // January 1, 1970, in the proleptic Gregorian calendar which extends the 47 | // Gregorian calendar backwards to year one. 48 | // 49 | // All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap 50 | // second table is needed for interpretation, using a [24-hour linear 51 | // smear](https://developers.google.com/time/smear). 52 | // 53 | // The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By 54 | // restricting to that range, we ensure that we can convert to and from [RFC 55 | // 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. 56 | // 57 | // # Examples 58 | // 59 | // Example 1: Compute Timestamp from POSIX `time()`. 60 | // 61 | // Timestamp timestamp; 62 | // timestamp.set_seconds(time(NULL)); 63 | // timestamp.set_nanos(0); 64 | // 65 | // Example 2: Compute Timestamp from POSIX `gettimeofday()`. 66 | // 67 | // struct timeval tv; 68 | // gettimeofday(&tv, NULL); 69 | // 70 | // Timestamp timestamp; 71 | // timestamp.set_seconds(tv.tv_sec); 72 | // timestamp.set_nanos(tv.tv_usec * 1000); 73 | // 74 | // Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. 75 | // 76 | // FILETIME ft; 77 | // GetSystemTimeAsFileTime(&ft); 78 | // UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 79 | // 80 | // // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z 81 | // // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. 82 | // Timestamp timestamp; 83 | // timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); 84 | // timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); 85 | // 86 | // Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. 87 | // 88 | // long millis = System.currentTimeMillis(); 89 | // 90 | // Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) 91 | // .setNanos((int) ((millis % 1000) * 1000000)).build(); 92 | // 93 | // 94 | // Example 5: Compute Timestamp from Java `Instant.now()`. 95 | // 96 | // Instant now = Instant.now(); 97 | // 98 | // Timestamp timestamp = 99 | // Timestamp.newBuilder().setSeconds(now.getEpochSecond()) 100 | // .setNanos(now.getNano()).build(); 101 | // 102 | // 103 | // Example 6: Compute Timestamp from current time in Python. 104 | // 105 | // timestamp = Timestamp() 106 | // timestamp.GetCurrentTime() 107 | // 108 | // # JSON Mapping 109 | // 110 | // In JSON format, the Timestamp type is encoded as a string in the 111 | // [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the 112 | // format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" 113 | // where {year} is always expressed using four digits while {month}, {day}, 114 | // {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional 115 | // seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), 116 | // are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone 117 | // is required. A proto3 JSON serializer should always use UTC (as indicated by 118 | // "Z") when printing the Timestamp type and a proto3 JSON parser should be 119 | // able to accept both UTC and other timezones (as indicated by an offset). 120 | // 121 | // For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past 122 | // 01:30 UTC on January 15, 2017. 123 | // 124 | // In JavaScript, one can convert a Date object to this format using the 125 | // standard 126 | // [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) 127 | // method. In Python, a standard `datetime.datetime` object can be converted 128 | // to this format using 129 | // [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with 130 | // the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use 131 | // the Joda Time's [`ISODateTimeFormat.dateTime()`]( 132 | // http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D 133 | // ) to obtain a formatter capable of generating timestamps in this format. 134 | // 135 | // 136 | message Timestamp { 137 | // Represents seconds of UTC time since Unix epoch 138 | // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to 139 | // 9999-12-31T23:59:59Z inclusive. 140 | int64 seconds = 1; 141 | 142 | // Non-negative fractions of a second at nanosecond resolution. Negative 143 | // second values with fractions must still have non-negative nanos values 144 | // that count forward in time. Must be from 0 to 999,999,999 145 | // inclusive. 146 | int32 nanos = 2; 147 | } 148 | -------------------------------------------------------------------------------- /third_party/google/protobuf/type.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | syntax = "proto3"; 32 | 33 | package google.protobuf; 34 | 35 | import "google/protobuf/any.proto"; 36 | import "google/protobuf/source_context.proto"; 37 | 38 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 39 | option cc_enable_arenas = true; 40 | option java_package = "com.google.protobuf"; 41 | option java_outer_classname = "TypeProto"; 42 | option java_multiple_files = true; 43 | option objc_class_prefix = "GPB"; 44 | option go_package = "google.golang.org/protobuf/types/known/typepb"; 45 | 46 | // A protocol buffer message type. 47 | message Type { 48 | // The fully qualified message name. 49 | string name = 1; 50 | // The list of fields. 51 | repeated Field fields = 2; 52 | // The list of types appearing in `oneof` definitions in this type. 53 | repeated string oneofs = 3; 54 | // The protocol buffer options. 55 | repeated Option options = 4; 56 | // The source context. 57 | SourceContext source_context = 5; 58 | // The source syntax. 59 | Syntax syntax = 6; 60 | } 61 | 62 | // A single field of a message type. 63 | message Field { 64 | // Basic field types. 65 | enum Kind { 66 | // Field type unknown. 67 | TYPE_UNKNOWN = 0; 68 | // Field type double. 69 | TYPE_DOUBLE = 1; 70 | // Field type float. 71 | TYPE_FLOAT = 2; 72 | // Field type int64. 73 | TYPE_INT64 = 3; 74 | // Field type uint64. 75 | TYPE_UINT64 = 4; 76 | // Field type int32. 77 | TYPE_INT32 = 5; 78 | // Field type fixed64. 79 | TYPE_FIXED64 = 6; 80 | // Field type fixed32. 81 | TYPE_FIXED32 = 7; 82 | // Field type bool. 83 | TYPE_BOOL = 8; 84 | // Field type string. 85 | TYPE_STRING = 9; 86 | // Field type group. Proto2 syntax only, and deprecated. 87 | TYPE_GROUP = 10; 88 | // Field type message. 89 | TYPE_MESSAGE = 11; 90 | // Field type bytes. 91 | TYPE_BYTES = 12; 92 | // Field type uint32. 93 | TYPE_UINT32 = 13; 94 | // Field type enum. 95 | TYPE_ENUM = 14; 96 | // Field type sfixed32. 97 | TYPE_SFIXED32 = 15; 98 | // Field type sfixed64. 99 | TYPE_SFIXED64 = 16; 100 | // Field type sint32. 101 | TYPE_SINT32 = 17; 102 | // Field type sint64. 103 | TYPE_SINT64 = 18; 104 | } 105 | 106 | // Whether a field is optional, required, or repeated. 107 | enum Cardinality { 108 | // For fields with unknown cardinality. 109 | CARDINALITY_UNKNOWN = 0; 110 | // For optional fields. 111 | CARDINALITY_OPTIONAL = 1; 112 | // For required fields. Proto2 syntax only. 113 | CARDINALITY_REQUIRED = 2; 114 | // For repeated fields. 115 | CARDINALITY_REPEATED = 3; 116 | } 117 | 118 | // The field type. 119 | Kind kind = 1; 120 | // The field cardinality. 121 | Cardinality cardinality = 2; 122 | // The field number. 123 | int32 number = 3; 124 | // The field name. 125 | string name = 4; 126 | // The field type URL, without the scheme, for message or enumeration 127 | // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. 128 | string type_url = 6; 129 | // The index of the field type in `Type.oneofs`, for message or enumeration 130 | // types. The first type has index 1; zero means the type is not in the list. 131 | int32 oneof_index = 7; 132 | // Whether to use alternative packed wire representation. 133 | bool packed = 8; 134 | // The protocol buffer options. 135 | repeated Option options = 9; 136 | // The field JSON name. 137 | string json_name = 10; 138 | // The string value of the default value of this field. Proto2 syntax only. 139 | string default_value = 11; 140 | } 141 | 142 | // Enum type definition. 143 | message Enum { 144 | // Enum type name. 145 | string name = 1; 146 | // Enum value definitions. 147 | repeated EnumValue enumvalue = 2; 148 | // Protocol buffer options. 149 | repeated Option options = 3; 150 | // The source context. 151 | SourceContext source_context = 4; 152 | // The source syntax. 153 | Syntax syntax = 5; 154 | } 155 | 156 | // Enum value definition. 157 | message EnumValue { 158 | // Enum value name. 159 | string name = 1; 160 | // Enum value number. 161 | int32 number = 2; 162 | // Protocol buffer options. 163 | repeated Option options = 3; 164 | } 165 | 166 | // A protocol buffer option, which can be attached to a message, field, 167 | // enumeration, etc. 168 | message Option { 169 | // The option's name. For protobuf built-in options (options defined in 170 | // descriptor.proto), this is the short name. For example, `"map_entry"`. 171 | // For custom options, it should be the fully-qualified name. For example, 172 | // `"google.api.http"`. 173 | string name = 1; 174 | // The option's value packed in an Any message. If the value is a primitive, 175 | // the corresponding wrapper type defined in google/protobuf/wrappers.proto 176 | // should be used. If the value is an enum, it should be stored as an int32 177 | // value using the google.protobuf.Int32Value type. 178 | Any value = 2; 179 | } 180 | 181 | // The syntax in which a protocol buffer element is defined. 182 | enum Syntax { 183 | // Syntax `proto2`. 184 | SYNTAX_PROTO2 = 0; 185 | // Syntax `proto3`. 186 | SYNTAX_PROTO3 = 1; 187 | } 188 | -------------------------------------------------------------------------------- /third_party/google/protobuf/wrappers.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Wrappers for primitive (non-message) types. These types are useful 32 | // for embedding primitives in the `google.protobuf.Any` type and for places 33 | // where we need to distinguish between the absence of a primitive 34 | // typed field and its default value. 35 | // 36 | // These wrappers have no meaningful use within repeated fields as they lack 37 | // the ability to detect presence on individual elements. 38 | // These wrappers have no meaningful use within a map or a oneof since 39 | // individual entries of a map or fields of a oneof can already detect presence. 40 | 41 | syntax = "proto3"; 42 | 43 | package google.protobuf; 44 | 45 | option csharp_namespace = "Google.Protobuf.WellKnownTypes"; 46 | option cc_enable_arenas = true; 47 | option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; 48 | option java_package = "com.google.protobuf"; 49 | option java_outer_classname = "WrappersProto"; 50 | option java_multiple_files = true; 51 | option objc_class_prefix = "GPB"; 52 | 53 | // Wrapper message for `double`. 54 | // 55 | // The JSON representation for `DoubleValue` is JSON number. 56 | message DoubleValue { 57 | // The double value. 58 | double value = 1; 59 | } 60 | 61 | // Wrapper message for `float`. 62 | // 63 | // The JSON representation for `FloatValue` is JSON number. 64 | message FloatValue { 65 | // The float value. 66 | float value = 1; 67 | } 68 | 69 | // Wrapper message for `int64`. 70 | // 71 | // The JSON representation for `Int64Value` is JSON string. 72 | message Int64Value { 73 | // The int64 value. 74 | int64 value = 1; 75 | } 76 | 77 | // Wrapper message for `uint64`. 78 | // 79 | // The JSON representation for `UInt64Value` is JSON string. 80 | message UInt64Value { 81 | // The uint64 value. 82 | uint64 value = 1; 83 | } 84 | 85 | // Wrapper message for `int32`. 86 | // 87 | // The JSON representation for `Int32Value` is JSON number. 88 | message Int32Value { 89 | // The int32 value. 90 | int32 value = 1; 91 | } 92 | 93 | // Wrapper message for `uint32`. 94 | // 95 | // The JSON representation for `UInt32Value` is JSON number. 96 | message UInt32Value { 97 | // The uint32 value. 98 | uint32 value = 1; 99 | } 100 | 101 | // Wrapper message for `bool`. 102 | // 103 | // The JSON representation for `BoolValue` is JSON `true` and `false`. 104 | message BoolValue { 105 | // The bool value. 106 | bool value = 1; 107 | } 108 | 109 | // Wrapper message for `string`. 110 | // 111 | // The JSON representation for `StringValue` is JSON string. 112 | message StringValue { 113 | // The string value. 114 | string value = 1; 115 | } 116 | 117 | // Wrapper message for `bytes`. 118 | // 119 | // The JSON representation for `BytesValue` is JSON string. 120 | message BytesValue { 121 | // The bytes value. 122 | bytes value = 1; 123 | } 124 | --------------------------------------------------------------------------------