├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── app.yaml
├── go.mod
├── go.sum
├── handler.go
├── handler_test.go
├── main.go
├── vanity.yaml
└── vendor
├── github.com
└── golang
│ └── protobuf
│ ├── AUTHORS
│ ├── CONTRIBUTORS
│ ├── LICENSE
│ └── proto
│ ├── clone.go
│ ├── decode.go
│ ├── deprecated.go
│ ├── discard.go
│ ├── encode.go
│ ├── equal.go
│ ├── extensions.go
│ ├── lib.go
│ ├── message_set.go
│ ├── pointer_reflect.go
│ ├── pointer_unsafe.go
│ ├── properties.go
│ ├── table_marshal.go
│ ├── table_merge.go
│ ├── table_unmarshal.go
│ ├── text.go
│ └── text_parser.go
├── golang.org
└── x
│ └── net
│ ├── AUTHORS
│ ├── CONTRIBUTORS
│ ├── LICENSE
│ ├── PATENTS
│ └── context
│ ├── context.go
│ ├── go17.go
│ ├── go19.go
│ ├── pre_go17.go
│ └── pre_go19.go
├── google.golang.org
└── appengine
│ ├── .travis.yml
│ ├── CONTRIBUTING.md
│ ├── LICENSE
│ ├── README.md
│ ├── appengine.go
│ ├── appengine_vm.go
│ ├── errors.go
│ ├── go.mod
│ ├── go.sum
│ ├── identity.go
│ ├── internal
│ ├── api.go
│ ├── api_classic.go
│ ├── api_common.go
│ ├── app_id.go
│ ├── app_identity
│ │ ├── app_identity_service.pb.go
│ │ └── app_identity_service.proto
│ ├── base
│ │ ├── api_base.pb.go
│ │ └── api_base.proto
│ ├── datastore
│ │ ├── datastore_v3.pb.go
│ │ └── datastore_v3.proto
│ ├── identity.go
│ ├── identity_classic.go
│ ├── identity_flex.go
│ ├── identity_vm.go
│ ├── internal.go
│ ├── log
│ │ ├── log_service.pb.go
│ │ └── log_service.proto
│ ├── main.go
│ ├── main_common.go
│ ├── main_vm.go
│ ├── metadata.go
│ ├── modules
│ │ ├── modules_service.pb.go
│ │ └── modules_service.proto
│ ├── net.go
│ ├── regen.sh
│ ├── remote_api
│ │ ├── remote_api.pb.go
│ │ └── remote_api.proto
│ └── transaction.go
│ ├── namespace.go
│ ├── timeout.go
│ ├── travis_install.sh
│ └── travis_test.sh
├── gopkg.in
└── yaml.v2
│ ├── .travis.yml
│ ├── LICENSE
│ ├── LICENSE.libyaml
│ ├── NOTICE
│ ├── README.md
│ ├── apic.go
│ ├── decode.go
│ ├── emitterc.go
│ ├── encode.go
│ ├── go.mod
│ ├── parserc.go
│ ├── readerc.go
│ ├── resolve.go
│ ├── scannerc.go
│ ├── sorter.go
│ ├── writerc.go
│ ├── yaml.go
│ ├── yamlh.go
│ └── yamlprivateh.go
└── modules.txt
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: go
3 | go:
4 | - 1.12
5 | - 1.x
6 |
--------------------------------------------------------------------------------
/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. You (or your employer) retain the copyright to your contribution,
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Go Vanity URLs
2 |
3 | Go Vanity URLs is a simple Go server that allows you
4 | to set custom import paths for your Go packages.
5 | It also can run on Google App Engine.
6 |
7 | ## Quickstart
8 |
9 | Install and run the binary:
10 |
11 | ```
12 | $ go get -u github.com/GoogleCloudPlatform/govanityurls
13 | $ # update vanity.yaml
14 | $ govanityurls
15 | $ # open http://localhost:8080
16 | ```
17 |
18 |
19 | ### Google App Engine
20 |
21 | Install [gcloud](https://cloud.google.com/sdk/downloads) and install Go App Engine component:
22 |
23 | ```
24 | $ gcloud components install app-engine-go
25 | ```
26 |
27 | Setup a [custom domain](https://cloud.google.com/appengine/docs/standard/python/using-custom-domains-and-ssl) for your app.
28 |
29 | Get the application:
30 | ```
31 | git clone https://github.com/GoogleCloudPlatform/govanityurls
32 | cd govanityurls
33 | ```
34 |
35 | Edit `vanity.yaml` to add any number of git repos. E.g., `customdomain.com/portmidi` will
36 | serve the [https://github.com/rakyll/portmidi](https://github.com/rakyll/portmidi) repo.
37 |
38 | ```
39 | paths:
40 | /portmidi:
41 | repo: https://github.com/rakyll/portmidi
42 | ```
43 |
44 | You can add as many rules as you wish.
45 |
46 | Deploy the app:
47 |
48 | ```
49 | $ gcloud app deploy
50 | ```
51 |
52 | That's it! You can use `go get` to get the package from your custom domain.
53 |
54 | ```
55 | $ go get customdomain.com/portmidi
56 | ```
57 |
58 | ### Running in other environments
59 |
60 | You can also deploy this as an App Engine Flexible app by changing the
61 | `app.yaml` file:
62 |
63 | ```
64 | runtime: go
65 | env: flex
66 | ```
67 |
68 | This project is a normal Go HTTP server, so you can also incorporate the
69 | handler into larger Go servers.
70 |
71 | ## Configuration File
72 |
73 | ```
74 | host: example.com
75 | cache_max_age: 3600
76 | paths:
77 | /foo:
78 | repo: https://github.com/example/foo
79 | display: "https://github.com/example/foo https://github.com/example/foo/tree/master{/dir} https://github.com/example/foo/blob/master{/dir}/{file}#L{line}"
80 | vcs: git
81 | ```
82 |
83 |
84 |
85 |
86 | Key |
87 | Required |
88 | Description |
89 |
90 |
91 |
92 |
93 | cache_max_age |
94 | optional |
95 | The amount of time to cache package pages in seconds. Controls the max-age directive sent in the Cache-Control HTTP header. |
96 |
97 |
98 | host |
99 | optional |
100 | Host name to use in meta tags. If omitted, uses the App Engine default version host or the Host header on non-App Engine Standard environments. You can use this option to fix the host when using this service behind a reverse proxy or a custom dispatch file. |
101 |
102 |
103 | paths |
104 | required |
105 | Map of paths to path configurations. Each key is a path that will point to the root of a repository hosted elsewhere. The fields are documented in the Path Configuration section below. |
106 |
107 |
108 |
109 |
110 | ### Path Configuration
111 |
112 |
113 |
114 |
115 | Key |
116 | Required |
117 | Description |
118 |
119 |
120 |
121 |
122 | display |
123 | optional |
124 | The last three fields of the go-source meta tag. If omitted, it is inferred from the code hosting service if possible. |
125 |
126 |
127 | repo |
128 | required |
129 | Root URL of the repository as it would appear in go-import meta tag. |
130 |
131 |
132 | vcs |
133 | required if ambiguous |
134 | If the version control system cannot be inferred (e.g. for Bitbucket or a custom domain), then this specifies the version control system as it would appear in go-import meta tag. This can be one of git , hg , svn , or bzr . |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/app.yaml:
--------------------------------------------------------------------------------
1 | runtime: go112
2 |
3 | handlers:
4 | - url: /.*
5 | script: auto
6 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/GoogleCloudPlatform/govanityurls
2 |
3 | go 1.13
4 |
5 | require (
6 | github.com/golang/protobuf v1.3.3 // indirect
7 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
8 | google.golang.org/appengine v1.6.5
9 | gopkg.in/yaml.v2 v2.2.8
10 | )
11 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
2 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
3 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
4 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
5 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
6 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
7 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
8 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
9 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
10 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
11 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
12 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
13 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
14 | google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
15 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
16 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
17 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
18 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
19 |
--------------------------------------------------------------------------------
/handler.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc. 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 | // govanityurls serves Go vanity URLs.
16 | package main
17 |
18 | import (
19 | "errors"
20 | "fmt"
21 | "html/template"
22 | "net/http"
23 | "sort"
24 | "strings"
25 |
26 | "gopkg.in/yaml.v2"
27 | )
28 |
29 | type handler struct {
30 | host string
31 | cacheControl string
32 | paths pathConfigSet
33 | }
34 |
35 | type pathConfig struct {
36 | path string
37 | repo string
38 | display string
39 | vcs string
40 | }
41 |
42 | func newHandler(config []byte) (*handler, error) {
43 | var parsed struct {
44 | Host string `yaml:"host,omitempty"`
45 | CacheAge *int64 `yaml:"cache_max_age,omitempty"`
46 | Paths map[string]struct {
47 | Repo string `yaml:"repo,omitempty"`
48 | Display string `yaml:"display,omitempty"`
49 | VCS string `yaml:"vcs,omitempty"`
50 | } `yaml:"paths,omitempty"`
51 | }
52 | if err := yaml.Unmarshal(config, &parsed); err != nil {
53 | return nil, err
54 | }
55 | h := &handler{host: parsed.Host}
56 | cacheAge := int64(86400) // 24 hours (in seconds)
57 | if parsed.CacheAge != nil {
58 | cacheAge = *parsed.CacheAge
59 | if cacheAge < 0 {
60 | return nil, errors.New("cache_max_age is negative")
61 | }
62 | }
63 | h.cacheControl = fmt.Sprintf("public, max-age=%d", cacheAge)
64 | for path, e := range parsed.Paths {
65 | pc := pathConfig{
66 | path: strings.TrimSuffix(path, "/"),
67 | repo: e.Repo,
68 | display: e.Display,
69 | vcs: e.VCS,
70 | }
71 | switch {
72 | case e.Display != "":
73 | // Already filled in.
74 | case strings.HasPrefix(e.Repo, "https://github.com/"):
75 | pc.display = fmt.Sprintf("%v %v/tree/master{/dir} %v/blob/master{/dir}/{file}#L{line}", e.Repo, e.Repo, e.Repo)
76 | case strings.HasPrefix(e.Repo, "https://bitbucket.org"):
77 | pc.display = fmt.Sprintf("%v %v/src/default{/dir} %v/src/default{/dir}/{file}#{file}-{line}", e.Repo, e.Repo, e.Repo)
78 | }
79 | switch {
80 | case e.VCS != "":
81 | // Already filled in.
82 | if e.VCS != "bzr" && e.VCS != "git" && e.VCS != "hg" && e.VCS != "svn" {
83 | return nil, fmt.Errorf("configuration for %v: unknown VCS %s", path, e.VCS)
84 | }
85 | case strings.HasPrefix(e.Repo, "https://github.com/"):
86 | pc.vcs = "git"
87 | default:
88 | return nil, fmt.Errorf("configuration for %v: cannot infer VCS from %s", path, e.Repo)
89 | }
90 | h.paths = append(h.paths, pc)
91 | }
92 | sort.Sort(h.paths)
93 | return h, nil
94 | }
95 |
96 | func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
97 | current := r.URL.Path
98 | pc, subpath := h.paths.find(current)
99 | if pc == nil && current == "/" {
100 | h.serveIndex(w, r)
101 | return
102 | }
103 | if pc == nil {
104 | http.NotFound(w, r)
105 | return
106 | }
107 |
108 | w.Header().Set("Cache-Control", h.cacheControl)
109 | if err := vanityTmpl.Execute(w, struct {
110 | Import string
111 | Subpath string
112 | Repo string
113 | Display string
114 | VCS string
115 | }{
116 | Import: h.Host(r) + pc.path,
117 | Subpath: subpath,
118 | Repo: pc.repo,
119 | Display: pc.display,
120 | VCS: pc.vcs,
121 | }); err != nil {
122 | http.Error(w, "cannot render the page", http.StatusInternalServerError)
123 | }
124 | }
125 |
126 | func (h *handler) serveIndex(w http.ResponseWriter, r *http.Request) {
127 | host := h.Host(r)
128 | handlers := make([]string, len(h.paths))
129 | for i, h := range h.paths {
130 | handlers[i] = host + h.path
131 | }
132 | if err := indexTmpl.Execute(w, struct {
133 | Host string
134 | Handlers []string
135 | }{
136 | Host: host,
137 | Handlers: handlers,
138 | }); err != nil {
139 | http.Error(w, "cannot render the page", http.StatusInternalServerError)
140 | }
141 | }
142 |
143 | func (h *handler) Host(r *http.Request) string {
144 | host := h.host
145 | if host == "" {
146 | host = defaultHost(r)
147 | }
148 | return host
149 | }
150 |
151 | var indexTmpl = template.Must(template.New("index").Parse(`
152 |
153 | {{.Host}}
154 |
155 | {{range .Handlers}}- {{.}}
{{end}}
156 |
157 |
158 | `))
159 |
160 | var vanityTmpl = template.Must(template.New("vanity").Parse(`
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | Nothing to see here; see the package on pkg.go.dev.
170 |
171 | `))
172 |
173 | type pathConfigSet []pathConfig
174 |
175 | func (pset pathConfigSet) Len() int {
176 | return len(pset)
177 | }
178 |
179 | func (pset pathConfigSet) Less(i, j int) bool {
180 | return pset[i].path < pset[j].path
181 | }
182 |
183 | func (pset pathConfigSet) Swap(i, j int) {
184 | pset[i], pset[j] = pset[j], pset[i]
185 | }
186 |
187 | func (pset pathConfigSet) find(path string) (pc *pathConfig, subpath string) {
188 | // Fast path with binary search to retrieve exact matches
189 | // e.g. given pset ["/", "/abc", "/xyz"], path "/def" won't match.
190 | i := sort.Search(len(pset), func(i int) bool {
191 | return pset[i].path >= path
192 | })
193 | if i < len(pset) && pset[i].path == path {
194 | return &pset[i], ""
195 | }
196 | if i > 0 && strings.HasPrefix(path, pset[i-1].path+"/") {
197 | return &pset[i-1], path[len(pset[i-1].path)+1:]
198 | }
199 |
200 | // Slow path, now looking for the longest prefix/shortest subpath i.e.
201 | // e.g. given pset ["/", "/abc/", "/abc/def/", "/xyz"/]
202 | // * query "/abc/foo" returns "/abc/" with a subpath of "foo"
203 | // * query "/x" returns "/" with a subpath of "x"
204 | lenShortestSubpath := len(path)
205 | var bestMatchConfig *pathConfig
206 |
207 | // After binary search with the >= lexicographic comparison,
208 | // nothing greater than i will be a prefix of path.
209 | max := i
210 | for i := 0; i < max; i++ {
211 | ps := pset[i]
212 | if len(ps.path) >= len(path) {
213 | // We previously didn't find the path by search, so any
214 | // route with equal or greater length is NOT a match.
215 | continue
216 | }
217 | sSubpath := strings.TrimPrefix(path, ps.path)
218 | if len(sSubpath) < lenShortestSubpath {
219 | subpath = sSubpath
220 | lenShortestSubpath = len(sSubpath)
221 | bestMatchConfig = &pset[i]
222 | }
223 | }
224 | return bestMatchConfig, subpath
225 | }
226 |
--------------------------------------------------------------------------------
/handler_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc. 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 main
16 |
17 | import (
18 | "bytes"
19 | "io/ioutil"
20 | "net/http"
21 | "net/http/httptest"
22 | "sort"
23 | "testing"
24 | )
25 |
26 | func TestHandler(t *testing.T) {
27 | tests := []struct {
28 | name string
29 | config string
30 | path string
31 |
32 | goImport string
33 | goSource string
34 | }{
35 | {
36 | name: "explicit display",
37 | config: "host: example.com\n" +
38 | "paths:\n" +
39 | " /portmidi:\n" +
40 | " repo: https://github.com/rakyll/portmidi\n" +
41 | " display: https://github.com/rakyll/portmidi _ _\n",
42 | path: "/portmidi",
43 | goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
44 | goSource: "example.com/portmidi https://github.com/rakyll/portmidi _ _",
45 | },
46 | {
47 | name: "display GitHub inference",
48 | config: "host: example.com\n" +
49 | "paths:\n" +
50 | " /portmidi:\n" +
51 | " repo: https://github.com/rakyll/portmidi\n",
52 | path: "/portmidi",
53 | goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
54 | goSource: "example.com/portmidi https://github.com/rakyll/portmidi https://github.com/rakyll/portmidi/tree/master{/dir} https://github.com/rakyll/portmidi/blob/master{/dir}/{file}#L{line}",
55 | },
56 | {
57 | name: "Bitbucket Mercurial",
58 | config: "host: example.com\n" +
59 | "paths:\n" +
60 | " /gopdf:\n" +
61 | " repo: https://bitbucket.org/zombiezen/gopdf\n" +
62 | " vcs: hg\n",
63 | path: "/gopdf",
64 | goImport: "example.com/gopdf hg https://bitbucket.org/zombiezen/gopdf",
65 | goSource: "example.com/gopdf https://bitbucket.org/zombiezen/gopdf https://bitbucket.org/zombiezen/gopdf/src/default{/dir} https://bitbucket.org/zombiezen/gopdf/src/default{/dir}/{file}#{file}-{line}",
66 | },
67 | {
68 | name: "Bitbucket Git",
69 | config: "host: example.com\n" +
70 | "paths:\n" +
71 | " /mygit:\n" +
72 | " repo: https://bitbucket.org/zombiezen/mygit\n" +
73 | " vcs: git\n",
74 | path: "/mygit",
75 | goImport: "example.com/mygit git https://bitbucket.org/zombiezen/mygit",
76 | goSource: "example.com/mygit https://bitbucket.org/zombiezen/mygit https://bitbucket.org/zombiezen/mygit/src/default{/dir} https://bitbucket.org/zombiezen/mygit/src/default{/dir}/{file}#{file}-{line}",
77 | },
78 | {
79 | name: "subpath",
80 | config: "host: example.com\n" +
81 | "paths:\n" +
82 | " /portmidi:\n" +
83 | " repo: https://github.com/rakyll/portmidi\n" +
84 | " display: https://github.com/rakyll/portmidi _ _\n",
85 | path: "/portmidi/foo",
86 | goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
87 | goSource: "example.com/portmidi https://github.com/rakyll/portmidi _ _",
88 | },
89 | {
90 | name: "subpath with trailing config slash",
91 | config: "host: example.com\n" +
92 | "paths:\n" +
93 | " /portmidi/:\n" +
94 | " repo: https://github.com/rakyll/portmidi\n" +
95 | " display: https://github.com/rakyll/portmidi _ _\n",
96 | path: "/portmidi/foo",
97 | goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
98 | goSource: "example.com/portmidi https://github.com/rakyll/portmidi _ _",
99 | },
100 | }
101 | for _, test := range tests {
102 | h, err := newHandler([]byte(test.config))
103 | if err != nil {
104 | t.Errorf("%s: newHandler: %v", test.name, err)
105 | continue
106 | }
107 | s := httptest.NewServer(h)
108 | resp, err := http.Get(s.URL + test.path)
109 | if err != nil {
110 | s.Close()
111 | t.Errorf("%s: http.Get: %v", test.name, err)
112 | continue
113 | }
114 | data, err := ioutil.ReadAll(resp.Body)
115 | resp.Body.Close()
116 | s.Close()
117 | if resp.StatusCode != http.StatusOK {
118 | t.Errorf("%s: status code = %s; want 200 OK", test.name, resp.Status)
119 | }
120 | if err != nil {
121 | t.Errorf("%s: ioutil.ReadAll: %v", test.name, err)
122 | continue
123 | }
124 | if got := findMeta(data, "go-import"); got != test.goImport {
125 | t.Errorf("%s: meta go-import = %q; want %q", test.name, got, test.goImport)
126 | }
127 | if got := findMeta(data, "go-source"); got != test.goSource {
128 | t.Errorf("%s: meta go-source = %q; want %q", test.name, got, test.goSource)
129 | }
130 | }
131 | }
132 |
133 | func TestBadConfigs(t *testing.T) {
134 | badConfigs := []string{
135 | "paths:\n" +
136 | " /missingvcs:\n" +
137 | " repo: https://bitbucket.org/zombiezen/gopdf\n",
138 | "paths:\n" +
139 | " /unknownvcs:\n" +
140 | " repo: https://bitbucket.org/zombiezen/gopdf\n" +
141 | " vcs: xyzzy\n",
142 | "cache_max_age: -1\n" +
143 | "paths:\n" +
144 | " /portmidi:\n" +
145 | " repo: https://github.com/rakyll/portmidi\n",
146 | }
147 | for _, config := range badConfigs {
148 | _, err := newHandler([]byte(config))
149 | if err == nil {
150 | t.Errorf("expected config to produce an error, but did not:\n%s", config)
151 | }
152 | }
153 | }
154 |
155 | func findMeta(data []byte, name string) string {
156 | var sep []byte
157 | sep = append(sep, `"
254 | }
255 | return s
256 | }
257 | for _, test := range tests {
258 | pset := make(pathConfigSet, len(test.paths))
259 | for i := range test.paths {
260 | pset[i].path = test.paths[i]
261 | }
262 | sort.Sort(pset)
263 | pc, subpath := pset.find(test.query)
264 | var got string
265 | if pc != nil {
266 | got = pc.path
267 | }
268 | if got != test.want || subpath != test.subpath {
269 | t.Errorf("pathConfigSet(%v).find(%q) = %v, %v; want %v, %v",
270 | test.paths, test.query, emptyToNil(got), subpath, emptyToNil(test.want), test.subpath)
271 | }
272 | }
273 | }
274 |
275 | func TestCacheHeader(t *testing.T) {
276 | tests := []struct {
277 | name string
278 | config string
279 | cacheControl string
280 | }{
281 | {
282 | name: "default",
283 | cacheControl: "public, max-age=86400",
284 | },
285 | {
286 | name: "specify time",
287 | config: "cache_max_age: 60\n",
288 | cacheControl: "public, max-age=60",
289 | },
290 | {
291 | name: "zero",
292 | config: "cache_max_age: 0\n",
293 | cacheControl: "public, max-age=0",
294 | },
295 | }
296 | for _, test := range tests {
297 | h, err := newHandler([]byte("paths:\n /portmidi:\n repo: https://github.com/rakyll/portmidi\n" +
298 | test.config))
299 | if err != nil {
300 | t.Errorf("%s: newHandler: %v", test.name, err)
301 | continue
302 | }
303 | s := httptest.NewServer(h)
304 | resp, err := http.Get(s.URL + "/portmidi")
305 | if err != nil {
306 | t.Errorf("%s: http.Get: %v", test.name, err)
307 | continue
308 | }
309 | resp.Body.Close()
310 | got := resp.Header.Get("Cache-Control")
311 | if got != test.cacheControl {
312 | t.Errorf("%s: Cache-Control header = %q; want %q", test.name, got, test.cacheControl)
313 | }
314 | }
315 | }
316 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 Google Inc. 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 main
16 |
17 | import (
18 | "io/ioutil"
19 | "log"
20 | "net/http"
21 | "os"
22 | )
23 |
24 | func main() {
25 | var configPath string
26 | switch len(os.Args) {
27 | case 1:
28 | configPath = "vanity.yaml"
29 | case 2:
30 | configPath = os.Args[1]
31 | default:
32 | log.Fatal("usage: govanityurls [CONFIG]")
33 | }
34 | vanity, err := ioutil.ReadFile(configPath)
35 | if err != nil {
36 | log.Fatal(err)
37 | }
38 | h, err := newHandler(vanity)
39 | if err != nil {
40 | log.Fatal(err)
41 | }
42 | http.Handle("/", h)
43 |
44 | port := os.Getenv("PORT")
45 | if port == "" {
46 | port = "8080"
47 | }
48 | if err := http.ListenAndServe(":"+port, nil); err != nil {
49 | log.Fatal(err)
50 | }
51 | }
52 |
53 | func defaultHost(r *http.Request) string {
54 | return r.Host
55 | }
56 |
--------------------------------------------------------------------------------
/vanity.yaml:
--------------------------------------------------------------------------------
1 | host: rakyll.pizza
2 |
3 | paths:
4 | /portmidi:
5 | repo: https://github.com/rakyll/portmidi
6 |
7 | /launchpad:
8 | repo: https://github.com/rakyll/launchpad
9 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/AUTHORS:
--------------------------------------------------------------------------------
1 | # This source code refers to The Go Authors for copyright purposes.
2 | # The master list of authors is in the main Go distribution,
3 | # visible at http://tip.golang.org/AUTHORS.
4 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | # This source code was written by the Go contributors.
2 | # The master list of contributors is in the main Go distribution,
3 | # visible at http://tip.golang.org/CONTRIBUTORS.
4 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2010 The Go Authors. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Google Inc. nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/clone.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2011 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | // Protocol buffer deep copy and merge.
33 | // TODO: RawMessage.
34 |
35 | package proto
36 |
37 | import (
38 | "fmt"
39 | "log"
40 | "reflect"
41 | "strings"
42 | )
43 |
44 | // Clone returns a deep copy of a protocol buffer.
45 | func Clone(src Message) Message {
46 | in := reflect.ValueOf(src)
47 | if in.IsNil() {
48 | return src
49 | }
50 | out := reflect.New(in.Type().Elem())
51 | dst := out.Interface().(Message)
52 | Merge(dst, src)
53 | return dst
54 | }
55 |
56 | // Merger is the interface representing objects that can merge messages of the same type.
57 | type Merger interface {
58 | // Merge merges src into this message.
59 | // Required and optional fields that are set in src will be set to that value in dst.
60 | // Elements of repeated fields will be appended.
61 | //
62 | // Merge may panic if called with a different argument type than the receiver.
63 | Merge(src Message)
64 | }
65 |
66 | // generatedMerger is the custom merge method that generated protos will have.
67 | // We must add this method since a generate Merge method will conflict with
68 | // many existing protos that have a Merge data field already defined.
69 | type generatedMerger interface {
70 | XXX_Merge(src Message)
71 | }
72 |
73 | // Merge merges src into dst.
74 | // Required and optional fields that are set in src will be set to that value in dst.
75 | // Elements of repeated fields will be appended.
76 | // Merge panics if src and dst are not the same type, or if dst is nil.
77 | func Merge(dst, src Message) {
78 | if m, ok := dst.(Merger); ok {
79 | m.Merge(src)
80 | return
81 | }
82 |
83 | in := reflect.ValueOf(src)
84 | out := reflect.ValueOf(dst)
85 | if out.IsNil() {
86 | panic("proto: nil destination")
87 | }
88 | if in.Type() != out.Type() {
89 | panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
90 | }
91 | if in.IsNil() {
92 | return // Merge from nil src is a noop
93 | }
94 | if m, ok := dst.(generatedMerger); ok {
95 | m.XXX_Merge(src)
96 | return
97 | }
98 | mergeStruct(out.Elem(), in.Elem())
99 | }
100 |
101 | func mergeStruct(out, in reflect.Value) {
102 | sprop := GetProperties(in.Type())
103 | for i := 0; i < in.NumField(); i++ {
104 | f := in.Type().Field(i)
105 | if strings.HasPrefix(f.Name, "XXX_") {
106 | continue
107 | }
108 | mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
109 | }
110 |
111 | if emIn, err := extendable(in.Addr().Interface()); err == nil {
112 | emOut, _ := extendable(out.Addr().Interface())
113 | mIn, muIn := emIn.extensionsRead()
114 | if mIn != nil {
115 | mOut := emOut.extensionsWrite()
116 | muIn.Lock()
117 | mergeExtension(mOut, mIn)
118 | muIn.Unlock()
119 | }
120 | }
121 |
122 | uf := in.FieldByName("XXX_unrecognized")
123 | if !uf.IsValid() {
124 | return
125 | }
126 | uin := uf.Bytes()
127 | if len(uin) > 0 {
128 | out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
129 | }
130 | }
131 |
132 | // mergeAny performs a merge between two values of the same type.
133 | // viaPtr indicates whether the values were indirected through a pointer (implying proto2).
134 | // prop is set if this is a struct field (it may be nil).
135 | func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
136 | if in.Type() == protoMessageType {
137 | if !in.IsNil() {
138 | if out.IsNil() {
139 | out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
140 | } else {
141 | Merge(out.Interface().(Message), in.Interface().(Message))
142 | }
143 | }
144 | return
145 | }
146 | switch in.Kind() {
147 | case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
148 | reflect.String, reflect.Uint32, reflect.Uint64:
149 | if !viaPtr && isProto3Zero(in) {
150 | return
151 | }
152 | out.Set(in)
153 | case reflect.Interface:
154 | // Probably a oneof field; copy non-nil values.
155 | if in.IsNil() {
156 | return
157 | }
158 | // Allocate destination if it is not set, or set to a different type.
159 | // Otherwise we will merge as normal.
160 | if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
161 | out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
162 | }
163 | mergeAny(out.Elem(), in.Elem(), false, nil)
164 | case reflect.Map:
165 | if in.Len() == 0 {
166 | return
167 | }
168 | if out.IsNil() {
169 | out.Set(reflect.MakeMap(in.Type()))
170 | }
171 | // For maps with value types of *T or []byte we need to deep copy each value.
172 | elemKind := in.Type().Elem().Kind()
173 | for _, key := range in.MapKeys() {
174 | var val reflect.Value
175 | switch elemKind {
176 | case reflect.Ptr:
177 | val = reflect.New(in.Type().Elem().Elem())
178 | mergeAny(val, in.MapIndex(key), false, nil)
179 | case reflect.Slice:
180 | val = in.MapIndex(key)
181 | val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
182 | default:
183 | val = in.MapIndex(key)
184 | }
185 | out.SetMapIndex(key, val)
186 | }
187 | case reflect.Ptr:
188 | if in.IsNil() {
189 | return
190 | }
191 | if out.IsNil() {
192 | out.Set(reflect.New(in.Elem().Type()))
193 | }
194 | mergeAny(out.Elem(), in.Elem(), true, nil)
195 | case reflect.Slice:
196 | if in.IsNil() {
197 | return
198 | }
199 | if in.Type().Elem().Kind() == reflect.Uint8 {
200 | // []byte is a scalar bytes field, not a repeated field.
201 |
202 | // Edge case: if this is in a proto3 message, a zero length
203 | // bytes field is considered the zero value, and should not
204 | // be merged.
205 | if prop != nil && prop.proto3 && in.Len() == 0 {
206 | return
207 | }
208 |
209 | // Make a deep copy.
210 | // Append to []byte{} instead of []byte(nil) so that we never end up
211 | // with a nil result.
212 | out.SetBytes(append([]byte{}, in.Bytes()...))
213 | return
214 | }
215 | n := in.Len()
216 | if out.IsNil() {
217 | out.Set(reflect.MakeSlice(in.Type(), 0, n))
218 | }
219 | switch in.Type().Elem().Kind() {
220 | case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
221 | reflect.String, reflect.Uint32, reflect.Uint64:
222 | out.Set(reflect.AppendSlice(out, in))
223 | default:
224 | for i := 0; i < n; i++ {
225 | x := reflect.Indirect(reflect.New(in.Type().Elem()))
226 | mergeAny(x, in.Index(i), false, nil)
227 | out.Set(reflect.Append(out, x))
228 | }
229 | }
230 | case reflect.Struct:
231 | mergeStruct(out, in)
232 | default:
233 | // unknown type, so not a protocol buffer
234 | log.Printf("proto: don't know how to copy %v", in)
235 | }
236 | }
237 |
238 | func mergeExtension(out, in map[int32]Extension) {
239 | for extNum, eIn := range in {
240 | eOut := Extension{desc: eIn.desc}
241 | if eIn.value != nil {
242 | v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
243 | mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
244 | eOut.value = v.Interface()
245 | }
246 | if eIn.enc != nil {
247 | eOut.enc = make([]byte, len(eIn.enc))
248 | copy(eOut.enc, eIn.enc)
249 | }
250 |
251 | out[extNum] = eOut
252 | }
253 | }
254 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/deprecated.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2018 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | package proto
33 |
34 | import "errors"
35 |
36 | // Deprecated: do not use.
37 | type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
38 |
39 | // Deprecated: do not use.
40 | func GetStats() Stats { return Stats{} }
41 |
42 | // Deprecated: do not use.
43 | func MarshalMessageSet(interface{}) ([]byte, error) {
44 | return nil, errors.New("proto: not implemented")
45 | }
46 |
47 | // Deprecated: do not use.
48 | func UnmarshalMessageSet([]byte, interface{}) error {
49 | return errors.New("proto: not implemented")
50 | }
51 |
52 | // Deprecated: do not use.
53 | func MarshalMessageSetJSON(interface{}) ([]byte, error) {
54 | return nil, errors.New("proto: not implemented")
55 | }
56 |
57 | // Deprecated: do not use.
58 | func UnmarshalMessageSetJSON([]byte, interface{}) error {
59 | return errors.New("proto: not implemented")
60 | }
61 |
62 | // Deprecated: do not use.
63 | func RegisterMessageSetType(Message, int32, string) {}
64 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/discard.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2017 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | package proto
33 |
34 | import (
35 | "fmt"
36 | "reflect"
37 | "strings"
38 | "sync"
39 | "sync/atomic"
40 | )
41 |
42 | type generatedDiscarder interface {
43 | XXX_DiscardUnknown()
44 | }
45 |
46 | // DiscardUnknown recursively discards all unknown fields from this message
47 | // and all embedded messages.
48 | //
49 | // When unmarshaling a message with unrecognized fields, the tags and values
50 | // of such fields are preserved in the Message. This allows a later call to
51 | // marshal to be able to produce a message that continues to have those
52 | // unrecognized fields. To avoid this, DiscardUnknown is used to
53 | // explicitly clear the unknown fields after unmarshaling.
54 | //
55 | // For proto2 messages, the unknown fields of message extensions are only
56 | // discarded from messages that have been accessed via GetExtension.
57 | func DiscardUnknown(m Message) {
58 | if m, ok := m.(generatedDiscarder); ok {
59 | m.XXX_DiscardUnknown()
60 | return
61 | }
62 | // TODO: Dynamically populate a InternalMessageInfo for legacy messages,
63 | // but the master branch has no implementation for InternalMessageInfo,
64 | // so it would be more work to replicate that approach.
65 | discardLegacy(m)
66 | }
67 |
68 | // DiscardUnknown recursively discards all unknown fields.
69 | func (a *InternalMessageInfo) DiscardUnknown(m Message) {
70 | di := atomicLoadDiscardInfo(&a.discard)
71 | if di == nil {
72 | di = getDiscardInfo(reflect.TypeOf(m).Elem())
73 | atomicStoreDiscardInfo(&a.discard, di)
74 | }
75 | di.discard(toPointer(&m))
76 | }
77 |
78 | type discardInfo struct {
79 | typ reflect.Type
80 |
81 | initialized int32 // 0: only typ is valid, 1: everything is valid
82 | lock sync.Mutex
83 |
84 | fields []discardFieldInfo
85 | unrecognized field
86 | }
87 |
88 | type discardFieldInfo struct {
89 | field field // Offset of field, guaranteed to be valid
90 | discard func(src pointer)
91 | }
92 |
93 | var (
94 | discardInfoMap = map[reflect.Type]*discardInfo{}
95 | discardInfoLock sync.Mutex
96 | )
97 |
98 | func getDiscardInfo(t reflect.Type) *discardInfo {
99 | discardInfoLock.Lock()
100 | defer discardInfoLock.Unlock()
101 | di := discardInfoMap[t]
102 | if di == nil {
103 | di = &discardInfo{typ: t}
104 | discardInfoMap[t] = di
105 | }
106 | return di
107 | }
108 |
109 | func (di *discardInfo) discard(src pointer) {
110 | if src.isNil() {
111 | return // Nothing to do.
112 | }
113 |
114 | if atomic.LoadInt32(&di.initialized) == 0 {
115 | di.computeDiscardInfo()
116 | }
117 |
118 | for _, fi := range di.fields {
119 | sfp := src.offset(fi.field)
120 | fi.discard(sfp)
121 | }
122 |
123 | // For proto2 messages, only discard unknown fields in message extensions
124 | // that have been accessed via GetExtension.
125 | if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
126 | // Ignore lock since DiscardUnknown is not concurrency safe.
127 | emm, _ := em.extensionsRead()
128 | for _, mx := range emm {
129 | if m, ok := mx.value.(Message); ok {
130 | DiscardUnknown(m)
131 | }
132 | }
133 | }
134 |
135 | if di.unrecognized.IsValid() {
136 | *src.offset(di.unrecognized).toBytes() = nil
137 | }
138 | }
139 |
140 | func (di *discardInfo) computeDiscardInfo() {
141 | di.lock.Lock()
142 | defer di.lock.Unlock()
143 | if di.initialized != 0 {
144 | return
145 | }
146 | t := di.typ
147 | n := t.NumField()
148 |
149 | for i := 0; i < n; i++ {
150 | f := t.Field(i)
151 | if strings.HasPrefix(f.Name, "XXX_") {
152 | continue
153 | }
154 |
155 | dfi := discardFieldInfo{field: toField(&f)}
156 | tf := f.Type
157 |
158 | // Unwrap tf to get its most basic type.
159 | var isPointer, isSlice bool
160 | if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
161 | isSlice = true
162 | tf = tf.Elem()
163 | }
164 | if tf.Kind() == reflect.Ptr {
165 | isPointer = true
166 | tf = tf.Elem()
167 | }
168 | if isPointer && isSlice && tf.Kind() != reflect.Struct {
169 | panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
170 | }
171 |
172 | switch tf.Kind() {
173 | case reflect.Struct:
174 | switch {
175 | case !isPointer:
176 | panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
177 | case isSlice: // E.g., []*pb.T
178 | di := getDiscardInfo(tf)
179 | dfi.discard = func(src pointer) {
180 | sps := src.getPointerSlice()
181 | for _, sp := range sps {
182 | if !sp.isNil() {
183 | di.discard(sp)
184 | }
185 | }
186 | }
187 | default: // E.g., *pb.T
188 | di := getDiscardInfo(tf)
189 | dfi.discard = func(src pointer) {
190 | sp := src.getPointer()
191 | if !sp.isNil() {
192 | di.discard(sp)
193 | }
194 | }
195 | }
196 | case reflect.Map:
197 | switch {
198 | case isPointer || isSlice:
199 | panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
200 | default: // E.g., map[K]V
201 | if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
202 | dfi.discard = func(src pointer) {
203 | sm := src.asPointerTo(tf).Elem()
204 | if sm.Len() == 0 {
205 | return
206 | }
207 | for _, key := range sm.MapKeys() {
208 | val := sm.MapIndex(key)
209 | DiscardUnknown(val.Interface().(Message))
210 | }
211 | }
212 | } else {
213 | dfi.discard = func(pointer) {} // Noop
214 | }
215 | }
216 | case reflect.Interface:
217 | // Must be oneof field.
218 | switch {
219 | case isPointer || isSlice:
220 | panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
221 | default: // E.g., interface{}
222 | // TODO: Make this faster?
223 | dfi.discard = func(src pointer) {
224 | su := src.asPointerTo(tf).Elem()
225 | if !su.IsNil() {
226 | sv := su.Elem().Elem().Field(0)
227 | if sv.Kind() == reflect.Ptr && sv.IsNil() {
228 | return
229 | }
230 | switch sv.Type().Kind() {
231 | case reflect.Ptr: // Proto struct (e.g., *T)
232 | DiscardUnknown(sv.Interface().(Message))
233 | }
234 | }
235 | }
236 | }
237 | default:
238 | continue
239 | }
240 | di.fields = append(di.fields, dfi)
241 | }
242 |
243 | di.unrecognized = invalidField
244 | if f, ok := t.FieldByName("XXX_unrecognized"); ok {
245 | if f.Type != reflect.TypeOf([]byte{}) {
246 | panic("expected XXX_unrecognized to be of type []byte")
247 | }
248 | di.unrecognized = toField(&f)
249 | }
250 |
251 | atomic.StoreInt32(&di.initialized, 1)
252 | }
253 |
254 | func discardLegacy(m Message) {
255 | v := reflect.ValueOf(m)
256 | if v.Kind() != reflect.Ptr || v.IsNil() {
257 | return
258 | }
259 | v = v.Elem()
260 | if v.Kind() != reflect.Struct {
261 | return
262 | }
263 | t := v.Type()
264 |
265 | for i := 0; i < v.NumField(); i++ {
266 | f := t.Field(i)
267 | if strings.HasPrefix(f.Name, "XXX_") {
268 | continue
269 | }
270 | vf := v.Field(i)
271 | tf := f.Type
272 |
273 | // Unwrap tf to get its most basic type.
274 | var isPointer, isSlice bool
275 | if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
276 | isSlice = true
277 | tf = tf.Elem()
278 | }
279 | if tf.Kind() == reflect.Ptr {
280 | isPointer = true
281 | tf = tf.Elem()
282 | }
283 | if isPointer && isSlice && tf.Kind() != reflect.Struct {
284 | panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name))
285 | }
286 |
287 | switch tf.Kind() {
288 | case reflect.Struct:
289 | switch {
290 | case !isPointer:
291 | panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name))
292 | case isSlice: // E.g., []*pb.T
293 | for j := 0; j < vf.Len(); j++ {
294 | discardLegacy(vf.Index(j).Interface().(Message))
295 | }
296 | default: // E.g., *pb.T
297 | discardLegacy(vf.Interface().(Message))
298 | }
299 | case reflect.Map:
300 | switch {
301 | case isPointer || isSlice:
302 | panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name))
303 | default: // E.g., map[K]V
304 | tv := vf.Type().Elem()
305 | if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)
306 | for _, key := range vf.MapKeys() {
307 | val := vf.MapIndex(key)
308 | discardLegacy(val.Interface().(Message))
309 | }
310 | }
311 | }
312 | case reflect.Interface:
313 | // Must be oneof field.
314 | switch {
315 | case isPointer || isSlice:
316 | panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name))
317 | default: // E.g., test_proto.isCommunique_Union interface
318 | if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" {
319 | vf = vf.Elem() // E.g., *test_proto.Communique_Msg
320 | if !vf.IsNil() {
321 | vf = vf.Elem() // E.g., test_proto.Communique_Msg
322 | vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value
323 | if vf.Kind() == reflect.Ptr {
324 | discardLegacy(vf.Interface().(Message))
325 | }
326 | }
327 | }
328 | }
329 | }
330 | }
331 |
332 | if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() {
333 | if vf.Type() != reflect.TypeOf([]byte{}) {
334 | panic("expected XXX_unrecognized to be of type []byte")
335 | }
336 | vf.Set(reflect.ValueOf([]byte(nil)))
337 | }
338 |
339 | // For proto2 messages, only discard unknown fields in message extensions
340 | // that have been accessed via GetExtension.
341 | if em, err := extendable(m); err == nil {
342 | // Ignore lock since discardLegacy is not concurrency safe.
343 | emm, _ := em.extensionsRead()
344 | for _, mx := range emm {
345 | if m, ok := mx.value.(Message); ok {
346 | discardLegacy(m)
347 | }
348 | }
349 | }
350 | }
351 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/encode.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2010 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | package proto
33 |
34 | /*
35 | * Routines for encoding data into the wire format for protocol buffers.
36 | */
37 |
38 | import (
39 | "errors"
40 | "reflect"
41 | )
42 |
43 | var (
44 | // errRepeatedHasNil is the error returned if Marshal is called with
45 | // a struct with a repeated field containing a nil element.
46 | errRepeatedHasNil = errors.New("proto: repeated field has nil element")
47 |
48 | // errOneofHasNil is the error returned if Marshal is called with
49 | // a struct with a oneof field containing a nil element.
50 | errOneofHasNil = errors.New("proto: oneof field has nil value")
51 |
52 | // ErrNil is the error returned if Marshal is called with nil.
53 | ErrNil = errors.New("proto: Marshal called with nil")
54 |
55 | // ErrTooLarge is the error returned if Marshal is called with a
56 | // message that encodes to >2GB.
57 | ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
58 | )
59 |
60 | // The fundamental encoders that put bytes on the wire.
61 | // Those that take integer types all accept uint64 and are
62 | // therefore of type valueEncoder.
63 |
64 | const maxVarintBytes = 10 // maximum length of a varint
65 |
66 | // EncodeVarint returns the varint encoding of x.
67 | // This is the format for the
68 | // int32, int64, uint32, uint64, bool, and enum
69 | // protocol buffer types.
70 | // Not used by the package itself, but helpful to clients
71 | // wishing to use the same encoding.
72 | func EncodeVarint(x uint64) []byte {
73 | var buf [maxVarintBytes]byte
74 | var n int
75 | for n = 0; x > 127; n++ {
76 | buf[n] = 0x80 | uint8(x&0x7F)
77 | x >>= 7
78 | }
79 | buf[n] = uint8(x)
80 | n++
81 | return buf[0:n]
82 | }
83 |
84 | // EncodeVarint writes a varint-encoded integer to the Buffer.
85 | // This is the format for the
86 | // int32, int64, uint32, uint64, bool, and enum
87 | // protocol buffer types.
88 | func (p *Buffer) EncodeVarint(x uint64) error {
89 | for x >= 1<<7 {
90 | p.buf = append(p.buf, uint8(x&0x7f|0x80))
91 | x >>= 7
92 | }
93 | p.buf = append(p.buf, uint8(x))
94 | return nil
95 | }
96 |
97 | // SizeVarint returns the varint encoding size of an integer.
98 | func SizeVarint(x uint64) int {
99 | switch {
100 | case x < 1<<7:
101 | return 1
102 | case x < 1<<14:
103 | return 2
104 | case x < 1<<21:
105 | return 3
106 | case x < 1<<28:
107 | return 4
108 | case x < 1<<35:
109 | return 5
110 | case x < 1<<42:
111 | return 6
112 | case x < 1<<49:
113 | return 7
114 | case x < 1<<56:
115 | return 8
116 | case x < 1<<63:
117 | return 9
118 | }
119 | return 10
120 | }
121 |
122 | // EncodeFixed64 writes a 64-bit integer to the Buffer.
123 | // This is the format for the
124 | // fixed64, sfixed64, and double protocol buffer types.
125 | func (p *Buffer) EncodeFixed64(x uint64) error {
126 | p.buf = append(p.buf,
127 | uint8(x),
128 | uint8(x>>8),
129 | uint8(x>>16),
130 | uint8(x>>24),
131 | uint8(x>>32),
132 | uint8(x>>40),
133 | uint8(x>>48),
134 | uint8(x>>56))
135 | return nil
136 | }
137 |
138 | // EncodeFixed32 writes a 32-bit integer to the Buffer.
139 | // This is the format for the
140 | // fixed32, sfixed32, and float protocol buffer types.
141 | func (p *Buffer) EncodeFixed32(x uint64) error {
142 | p.buf = append(p.buf,
143 | uint8(x),
144 | uint8(x>>8),
145 | uint8(x>>16),
146 | uint8(x>>24))
147 | return nil
148 | }
149 |
150 | // EncodeZigzag64 writes a zigzag-encoded 64-bit integer
151 | // to the Buffer.
152 | // This is the format used for the sint64 protocol buffer type.
153 | func (p *Buffer) EncodeZigzag64(x uint64) error {
154 | // use signed number to get arithmetic right shift.
155 | return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
156 | }
157 |
158 | // EncodeZigzag32 writes a zigzag-encoded 32-bit integer
159 | // to the Buffer.
160 | // This is the format used for the sint32 protocol buffer type.
161 | func (p *Buffer) EncodeZigzag32(x uint64) error {
162 | // use signed number to get arithmetic right shift.
163 | return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
164 | }
165 |
166 | // EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
167 | // This is the format used for the bytes protocol buffer
168 | // type and for embedded messages.
169 | func (p *Buffer) EncodeRawBytes(b []byte) error {
170 | p.EncodeVarint(uint64(len(b)))
171 | p.buf = append(p.buf, b...)
172 | return nil
173 | }
174 |
175 | // EncodeStringBytes writes an encoded string to the Buffer.
176 | // This is the format used for the proto2 string type.
177 | func (p *Buffer) EncodeStringBytes(s string) error {
178 | p.EncodeVarint(uint64(len(s)))
179 | p.buf = append(p.buf, s...)
180 | return nil
181 | }
182 |
183 | // Marshaler is the interface representing objects that can marshal themselves.
184 | type Marshaler interface {
185 | Marshal() ([]byte, error)
186 | }
187 |
188 | // EncodeMessage writes the protocol buffer to the Buffer,
189 | // prefixed by a varint-encoded length.
190 | func (p *Buffer) EncodeMessage(pb Message) error {
191 | siz := Size(pb)
192 | p.EncodeVarint(uint64(siz))
193 | return p.Marshal(pb)
194 | }
195 |
196 | // All protocol buffer fields are nillable, but be careful.
197 | func isNil(v reflect.Value) bool {
198 | switch v.Kind() {
199 | case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
200 | return v.IsNil()
201 | }
202 | return false
203 | }
204 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/equal.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2011 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | // Protocol buffer comparison.
33 |
34 | package proto
35 |
36 | import (
37 | "bytes"
38 | "log"
39 | "reflect"
40 | "strings"
41 | )
42 |
43 | /*
44 | Equal returns true iff protocol buffers a and b are equal.
45 | The arguments must both be pointers to protocol buffer structs.
46 |
47 | Equality is defined in this way:
48 | - Two messages are equal iff they are the same type,
49 | corresponding fields are equal, unknown field sets
50 | are equal, and extensions sets are equal.
51 | - Two set scalar fields are equal iff their values are equal.
52 | If the fields are of a floating-point type, remember that
53 | NaN != x for all x, including NaN. If the message is defined
54 | in a proto3 .proto file, fields are not "set"; specifically,
55 | zero length proto3 "bytes" fields are equal (nil == {}).
56 | - Two repeated fields are equal iff their lengths are the same,
57 | and their corresponding elements are equal. Note a "bytes" field,
58 | although represented by []byte, is not a repeated field and the
59 | rule for the scalar fields described above applies.
60 | - Two unset fields are equal.
61 | - Two unknown field sets are equal if their current
62 | encoded state is equal.
63 | - Two extension sets are equal iff they have corresponding
64 | elements that are pairwise equal.
65 | - Two map fields are equal iff their lengths are the same,
66 | and they contain the same set of elements. Zero-length map
67 | fields are equal.
68 | - Every other combination of things are not equal.
69 |
70 | The return value is undefined if a and b are not protocol buffers.
71 | */
72 | func Equal(a, b Message) bool {
73 | if a == nil || b == nil {
74 | return a == b
75 | }
76 | v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
77 | if v1.Type() != v2.Type() {
78 | return false
79 | }
80 | if v1.Kind() == reflect.Ptr {
81 | if v1.IsNil() {
82 | return v2.IsNil()
83 | }
84 | if v2.IsNil() {
85 | return false
86 | }
87 | v1, v2 = v1.Elem(), v2.Elem()
88 | }
89 | if v1.Kind() != reflect.Struct {
90 | return false
91 | }
92 | return equalStruct(v1, v2)
93 | }
94 |
95 | // v1 and v2 are known to have the same type.
96 | func equalStruct(v1, v2 reflect.Value) bool {
97 | sprop := GetProperties(v1.Type())
98 | for i := 0; i < v1.NumField(); i++ {
99 | f := v1.Type().Field(i)
100 | if strings.HasPrefix(f.Name, "XXX_") {
101 | continue
102 | }
103 | f1, f2 := v1.Field(i), v2.Field(i)
104 | if f.Type.Kind() == reflect.Ptr {
105 | if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
106 | // both unset
107 | continue
108 | } else if n1 != n2 {
109 | // set/unset mismatch
110 | return false
111 | }
112 | f1, f2 = f1.Elem(), f2.Elem()
113 | }
114 | if !equalAny(f1, f2, sprop.Prop[i]) {
115 | return false
116 | }
117 | }
118 |
119 | if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
120 | em2 := v2.FieldByName("XXX_InternalExtensions")
121 | if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
122 | return false
123 | }
124 | }
125 |
126 | if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
127 | em2 := v2.FieldByName("XXX_extensions")
128 | if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
129 | return false
130 | }
131 | }
132 |
133 | uf := v1.FieldByName("XXX_unrecognized")
134 | if !uf.IsValid() {
135 | return true
136 | }
137 |
138 | u1 := uf.Bytes()
139 | u2 := v2.FieldByName("XXX_unrecognized").Bytes()
140 | return bytes.Equal(u1, u2)
141 | }
142 |
143 | // v1 and v2 are known to have the same type.
144 | // prop may be nil.
145 | func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
146 | if v1.Type() == protoMessageType {
147 | m1, _ := v1.Interface().(Message)
148 | m2, _ := v2.Interface().(Message)
149 | return Equal(m1, m2)
150 | }
151 | switch v1.Kind() {
152 | case reflect.Bool:
153 | return v1.Bool() == v2.Bool()
154 | case reflect.Float32, reflect.Float64:
155 | return v1.Float() == v2.Float()
156 | case reflect.Int32, reflect.Int64:
157 | return v1.Int() == v2.Int()
158 | case reflect.Interface:
159 | // Probably a oneof field; compare the inner values.
160 | n1, n2 := v1.IsNil(), v2.IsNil()
161 | if n1 || n2 {
162 | return n1 == n2
163 | }
164 | e1, e2 := v1.Elem(), v2.Elem()
165 | if e1.Type() != e2.Type() {
166 | return false
167 | }
168 | return equalAny(e1, e2, nil)
169 | case reflect.Map:
170 | if v1.Len() != v2.Len() {
171 | return false
172 | }
173 | for _, key := range v1.MapKeys() {
174 | val2 := v2.MapIndex(key)
175 | if !val2.IsValid() {
176 | // This key was not found in the second map.
177 | return false
178 | }
179 | if !equalAny(v1.MapIndex(key), val2, nil) {
180 | return false
181 | }
182 | }
183 | return true
184 | case reflect.Ptr:
185 | // Maps may have nil values in them, so check for nil.
186 | if v1.IsNil() && v2.IsNil() {
187 | return true
188 | }
189 | if v1.IsNil() != v2.IsNil() {
190 | return false
191 | }
192 | return equalAny(v1.Elem(), v2.Elem(), prop)
193 | case reflect.Slice:
194 | if v1.Type().Elem().Kind() == reflect.Uint8 {
195 | // short circuit: []byte
196 |
197 | // Edge case: if this is in a proto3 message, a zero length
198 | // bytes field is considered the zero value.
199 | if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
200 | return true
201 | }
202 | if v1.IsNil() != v2.IsNil() {
203 | return false
204 | }
205 | return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
206 | }
207 |
208 | if v1.Len() != v2.Len() {
209 | return false
210 | }
211 | for i := 0; i < v1.Len(); i++ {
212 | if !equalAny(v1.Index(i), v2.Index(i), prop) {
213 | return false
214 | }
215 | }
216 | return true
217 | case reflect.String:
218 | return v1.Interface().(string) == v2.Interface().(string)
219 | case reflect.Struct:
220 | return equalStruct(v1, v2)
221 | case reflect.Uint32, reflect.Uint64:
222 | return v1.Uint() == v2.Uint()
223 | }
224 |
225 | // unknown type, so not a protocol buffer
226 | log.Printf("proto: don't know how to compare %v", v1)
227 | return false
228 | }
229 |
230 | // base is the struct type that the extensions are based on.
231 | // x1 and x2 are InternalExtensions.
232 | func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
233 | em1, _ := x1.extensionsRead()
234 | em2, _ := x2.extensionsRead()
235 | return equalExtMap(base, em1, em2)
236 | }
237 |
238 | func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
239 | if len(em1) != len(em2) {
240 | return false
241 | }
242 |
243 | for extNum, e1 := range em1 {
244 | e2, ok := em2[extNum]
245 | if !ok {
246 | return false
247 | }
248 |
249 | m1 := extensionAsLegacyType(e1.value)
250 | m2 := extensionAsLegacyType(e2.value)
251 |
252 | if m1 == nil && m2 == nil {
253 | // Both have only encoded form.
254 | if bytes.Equal(e1.enc, e2.enc) {
255 | continue
256 | }
257 | // The bytes are different, but the extensions might still be
258 | // equal. We need to decode them to compare.
259 | }
260 |
261 | if m1 != nil && m2 != nil {
262 | // Both are unencoded.
263 | if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
264 | return false
265 | }
266 | continue
267 | }
268 |
269 | // At least one is encoded. To do a semantically correct comparison
270 | // we need to unmarshal them first.
271 | var desc *ExtensionDesc
272 | if m := extensionMaps[base]; m != nil {
273 | desc = m[extNum]
274 | }
275 | if desc == nil {
276 | // If both have only encoded form and the bytes are the same,
277 | // it is handled above. We get here when the bytes are different.
278 | // We don't know how to decode it, so just compare them as byte
279 | // slices.
280 | log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
281 | return false
282 | }
283 | var err error
284 | if m1 == nil {
285 | m1, err = decodeExtension(e1.enc, desc)
286 | }
287 | if m2 == nil && err == nil {
288 | m2, err = decodeExtension(e2.enc, desc)
289 | }
290 | if err != nil {
291 | // The encoded form is invalid.
292 | log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
293 | return false
294 | }
295 | if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
296 | return false
297 | }
298 | }
299 |
300 | return true
301 | }
302 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/message_set.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2010 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | package proto
33 |
34 | /*
35 | * Support for message sets.
36 | */
37 |
38 | import (
39 | "errors"
40 | )
41 |
42 | // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
43 | // A message type ID is required for storing a protocol buffer in a message set.
44 | var errNoMessageTypeID = errors.New("proto does not have a message type ID")
45 |
46 | // The first two types (_MessageSet_Item and messageSet)
47 | // model what the protocol compiler produces for the following protocol message:
48 | // message MessageSet {
49 | // repeated group Item = 1 {
50 | // required int32 type_id = 2;
51 | // required string message = 3;
52 | // };
53 | // }
54 | // That is the MessageSet wire format. We can't use a proto to generate these
55 | // because that would introduce a circular dependency between it and this package.
56 |
57 | type _MessageSet_Item struct {
58 | TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
59 | Message []byte `protobuf:"bytes,3,req,name=message"`
60 | }
61 |
62 | type messageSet struct {
63 | Item []*_MessageSet_Item `protobuf:"group,1,rep"`
64 | XXX_unrecognized []byte
65 | // TODO: caching?
66 | }
67 |
68 | // Make sure messageSet is a Message.
69 | var _ Message = (*messageSet)(nil)
70 |
71 | // messageTypeIder is an interface satisfied by a protocol buffer type
72 | // that may be stored in a MessageSet.
73 | type messageTypeIder interface {
74 | MessageTypeId() int32
75 | }
76 |
77 | func (ms *messageSet) find(pb Message) *_MessageSet_Item {
78 | mti, ok := pb.(messageTypeIder)
79 | if !ok {
80 | return nil
81 | }
82 | id := mti.MessageTypeId()
83 | for _, item := range ms.Item {
84 | if *item.TypeId == id {
85 | return item
86 | }
87 | }
88 | return nil
89 | }
90 |
91 | func (ms *messageSet) Has(pb Message) bool {
92 | return ms.find(pb) != nil
93 | }
94 |
95 | func (ms *messageSet) Unmarshal(pb Message) error {
96 | if item := ms.find(pb); item != nil {
97 | return Unmarshal(item.Message, pb)
98 | }
99 | if _, ok := pb.(messageTypeIder); !ok {
100 | return errNoMessageTypeID
101 | }
102 | return nil // TODO: return error instead?
103 | }
104 |
105 | func (ms *messageSet) Marshal(pb Message) error {
106 | msg, err := Marshal(pb)
107 | if err != nil {
108 | return err
109 | }
110 | if item := ms.find(pb); item != nil {
111 | // reuse existing item
112 | item.Message = msg
113 | return nil
114 | }
115 |
116 | mti, ok := pb.(messageTypeIder)
117 | if !ok {
118 | return errNoMessageTypeID
119 | }
120 |
121 | mtid := mti.MessageTypeId()
122 | ms.Item = append(ms.Item, &_MessageSet_Item{
123 | TypeId: &mtid,
124 | Message: msg,
125 | })
126 | return nil
127 | }
128 |
129 | func (ms *messageSet) Reset() { *ms = messageSet{} }
130 | func (ms *messageSet) String() string { return CompactTextString(ms) }
131 | func (*messageSet) ProtoMessage() {}
132 |
133 | // Support for the message_set_wire_format message option.
134 |
135 | func skipVarint(buf []byte) []byte {
136 | i := 0
137 | for ; buf[i]&0x80 != 0; i++ {
138 | }
139 | return buf[i+1:]
140 | }
141 |
142 | // unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
143 | // It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
144 | func unmarshalMessageSet(buf []byte, exts interface{}) error {
145 | var m map[int32]Extension
146 | switch exts := exts.(type) {
147 | case *XXX_InternalExtensions:
148 | m = exts.extensionsWrite()
149 | case map[int32]Extension:
150 | m = exts
151 | default:
152 | return errors.New("proto: not an extension map")
153 | }
154 |
155 | ms := new(messageSet)
156 | if err := Unmarshal(buf, ms); err != nil {
157 | return err
158 | }
159 | for _, item := range ms.Item {
160 | id := *item.TypeId
161 | msg := item.Message
162 |
163 | // Restore wire type and field number varint, plus length varint.
164 | // Be careful to preserve duplicate items.
165 | b := EncodeVarint(uint64(id)<<3 | WireBytes)
166 | if ext, ok := m[id]; ok {
167 | // Existing data; rip off the tag and length varint
168 | // so we join the new data correctly.
169 | // We can assume that ext.enc is set because we are unmarshaling.
170 | o := ext.enc[len(b):] // skip wire type and field number
171 | _, n := DecodeVarint(o) // calculate length of length varint
172 | o = o[n:] // skip length varint
173 | msg = append(o, msg...) // join old data and new data
174 | }
175 | b = append(b, EncodeVarint(uint64(len(msg)))...)
176 | b = append(b, msg...)
177 |
178 | m[id] = Extension{enc: b}
179 | }
180 | return nil
181 | }
182 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go:
--------------------------------------------------------------------------------
1 | // Go support for Protocol Buffers - Google's data interchange format
2 | //
3 | // Copyright 2012 The Go Authors. All rights reserved.
4 | // https://github.com/golang/protobuf
5 | //
6 | // Redistribution and use in source and binary forms, with or without
7 | // modification, are permitted provided that the following conditions are
8 | // met:
9 | //
10 | // * Redistributions of source code must retain the above copyright
11 | // notice, this list of conditions and the following disclaimer.
12 | // * Redistributions in binary form must reproduce the above
13 | // copyright notice, this list of conditions and the following disclaimer
14 | // in the documentation and/or other materials provided with the
15 | // distribution.
16 | // * Neither the name of Google Inc. nor the names of its
17 | // contributors may be used to endorse or promote products derived from
18 | // this software without specific prior written permission.
19 | //
20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
32 | // +build !purego,!appengine,!js
33 |
34 | // This file contains the implementation of the proto field accesses using package unsafe.
35 |
36 | package proto
37 |
38 | import (
39 | "reflect"
40 | "sync/atomic"
41 | "unsafe"
42 | )
43 |
44 | const unsafeAllowed = true
45 |
46 | // A field identifies a field in a struct, accessible from a pointer.
47 | // In this implementation, a field is identified by its byte offset from the start of the struct.
48 | type field uintptr
49 |
50 | // toField returns a field equivalent to the given reflect field.
51 | func toField(f *reflect.StructField) field {
52 | return field(f.Offset)
53 | }
54 |
55 | // invalidField is an invalid field identifier.
56 | const invalidField = ^field(0)
57 |
58 | // zeroField is a noop when calling pointer.offset.
59 | const zeroField = field(0)
60 |
61 | // IsValid reports whether the field identifier is valid.
62 | func (f field) IsValid() bool {
63 | return f != invalidField
64 | }
65 |
66 | // The pointer type below is for the new table-driven encoder/decoder.
67 | // The implementation here uses unsafe.Pointer to create a generic pointer.
68 | // In pointer_reflect.go we use reflect instead of unsafe to implement
69 | // the same (but slower) interface.
70 | type pointer struct {
71 | p unsafe.Pointer
72 | }
73 |
74 | // size of pointer
75 | var ptrSize = unsafe.Sizeof(uintptr(0))
76 |
77 | // toPointer converts an interface of pointer type to a pointer
78 | // that points to the same target.
79 | func toPointer(i *Message) pointer {
80 | // Super-tricky - read pointer out of data word of interface value.
81 | // Saves ~25ns over the equivalent:
82 | // return valToPointer(reflect.ValueOf(*i))
83 | return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
84 | }
85 |
86 | // toAddrPointer converts an interface to a pointer that points to
87 | // the interface data.
88 | func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) {
89 | // Super-tricky - read or get the address of data word of interface value.
90 | if isptr {
91 | // The interface is of pointer type, thus it is a direct interface.
92 | // The data word is the pointer data itself. We take its address.
93 | p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
94 | } else {
95 | // The interface is not of pointer type. The data word is the pointer
96 | // to the data.
97 | p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
98 | }
99 | if deref {
100 | p.p = *(*unsafe.Pointer)(p.p)
101 | }
102 | return p
103 | }
104 |
105 | // valToPointer converts v to a pointer. v must be of pointer type.
106 | func valToPointer(v reflect.Value) pointer {
107 | return pointer{p: unsafe.Pointer(v.Pointer())}
108 | }
109 |
110 | // offset converts from a pointer to a structure to a pointer to
111 | // one of its fields.
112 | func (p pointer) offset(f field) pointer {
113 | // For safety, we should panic if !f.IsValid, however calling panic causes
114 | // this to no longer be inlineable, which is a serious performance cost.
115 | /*
116 | if !f.IsValid() {
117 | panic("invalid field")
118 | }
119 | */
120 | return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
121 | }
122 |
123 | func (p pointer) isNil() bool {
124 | return p.p == nil
125 | }
126 |
127 | func (p pointer) toInt64() *int64 {
128 | return (*int64)(p.p)
129 | }
130 | func (p pointer) toInt64Ptr() **int64 {
131 | return (**int64)(p.p)
132 | }
133 | func (p pointer) toInt64Slice() *[]int64 {
134 | return (*[]int64)(p.p)
135 | }
136 | func (p pointer) toInt32() *int32 {
137 | return (*int32)(p.p)
138 | }
139 |
140 | // See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
141 | /*
142 | func (p pointer) toInt32Ptr() **int32 {
143 | return (**int32)(p.p)
144 | }
145 | func (p pointer) toInt32Slice() *[]int32 {
146 | return (*[]int32)(p.p)
147 | }
148 | */
149 | func (p pointer) getInt32Ptr() *int32 {
150 | return *(**int32)(p.p)
151 | }
152 | func (p pointer) setInt32Ptr(v int32) {
153 | *(**int32)(p.p) = &v
154 | }
155 |
156 | // getInt32Slice loads a []int32 from p.
157 | // The value returned is aliased with the original slice.
158 | // This behavior differs from the implementation in pointer_reflect.go.
159 | func (p pointer) getInt32Slice() []int32 {
160 | return *(*[]int32)(p.p)
161 | }
162 |
163 | // setInt32Slice stores a []int32 to p.
164 | // The value set is aliased with the input slice.
165 | // This behavior differs from the implementation in pointer_reflect.go.
166 | func (p pointer) setInt32Slice(v []int32) {
167 | *(*[]int32)(p.p) = v
168 | }
169 |
170 | // TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
171 | func (p pointer) appendInt32Slice(v int32) {
172 | s := (*[]int32)(p.p)
173 | *s = append(*s, v)
174 | }
175 |
176 | func (p pointer) toUint64() *uint64 {
177 | return (*uint64)(p.p)
178 | }
179 | func (p pointer) toUint64Ptr() **uint64 {
180 | return (**uint64)(p.p)
181 | }
182 | func (p pointer) toUint64Slice() *[]uint64 {
183 | return (*[]uint64)(p.p)
184 | }
185 | func (p pointer) toUint32() *uint32 {
186 | return (*uint32)(p.p)
187 | }
188 | func (p pointer) toUint32Ptr() **uint32 {
189 | return (**uint32)(p.p)
190 | }
191 | func (p pointer) toUint32Slice() *[]uint32 {
192 | return (*[]uint32)(p.p)
193 | }
194 | func (p pointer) toBool() *bool {
195 | return (*bool)(p.p)
196 | }
197 | func (p pointer) toBoolPtr() **bool {
198 | return (**bool)(p.p)
199 | }
200 | func (p pointer) toBoolSlice() *[]bool {
201 | return (*[]bool)(p.p)
202 | }
203 | func (p pointer) toFloat64() *float64 {
204 | return (*float64)(p.p)
205 | }
206 | func (p pointer) toFloat64Ptr() **float64 {
207 | return (**float64)(p.p)
208 | }
209 | func (p pointer) toFloat64Slice() *[]float64 {
210 | return (*[]float64)(p.p)
211 | }
212 | func (p pointer) toFloat32() *float32 {
213 | return (*float32)(p.p)
214 | }
215 | func (p pointer) toFloat32Ptr() **float32 {
216 | return (**float32)(p.p)
217 | }
218 | func (p pointer) toFloat32Slice() *[]float32 {
219 | return (*[]float32)(p.p)
220 | }
221 | func (p pointer) toString() *string {
222 | return (*string)(p.p)
223 | }
224 | func (p pointer) toStringPtr() **string {
225 | return (**string)(p.p)
226 | }
227 | func (p pointer) toStringSlice() *[]string {
228 | return (*[]string)(p.p)
229 | }
230 | func (p pointer) toBytes() *[]byte {
231 | return (*[]byte)(p.p)
232 | }
233 | func (p pointer) toBytesSlice() *[][]byte {
234 | return (*[][]byte)(p.p)
235 | }
236 | func (p pointer) toExtensions() *XXX_InternalExtensions {
237 | return (*XXX_InternalExtensions)(p.p)
238 | }
239 | func (p pointer) toOldExtensions() *map[int32]Extension {
240 | return (*map[int32]Extension)(p.p)
241 | }
242 |
243 | // getPointerSlice loads []*T from p as a []pointer.
244 | // The value returned is aliased with the original slice.
245 | // This behavior differs from the implementation in pointer_reflect.go.
246 | func (p pointer) getPointerSlice() []pointer {
247 | // Super-tricky - p should point to a []*T where T is a
248 | // message type. We load it as []pointer.
249 | return *(*[]pointer)(p.p)
250 | }
251 |
252 | // setPointerSlice stores []pointer into p as a []*T.
253 | // The value set is aliased with the input slice.
254 | // This behavior differs from the implementation in pointer_reflect.go.
255 | func (p pointer) setPointerSlice(v []pointer) {
256 | // Super-tricky - p should point to a []*T where T is a
257 | // message type. We store it as []pointer.
258 | *(*[]pointer)(p.p) = v
259 | }
260 |
261 | // getPointer loads the pointer at p and returns it.
262 | func (p pointer) getPointer() pointer {
263 | return pointer{p: *(*unsafe.Pointer)(p.p)}
264 | }
265 |
266 | // setPointer stores the pointer q at p.
267 | func (p pointer) setPointer(q pointer) {
268 | *(*unsafe.Pointer)(p.p) = q.p
269 | }
270 |
271 | // append q to the slice pointed to by p.
272 | func (p pointer) appendPointer(q pointer) {
273 | s := (*[]unsafe.Pointer)(p.p)
274 | *s = append(*s, q.p)
275 | }
276 |
277 | // getInterfacePointer returns a pointer that points to the
278 | // interface data of the interface pointed by p.
279 | func (p pointer) getInterfacePointer() pointer {
280 | // Super-tricky - read pointer out of data word of interface value.
281 | return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
282 | }
283 |
284 | // asPointerTo returns a reflect.Value that is a pointer to an
285 | // object of type t stored at p.
286 | func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
287 | return reflect.NewAt(t, p.p)
288 | }
289 |
290 | func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
291 | return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
292 | }
293 | func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
294 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
295 | }
296 | func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
297 | return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
298 | }
299 | func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
300 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
301 | }
302 | func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
303 | return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
304 | }
305 | func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
306 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
307 | }
308 | func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
309 | return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
310 | }
311 | func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
312 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
313 | }
314 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/AUTHORS:
--------------------------------------------------------------------------------
1 | # This source code refers to The Go Authors for copyright purposes.
2 | # The master list of authors is in the main Go distribution,
3 | # visible at http://tip.golang.org/AUTHORS.
4 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | # This source code was written by the Go contributors.
2 | # The master list of contributors is in the main Go distribution,
3 | # visible at http://tip.golang.org/CONTRIBUTORS.
4 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009 The Go Authors. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Google Inc. nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/context/context.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package context defines the Context type, which carries deadlines,
6 | // cancelation signals, and other request-scoped values across API boundaries
7 | // and between processes.
8 | // As of Go 1.7 this package is available in the standard library under the
9 | // name context. https://golang.org/pkg/context.
10 | //
11 | // Incoming requests to a server should create a Context, and outgoing calls to
12 | // servers should accept a Context. The chain of function calls between must
13 | // propagate the Context, optionally replacing it with a modified copy created
14 | // using WithDeadline, WithTimeout, WithCancel, or WithValue.
15 | //
16 | // Programs that use Contexts should follow these rules to keep interfaces
17 | // consistent across packages and enable static analysis tools to check context
18 | // propagation:
19 | //
20 | // Do not store Contexts inside a struct type; instead, pass a Context
21 | // explicitly to each function that needs it. The Context should be the first
22 | // parameter, typically named ctx:
23 | //
24 | // func DoSomething(ctx context.Context, arg Arg) error {
25 | // // ... use ctx ...
26 | // }
27 | //
28 | // Do not pass a nil Context, even if a function permits it. Pass context.TODO
29 | // if you are unsure about which Context to use.
30 | //
31 | // Use context Values only for request-scoped data that transits processes and
32 | // APIs, not for passing optional parameters to functions.
33 | //
34 | // The same Context may be passed to functions running in different goroutines;
35 | // Contexts are safe for simultaneous use by multiple goroutines.
36 | //
37 | // See http://blog.golang.org/context for example code for a server that uses
38 | // Contexts.
39 | package context // import "golang.org/x/net/context"
40 |
41 | // Background returns a non-nil, empty Context. It is never canceled, has no
42 | // values, and has no deadline. It is typically used by the main function,
43 | // initialization, and tests, and as the top-level Context for incoming
44 | // requests.
45 | func Background() Context {
46 | return background
47 | }
48 |
49 | // TODO returns a non-nil, empty Context. Code should use context.TODO when
50 | // it's unclear which Context to use or it is not yet available (because the
51 | // surrounding function has not yet been extended to accept a Context
52 | // parameter). TODO is recognized by static analysis tools that determine
53 | // whether Contexts are propagated correctly in a program.
54 | func TODO() Context {
55 | return todo
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/context/go17.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build go1.7
6 |
7 | package context
8 |
9 | import (
10 | "context" // standard library's context, as of Go 1.7
11 | "time"
12 | )
13 |
14 | var (
15 | todo = context.TODO()
16 | background = context.Background()
17 | )
18 |
19 | // Canceled is the error returned by Context.Err when the context is canceled.
20 | var Canceled = context.Canceled
21 |
22 | // DeadlineExceeded is the error returned by Context.Err when the context's
23 | // deadline passes.
24 | var DeadlineExceeded = context.DeadlineExceeded
25 |
26 | // WithCancel returns a copy of parent with a new Done channel. The returned
27 | // context's Done channel is closed when the returned cancel function is called
28 | // or when the parent context's Done channel is closed, whichever happens first.
29 | //
30 | // Canceling this context releases resources associated with it, so code should
31 | // call cancel as soon as the operations running in this Context complete.
32 | func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
33 | ctx, f := context.WithCancel(parent)
34 | return ctx, CancelFunc(f)
35 | }
36 |
37 | // WithDeadline returns a copy of the parent context with the deadline adjusted
38 | // to be no later than d. If the parent's deadline is already earlier than d,
39 | // WithDeadline(parent, d) is semantically equivalent to parent. The returned
40 | // context's Done channel is closed when the deadline expires, when the returned
41 | // cancel function is called, or when the parent context's Done channel is
42 | // closed, whichever happens first.
43 | //
44 | // Canceling this context releases resources associated with it, so code should
45 | // call cancel as soon as the operations running in this Context complete.
46 | func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
47 | ctx, f := context.WithDeadline(parent, deadline)
48 | return ctx, CancelFunc(f)
49 | }
50 |
51 | // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
52 | //
53 | // Canceling this context releases resources associated with it, so code should
54 | // call cancel as soon as the operations running in this Context complete:
55 | //
56 | // func slowOperationWithTimeout(ctx context.Context) (Result, error) {
57 | // ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
58 | // defer cancel() // releases resources if slowOperation completes before timeout elapses
59 | // return slowOperation(ctx)
60 | // }
61 | func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
62 | return WithDeadline(parent, time.Now().Add(timeout))
63 | }
64 |
65 | // WithValue returns a copy of parent in which the value associated with key is
66 | // val.
67 | //
68 | // Use context Values only for request-scoped data that transits processes and
69 | // APIs, not for passing optional parameters to functions.
70 | func WithValue(parent Context, key interface{}, val interface{}) Context {
71 | return context.WithValue(parent, key, val)
72 | }
73 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/context/go19.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build go1.9
6 |
7 | package context
8 |
9 | import "context" // standard library's context, as of Go 1.7
10 |
11 | // A Context carries a deadline, a cancelation signal, and other values across
12 | // API boundaries.
13 | //
14 | // Context's methods may be called by multiple goroutines simultaneously.
15 | type Context = context.Context
16 |
17 | // A CancelFunc tells an operation to abandon its work.
18 | // A CancelFunc does not wait for the work to stop.
19 | // After the first call, subsequent calls to a CancelFunc do nothing.
20 | type CancelFunc = context.CancelFunc
21 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/context/pre_go17.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build !go1.7
6 |
7 | package context
8 |
9 | import (
10 | "errors"
11 | "fmt"
12 | "sync"
13 | "time"
14 | )
15 |
16 | // An emptyCtx is never canceled, has no values, and has no deadline. It is not
17 | // struct{}, since vars of this type must have distinct addresses.
18 | type emptyCtx int
19 |
20 | func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
21 | return
22 | }
23 |
24 | func (*emptyCtx) Done() <-chan struct{} {
25 | return nil
26 | }
27 |
28 | func (*emptyCtx) Err() error {
29 | return nil
30 | }
31 |
32 | func (*emptyCtx) Value(key interface{}) interface{} {
33 | return nil
34 | }
35 |
36 | func (e *emptyCtx) String() string {
37 | switch e {
38 | case background:
39 | return "context.Background"
40 | case todo:
41 | return "context.TODO"
42 | }
43 | return "unknown empty Context"
44 | }
45 |
46 | var (
47 | background = new(emptyCtx)
48 | todo = new(emptyCtx)
49 | )
50 |
51 | // Canceled is the error returned by Context.Err when the context is canceled.
52 | var Canceled = errors.New("context canceled")
53 |
54 | // DeadlineExceeded is the error returned by Context.Err when the context's
55 | // deadline passes.
56 | var DeadlineExceeded = errors.New("context deadline exceeded")
57 |
58 | // WithCancel returns a copy of parent with a new Done channel. The returned
59 | // context's Done channel is closed when the returned cancel function is called
60 | // or when the parent context's Done channel is closed, whichever happens first.
61 | //
62 | // Canceling this context releases resources associated with it, so code should
63 | // call cancel as soon as the operations running in this Context complete.
64 | func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
65 | c := newCancelCtx(parent)
66 | propagateCancel(parent, c)
67 | return c, func() { c.cancel(true, Canceled) }
68 | }
69 |
70 | // newCancelCtx returns an initialized cancelCtx.
71 | func newCancelCtx(parent Context) *cancelCtx {
72 | return &cancelCtx{
73 | Context: parent,
74 | done: make(chan struct{}),
75 | }
76 | }
77 |
78 | // propagateCancel arranges for child to be canceled when parent is.
79 | func propagateCancel(parent Context, child canceler) {
80 | if parent.Done() == nil {
81 | return // parent is never canceled
82 | }
83 | if p, ok := parentCancelCtx(parent); ok {
84 | p.mu.Lock()
85 | if p.err != nil {
86 | // parent has already been canceled
87 | child.cancel(false, p.err)
88 | } else {
89 | if p.children == nil {
90 | p.children = make(map[canceler]bool)
91 | }
92 | p.children[child] = true
93 | }
94 | p.mu.Unlock()
95 | } else {
96 | go func() {
97 | select {
98 | case <-parent.Done():
99 | child.cancel(false, parent.Err())
100 | case <-child.Done():
101 | }
102 | }()
103 | }
104 | }
105 |
106 | // parentCancelCtx follows a chain of parent references until it finds a
107 | // *cancelCtx. This function understands how each of the concrete types in this
108 | // package represents its parent.
109 | func parentCancelCtx(parent Context) (*cancelCtx, bool) {
110 | for {
111 | switch c := parent.(type) {
112 | case *cancelCtx:
113 | return c, true
114 | case *timerCtx:
115 | return c.cancelCtx, true
116 | case *valueCtx:
117 | parent = c.Context
118 | default:
119 | return nil, false
120 | }
121 | }
122 | }
123 |
124 | // removeChild removes a context from its parent.
125 | func removeChild(parent Context, child canceler) {
126 | p, ok := parentCancelCtx(parent)
127 | if !ok {
128 | return
129 | }
130 | p.mu.Lock()
131 | if p.children != nil {
132 | delete(p.children, child)
133 | }
134 | p.mu.Unlock()
135 | }
136 |
137 | // A canceler is a context type that can be canceled directly. The
138 | // implementations are *cancelCtx and *timerCtx.
139 | type canceler interface {
140 | cancel(removeFromParent bool, err error)
141 | Done() <-chan struct{}
142 | }
143 |
144 | // A cancelCtx can be canceled. When canceled, it also cancels any children
145 | // that implement canceler.
146 | type cancelCtx struct {
147 | Context
148 |
149 | done chan struct{} // closed by the first cancel call.
150 |
151 | mu sync.Mutex
152 | children map[canceler]bool // set to nil by the first cancel call
153 | err error // set to non-nil by the first cancel call
154 | }
155 |
156 | func (c *cancelCtx) Done() <-chan struct{} {
157 | return c.done
158 | }
159 |
160 | func (c *cancelCtx) Err() error {
161 | c.mu.Lock()
162 | defer c.mu.Unlock()
163 | return c.err
164 | }
165 |
166 | func (c *cancelCtx) String() string {
167 | return fmt.Sprintf("%v.WithCancel", c.Context)
168 | }
169 |
170 | // cancel closes c.done, cancels each of c's children, and, if
171 | // removeFromParent is true, removes c from its parent's children.
172 | func (c *cancelCtx) cancel(removeFromParent bool, err error) {
173 | if err == nil {
174 | panic("context: internal error: missing cancel error")
175 | }
176 | c.mu.Lock()
177 | if c.err != nil {
178 | c.mu.Unlock()
179 | return // already canceled
180 | }
181 | c.err = err
182 | close(c.done)
183 | for child := range c.children {
184 | // NOTE: acquiring the child's lock while holding parent's lock.
185 | child.cancel(false, err)
186 | }
187 | c.children = nil
188 | c.mu.Unlock()
189 |
190 | if removeFromParent {
191 | removeChild(c.Context, c)
192 | }
193 | }
194 |
195 | // WithDeadline returns a copy of the parent context with the deadline adjusted
196 | // to be no later than d. If the parent's deadline is already earlier than d,
197 | // WithDeadline(parent, d) is semantically equivalent to parent. The returned
198 | // context's Done channel is closed when the deadline expires, when the returned
199 | // cancel function is called, or when the parent context's Done channel is
200 | // closed, whichever happens first.
201 | //
202 | // Canceling this context releases resources associated with it, so code should
203 | // call cancel as soon as the operations running in this Context complete.
204 | func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
205 | if cur, ok := parent.Deadline(); ok && cur.Before(deadline) {
206 | // The current deadline is already sooner than the new one.
207 | return WithCancel(parent)
208 | }
209 | c := &timerCtx{
210 | cancelCtx: newCancelCtx(parent),
211 | deadline: deadline,
212 | }
213 | propagateCancel(parent, c)
214 | d := deadline.Sub(time.Now())
215 | if d <= 0 {
216 | c.cancel(true, DeadlineExceeded) // deadline has already passed
217 | return c, func() { c.cancel(true, Canceled) }
218 | }
219 | c.mu.Lock()
220 | defer c.mu.Unlock()
221 | if c.err == nil {
222 | c.timer = time.AfterFunc(d, func() {
223 | c.cancel(true, DeadlineExceeded)
224 | })
225 | }
226 | return c, func() { c.cancel(true, Canceled) }
227 | }
228 |
229 | // A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
230 | // implement Done and Err. It implements cancel by stopping its timer then
231 | // delegating to cancelCtx.cancel.
232 | type timerCtx struct {
233 | *cancelCtx
234 | timer *time.Timer // Under cancelCtx.mu.
235 |
236 | deadline time.Time
237 | }
238 |
239 | func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
240 | return c.deadline, true
241 | }
242 |
243 | func (c *timerCtx) String() string {
244 | return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now()))
245 | }
246 |
247 | func (c *timerCtx) cancel(removeFromParent bool, err error) {
248 | c.cancelCtx.cancel(false, err)
249 | if removeFromParent {
250 | // Remove this timerCtx from its parent cancelCtx's children.
251 | removeChild(c.cancelCtx.Context, c)
252 | }
253 | c.mu.Lock()
254 | if c.timer != nil {
255 | c.timer.Stop()
256 | c.timer = nil
257 | }
258 | c.mu.Unlock()
259 | }
260 |
261 | // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
262 | //
263 | // Canceling this context releases resources associated with it, so code should
264 | // call cancel as soon as the operations running in this Context complete:
265 | //
266 | // func slowOperationWithTimeout(ctx context.Context) (Result, error) {
267 | // ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
268 | // defer cancel() // releases resources if slowOperation completes before timeout elapses
269 | // return slowOperation(ctx)
270 | // }
271 | func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
272 | return WithDeadline(parent, time.Now().Add(timeout))
273 | }
274 |
275 | // WithValue returns a copy of parent in which the value associated with key is
276 | // val.
277 | //
278 | // Use context Values only for request-scoped data that transits processes and
279 | // APIs, not for passing optional parameters to functions.
280 | func WithValue(parent Context, key interface{}, val interface{}) Context {
281 | return &valueCtx{parent, key, val}
282 | }
283 |
284 | // A valueCtx carries a key-value pair. It implements Value for that key and
285 | // delegates all other calls to the embedded Context.
286 | type valueCtx struct {
287 | Context
288 | key, val interface{}
289 | }
290 |
291 | func (c *valueCtx) String() string {
292 | return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val)
293 | }
294 |
295 | func (c *valueCtx) Value(key interface{}) interface{} {
296 | if c.key == key {
297 | return c.val
298 | }
299 | return c.Context.Value(key)
300 | }
301 |
--------------------------------------------------------------------------------
/vendor/golang.org/x/net/context/pre_go19.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build !go1.9
6 |
7 | package context
8 |
9 | import "time"
10 |
11 | // A Context carries a deadline, a cancelation signal, and other values across
12 | // API boundaries.
13 | //
14 | // Context's methods may be called by multiple goroutines simultaneously.
15 | type Context interface {
16 | // Deadline returns the time when work done on behalf of this context
17 | // should be canceled. Deadline returns ok==false when no deadline is
18 | // set. Successive calls to Deadline return the same results.
19 | Deadline() (deadline time.Time, ok bool)
20 |
21 | // Done returns a channel that's closed when work done on behalf of this
22 | // context should be canceled. Done may return nil if this context can
23 | // never be canceled. Successive calls to Done return the same value.
24 | //
25 | // WithCancel arranges for Done to be closed when cancel is called;
26 | // WithDeadline arranges for Done to be closed when the deadline
27 | // expires; WithTimeout arranges for Done to be closed when the timeout
28 | // elapses.
29 | //
30 | // Done is provided for use in select statements:
31 | //
32 | // // Stream generates values with DoSomething and sends them to out
33 | // // until DoSomething returns an error or ctx.Done is closed.
34 | // func Stream(ctx context.Context, out chan<- Value) error {
35 | // for {
36 | // v, err := DoSomething(ctx)
37 | // if err != nil {
38 | // return err
39 | // }
40 | // select {
41 | // case <-ctx.Done():
42 | // return ctx.Err()
43 | // case out <- v:
44 | // }
45 | // }
46 | // }
47 | //
48 | // See http://blog.golang.org/pipelines for more examples of how to use
49 | // a Done channel for cancelation.
50 | Done() <-chan struct{}
51 |
52 | // Err returns a non-nil error value after Done is closed. Err returns
53 | // Canceled if the context was canceled or DeadlineExceeded if the
54 | // context's deadline passed. No other values for Err are defined.
55 | // After Done is closed, successive calls to Err return the same value.
56 | Err() error
57 |
58 | // Value returns the value associated with this context for key, or nil
59 | // if no value is associated with key. Successive calls to Value with
60 | // the same key returns the same result.
61 | //
62 | // Use context values only for request-scoped data that transits
63 | // processes and API boundaries, not for passing optional parameters to
64 | // functions.
65 | //
66 | // A key identifies a specific value in a Context. Functions that wish
67 | // to store values in Context typically allocate a key in a global
68 | // variable then use that key as the argument to context.WithValue and
69 | // Context.Value. A key can be any type that supports equality;
70 | // packages should define keys as an unexported type to avoid
71 | // collisions.
72 | //
73 | // Packages that define a Context key should provide type-safe accessors
74 | // for the values stores using that key:
75 | //
76 | // // Package user defines a User type that's stored in Contexts.
77 | // package user
78 | //
79 | // import "golang.org/x/net/context"
80 | //
81 | // // User is the type of value stored in the Contexts.
82 | // type User struct {...}
83 | //
84 | // // key is an unexported type for keys defined in this package.
85 | // // This prevents collisions with keys defined in other packages.
86 | // type key int
87 | //
88 | // // userKey is the key for user.User values in Contexts. It is
89 | // // unexported; clients use user.NewContext and user.FromContext
90 | // // instead of using this key directly.
91 | // var userKey key = 0
92 | //
93 | // // NewContext returns a new Context that carries value u.
94 | // func NewContext(ctx context.Context, u *User) context.Context {
95 | // return context.WithValue(ctx, userKey, u)
96 | // }
97 | //
98 | // // FromContext returns the User value stored in ctx, if any.
99 | // func FromContext(ctx context.Context) (*User, bool) {
100 | // u, ok := ctx.Value(userKey).(*User)
101 | // return u, ok
102 | // }
103 | Value(key interface{}) interface{}
104 | }
105 |
106 | // A CancelFunc tells an operation to abandon its work.
107 | // A CancelFunc does not wait for the work to stop.
108 | // After the first call, subsequent calls to a CancelFunc do nothing.
109 | type CancelFunc func()
110 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go_import_path: google.golang.org/appengine
4 |
5 | install:
6 | - ./travis_install.sh
7 |
8 | script:
9 | - ./travis_test.sh
10 |
11 | matrix:
12 | include:
13 | - go: 1.8.x
14 | env: GOAPP=true
15 | - go: 1.9.x
16 | env: GOAPP=true
17 | - go: 1.10.x
18 | env: GOAPP=false
19 | - go: 1.11.x
20 | env: GO111MODULE=on
21 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | 1. Sign one of the contributor license agreements below.
4 | 1. Get the package:
5 |
6 | `go get -d google.golang.org/appengine`
7 | 1. Change into the checked out source:
8 |
9 | `cd $GOPATH/src/google.golang.org/appengine`
10 | 1. Fork the repo.
11 | 1. Set your fork as a remote:
12 |
13 | `git remote add fork git@github.com:GITHUB_USERNAME/appengine.git`
14 | 1. Make changes, commit to your fork.
15 | 1. Send a pull request with your changes.
16 | The first line of your commit message is conventionally a one-line summary of the change, prefixed by the primary affected package, and is used as the title of your pull request.
17 |
18 | # Testing
19 |
20 | ## Running system tests
21 |
22 | Download and install the [Go App Engine SDK](https://cloud.google.com/appengine/docs/go/download). Make sure the `go_appengine` dir is in your `PATH`.
23 |
24 | Set the `APPENGINE_DEV_APPSERVER` environment variable to `/path/to/go_appengine/dev_appserver.py`.
25 |
26 | Run tests with `goapp test`:
27 |
28 | ```
29 | goapp test -v google.golang.org/appengine/...
30 | ```
31 |
32 | ## Contributor License Agreements
33 |
34 | Before we can accept your pull requests you'll need to sign a Contributor
35 | License Agreement (CLA):
36 |
37 | - **If you are an individual writing original source code** and **you own the
38 | intellectual property**, then you'll need to sign an [individual CLA][indvcla].
39 | - **If you work for a company that wants to allow you to contribute your work**,
40 | then you'll need to sign a [corporate CLA][corpcla].
41 |
42 | You can sign these electronically (just scroll to the bottom). After that,
43 | we'll be able to accept your pull requests.
44 |
45 | ## Contributor Code of Conduct
46 |
47 | As contributors and maintainers of this project,
48 | and in the interest of fostering an open and welcoming community,
49 | we pledge to respect all people who contribute through reporting issues,
50 | posting feature requests, updating documentation,
51 | submitting pull requests or patches, and other activities.
52 |
53 | We are committed to making participation in this project
54 | a harassment-free experience for everyone,
55 | regardless of level of experience, gender, gender identity and expression,
56 | sexual orientation, disability, personal appearance,
57 | body size, race, ethnicity, age, religion, or nationality.
58 |
59 | Examples of unacceptable behavior by participants include:
60 |
61 | * The use of sexualized language or imagery
62 | * Personal attacks
63 | * Trolling or insulting/derogatory comments
64 | * Public or private harassment
65 | * Publishing other's private information,
66 | such as physical or electronic
67 | addresses, without explicit permission
68 | * Other unethical or unprofessional conduct.
69 |
70 | Project maintainers have the right and responsibility to remove, edit, or reject
71 | comments, commits, code, wiki edits, issues, and other contributions
72 | that are not aligned to this Code of Conduct.
73 | By adopting this Code of Conduct,
74 | project maintainers commit themselves to fairly and consistently
75 | applying these principles to every aspect of managing this project.
76 | Project maintainers who do not follow or enforce the Code of Conduct
77 | may be permanently removed from the project team.
78 |
79 | This code of conduct applies both within project spaces and in public spaces
80 | when an individual is representing the project or its community.
81 |
82 | Instances of abusive, harassing, or otherwise unacceptable behavior
83 | may be reported by opening an issue
84 | or contacting one or more of the project maintainers.
85 |
86 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,
87 | available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
88 |
89 | [indvcla]: https://developers.google.com/open-source/cla/individual
90 | [corpcla]: https://developers.google.com/open-source/cla/corporate
91 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/README.md:
--------------------------------------------------------------------------------
1 | # Go App Engine packages
2 |
3 | [](https://travis-ci.org/golang/appengine)
4 |
5 | This repository supports the Go runtime on *App Engine standard*.
6 | It provides APIs for interacting with App Engine services.
7 | Its canonical import path is `google.golang.org/appengine`.
8 |
9 | See https://cloud.google.com/appengine/docs/go/
10 | for more information.
11 |
12 | File issue reports and feature requests on the [GitHub's issue
13 | tracker](https://github.com/golang/appengine/issues).
14 |
15 | ## Upgrading an App Engine app to the flexible environment
16 |
17 | This package does not work on *App Engine flexible*.
18 |
19 | There are many differences between the App Engine standard environment and
20 | the flexible environment.
21 |
22 | See the [documentation on upgrading to the flexible environment](https://cloud.google.com/appengine/docs/flexible/go/upgrading).
23 |
24 | ## Directory structure
25 |
26 | The top level directory of this repository is the `appengine` package. It
27 | contains the
28 | basic APIs (e.g. `appengine.NewContext`) that apply across APIs. Specific API
29 | packages are in subdirectories (e.g. `datastore`).
30 |
31 | There is an `internal` subdirectory that contains service protocol buffers,
32 | plus packages required for connectivity to make API calls. App Engine apps
33 | should not directly import any package under `internal`.
34 |
35 | ## Updating from legacy (`import "appengine"`) packages
36 |
37 | If you're currently using the bare `appengine` packages
38 | (that is, not these ones, imported via `google.golang.org/appengine`),
39 | then you can use the `aefix` tool to help automate an upgrade to these packages.
40 |
41 | Run `go get google.golang.org/appengine/cmd/aefix` to install it.
42 |
43 | ### 1. Update import paths
44 |
45 | The import paths for App Engine packages are now fully qualified, based at `google.golang.org/appengine`.
46 | You will need to update your code to use import paths starting with that; for instance,
47 | code importing `appengine/datastore` will now need to import `google.golang.org/appengine/datastore`.
48 |
49 | ### 2. Update code using deprecated, removed or modified APIs
50 |
51 | Most App Engine services are available with exactly the same API.
52 | A few APIs were cleaned up, and there are some differences:
53 |
54 | * `appengine.Context` has been replaced with the `Context` type from `golang.org/x/net/context`.
55 | * Logging methods that were on `appengine.Context` are now functions in `google.golang.org/appengine/log`.
56 | * `appengine.Timeout` has been removed. Use `context.WithTimeout` instead.
57 | * `appengine.Datacenter` now takes a `context.Context` argument.
58 | * `datastore.PropertyLoadSaver` has been simplified to use slices in place of channels.
59 | * `delay.Call` now returns an error.
60 | * `search.FieldLoadSaver` now handles document metadata.
61 | * `urlfetch.Transport` no longer has a Deadline field; set a deadline on the
62 | `context.Context` instead.
63 | * `aetest` no longer declares its own Context type, and uses the standard one instead.
64 | * `taskqueue.QueueStats` no longer takes a maxTasks argument. That argument has been
65 | deprecated and unused for a long time.
66 | * `appengine.BackendHostname` and `appengine.BackendInstance` were for the deprecated backends feature.
67 | Use `appengine.ModuleHostname`and `appengine.ModuleName` instead.
68 | * Most of `appengine/file` and parts of `appengine/blobstore` are deprecated.
69 | Use [Google Cloud Storage](https://godoc.org/cloud.google.com/go/storage) if the
70 | feature you require is not present in the new
71 | [blobstore package](https://google.golang.org/appengine/blobstore).
72 | * `appengine/socket` is not required on App Engine flexible environment / Managed VMs.
73 | Use the standard `net` package instead.
74 |
75 | ## Key Encode/Decode compatibiltiy to help with datastore library migrations
76 |
77 | Key compatibility updates have been added to help customers transition from google.golang.org/appengine/datastore to cloud.google.com/go/datastore.
78 | The `EnableKeyConversion` enables automatic conversion from a key encoded with cloud.google.com/go/datastore to google.golang.org/appengine/datastore key type.
79 |
80 | ### Enabling key conversion
81 |
82 | Enable key conversion by calling `EnableKeyConversion(ctx)` in the `/_ah/start` handler for basic and manual scaling or any handler in automatic scaling.
83 |
84 | #### 1. Basic or manual scaling
85 |
86 | This start handler will enable key conversion for all handlers in the service.
87 |
88 | ```
89 | http.HandleFunc("/_ah/start", func(w http.ResponseWriter, r *http.Request) {
90 | datastore.EnableKeyConversion(appengine.NewContext(r))
91 | })
92 | ```
93 |
94 | #### 2. Automatic scaling
95 |
96 | `/_ah/start` is not supported for automatic scaling and `/_ah/warmup` is not guaranteed to run, so you must call `datastore.EnableKeyConversion(appengine.NewContext(r))`
97 | before you use code that needs key conversion.
98 |
99 | You may want to add this to each of your handlers, or introduce middleware where it's called.
100 | `EnableKeyConversion` is safe for concurrent use. Any call to it after the first is ignored.
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/appengine.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package appengine provides basic functionality for Google App Engine.
6 | //
7 | // For more information on how to write Go apps for Google App Engine, see:
8 | // https://cloud.google.com/appengine/docs/go/
9 | package appengine // import "google.golang.org/appengine"
10 |
11 | import (
12 | "net/http"
13 |
14 | "github.com/golang/protobuf/proto"
15 | "golang.org/x/net/context"
16 |
17 | "google.golang.org/appengine/internal"
18 | )
19 |
20 | // The gophers party all night; the rabbits provide the beats.
21 |
22 | // Main is the principal entry point for an app running in App Engine.
23 | //
24 | // On App Engine Flexible it installs a trivial health checker if one isn't
25 | // already registered, and starts listening on port 8080 (overridden by the
26 | // $PORT environment variable).
27 | //
28 | // See https://cloud.google.com/appengine/docs/flexible/custom-runtimes#health_check_requests
29 | // for details on how to do your own health checking.
30 | //
31 | // On App Engine Standard it ensures the server has started and is prepared to
32 | // receive requests.
33 | //
34 | // Main never returns.
35 | //
36 | // Main is designed so that the app's main package looks like this:
37 | //
38 | // package main
39 | //
40 | // import (
41 | // "google.golang.org/appengine"
42 | //
43 | // _ "myapp/package0"
44 | // _ "myapp/package1"
45 | // )
46 | //
47 | // func main() {
48 | // appengine.Main()
49 | // }
50 | //
51 | // The "myapp/packageX" packages are expected to register HTTP handlers
52 | // in their init functions.
53 | func Main() {
54 | internal.Main()
55 | }
56 |
57 | // IsDevAppServer reports whether the App Engine app is running in the
58 | // development App Server.
59 | func IsDevAppServer() bool {
60 | return internal.IsDevAppServer()
61 | }
62 |
63 | // IsStandard reports whether the App Engine app is running in the standard
64 | // environment. This includes both the first generation runtimes (<= Go 1.9)
65 | // and the second generation runtimes (>= Go 1.11).
66 | func IsStandard() bool {
67 | return internal.IsStandard()
68 | }
69 |
70 | // IsFlex reports whether the App Engine app is running in the flexible environment.
71 | func IsFlex() bool {
72 | return internal.IsFlex()
73 | }
74 |
75 | // IsAppEngine reports whether the App Engine app is running on App Engine, in either
76 | // the standard or flexible environment.
77 | func IsAppEngine() bool {
78 | return internal.IsAppEngine()
79 | }
80 |
81 | // IsSecondGen reports whether the App Engine app is running on the second generation
82 | // runtimes (>= Go 1.11).
83 | func IsSecondGen() bool {
84 | return internal.IsSecondGen()
85 | }
86 |
87 | // NewContext returns a context for an in-flight HTTP request.
88 | // This function is cheap.
89 | func NewContext(req *http.Request) context.Context {
90 | return internal.ReqContext(req)
91 | }
92 |
93 | // WithContext returns a copy of the parent context
94 | // and associates it with an in-flight HTTP request.
95 | // This function is cheap.
96 | func WithContext(parent context.Context, req *http.Request) context.Context {
97 | return internal.WithContext(parent, req)
98 | }
99 |
100 | // BlobKey is a key for a blobstore blob.
101 | //
102 | // Conceptually, this type belongs in the blobstore package, but it lives in
103 | // the appengine package to avoid a circular dependency: blobstore depends on
104 | // datastore, and datastore needs to refer to the BlobKey type.
105 | type BlobKey string
106 |
107 | // GeoPoint represents a location as latitude/longitude in degrees.
108 | type GeoPoint struct {
109 | Lat, Lng float64
110 | }
111 |
112 | // Valid returns whether a GeoPoint is within [-90, 90] latitude and [-180, 180] longitude.
113 | func (g GeoPoint) Valid() bool {
114 | return -90 <= g.Lat && g.Lat <= 90 && -180 <= g.Lng && g.Lng <= 180
115 | }
116 |
117 | // APICallFunc defines a function type for handling an API call.
118 | // See WithCallOverride.
119 | type APICallFunc func(ctx context.Context, service, method string, in, out proto.Message) error
120 |
121 | // WithAPICallFunc returns a copy of the parent context
122 | // that will cause API calls to invoke f instead of their normal operation.
123 | //
124 | // This is intended for advanced users only.
125 | func WithAPICallFunc(ctx context.Context, f APICallFunc) context.Context {
126 | return internal.WithCallOverride(ctx, internal.CallOverrideFunc(f))
127 | }
128 |
129 | // APICall performs an API call.
130 | //
131 | // This is not intended for general use; it is exported for use in conjunction
132 | // with WithAPICallFunc.
133 | func APICall(ctx context.Context, service, method string, in, out proto.Message) error {
134 | return internal.Call(ctx, service, method, in, out)
135 | }
136 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/appengine_vm.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build !appengine
6 |
7 | package appengine
8 |
9 | import (
10 | "golang.org/x/net/context"
11 |
12 | "google.golang.org/appengine/internal"
13 | )
14 |
15 | // BackgroundContext returns a context not associated with a request.
16 | // This should only be used when not servicing a request.
17 | // This only works in App Engine "flexible environment".
18 | func BackgroundContext() context.Context {
19 | return internal.BackgroundContext()
20 | }
21 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // This file provides error functions for common API failure modes.
6 |
7 | package appengine
8 |
9 | import (
10 | "fmt"
11 |
12 | "google.golang.org/appengine/internal"
13 | )
14 |
15 | // IsOverQuota reports whether err represents an API call failure
16 | // due to insufficient available quota.
17 | func IsOverQuota(err error) bool {
18 | callErr, ok := err.(*internal.CallError)
19 | return ok && callErr.Code == 4
20 | }
21 |
22 | // MultiError is returned by batch operations when there are errors with
23 | // particular elements. Errors will be in a one-to-one correspondence with
24 | // the input elements; successful elements will have a nil entry.
25 | type MultiError []error
26 |
27 | func (m MultiError) Error() string {
28 | s, n := "", 0
29 | for _, e := range m {
30 | if e != nil {
31 | if n == 0 {
32 | s = e.Error()
33 | }
34 | n++
35 | }
36 | }
37 | switch n {
38 | case 0:
39 | return "(0 errors)"
40 | case 1:
41 | return s
42 | case 2:
43 | return s + " (and 1 other error)"
44 | }
45 | return fmt.Sprintf("%s (and %d other errors)", s, n-1)
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/go.mod:
--------------------------------------------------------------------------------
1 | module google.golang.org/appengine
2 |
3 | go 1.11
4 |
5 | require (
6 | github.com/golang/protobuf v1.3.1
7 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65
8 | golang.org/x/text v0.3.2
9 | )
10 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/go.sum:
--------------------------------------------------------------------------------
1 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
2 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
3 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
5 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
6 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
7 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
8 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
9 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
10 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
11 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
12 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/identity.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package appengine
6 |
7 | import (
8 | "time"
9 |
10 | "golang.org/x/net/context"
11 |
12 | "google.golang.org/appengine/internal"
13 | pb "google.golang.org/appengine/internal/app_identity"
14 | modpb "google.golang.org/appengine/internal/modules"
15 | )
16 |
17 | // AppID returns the application ID for the current application.
18 | // The string will be a plain application ID (e.g. "appid"), with a
19 | // domain prefix for custom domain deployments (e.g. "example.com:appid").
20 | func AppID(c context.Context) string { return internal.AppID(c) }
21 |
22 | // DefaultVersionHostname returns the standard hostname of the default version
23 | // of the current application (e.g. "my-app.appspot.com"). This is suitable for
24 | // use in constructing URLs.
25 | func DefaultVersionHostname(c context.Context) string {
26 | return internal.DefaultVersionHostname(c)
27 | }
28 |
29 | // ModuleName returns the module name of the current instance.
30 | func ModuleName(c context.Context) string {
31 | return internal.ModuleName(c)
32 | }
33 |
34 | // ModuleHostname returns a hostname of a module instance.
35 | // If module is the empty string, it refers to the module of the current instance.
36 | // If version is empty, it refers to the version of the current instance if valid,
37 | // or the default version of the module of the current instance.
38 | // If instance is empty, ModuleHostname returns the load-balancing hostname.
39 | func ModuleHostname(c context.Context, module, version, instance string) (string, error) {
40 | req := &modpb.GetHostnameRequest{}
41 | if module != "" {
42 | req.Module = &module
43 | }
44 | if version != "" {
45 | req.Version = &version
46 | }
47 | if instance != "" {
48 | req.Instance = &instance
49 | }
50 | res := &modpb.GetHostnameResponse{}
51 | if err := internal.Call(c, "modules", "GetHostname", req, res); err != nil {
52 | return "", err
53 | }
54 | return *res.Hostname, nil
55 | }
56 |
57 | // VersionID returns the version ID for the current application.
58 | // It will be of the form "X.Y", where X is specified in app.yaml,
59 | // and Y is a number generated when each version of the app is uploaded.
60 | // It does not include a module name.
61 | func VersionID(c context.Context) string { return internal.VersionID(c) }
62 |
63 | // InstanceID returns a mostly-unique identifier for this instance.
64 | func InstanceID() string { return internal.InstanceID() }
65 |
66 | // Datacenter returns an identifier for the datacenter that the instance is running in.
67 | func Datacenter(c context.Context) string { return internal.Datacenter(c) }
68 |
69 | // ServerSoftware returns the App Engine release version.
70 | // In production, it looks like "Google App Engine/X.Y.Z".
71 | // In the development appserver, it looks like "Development/X.Y".
72 | func ServerSoftware() string { return internal.ServerSoftware() }
73 |
74 | // RequestID returns a string that uniquely identifies the request.
75 | func RequestID(c context.Context) string { return internal.RequestID(c) }
76 |
77 | // AccessToken generates an OAuth2 access token for the specified scopes on
78 | // behalf of service account of this application. This token will expire after
79 | // the returned time.
80 | func AccessToken(c context.Context, scopes ...string) (token string, expiry time.Time, err error) {
81 | req := &pb.GetAccessTokenRequest{Scope: scopes}
82 | res := &pb.GetAccessTokenResponse{}
83 |
84 | err = internal.Call(c, "app_identity_service", "GetAccessToken", req, res)
85 | if err != nil {
86 | return "", time.Time{}, err
87 | }
88 | return res.GetAccessToken(), time.Unix(res.GetExpirationTime(), 0), nil
89 | }
90 |
91 | // Certificate represents a public certificate for the app.
92 | type Certificate struct {
93 | KeyName string
94 | Data []byte // PEM-encoded X.509 certificate
95 | }
96 |
97 | // PublicCertificates retrieves the public certificates for the app.
98 | // They can be used to verify a signature returned by SignBytes.
99 | func PublicCertificates(c context.Context) ([]Certificate, error) {
100 | req := &pb.GetPublicCertificateForAppRequest{}
101 | res := &pb.GetPublicCertificateForAppResponse{}
102 | if err := internal.Call(c, "app_identity_service", "GetPublicCertificatesForApp", req, res); err != nil {
103 | return nil, err
104 | }
105 | var cs []Certificate
106 | for _, pc := range res.PublicCertificateList {
107 | cs = append(cs, Certificate{
108 | KeyName: pc.GetKeyName(),
109 | Data: []byte(pc.GetX509CertificatePem()),
110 | })
111 | }
112 | return cs, nil
113 | }
114 |
115 | // ServiceAccount returns a string representing the service account name, in
116 | // the form of an email address (typically app_id@appspot.gserviceaccount.com).
117 | func ServiceAccount(c context.Context) (string, error) {
118 | req := &pb.GetServiceAccountNameRequest{}
119 | res := &pb.GetServiceAccountNameResponse{}
120 |
121 | err := internal.Call(c, "app_identity_service", "GetServiceAccountName", req, res)
122 | if err != nil {
123 | return "", err
124 | }
125 | return res.GetServiceAccountName(), err
126 | }
127 |
128 | // SignBytes signs bytes using a private key unique to your application.
129 | func SignBytes(c context.Context, bytes []byte) (keyName string, signature []byte, err error) {
130 | req := &pb.SignForAppRequest{BytesToSign: bytes}
131 | res := &pb.SignForAppResponse{}
132 |
133 | if err := internal.Call(c, "app_identity_service", "SignForApp", req, res); err != nil {
134 | return "", nil, err
135 | }
136 | return res.GetKeyName(), res.GetSignatureBytes(), nil
137 | }
138 |
139 | func init() {
140 | internal.RegisterErrorCodeMap("app_identity_service", pb.AppIdentityServiceError_ErrorCode_name)
141 | internal.RegisterErrorCodeMap("modules", modpb.ModulesServiceError_ErrorCode_name)
142 | }
143 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/api_classic.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build appengine
6 |
7 | package internal
8 |
9 | import (
10 | "errors"
11 | "fmt"
12 | "net/http"
13 | "time"
14 |
15 | "appengine"
16 | "appengine_internal"
17 | basepb "appengine_internal/base"
18 |
19 | "github.com/golang/protobuf/proto"
20 | netcontext "golang.org/x/net/context"
21 | )
22 |
23 | var contextKey = "holds an appengine.Context"
24 |
25 | // fromContext returns the App Engine context or nil if ctx is not
26 | // derived from an App Engine context.
27 | func fromContext(ctx netcontext.Context) appengine.Context {
28 | c, _ := ctx.Value(&contextKey).(appengine.Context)
29 | return c
30 | }
31 |
32 | // This is only for classic App Engine adapters.
33 | func ClassicContextFromContext(ctx netcontext.Context) (appengine.Context, error) {
34 | c := fromContext(ctx)
35 | if c == nil {
36 | return nil, errNotAppEngineContext
37 | }
38 | return c, nil
39 | }
40 |
41 | func withContext(parent netcontext.Context, c appengine.Context) netcontext.Context {
42 | ctx := netcontext.WithValue(parent, &contextKey, c)
43 |
44 | s := &basepb.StringProto{}
45 | c.Call("__go__", "GetNamespace", &basepb.VoidProto{}, s, nil)
46 | if ns := s.GetValue(); ns != "" {
47 | ctx = NamespacedContext(ctx, ns)
48 | }
49 |
50 | return ctx
51 | }
52 |
53 | func IncomingHeaders(ctx netcontext.Context) http.Header {
54 | if c := fromContext(ctx); c != nil {
55 | if req, ok := c.Request().(*http.Request); ok {
56 | return req.Header
57 | }
58 | }
59 | return nil
60 | }
61 |
62 | func ReqContext(req *http.Request) netcontext.Context {
63 | return WithContext(netcontext.Background(), req)
64 | }
65 |
66 | func WithContext(parent netcontext.Context, req *http.Request) netcontext.Context {
67 | c := appengine.NewContext(req)
68 | return withContext(parent, c)
69 | }
70 |
71 | type testingContext struct {
72 | appengine.Context
73 |
74 | req *http.Request
75 | }
76 |
77 | func (t *testingContext) FullyQualifiedAppID() string { return "dev~testcontext" }
78 | func (t *testingContext) Call(service, method string, _, _ appengine_internal.ProtoMessage, _ *appengine_internal.CallOptions) error {
79 | if service == "__go__" && method == "GetNamespace" {
80 | return nil
81 | }
82 | return fmt.Errorf("testingContext: unsupported Call")
83 | }
84 | func (t *testingContext) Request() interface{} { return t.req }
85 |
86 | func ContextForTesting(req *http.Request) netcontext.Context {
87 | return withContext(netcontext.Background(), &testingContext{req: req})
88 | }
89 |
90 | func Call(ctx netcontext.Context, service, method string, in, out proto.Message) error {
91 | if ns := NamespaceFromContext(ctx); ns != "" {
92 | if fn, ok := NamespaceMods[service]; ok {
93 | fn(in, ns)
94 | }
95 | }
96 |
97 | if f, ctx, ok := callOverrideFromContext(ctx); ok {
98 | return f(ctx, service, method, in, out)
99 | }
100 |
101 | // Handle already-done contexts quickly.
102 | select {
103 | case <-ctx.Done():
104 | return ctx.Err()
105 | default:
106 | }
107 |
108 | c := fromContext(ctx)
109 | if c == nil {
110 | // Give a good error message rather than a panic lower down.
111 | return errNotAppEngineContext
112 | }
113 |
114 | // Apply transaction modifications if we're in a transaction.
115 | if t := transactionFromContext(ctx); t != nil {
116 | if t.finished {
117 | return errors.New("transaction context has expired")
118 | }
119 | applyTransaction(in, &t.transaction)
120 | }
121 |
122 | var opts *appengine_internal.CallOptions
123 | if d, ok := ctx.Deadline(); ok {
124 | opts = &appengine_internal.CallOptions{
125 | Timeout: d.Sub(time.Now()),
126 | }
127 | }
128 |
129 | err := c.Call(service, method, in, out, opts)
130 | switch v := err.(type) {
131 | case *appengine_internal.APIError:
132 | return &APIError{
133 | Service: v.Service,
134 | Detail: v.Detail,
135 | Code: v.Code,
136 | }
137 | case *appengine_internal.CallError:
138 | return &CallError{
139 | Detail: v.Detail,
140 | Code: v.Code,
141 | Timeout: v.Timeout,
142 | }
143 | }
144 | return err
145 | }
146 |
147 | func handleHTTP(w http.ResponseWriter, r *http.Request) {
148 | panic("handleHTTP called; this should be impossible")
149 | }
150 |
151 | func logf(c appengine.Context, level int64, format string, args ...interface{}) {
152 | var fn func(format string, args ...interface{})
153 | switch level {
154 | case 0:
155 | fn = c.Debugf
156 | case 1:
157 | fn = c.Infof
158 | case 2:
159 | fn = c.Warningf
160 | case 3:
161 | fn = c.Errorf
162 | case 4:
163 | fn = c.Criticalf
164 | default:
165 | // This shouldn't happen.
166 | fn = c.Criticalf
167 | }
168 | fn(format, args...)
169 | }
170 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/api_common.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | import (
8 | "errors"
9 | "os"
10 |
11 | "github.com/golang/protobuf/proto"
12 | netcontext "golang.org/x/net/context"
13 | )
14 |
15 | var errNotAppEngineContext = errors.New("not an App Engine context")
16 |
17 | type CallOverrideFunc func(ctx netcontext.Context, service, method string, in, out proto.Message) error
18 |
19 | var callOverrideKey = "holds []CallOverrideFunc"
20 |
21 | func WithCallOverride(ctx netcontext.Context, f CallOverrideFunc) netcontext.Context {
22 | // We avoid appending to any existing call override
23 | // so we don't risk overwriting a popped stack below.
24 | var cofs []CallOverrideFunc
25 | if uf, ok := ctx.Value(&callOverrideKey).([]CallOverrideFunc); ok {
26 | cofs = append(cofs, uf...)
27 | }
28 | cofs = append(cofs, f)
29 | return netcontext.WithValue(ctx, &callOverrideKey, cofs)
30 | }
31 |
32 | func callOverrideFromContext(ctx netcontext.Context) (CallOverrideFunc, netcontext.Context, bool) {
33 | cofs, _ := ctx.Value(&callOverrideKey).([]CallOverrideFunc)
34 | if len(cofs) == 0 {
35 | return nil, nil, false
36 | }
37 | // We found a list of overrides; grab the last, and reconstitute a
38 | // context that will hide it.
39 | f := cofs[len(cofs)-1]
40 | ctx = netcontext.WithValue(ctx, &callOverrideKey, cofs[:len(cofs)-1])
41 | return f, ctx, true
42 | }
43 |
44 | type logOverrideFunc func(level int64, format string, args ...interface{})
45 |
46 | var logOverrideKey = "holds a logOverrideFunc"
47 |
48 | func WithLogOverride(ctx netcontext.Context, f logOverrideFunc) netcontext.Context {
49 | return netcontext.WithValue(ctx, &logOverrideKey, f)
50 | }
51 |
52 | var appIDOverrideKey = "holds a string, being the full app ID"
53 |
54 | func WithAppIDOverride(ctx netcontext.Context, appID string) netcontext.Context {
55 | return netcontext.WithValue(ctx, &appIDOverrideKey, appID)
56 | }
57 |
58 | var namespaceKey = "holds the namespace string"
59 |
60 | func withNamespace(ctx netcontext.Context, ns string) netcontext.Context {
61 | return netcontext.WithValue(ctx, &namespaceKey, ns)
62 | }
63 |
64 | func NamespaceFromContext(ctx netcontext.Context) string {
65 | // If there's no namespace, return the empty string.
66 | ns, _ := ctx.Value(&namespaceKey).(string)
67 | return ns
68 | }
69 |
70 | // FullyQualifiedAppID returns the fully-qualified application ID.
71 | // This may contain a partition prefix (e.g. "s~" for High Replication apps),
72 | // or a domain prefix (e.g. "example.com:").
73 | func FullyQualifiedAppID(ctx netcontext.Context) string {
74 | if id, ok := ctx.Value(&appIDOverrideKey).(string); ok {
75 | return id
76 | }
77 | return fullyQualifiedAppID(ctx)
78 | }
79 |
80 | func Logf(ctx netcontext.Context, level int64, format string, args ...interface{}) {
81 | if f, ok := ctx.Value(&logOverrideKey).(logOverrideFunc); ok {
82 | f(level, format, args...)
83 | return
84 | }
85 | c := fromContext(ctx)
86 | if c == nil {
87 | panic(errNotAppEngineContext)
88 | }
89 | logf(c, level, format, args...)
90 | }
91 |
92 | // NamespacedContext wraps a Context to support namespaces.
93 | func NamespacedContext(ctx netcontext.Context, namespace string) netcontext.Context {
94 | return withNamespace(ctx, namespace)
95 | }
96 |
97 | // SetTestEnv sets the env variables for testing background ticket in Flex.
98 | func SetTestEnv() func() {
99 | var environ = []struct {
100 | key, value string
101 | }{
102 | {"GAE_LONG_APP_ID", "my-app-id"},
103 | {"GAE_MINOR_VERSION", "067924799508853122"},
104 | {"GAE_MODULE_INSTANCE", "0"},
105 | {"GAE_MODULE_NAME", "default"},
106 | {"GAE_MODULE_VERSION", "20150612t184001"},
107 | }
108 |
109 | for _, v := range environ {
110 | old := os.Getenv(v.key)
111 | os.Setenv(v.key, v.value)
112 | v.value = old
113 | }
114 | return func() { // Restore old environment after the test completes.
115 | for _, v := range environ {
116 | if v.value == "" {
117 | os.Unsetenv(v.key)
118 | continue
119 | }
120 | os.Setenv(v.key, v.value)
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/app_id.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | import (
8 | "strings"
9 | )
10 |
11 | func parseFullAppID(appid string) (partition, domain, displayID string) {
12 | if i := strings.Index(appid, "~"); i != -1 {
13 | partition, appid = appid[:i], appid[i+1:]
14 | }
15 | if i := strings.Index(appid, ":"); i != -1 {
16 | domain, appid = appid[:i], appid[i+1:]
17 | }
18 | return partition, domain, appid
19 | }
20 |
21 | // appID returns "appid" or "domain.com:appid".
22 | func appID(fullAppID string) string {
23 | _, dom, dis := parseFullAppID(fullAppID)
24 | if dom != "" {
25 | return dom + ":" + dis
26 | }
27 | return dis
28 | }
29 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/app_identity/app_identity_service.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | option go_package = "app_identity";
3 |
4 | package appengine;
5 |
6 | message AppIdentityServiceError {
7 | enum ErrorCode {
8 | SUCCESS = 0;
9 | UNKNOWN_SCOPE = 9;
10 | BLOB_TOO_LARGE = 1000;
11 | DEADLINE_EXCEEDED = 1001;
12 | NOT_A_VALID_APP = 1002;
13 | UNKNOWN_ERROR = 1003;
14 | NOT_ALLOWED = 1005;
15 | NOT_IMPLEMENTED = 1006;
16 | }
17 | }
18 |
19 | message SignForAppRequest {
20 | optional bytes bytes_to_sign = 1;
21 | }
22 |
23 | message SignForAppResponse {
24 | optional string key_name = 1;
25 | optional bytes signature_bytes = 2;
26 | }
27 |
28 | message GetPublicCertificateForAppRequest {
29 | }
30 |
31 | message PublicCertificate {
32 | optional string key_name = 1;
33 | optional string x509_certificate_pem = 2;
34 | }
35 |
36 | message GetPublicCertificateForAppResponse {
37 | repeated PublicCertificate public_certificate_list = 1;
38 | optional int64 max_client_cache_time_in_second = 2;
39 | }
40 |
41 | message GetServiceAccountNameRequest {
42 | }
43 |
44 | message GetServiceAccountNameResponse {
45 | optional string service_account_name = 1;
46 | }
47 |
48 | message GetAccessTokenRequest {
49 | repeated string scope = 1;
50 | optional int64 service_account_id = 2;
51 | optional string service_account_name = 3;
52 | }
53 |
54 | message GetAccessTokenResponse {
55 | optional string access_token = 1;
56 | optional int64 expiration_time = 2;
57 | }
58 |
59 | message GetDefaultGcsBucketNameRequest {
60 | }
61 |
62 | message GetDefaultGcsBucketNameResponse {
63 | optional string default_gcs_bucket_name = 1;
64 | }
65 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/base/api_base.proto:
--------------------------------------------------------------------------------
1 | // Built-in base types for API calls. Primarily useful as return types.
2 |
3 | syntax = "proto2";
4 | option go_package = "base";
5 |
6 | package appengine.base;
7 |
8 | message StringProto {
9 | required string value = 1;
10 | }
11 |
12 | message Integer32Proto {
13 | required int32 value = 1;
14 | }
15 |
16 | message Integer64Proto {
17 | required int64 value = 1;
18 | }
19 |
20 | message BoolProto {
21 | required bool value = 1;
22 | }
23 |
24 | message DoubleProto {
25 | required double value = 1;
26 | }
27 |
28 | message BytesProto {
29 | required bytes value = 1 [ctype=CORD];
30 | }
31 |
32 | message VoidProto {
33 | }
34 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/identity.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | import (
8 | "os"
9 |
10 | netcontext "golang.org/x/net/context"
11 | )
12 |
13 | var (
14 | // This is set to true in identity_classic.go, which is behind the appengine build tag.
15 | // The appengine build tag is set for the first generation runtimes (<= Go 1.9) but not
16 | // the second generation runtimes (>= Go 1.11), so this indicates whether we're on a
17 | // first-gen runtime. See IsStandard below for the second-gen check.
18 | appengineStandard bool
19 |
20 | // This is set to true in identity_flex.go, which is behind the appenginevm build tag.
21 | appengineFlex bool
22 | )
23 |
24 | // AppID is the implementation of the wrapper function of the same name in
25 | // ../identity.go. See that file for commentary.
26 | func AppID(c netcontext.Context) string {
27 | return appID(FullyQualifiedAppID(c))
28 | }
29 |
30 | // IsStandard is the implementation of the wrapper function of the same name in
31 | // ../appengine.go. See that file for commentary.
32 | func IsStandard() bool {
33 | // appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not
34 | // second-gen (>= Go 1.11).
35 | return appengineStandard || IsSecondGen()
36 | }
37 |
38 | // IsStandard is the implementation of the wrapper function of the same name in
39 | // ../appengine.go. See that file for commentary.
40 | func IsSecondGen() bool {
41 | // Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime.
42 | return os.Getenv("GAE_ENV") == "standard"
43 | }
44 |
45 | // IsFlex is the implementation of the wrapper function of the same name in
46 | // ../appengine.go. See that file for commentary.
47 | func IsFlex() bool {
48 | return appengineFlex
49 | }
50 |
51 | // IsAppEngine is the implementation of the wrapper function of the same name in
52 | // ../appengine.go. See that file for commentary.
53 | func IsAppEngine() bool {
54 | return IsStandard() || IsFlex()
55 | }
56 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/identity_classic.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build appengine
6 |
7 | package internal
8 |
9 | import (
10 | "appengine"
11 |
12 | netcontext "golang.org/x/net/context"
13 | )
14 |
15 | func init() {
16 | appengineStandard = true
17 | }
18 |
19 | func DefaultVersionHostname(ctx netcontext.Context) string {
20 | c := fromContext(ctx)
21 | if c == nil {
22 | panic(errNotAppEngineContext)
23 | }
24 | return appengine.DefaultVersionHostname(c)
25 | }
26 |
27 | func Datacenter(_ netcontext.Context) string { return appengine.Datacenter() }
28 | func ServerSoftware() string { return appengine.ServerSoftware() }
29 | func InstanceID() string { return appengine.InstanceID() }
30 | func IsDevAppServer() bool { return appengine.IsDevAppServer() }
31 |
32 | func RequestID(ctx netcontext.Context) string {
33 | c := fromContext(ctx)
34 | if c == nil {
35 | panic(errNotAppEngineContext)
36 | }
37 | return appengine.RequestID(c)
38 | }
39 |
40 | func ModuleName(ctx netcontext.Context) string {
41 | c := fromContext(ctx)
42 | if c == nil {
43 | panic(errNotAppEngineContext)
44 | }
45 | return appengine.ModuleName(c)
46 | }
47 | func VersionID(ctx netcontext.Context) string {
48 | c := fromContext(ctx)
49 | if c == nil {
50 | panic(errNotAppEngineContext)
51 | }
52 | return appengine.VersionID(c)
53 | }
54 |
55 | func fullyQualifiedAppID(ctx netcontext.Context) string {
56 | c := fromContext(ctx)
57 | if c == nil {
58 | panic(errNotAppEngineContext)
59 | }
60 | return c.FullyQualifiedAppID()
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/identity_flex.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 Google LLC. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build appenginevm
6 |
7 | package internal
8 |
9 | func init() {
10 | appengineFlex = true
11 | }
12 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/identity_vm.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build !appengine
6 |
7 | package internal
8 |
9 | import (
10 | "log"
11 | "net/http"
12 | "os"
13 | "strings"
14 |
15 | netcontext "golang.org/x/net/context"
16 | )
17 |
18 | // These functions are implementations of the wrapper functions
19 | // in ../appengine/identity.go. See that file for commentary.
20 |
21 | const (
22 | hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname"
23 | hRequestLogId = "X-AppEngine-Request-Log-Id"
24 | hDatacenter = "X-AppEngine-Datacenter"
25 | )
26 |
27 | func ctxHeaders(ctx netcontext.Context) http.Header {
28 | c := fromContext(ctx)
29 | if c == nil {
30 | return nil
31 | }
32 | return c.Request().Header
33 | }
34 |
35 | func DefaultVersionHostname(ctx netcontext.Context) string {
36 | return ctxHeaders(ctx).Get(hDefaultVersionHostname)
37 | }
38 |
39 | func RequestID(ctx netcontext.Context) string {
40 | return ctxHeaders(ctx).Get(hRequestLogId)
41 | }
42 |
43 | func Datacenter(ctx netcontext.Context) string {
44 | if dc := ctxHeaders(ctx).Get(hDatacenter); dc != "" {
45 | return dc
46 | }
47 | // If the header isn't set, read zone from the metadata service.
48 | // It has the format projects/[NUMERIC_PROJECT_ID]/zones/[ZONE]
49 | zone, err := getMetadata("instance/zone")
50 | if err != nil {
51 | log.Printf("Datacenter: %v", err)
52 | return ""
53 | }
54 | parts := strings.Split(string(zone), "/")
55 | if len(parts) == 0 {
56 | return ""
57 | }
58 | return parts[len(parts)-1]
59 | }
60 |
61 | func ServerSoftware() string {
62 | // TODO(dsymonds): Remove fallback when we've verified this.
63 | if s := os.Getenv("SERVER_SOFTWARE"); s != "" {
64 | return s
65 | }
66 | if s := os.Getenv("GAE_ENV"); s != "" {
67 | return s
68 | }
69 | return "Google App Engine/1.x.x"
70 | }
71 |
72 | // TODO(dsymonds): Remove the metadata fetches.
73 |
74 | func ModuleName(_ netcontext.Context) string {
75 | if s := os.Getenv("GAE_MODULE_NAME"); s != "" {
76 | return s
77 | }
78 | if s := os.Getenv("GAE_SERVICE"); s != "" {
79 | return s
80 | }
81 | return string(mustGetMetadata("instance/attributes/gae_backend_name"))
82 | }
83 |
84 | func VersionID(_ netcontext.Context) string {
85 | if s1, s2 := os.Getenv("GAE_MODULE_VERSION"), os.Getenv("GAE_MINOR_VERSION"); s1 != "" && s2 != "" {
86 | return s1 + "." + s2
87 | }
88 | if s1, s2 := os.Getenv("GAE_VERSION"), os.Getenv("GAE_DEPLOYMENT_ID"); s1 != "" && s2 != "" {
89 | return s1 + "." + s2
90 | }
91 | return string(mustGetMetadata("instance/attributes/gae_backend_version")) + "." + string(mustGetMetadata("instance/attributes/gae_backend_minor_version"))
92 | }
93 |
94 | func InstanceID() string {
95 | if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" {
96 | return s
97 | }
98 | if s := os.Getenv("GAE_INSTANCE"); s != "" {
99 | return s
100 | }
101 | return string(mustGetMetadata("instance/attributes/gae_backend_instance"))
102 | }
103 |
104 | func partitionlessAppID() string {
105 | // gae_project has everything except the partition prefix.
106 | if appID := os.Getenv("GAE_LONG_APP_ID"); appID != "" {
107 | return appID
108 | }
109 | if project := os.Getenv("GOOGLE_CLOUD_PROJECT"); project != "" {
110 | return project
111 | }
112 | return string(mustGetMetadata("instance/attributes/gae_project"))
113 | }
114 |
115 | func fullyQualifiedAppID(_ netcontext.Context) string {
116 | if s := os.Getenv("GAE_APPLICATION"); s != "" {
117 | return s
118 | }
119 | appID := partitionlessAppID()
120 |
121 | part := os.Getenv("GAE_PARTITION")
122 | if part == "" {
123 | part = string(mustGetMetadata("instance/attributes/gae_partition"))
124 | }
125 |
126 | if part != "" {
127 | appID = part + "~" + appID
128 | }
129 | return appID
130 | }
131 |
132 | func IsDevAppServer() bool {
133 | return os.Getenv("RUN_WITH_DEVAPPSERVER") != ""
134 | }
135 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/internal.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package internal provides support for package appengine.
6 | //
7 | // Programs should not use this package directly. Its API is not stable.
8 | // Use packages appengine and appengine/* instead.
9 | package internal
10 |
11 | import (
12 | "fmt"
13 |
14 | "github.com/golang/protobuf/proto"
15 |
16 | remotepb "google.golang.org/appengine/internal/remote_api"
17 | )
18 |
19 | // errorCodeMaps is a map of service name to the error code map for the service.
20 | var errorCodeMaps = make(map[string]map[int32]string)
21 |
22 | // RegisterErrorCodeMap is called from API implementations to register their
23 | // error code map. This should only be called from init functions.
24 | func RegisterErrorCodeMap(service string, m map[int32]string) {
25 | errorCodeMaps[service] = m
26 | }
27 |
28 | type timeoutCodeKey struct {
29 | service string
30 | code int32
31 | }
32 |
33 | // timeoutCodes is the set of service+code pairs that represent timeouts.
34 | var timeoutCodes = make(map[timeoutCodeKey]bool)
35 |
36 | func RegisterTimeoutErrorCode(service string, code int32) {
37 | timeoutCodes[timeoutCodeKey{service, code}] = true
38 | }
39 |
40 | // APIError is the type returned by appengine.Context's Call method
41 | // when an API call fails in an API-specific way. This may be, for instance,
42 | // a taskqueue API call failing with TaskQueueServiceError::UNKNOWN_QUEUE.
43 | type APIError struct {
44 | Service string
45 | Detail string
46 | Code int32 // API-specific error code
47 | }
48 |
49 | func (e *APIError) Error() string {
50 | if e.Code == 0 {
51 | if e.Detail == "" {
52 | return "APIError "
53 | }
54 | return e.Detail
55 | }
56 | s := fmt.Sprintf("API error %d", e.Code)
57 | if m, ok := errorCodeMaps[e.Service]; ok {
58 | s += " (" + e.Service + ": " + m[e.Code] + ")"
59 | } else {
60 | // Shouldn't happen, but provide a bit more detail if it does.
61 | s = e.Service + " " + s
62 | }
63 | if e.Detail != "" {
64 | s += ": " + e.Detail
65 | }
66 | return s
67 | }
68 |
69 | func (e *APIError) IsTimeout() bool {
70 | return timeoutCodes[timeoutCodeKey{e.Service, e.Code}]
71 | }
72 |
73 | // CallError is the type returned by appengine.Context's Call method when an
74 | // API call fails in a generic way, such as RpcError::CAPABILITY_DISABLED.
75 | type CallError struct {
76 | Detail string
77 | Code int32
78 | // TODO: Remove this if we get a distinguishable error code.
79 | Timeout bool
80 | }
81 |
82 | func (e *CallError) Error() string {
83 | var msg string
84 | switch remotepb.RpcError_ErrorCode(e.Code) {
85 | case remotepb.RpcError_UNKNOWN:
86 | return e.Detail
87 | case remotepb.RpcError_OVER_QUOTA:
88 | msg = "Over quota"
89 | case remotepb.RpcError_CAPABILITY_DISABLED:
90 | msg = "Capability disabled"
91 | case remotepb.RpcError_CANCELLED:
92 | msg = "Canceled"
93 | default:
94 | msg = fmt.Sprintf("Call error %d", e.Code)
95 | }
96 | s := msg + ": " + e.Detail
97 | if e.Timeout {
98 | s += " (timeout)"
99 | }
100 | return s
101 | }
102 |
103 | func (e *CallError) IsTimeout() bool {
104 | return e.Timeout
105 | }
106 |
107 | // NamespaceMods is a map from API service to a function that will mutate an RPC request to attach a namespace.
108 | // The function should be prepared to be called on the same message more than once; it should only modify the
109 | // RPC request the first time.
110 | var NamespaceMods = make(map[string]func(m proto.Message, namespace string))
111 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/log/log_service.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | option go_package = "log";
3 |
4 | package appengine;
5 |
6 | message LogServiceError {
7 | enum ErrorCode {
8 | OK = 0;
9 | INVALID_REQUEST = 1;
10 | STORAGE_ERROR = 2;
11 | }
12 | }
13 |
14 | message UserAppLogLine {
15 | required int64 timestamp_usec = 1;
16 | required int64 level = 2;
17 | required string message = 3;
18 | }
19 |
20 | message UserAppLogGroup {
21 | repeated UserAppLogLine log_line = 2;
22 | }
23 |
24 | message FlushRequest {
25 | optional bytes logs = 1;
26 | }
27 |
28 | message SetStatusRequest {
29 | required string status = 1;
30 | }
31 |
32 |
33 | message LogOffset {
34 | optional bytes request_id = 1;
35 | }
36 |
37 | message LogLine {
38 | required int64 time = 1;
39 | required int32 level = 2;
40 | required string log_message = 3;
41 | }
42 |
43 | message RequestLog {
44 | required string app_id = 1;
45 | optional string module_id = 37 [default="default"];
46 | required string version_id = 2;
47 | required bytes request_id = 3;
48 | optional LogOffset offset = 35;
49 | required string ip = 4;
50 | optional string nickname = 5;
51 | required int64 start_time = 6;
52 | required int64 end_time = 7;
53 | required int64 latency = 8;
54 | required int64 mcycles = 9;
55 | required string method = 10;
56 | required string resource = 11;
57 | required string http_version = 12;
58 | required int32 status = 13;
59 | required int64 response_size = 14;
60 | optional string referrer = 15;
61 | optional string user_agent = 16;
62 | required string url_map_entry = 17;
63 | required string combined = 18;
64 | optional int64 api_mcycles = 19;
65 | optional string host = 20;
66 | optional double cost = 21;
67 |
68 | optional string task_queue_name = 22;
69 | optional string task_name = 23;
70 |
71 | optional bool was_loading_request = 24;
72 | optional int64 pending_time = 25;
73 | optional int32 replica_index = 26 [default = -1];
74 | optional bool finished = 27 [default = true];
75 | optional bytes clone_key = 28;
76 |
77 | repeated LogLine line = 29;
78 |
79 | optional bool lines_incomplete = 36;
80 | optional bytes app_engine_release = 38;
81 |
82 | optional int32 exit_reason = 30;
83 | optional bool was_throttled_for_time = 31;
84 | optional bool was_throttled_for_requests = 32;
85 | optional int64 throttled_time = 33;
86 |
87 | optional bytes server_name = 34;
88 | }
89 |
90 | message LogModuleVersion {
91 | optional string module_id = 1 [default="default"];
92 | optional string version_id = 2;
93 | }
94 |
95 | message LogReadRequest {
96 | required string app_id = 1;
97 | repeated string version_id = 2;
98 | repeated LogModuleVersion module_version = 19;
99 |
100 | optional int64 start_time = 3;
101 | optional int64 end_time = 4;
102 | optional LogOffset offset = 5;
103 | repeated bytes request_id = 6;
104 |
105 | optional int32 minimum_log_level = 7;
106 | optional bool include_incomplete = 8;
107 | optional int64 count = 9;
108 |
109 | optional string combined_log_regex = 14;
110 | optional string host_regex = 15;
111 | optional int32 replica_index = 16;
112 |
113 | optional bool include_app_logs = 10;
114 | optional int32 app_logs_per_request = 17;
115 | optional bool include_host = 11;
116 | optional bool include_all = 12;
117 | optional bool cache_iterator = 13;
118 | optional int32 num_shards = 18;
119 | }
120 |
121 | message LogReadResponse {
122 | repeated RequestLog log = 1;
123 | optional LogOffset offset = 2;
124 | optional int64 last_end_time = 3;
125 | }
126 |
127 | message LogUsageRecord {
128 | optional string version_id = 1;
129 | optional int32 start_time = 2;
130 | optional int32 end_time = 3;
131 | optional int64 count = 4;
132 | optional int64 total_size = 5;
133 | optional int32 records = 6;
134 | }
135 |
136 | message LogUsageRequest {
137 | required string app_id = 1;
138 | repeated string version_id = 2;
139 | optional int32 start_time = 3;
140 | optional int32 end_time = 4;
141 | optional uint32 resolution_hours = 5 [default = 1];
142 | optional bool combine_versions = 6;
143 | optional int32 usage_version = 7;
144 | optional bool versions_only = 8;
145 | }
146 |
147 | message LogUsageResponse {
148 | repeated LogUsageRecord usage = 1;
149 | optional LogUsageRecord summary = 2;
150 | }
151 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/main.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build appengine
6 |
7 | package internal
8 |
9 | import (
10 | "appengine_internal"
11 | )
12 |
13 | func Main() {
14 | MainPath = ""
15 | appengine_internal.Main()
16 | }
17 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/main_common.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
3 | // MainPath stores the file path of the main package. On App Engine Standard
4 | // using Go version 1.9 and below, this will be unset. On App Engine Flex and
5 | // App Engine Standard second-gen (Go 1.11 and above), this will be the
6 | // filepath to package main.
7 | var MainPath string
8 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/main_vm.go:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | // +build !appengine
6 |
7 | package internal
8 |
9 | import (
10 | "io"
11 | "log"
12 | "net/http"
13 | "net/url"
14 | "os"
15 | "path/filepath"
16 | "runtime"
17 | )
18 |
19 | func Main() {
20 | MainPath = filepath.Dir(findMainPath())
21 | installHealthChecker(http.DefaultServeMux)
22 |
23 | port := "8080"
24 | if s := os.Getenv("PORT"); s != "" {
25 | port = s
26 | }
27 |
28 | host := ""
29 | if IsDevAppServer() {
30 | host = "127.0.0.1"
31 | }
32 | if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
33 | log.Fatalf("http.ListenAndServe: %v", err)
34 | }
35 | }
36 |
37 | // Find the path to package main by looking at the root Caller.
38 | func findMainPath() string {
39 | pc := make([]uintptr, 100)
40 | n := runtime.Callers(2, pc)
41 | frames := runtime.CallersFrames(pc[:n])
42 | for {
43 | frame, more := frames.Next()
44 | // Tests won't have package main, instead they have testing.tRunner
45 | if frame.Function == "main.main" || frame.Function == "testing.tRunner" {
46 | return frame.File
47 | }
48 | if !more {
49 | break
50 | }
51 | }
52 | return ""
53 | }
54 |
55 | func installHealthChecker(mux *http.ServeMux) {
56 | // If no health check handler has been installed by this point, add a trivial one.
57 | const healthPath = "/_ah/health"
58 | hreq := &http.Request{
59 | Method: "GET",
60 | URL: &url.URL{
61 | Path: healthPath,
62 | },
63 | }
64 | if _, pat := mux.Handler(hreq); pat != healthPath {
65 | mux.HandleFunc(healthPath, func(w http.ResponseWriter, r *http.Request) {
66 | io.WriteString(w, "ok")
67 | })
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/metadata.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | // This file has code for accessing metadata.
8 | //
9 | // References:
10 | // https://cloud.google.com/compute/docs/metadata
11 |
12 | import (
13 | "fmt"
14 | "io/ioutil"
15 | "net/http"
16 | "net/url"
17 | )
18 |
19 | const (
20 | metadataHost = "metadata"
21 | metadataPath = "/computeMetadata/v1/"
22 | )
23 |
24 | var (
25 | metadataRequestHeaders = http.Header{
26 | "Metadata-Flavor": []string{"Google"},
27 | }
28 | )
29 |
30 | // TODO(dsymonds): Do we need to support default values, like Python?
31 | func mustGetMetadata(key string) []byte {
32 | b, err := getMetadata(key)
33 | if err != nil {
34 | panic(fmt.Sprintf("Metadata fetch failed for '%s': %v", key, err))
35 | }
36 | return b
37 | }
38 |
39 | func getMetadata(key string) ([]byte, error) {
40 | // TODO(dsymonds): May need to use url.Parse to support keys with query args.
41 | req := &http.Request{
42 | Method: "GET",
43 | URL: &url.URL{
44 | Scheme: "http",
45 | Host: metadataHost,
46 | Path: metadataPath + key,
47 | },
48 | Header: metadataRequestHeaders,
49 | Host: metadataHost,
50 | }
51 | resp, err := http.DefaultClient.Do(req)
52 | if err != nil {
53 | return nil, err
54 | }
55 | defer resp.Body.Close()
56 | if resp.StatusCode != 200 {
57 | return nil, fmt.Errorf("metadata server returned HTTP %d", resp.StatusCode)
58 | }
59 | return ioutil.ReadAll(resp.Body)
60 | }
61 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/modules/modules_service.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | option go_package = "modules";
3 |
4 | package appengine;
5 |
6 | message ModulesServiceError {
7 | enum ErrorCode {
8 | OK = 0;
9 | INVALID_MODULE = 1;
10 | INVALID_VERSION = 2;
11 | INVALID_INSTANCES = 3;
12 | TRANSIENT_ERROR = 4;
13 | UNEXPECTED_STATE = 5;
14 | }
15 | }
16 |
17 | message GetModulesRequest {
18 | }
19 |
20 | message GetModulesResponse {
21 | repeated string module = 1;
22 | }
23 |
24 | message GetVersionsRequest {
25 | optional string module = 1;
26 | }
27 |
28 | message GetVersionsResponse {
29 | repeated string version = 1;
30 | }
31 |
32 | message GetDefaultVersionRequest {
33 | optional string module = 1;
34 | }
35 |
36 | message GetDefaultVersionResponse {
37 | required string version = 1;
38 | }
39 |
40 | message GetNumInstancesRequest {
41 | optional string module = 1;
42 | optional string version = 2;
43 | }
44 |
45 | message GetNumInstancesResponse {
46 | required int64 instances = 1;
47 | }
48 |
49 | message SetNumInstancesRequest {
50 | optional string module = 1;
51 | optional string version = 2;
52 | required int64 instances = 3;
53 | }
54 |
55 | message SetNumInstancesResponse {}
56 |
57 | message StartModuleRequest {
58 | required string module = 1;
59 | required string version = 2;
60 | }
61 |
62 | message StartModuleResponse {}
63 |
64 | message StopModuleRequest {
65 | optional string module = 1;
66 | optional string version = 2;
67 | }
68 |
69 | message StopModuleResponse {}
70 |
71 | message GetHostnameRequest {
72 | optional string module = 1;
73 | optional string version = 2;
74 | optional string instance = 3;
75 | }
76 |
77 | message GetHostnameResponse {
78 | required string hostname = 1;
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/net.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | // This file implements a network dialer that limits the number of concurrent connections.
8 | // It is only used for API calls.
9 |
10 | import (
11 | "log"
12 | "net"
13 | "runtime"
14 | "sync"
15 | "time"
16 | )
17 |
18 | var limitSem = make(chan int, 100) // TODO(dsymonds): Use environment variable.
19 |
20 | func limitRelease() {
21 | // non-blocking
22 | select {
23 | case <-limitSem:
24 | default:
25 | // This should not normally happen.
26 | log.Print("appengine: unbalanced limitSem release!")
27 | }
28 | }
29 |
30 | func limitDial(network, addr string) (net.Conn, error) {
31 | limitSem <- 1
32 |
33 | // Dial with a timeout in case the API host is MIA.
34 | // The connection should normally be very fast.
35 | conn, err := net.DialTimeout(network, addr, 10*time.Second)
36 | if err != nil {
37 | limitRelease()
38 | return nil, err
39 | }
40 | lc := &limitConn{Conn: conn}
41 | runtime.SetFinalizer(lc, (*limitConn).Close) // shouldn't usually be required
42 | return lc, nil
43 | }
44 |
45 | type limitConn struct {
46 | close sync.Once
47 | net.Conn
48 | }
49 |
50 | func (lc *limitConn) Close() error {
51 | defer lc.close.Do(func() {
52 | limitRelease()
53 | runtime.SetFinalizer(lc, nil)
54 | })
55 | return lc.Conn.Close()
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/regen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 | #
3 | # This script rebuilds the generated code for the protocol buffers.
4 | # To run this you will need protoc and goprotobuf installed;
5 | # see https://github.com/golang/protobuf for instructions.
6 |
7 | PKG=google.golang.org/appengine
8 |
9 | function die() {
10 | echo 1>&2 $*
11 | exit 1
12 | }
13 |
14 | # Sanity check that the right tools are accessible.
15 | for tool in go protoc protoc-gen-go; do
16 | q=$(which $tool) || die "didn't find $tool"
17 | echo 1>&2 "$tool: $q"
18 | done
19 |
20 | echo -n 1>&2 "finding package dir... "
21 | pkgdir=$(go list -f '{{.Dir}}' $PKG)
22 | echo 1>&2 $pkgdir
23 | base=$(echo $pkgdir | sed "s,/$PKG\$,,")
24 | echo 1>&2 "base: $base"
25 | cd $base
26 |
27 | # Run protoc once per package.
28 | for dir in $(find $PKG/internal -name '*.proto' | xargs dirname | sort | uniq); do
29 | echo 1>&2 "* $dir"
30 | protoc --go_out=. $dir/*.proto
31 | done
32 |
33 | for f in $(find $PKG/internal -name '*.pb.go'); do
34 | # Remove proto.RegisterEnum calls.
35 | # These cause duplicate registration panics when these packages
36 | # are used on classic App Engine. proto.RegisterEnum only affects
37 | # parsing the text format; we don't care about that.
38 | # https://code.google.com/p/googleappengine/issues/detail?id=11670#c17
39 | sed -i '/proto.RegisterEnum/d' $f
40 | done
41 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/remote_api/remote_api.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto2";
2 | option go_package = "remote_api";
3 |
4 | package remote_api;
5 |
6 | message Request {
7 | required string service_name = 2;
8 | required string method = 3;
9 | required bytes request = 4;
10 | optional string request_id = 5;
11 | }
12 |
13 | message ApplicationError {
14 | required int32 code = 1;
15 | required string detail = 2;
16 | }
17 |
18 | message RpcError {
19 | enum ErrorCode {
20 | UNKNOWN = 0;
21 | CALL_NOT_FOUND = 1;
22 | PARSE_ERROR = 2;
23 | SECURITY_VIOLATION = 3;
24 | OVER_QUOTA = 4;
25 | REQUEST_TOO_LARGE = 5;
26 | CAPABILITY_DISABLED = 6;
27 | FEATURE_DISABLED = 7;
28 | BAD_REQUEST = 8;
29 | RESPONSE_TOO_LARGE = 9;
30 | CANCELLED = 10;
31 | REPLAY_ERROR = 11;
32 | DEADLINE_EXCEEDED = 12;
33 | }
34 | required int32 code = 1;
35 | optional string detail = 2;
36 | }
37 |
38 | message Response {
39 | optional bytes response = 1;
40 | optional bytes exception = 2;
41 | optional ApplicationError application_error = 3;
42 | optional bytes java_exception = 4;
43 | optional RpcError rpc_error = 5;
44 | }
45 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/internal/transaction.go:
--------------------------------------------------------------------------------
1 | // Copyright 2014 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal
6 |
7 | // This file implements hooks for applying datastore transactions.
8 |
9 | import (
10 | "errors"
11 | "reflect"
12 |
13 | "github.com/golang/protobuf/proto"
14 | netcontext "golang.org/x/net/context"
15 |
16 | basepb "google.golang.org/appengine/internal/base"
17 | pb "google.golang.org/appengine/internal/datastore"
18 | )
19 |
20 | var transactionSetters = make(map[reflect.Type]reflect.Value)
21 |
22 | // RegisterTransactionSetter registers a function that sets transaction information
23 | // in a protocol buffer message. f should be a function with two arguments,
24 | // the first being a protocol buffer type, and the second being *datastore.Transaction.
25 | func RegisterTransactionSetter(f interface{}) {
26 | v := reflect.ValueOf(f)
27 | transactionSetters[v.Type().In(0)] = v
28 | }
29 |
30 | // applyTransaction applies the transaction t to message pb
31 | // by using the relevant setter passed to RegisterTransactionSetter.
32 | func applyTransaction(pb proto.Message, t *pb.Transaction) {
33 | v := reflect.ValueOf(pb)
34 | if f, ok := transactionSetters[v.Type()]; ok {
35 | f.Call([]reflect.Value{v, reflect.ValueOf(t)})
36 | }
37 | }
38 |
39 | var transactionKey = "used for *Transaction"
40 |
41 | func transactionFromContext(ctx netcontext.Context) *transaction {
42 | t, _ := ctx.Value(&transactionKey).(*transaction)
43 | return t
44 | }
45 |
46 | func withTransaction(ctx netcontext.Context, t *transaction) netcontext.Context {
47 | return netcontext.WithValue(ctx, &transactionKey, t)
48 | }
49 |
50 | type transaction struct {
51 | transaction pb.Transaction
52 | finished bool
53 | }
54 |
55 | var ErrConcurrentTransaction = errors.New("internal: concurrent transaction")
56 |
57 | func RunTransactionOnce(c netcontext.Context, f func(netcontext.Context) error, xg bool, readOnly bool, previousTransaction *pb.Transaction) (*pb.Transaction, error) {
58 | if transactionFromContext(c) != nil {
59 | return nil, errors.New("nested transactions are not supported")
60 | }
61 |
62 | // Begin the transaction.
63 | t := &transaction{}
64 | req := &pb.BeginTransactionRequest{
65 | App: proto.String(FullyQualifiedAppID(c)),
66 | }
67 | if xg {
68 | req.AllowMultipleEg = proto.Bool(true)
69 | }
70 | if previousTransaction != nil {
71 | req.PreviousTransaction = previousTransaction
72 | }
73 | if readOnly {
74 | req.Mode = pb.BeginTransactionRequest_READ_ONLY.Enum()
75 | } else {
76 | req.Mode = pb.BeginTransactionRequest_READ_WRITE.Enum()
77 | }
78 | if err := Call(c, "datastore_v3", "BeginTransaction", req, &t.transaction); err != nil {
79 | return nil, err
80 | }
81 |
82 | // Call f, rolling back the transaction if f returns a non-nil error, or panics.
83 | // The panic is not recovered.
84 | defer func() {
85 | if t.finished {
86 | return
87 | }
88 | t.finished = true
89 | // Ignore the error return value, since we are already returning a non-nil
90 | // error (or we're panicking).
91 | Call(c, "datastore_v3", "Rollback", &t.transaction, &basepb.VoidProto{})
92 | }()
93 | if err := f(withTransaction(c, t)); err != nil {
94 | return &t.transaction, err
95 | }
96 | t.finished = true
97 |
98 | // Commit the transaction.
99 | res := &pb.CommitResponse{}
100 | err := Call(c, "datastore_v3", "Commit", &t.transaction, res)
101 | if ae, ok := err.(*APIError); ok {
102 | /* TODO: restore this conditional
103 | if appengine.IsDevAppServer() {
104 | */
105 | // The Python Dev AppServer raises an ApplicationError with error code 2 (which is
106 | // Error.CONCURRENT_TRANSACTION) and message "Concurrency exception.".
107 | if ae.Code == int32(pb.Error_BAD_REQUEST) && ae.Detail == "ApplicationError: 2 Concurrency exception." {
108 | return &t.transaction, ErrConcurrentTransaction
109 | }
110 | if ae.Code == int32(pb.Error_CONCURRENT_TRANSACTION) {
111 | return &t.transaction, ErrConcurrentTransaction
112 | }
113 | }
114 | return &t.transaction, err
115 | }
116 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/namespace.go:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package appengine
6 |
7 | import (
8 | "fmt"
9 | "regexp"
10 |
11 | "golang.org/x/net/context"
12 |
13 | "google.golang.org/appengine/internal"
14 | )
15 |
16 | // Namespace returns a replacement context that operates within the given namespace.
17 | func Namespace(c context.Context, namespace string) (context.Context, error) {
18 | if !validNamespace.MatchString(namespace) {
19 | return nil, fmt.Errorf("appengine: namespace %q does not match /%s/", namespace, validNamespace)
20 | }
21 | return internal.NamespacedContext(c, namespace), nil
22 | }
23 |
24 | // validNamespace matches valid namespace names.
25 | var validNamespace = regexp.MustCompile(`^[0-9A-Za-z._-]{0,100}$`)
26 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/timeout.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Google Inc. All rights reserved.
2 | // Use of this source code is governed by the Apache 2.0
3 | // license that can be found in the LICENSE file.
4 |
5 | package appengine
6 |
7 | import "golang.org/x/net/context"
8 |
9 | // IsTimeoutError reports whether err is a timeout error.
10 | func IsTimeoutError(err error) bool {
11 | if err == context.DeadlineExceeded {
12 | return true
13 | }
14 | if t, ok := err.(interface {
15 | IsTimeout() bool
16 | }); ok {
17 | return t.IsTimeout()
18 | }
19 | return false
20 | }
21 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/travis_install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | if [[ $GO111MODULE == "on" ]]; then
5 | go get .
6 | else
7 | go get -u -v $(go list -f '{{join .Imports "\n"}}{{"\n"}}{{join .TestImports "\n"}}' ./... | sort | uniq | grep -v appengine)
8 | fi
9 |
10 | if [[ $GOAPP == "true" ]]; then
11 | mkdir /tmp/sdk
12 | curl -o /tmp/sdk.zip "https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-1.9.68.zip"
13 | unzip -q /tmp/sdk.zip -d /tmp/sdk
14 | # NOTE: Set the following env vars in the test script:
15 | # export PATH="$PATH:/tmp/sdk/go_appengine"
16 | # export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
17 | fi
18 |
19 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/appengine/travis_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | go version
5 | go test -v google.golang.org/appengine/...
6 | go test -v -race google.golang.org/appengine/...
7 | if [[ $GOAPP == "true" ]]; then
8 | export PATH="$PATH:/tmp/sdk/go_appengine"
9 | export APPENGINE_DEV_APPSERVER=/tmp/sdk/go_appengine/dev_appserver.py
10 | goapp version
11 | goapp test -v google.golang.org/appengine/...
12 | fi
13 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - "1.4.x"
5 | - "1.5.x"
6 | - "1.6.x"
7 | - "1.7.x"
8 | - "1.8.x"
9 | - "1.9.x"
10 | - "1.10.x"
11 | - "1.11.x"
12 | - "1.12.x"
13 | - "1.13.x"
14 | - "tip"
15 |
16 | go_import_path: gopkg.in/yaml.v2
17 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/LICENSE.libyaml:
--------------------------------------------------------------------------------
1 | The following files were ported to Go from C files of libyaml, and thus
2 | are still covered by their original copyright and license:
3 |
4 | apic.go
5 | emitterc.go
6 | parserc.go
7 | readerc.go
8 | scannerc.go
9 | writerc.go
10 | yamlh.go
11 | yamlprivateh.go
12 |
13 | Copyright (c) 2006 Kirill Simonov
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy of
16 | this software and associated documentation files (the "Software"), to deal in
17 | the Software without restriction, including without limitation the rights to
18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
19 | of the Software, and to permit persons to whom the Software is furnished to do
20 | so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/NOTICE:
--------------------------------------------------------------------------------
1 | Copyright 2011-2016 Canonical Ltd.
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 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/README.md:
--------------------------------------------------------------------------------
1 | # YAML support for the Go language
2 |
3 | Introduction
4 | ------------
5 |
6 | The yaml package enables Go programs to comfortably encode and decode YAML
7 | values. It was developed within [Canonical](https://www.canonical.com) as
8 | part of the [juju](https://juju.ubuntu.com) project, and is based on a
9 | pure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)
10 | C library to parse and generate YAML data quickly and reliably.
11 |
12 | Compatibility
13 | -------------
14 |
15 | The yaml package supports most of YAML 1.1 and 1.2, including support for
16 | anchors, tags, map merging, etc. Multi-document unmarshalling is not yet
17 | implemented, and base-60 floats from YAML 1.1 are purposefully not
18 | supported since they're a poor design and are gone in YAML 1.2.
19 |
20 | Installation and usage
21 | ----------------------
22 |
23 | The import path for the package is *gopkg.in/yaml.v2*.
24 |
25 | To install it, run:
26 |
27 | go get gopkg.in/yaml.v2
28 |
29 | API documentation
30 | -----------------
31 |
32 | If opened in a browser, the import path itself leads to the API documentation:
33 |
34 | * [https://gopkg.in/yaml.v2](https://gopkg.in/yaml.v2)
35 |
36 | API stability
37 | -------------
38 |
39 | The package API for yaml v2 will remain stable as described in [gopkg.in](https://gopkg.in).
40 |
41 |
42 | License
43 | -------
44 |
45 | The yaml package is licensed under the Apache License 2.0. Please see the LICENSE file for details.
46 |
47 |
48 | Example
49 | -------
50 |
51 | ```Go
52 | package main
53 |
54 | import (
55 | "fmt"
56 | "log"
57 |
58 | "gopkg.in/yaml.v2"
59 | )
60 |
61 | var data = `
62 | a: Easy!
63 | b:
64 | c: 2
65 | d: [3, 4]
66 | `
67 |
68 | // Note: struct fields must be public in order for unmarshal to
69 | // correctly populate the data.
70 | type T struct {
71 | A string
72 | B struct {
73 | RenamedC int `yaml:"c"`
74 | D []int `yaml:",flow"`
75 | }
76 | }
77 |
78 | func main() {
79 | t := T{}
80 |
81 | err := yaml.Unmarshal([]byte(data), &t)
82 | if err != nil {
83 | log.Fatalf("error: %v", err)
84 | }
85 | fmt.Printf("--- t:\n%v\n\n", t)
86 |
87 | d, err := yaml.Marshal(&t)
88 | if err != nil {
89 | log.Fatalf("error: %v", err)
90 | }
91 | fmt.Printf("--- t dump:\n%s\n\n", string(d))
92 |
93 | m := make(map[interface{}]interface{})
94 |
95 | err = yaml.Unmarshal([]byte(data), &m)
96 | if err != nil {
97 | log.Fatalf("error: %v", err)
98 | }
99 | fmt.Printf("--- m:\n%v\n\n", m)
100 |
101 | d, err = yaml.Marshal(&m)
102 | if err != nil {
103 | log.Fatalf("error: %v", err)
104 | }
105 | fmt.Printf("--- m dump:\n%s\n\n", string(d))
106 | }
107 | ```
108 |
109 | This example will generate the following output:
110 |
111 | ```
112 | --- t:
113 | {Easy! {2 [3 4]}}
114 |
115 | --- t dump:
116 | a: Easy!
117 | b:
118 | c: 2
119 | d: [3, 4]
120 |
121 |
122 | --- m:
123 | map[a:Easy! b:map[c:2 d:[3 4]]]
124 |
125 | --- m dump:
126 | a: Easy!
127 | b:
128 | c: 2
129 | d:
130 | - 3
131 | - 4
132 | ```
133 |
134 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/encode.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding"
5 | "fmt"
6 | "io"
7 | "reflect"
8 | "regexp"
9 | "sort"
10 | "strconv"
11 | "strings"
12 | "time"
13 | "unicode/utf8"
14 | )
15 |
16 | // jsonNumber is the interface of the encoding/json.Number datatype.
17 | // Repeating the interface here avoids a dependency on encoding/json, and also
18 | // supports other libraries like jsoniter, which use a similar datatype with
19 | // the same interface. Detecting this interface is useful when dealing with
20 | // structures containing json.Number, which is a string under the hood. The
21 | // encoder should prefer the use of Int64(), Float64() and string(), in that
22 | // order, when encoding this type.
23 | type jsonNumber interface {
24 | Float64() (float64, error)
25 | Int64() (int64, error)
26 | String() string
27 | }
28 |
29 | type encoder struct {
30 | emitter yaml_emitter_t
31 | event yaml_event_t
32 | out []byte
33 | flow bool
34 | // doneInit holds whether the initial stream_start_event has been
35 | // emitted.
36 | doneInit bool
37 | }
38 |
39 | func newEncoder() *encoder {
40 | e := &encoder{}
41 | yaml_emitter_initialize(&e.emitter)
42 | yaml_emitter_set_output_string(&e.emitter, &e.out)
43 | yaml_emitter_set_unicode(&e.emitter, true)
44 | return e
45 | }
46 |
47 | func newEncoderWithWriter(w io.Writer) *encoder {
48 | e := &encoder{}
49 | yaml_emitter_initialize(&e.emitter)
50 | yaml_emitter_set_output_writer(&e.emitter, w)
51 | yaml_emitter_set_unicode(&e.emitter, true)
52 | return e
53 | }
54 |
55 | func (e *encoder) init() {
56 | if e.doneInit {
57 | return
58 | }
59 | yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
60 | e.emit()
61 | e.doneInit = true
62 | }
63 |
64 | func (e *encoder) finish() {
65 | e.emitter.open_ended = false
66 | yaml_stream_end_event_initialize(&e.event)
67 | e.emit()
68 | }
69 |
70 | func (e *encoder) destroy() {
71 | yaml_emitter_delete(&e.emitter)
72 | }
73 |
74 | func (e *encoder) emit() {
75 | // This will internally delete the e.event value.
76 | e.must(yaml_emitter_emit(&e.emitter, &e.event))
77 | }
78 |
79 | func (e *encoder) must(ok bool) {
80 | if !ok {
81 | msg := e.emitter.problem
82 | if msg == "" {
83 | msg = "unknown problem generating YAML content"
84 | }
85 | failf("%s", msg)
86 | }
87 | }
88 |
89 | func (e *encoder) marshalDoc(tag string, in reflect.Value) {
90 | e.init()
91 | yaml_document_start_event_initialize(&e.event, nil, nil, true)
92 | e.emit()
93 | e.marshal(tag, in)
94 | yaml_document_end_event_initialize(&e.event, true)
95 | e.emit()
96 | }
97 |
98 | func (e *encoder) marshal(tag string, in reflect.Value) {
99 | if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
100 | e.nilv()
101 | return
102 | }
103 | iface := in.Interface()
104 | switch m := iface.(type) {
105 | case jsonNumber:
106 | integer, err := m.Int64()
107 | if err == nil {
108 | // In this case the json.Number is a valid int64
109 | in = reflect.ValueOf(integer)
110 | break
111 | }
112 | float, err := m.Float64()
113 | if err == nil {
114 | // In this case the json.Number is a valid float64
115 | in = reflect.ValueOf(float)
116 | break
117 | }
118 | // fallback case - no number could be obtained
119 | in = reflect.ValueOf(m.String())
120 | case time.Time, *time.Time:
121 | // Although time.Time implements TextMarshaler,
122 | // we don't want to treat it as a string for YAML
123 | // purposes because YAML has special support for
124 | // timestamps.
125 | case Marshaler:
126 | v, err := m.MarshalYAML()
127 | if err != nil {
128 | fail(err)
129 | }
130 | if v == nil {
131 | e.nilv()
132 | return
133 | }
134 | in = reflect.ValueOf(v)
135 | case encoding.TextMarshaler:
136 | text, err := m.MarshalText()
137 | if err != nil {
138 | fail(err)
139 | }
140 | in = reflect.ValueOf(string(text))
141 | case nil:
142 | e.nilv()
143 | return
144 | }
145 | switch in.Kind() {
146 | case reflect.Interface:
147 | e.marshal(tag, in.Elem())
148 | case reflect.Map:
149 | e.mapv(tag, in)
150 | case reflect.Ptr:
151 | if in.Type() == ptrTimeType {
152 | e.timev(tag, in.Elem())
153 | } else {
154 | e.marshal(tag, in.Elem())
155 | }
156 | case reflect.Struct:
157 | if in.Type() == timeType {
158 | e.timev(tag, in)
159 | } else {
160 | e.structv(tag, in)
161 | }
162 | case reflect.Slice, reflect.Array:
163 | if in.Type().Elem() == mapItemType {
164 | e.itemsv(tag, in)
165 | } else {
166 | e.slicev(tag, in)
167 | }
168 | case reflect.String:
169 | e.stringv(tag, in)
170 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
171 | if in.Type() == durationType {
172 | e.stringv(tag, reflect.ValueOf(iface.(time.Duration).String()))
173 | } else {
174 | e.intv(tag, in)
175 | }
176 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
177 | e.uintv(tag, in)
178 | case reflect.Float32, reflect.Float64:
179 | e.floatv(tag, in)
180 | case reflect.Bool:
181 | e.boolv(tag, in)
182 | default:
183 | panic("cannot marshal type: " + in.Type().String())
184 | }
185 | }
186 |
187 | func (e *encoder) mapv(tag string, in reflect.Value) {
188 | e.mappingv(tag, func() {
189 | keys := keyList(in.MapKeys())
190 | sort.Sort(keys)
191 | for _, k := range keys {
192 | e.marshal("", k)
193 | e.marshal("", in.MapIndex(k))
194 | }
195 | })
196 | }
197 |
198 | func (e *encoder) itemsv(tag string, in reflect.Value) {
199 | e.mappingv(tag, func() {
200 | slice := in.Convert(reflect.TypeOf([]MapItem{})).Interface().([]MapItem)
201 | for _, item := range slice {
202 | e.marshal("", reflect.ValueOf(item.Key))
203 | e.marshal("", reflect.ValueOf(item.Value))
204 | }
205 | })
206 | }
207 |
208 | func (e *encoder) structv(tag string, in reflect.Value) {
209 | sinfo, err := getStructInfo(in.Type())
210 | if err != nil {
211 | panic(err)
212 | }
213 | e.mappingv(tag, func() {
214 | for _, info := range sinfo.FieldsList {
215 | var value reflect.Value
216 | if info.Inline == nil {
217 | value = in.Field(info.Num)
218 | } else {
219 | value = in.FieldByIndex(info.Inline)
220 | }
221 | if info.OmitEmpty && isZero(value) {
222 | continue
223 | }
224 | e.marshal("", reflect.ValueOf(info.Key))
225 | e.flow = info.Flow
226 | e.marshal("", value)
227 | }
228 | if sinfo.InlineMap >= 0 {
229 | m := in.Field(sinfo.InlineMap)
230 | if m.Len() > 0 {
231 | e.flow = false
232 | keys := keyList(m.MapKeys())
233 | sort.Sort(keys)
234 | for _, k := range keys {
235 | if _, found := sinfo.FieldsMap[k.String()]; found {
236 | panic(fmt.Sprintf("Can't have key %q in inlined map; conflicts with struct field", k.String()))
237 | }
238 | e.marshal("", k)
239 | e.flow = false
240 | e.marshal("", m.MapIndex(k))
241 | }
242 | }
243 | }
244 | })
245 | }
246 |
247 | func (e *encoder) mappingv(tag string, f func()) {
248 | implicit := tag == ""
249 | style := yaml_BLOCK_MAPPING_STYLE
250 | if e.flow {
251 | e.flow = false
252 | style = yaml_FLOW_MAPPING_STYLE
253 | }
254 | yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
255 | e.emit()
256 | f()
257 | yaml_mapping_end_event_initialize(&e.event)
258 | e.emit()
259 | }
260 |
261 | func (e *encoder) slicev(tag string, in reflect.Value) {
262 | implicit := tag == ""
263 | style := yaml_BLOCK_SEQUENCE_STYLE
264 | if e.flow {
265 | e.flow = false
266 | style = yaml_FLOW_SEQUENCE_STYLE
267 | }
268 | e.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
269 | e.emit()
270 | n := in.Len()
271 | for i := 0; i < n; i++ {
272 | e.marshal("", in.Index(i))
273 | }
274 | e.must(yaml_sequence_end_event_initialize(&e.event))
275 | e.emit()
276 | }
277 |
278 | // isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.
279 | //
280 | // The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported
281 | // in YAML 1.2 and by this package, but these should be marshalled quoted for
282 | // the time being for compatibility with other parsers.
283 | func isBase60Float(s string) (result bool) {
284 | // Fast path.
285 | if s == "" {
286 | return false
287 | }
288 | c := s[0]
289 | if !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {
290 | return false
291 | }
292 | // Do the full match.
293 | return base60float.MatchString(s)
294 | }
295 |
296 | // From http://yaml.org/type/float.html, except the regular expression there
297 | // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix.
298 | var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`)
299 |
300 | func (e *encoder) stringv(tag string, in reflect.Value) {
301 | var style yaml_scalar_style_t
302 | s := in.String()
303 | canUsePlain := true
304 | switch {
305 | case !utf8.ValidString(s):
306 | if tag == yaml_BINARY_TAG {
307 | failf("explicitly tagged !!binary data must be base64-encoded")
308 | }
309 | if tag != "" {
310 | failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
311 | }
312 | // It can't be encoded directly as YAML so use a binary tag
313 | // and encode it as base64.
314 | tag = yaml_BINARY_TAG
315 | s = encodeBase64(s)
316 | case tag == "":
317 | // Check to see if it would resolve to a specific
318 | // tag when encoded unquoted. If it doesn't,
319 | // there's no need to quote it.
320 | rtag, _ := resolve("", s)
321 | canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
322 | }
323 | // Note: it's possible for user code to emit invalid YAML
324 | // if they explicitly specify a tag and a string containing
325 | // text that's incompatible with that tag.
326 | switch {
327 | case strings.Contains(s, "\n"):
328 | style = yaml_LITERAL_SCALAR_STYLE
329 | case canUsePlain:
330 | style = yaml_PLAIN_SCALAR_STYLE
331 | default:
332 | style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
333 | }
334 | e.emitScalar(s, "", tag, style)
335 | }
336 |
337 | func (e *encoder) boolv(tag string, in reflect.Value) {
338 | var s string
339 | if in.Bool() {
340 | s = "true"
341 | } else {
342 | s = "false"
343 | }
344 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
345 | }
346 |
347 | func (e *encoder) intv(tag string, in reflect.Value) {
348 | s := strconv.FormatInt(in.Int(), 10)
349 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
350 | }
351 |
352 | func (e *encoder) uintv(tag string, in reflect.Value) {
353 | s := strconv.FormatUint(in.Uint(), 10)
354 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
355 | }
356 |
357 | func (e *encoder) timev(tag string, in reflect.Value) {
358 | t := in.Interface().(time.Time)
359 | s := t.Format(time.RFC3339Nano)
360 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
361 | }
362 |
363 | func (e *encoder) floatv(tag string, in reflect.Value) {
364 | // Issue #352: When formatting, use the precision of the underlying value
365 | precision := 64
366 | if in.Kind() == reflect.Float32 {
367 | precision = 32
368 | }
369 |
370 | s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
371 | switch s {
372 | case "+Inf":
373 | s = ".inf"
374 | case "-Inf":
375 | s = "-.inf"
376 | case "NaN":
377 | s = ".nan"
378 | }
379 | e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
380 | }
381 |
382 | func (e *encoder) nilv() {
383 | e.emitScalar("null", "", "", yaml_PLAIN_SCALAR_STYLE)
384 | }
385 |
386 | func (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t) {
387 | implicit := tag == ""
388 | e.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))
389 | e.emit()
390 | }
391 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/go.mod:
--------------------------------------------------------------------------------
1 | module "gopkg.in/yaml.v2"
2 |
3 | require (
4 | "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
5 | )
6 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/resolve.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "encoding/base64"
5 | "math"
6 | "regexp"
7 | "strconv"
8 | "strings"
9 | "time"
10 | )
11 |
12 | type resolveMapItem struct {
13 | value interface{}
14 | tag string
15 | }
16 |
17 | var resolveTable = make([]byte, 256)
18 | var resolveMap = make(map[string]resolveMapItem)
19 |
20 | func init() {
21 | t := resolveTable
22 | t[int('+')] = 'S' // Sign
23 | t[int('-')] = 'S'
24 | for _, c := range "0123456789" {
25 | t[int(c)] = 'D' // Digit
26 | }
27 | for _, c := range "yYnNtTfFoO~" {
28 | t[int(c)] = 'M' // In map
29 | }
30 | t[int('.')] = '.' // Float (potentially in map)
31 |
32 | var resolveMapList = []struct {
33 | v interface{}
34 | tag string
35 | l []string
36 | }{
37 | {true, yaml_BOOL_TAG, []string{"y", "Y", "yes", "Yes", "YES"}},
38 | {true, yaml_BOOL_TAG, []string{"true", "True", "TRUE"}},
39 | {true, yaml_BOOL_TAG, []string{"on", "On", "ON"}},
40 | {false, yaml_BOOL_TAG, []string{"n", "N", "no", "No", "NO"}},
41 | {false, yaml_BOOL_TAG, []string{"false", "False", "FALSE"}},
42 | {false, yaml_BOOL_TAG, []string{"off", "Off", "OFF"}},
43 | {nil, yaml_NULL_TAG, []string{"", "~", "null", "Null", "NULL"}},
44 | {math.NaN(), yaml_FLOAT_TAG, []string{".nan", ".NaN", ".NAN"}},
45 | {math.Inf(+1), yaml_FLOAT_TAG, []string{".inf", ".Inf", ".INF"}},
46 | {math.Inf(+1), yaml_FLOAT_TAG, []string{"+.inf", "+.Inf", "+.INF"}},
47 | {math.Inf(-1), yaml_FLOAT_TAG, []string{"-.inf", "-.Inf", "-.INF"}},
48 | {"<<", yaml_MERGE_TAG, []string{"<<"}},
49 | }
50 |
51 | m := resolveMap
52 | for _, item := range resolveMapList {
53 | for _, s := range item.l {
54 | m[s] = resolveMapItem{item.v, item.tag}
55 | }
56 | }
57 | }
58 |
59 | const longTagPrefix = "tag:yaml.org,2002:"
60 |
61 | func shortTag(tag string) string {
62 | // TODO This can easily be made faster and produce less garbage.
63 | if strings.HasPrefix(tag, longTagPrefix) {
64 | return "!!" + tag[len(longTagPrefix):]
65 | }
66 | return tag
67 | }
68 |
69 | func longTag(tag string) string {
70 | if strings.HasPrefix(tag, "!!") {
71 | return longTagPrefix + tag[2:]
72 | }
73 | return tag
74 | }
75 |
76 | func resolvableTag(tag string) bool {
77 | switch tag {
78 | case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
79 | return true
80 | }
81 | return false
82 | }
83 |
84 | var yamlStyleFloat = regexp.MustCompile(`^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$`)
85 |
86 | func resolve(tag string, in string) (rtag string, out interface{}) {
87 | if !resolvableTag(tag) {
88 | return tag, in
89 | }
90 |
91 | defer func() {
92 | switch tag {
93 | case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
94 | return
95 | case yaml_FLOAT_TAG:
96 | if rtag == yaml_INT_TAG {
97 | switch v := out.(type) {
98 | case int64:
99 | rtag = yaml_FLOAT_TAG
100 | out = float64(v)
101 | return
102 | case int:
103 | rtag = yaml_FLOAT_TAG
104 | out = float64(v)
105 | return
106 | }
107 | }
108 | }
109 | failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
110 | }()
111 |
112 | // Any data is accepted as a !!str or !!binary.
113 | // Otherwise, the prefix is enough of a hint about what it might be.
114 | hint := byte('N')
115 | if in != "" {
116 | hint = resolveTable[in[0]]
117 | }
118 | if hint != 0 && tag != yaml_STR_TAG && tag != yaml_BINARY_TAG {
119 | // Handle things we can lookup in a map.
120 | if item, ok := resolveMap[in]; ok {
121 | return item.tag, item.value
122 | }
123 |
124 | // Base 60 floats are a bad idea, were dropped in YAML 1.2, and
125 | // are purposefully unsupported here. They're still quoted on
126 | // the way out for compatibility with other parser, though.
127 |
128 | switch hint {
129 | case 'M':
130 | // We've already checked the map above.
131 |
132 | case '.':
133 | // Not in the map, so maybe a normal float.
134 | floatv, err := strconv.ParseFloat(in, 64)
135 | if err == nil {
136 | return yaml_FLOAT_TAG, floatv
137 | }
138 |
139 | case 'D', 'S':
140 | // Int, float, or timestamp.
141 | // Only try values as a timestamp if the value is unquoted or there's an explicit
142 | // !!timestamp tag.
143 | if tag == "" || tag == yaml_TIMESTAMP_TAG {
144 | t, ok := parseTimestamp(in)
145 | if ok {
146 | return yaml_TIMESTAMP_TAG, t
147 | }
148 | }
149 |
150 | plain := strings.Replace(in, "_", "", -1)
151 | intv, err := strconv.ParseInt(plain, 0, 64)
152 | if err == nil {
153 | if intv == int64(int(intv)) {
154 | return yaml_INT_TAG, int(intv)
155 | } else {
156 | return yaml_INT_TAG, intv
157 | }
158 | }
159 | uintv, err := strconv.ParseUint(plain, 0, 64)
160 | if err == nil {
161 | return yaml_INT_TAG, uintv
162 | }
163 | if yamlStyleFloat.MatchString(plain) {
164 | floatv, err := strconv.ParseFloat(plain, 64)
165 | if err == nil {
166 | return yaml_FLOAT_TAG, floatv
167 | }
168 | }
169 | if strings.HasPrefix(plain, "0b") {
170 | intv, err := strconv.ParseInt(plain[2:], 2, 64)
171 | if err == nil {
172 | if intv == int64(int(intv)) {
173 | return yaml_INT_TAG, int(intv)
174 | } else {
175 | return yaml_INT_TAG, intv
176 | }
177 | }
178 | uintv, err := strconv.ParseUint(plain[2:], 2, 64)
179 | if err == nil {
180 | return yaml_INT_TAG, uintv
181 | }
182 | } else if strings.HasPrefix(plain, "-0b") {
183 | intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
184 | if err == nil {
185 | if true || intv == int64(int(intv)) {
186 | return yaml_INT_TAG, int(intv)
187 | } else {
188 | return yaml_INT_TAG, intv
189 | }
190 | }
191 | }
192 | default:
193 | panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
194 | }
195 | }
196 | return yaml_STR_TAG, in
197 | }
198 |
199 | // encodeBase64 encodes s as base64 that is broken up into multiple lines
200 | // as appropriate for the resulting length.
201 | func encodeBase64(s string) string {
202 | const lineLen = 70
203 | encLen := base64.StdEncoding.EncodedLen(len(s))
204 | lines := encLen/lineLen + 1
205 | buf := make([]byte, encLen*2+lines)
206 | in := buf[0:encLen]
207 | out := buf[encLen:]
208 | base64.StdEncoding.Encode(in, []byte(s))
209 | k := 0
210 | for i := 0; i < len(in); i += lineLen {
211 | j := i + lineLen
212 | if j > len(in) {
213 | j = len(in)
214 | }
215 | k += copy(out[k:], in[i:j])
216 | if lines > 1 {
217 | out[k] = '\n'
218 | k++
219 | }
220 | }
221 | return string(out[:k])
222 | }
223 |
224 | // This is a subset of the formats allowed by the regular expression
225 | // defined at http://yaml.org/type/timestamp.html.
226 | var allowedTimestampFormats = []string{
227 | "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
228 | "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
229 | "2006-1-2 15:4:5.999999999", // space separated with no time zone
230 | "2006-1-2", // date only
231 | // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
232 | // from the set of examples.
233 | }
234 |
235 | // parseTimestamp parses s as a timestamp string and
236 | // returns the timestamp and reports whether it succeeded.
237 | // Timestamp formats are defined at http://yaml.org/type/timestamp.html
238 | func parseTimestamp(s string) (time.Time, bool) {
239 | // TODO write code to check all the formats supported by
240 | // http://yaml.org/type/timestamp.html instead of using time.Parse.
241 |
242 | // Quick check: all date formats start with YYYY-.
243 | i := 0
244 | for ; i < len(s); i++ {
245 | if c := s[i]; c < '0' || c > '9' {
246 | break
247 | }
248 | }
249 | if i != 4 || i == len(s) || s[i] != '-' {
250 | return time.Time{}, false
251 | }
252 | for _, format := range allowedTimestampFormats {
253 | if t, err := time.Parse(format, s); err == nil {
254 | return t, true
255 | }
256 | }
257 | return time.Time{}, false
258 | }
259 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/sorter.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | import (
4 | "reflect"
5 | "unicode"
6 | )
7 |
8 | type keyList []reflect.Value
9 |
10 | func (l keyList) Len() int { return len(l) }
11 | func (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
12 | func (l keyList) Less(i, j int) bool {
13 | a := l[i]
14 | b := l[j]
15 | ak := a.Kind()
16 | bk := b.Kind()
17 | for (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {
18 | a = a.Elem()
19 | ak = a.Kind()
20 | }
21 | for (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {
22 | b = b.Elem()
23 | bk = b.Kind()
24 | }
25 | af, aok := keyFloat(a)
26 | bf, bok := keyFloat(b)
27 | if aok && bok {
28 | if af != bf {
29 | return af < bf
30 | }
31 | if ak != bk {
32 | return ak < bk
33 | }
34 | return numLess(a, b)
35 | }
36 | if ak != reflect.String || bk != reflect.String {
37 | return ak < bk
38 | }
39 | ar, br := []rune(a.String()), []rune(b.String())
40 | for i := 0; i < len(ar) && i < len(br); i++ {
41 | if ar[i] == br[i] {
42 | continue
43 | }
44 | al := unicode.IsLetter(ar[i])
45 | bl := unicode.IsLetter(br[i])
46 | if al && bl {
47 | return ar[i] < br[i]
48 | }
49 | if al || bl {
50 | return bl
51 | }
52 | var ai, bi int
53 | var an, bn int64
54 | if ar[i] == '0' || br[i] == '0' {
55 | for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
56 | if ar[j] != '0' {
57 | an = 1
58 | bn = 1
59 | break
60 | }
61 | }
62 | }
63 | for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
64 | an = an*10 + int64(ar[ai]-'0')
65 | }
66 | for bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {
67 | bn = bn*10 + int64(br[bi]-'0')
68 | }
69 | if an != bn {
70 | return an < bn
71 | }
72 | if ai != bi {
73 | return ai < bi
74 | }
75 | return ar[i] < br[i]
76 | }
77 | return len(ar) < len(br)
78 | }
79 |
80 | // keyFloat returns a float value for v if it is a number/bool
81 | // and whether it is a number/bool or not.
82 | func keyFloat(v reflect.Value) (f float64, ok bool) {
83 | switch v.Kind() {
84 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
85 | return float64(v.Int()), true
86 | case reflect.Float32, reflect.Float64:
87 | return v.Float(), true
88 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
89 | return float64(v.Uint()), true
90 | case reflect.Bool:
91 | if v.Bool() {
92 | return 1, true
93 | }
94 | return 0, true
95 | }
96 | return 0, false
97 | }
98 |
99 | // numLess returns whether a < b.
100 | // a and b must necessarily have the same kind.
101 | func numLess(a, b reflect.Value) bool {
102 | switch a.Kind() {
103 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
104 | return a.Int() < b.Int()
105 | case reflect.Float32, reflect.Float64:
106 | return a.Float() < b.Float()
107 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
108 | return a.Uint() < b.Uint()
109 | case reflect.Bool:
110 | return !a.Bool() && b.Bool()
111 | }
112 | panic("not a number")
113 | }
114 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/writerc.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | // Set the writer error and return false.
4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
5 | emitter.error = yaml_WRITER_ERROR
6 | emitter.problem = problem
7 | return false
8 | }
9 |
10 | // Flush the output buffer.
11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
12 | if emitter.write_handler == nil {
13 | panic("write handler not set")
14 | }
15 |
16 | // Check if the buffer is empty.
17 | if emitter.buffer_pos == 0 {
18 | return true
19 | }
20 |
21 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
22 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
23 | }
24 | emitter.buffer_pos = 0
25 | return true
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/yamlprivateh.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | const (
4 | // The size of the input raw buffer.
5 | input_raw_buffer_size = 512
6 |
7 | // The size of the input buffer.
8 | // It should be possible to decode the whole raw buffer.
9 | input_buffer_size = input_raw_buffer_size * 3
10 |
11 | // The size of the output buffer.
12 | output_buffer_size = 128
13 |
14 | // The size of the output raw buffer.
15 | // It should be possible to encode the whole output buffer.
16 | output_raw_buffer_size = (output_buffer_size*2 + 2)
17 |
18 | // The size of other stacks and queues.
19 | initial_stack_size = 16
20 | initial_queue_size = 16
21 | initial_string_size = 16
22 | )
23 |
24 | // Check if the character at the specified position is an alphabetical
25 | // character, a digit, '_', or '-'.
26 | func is_alpha(b []byte, i int) bool {
27 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'
28 | }
29 |
30 | // Check if the character at the specified position is a digit.
31 | func is_digit(b []byte, i int) bool {
32 | return b[i] >= '0' && b[i] <= '9'
33 | }
34 |
35 | // Get the value of a digit.
36 | func as_digit(b []byte, i int) int {
37 | return int(b[i]) - '0'
38 | }
39 |
40 | // Check if the character at the specified position is a hex-digit.
41 | func is_hex(b []byte, i int) bool {
42 | return b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'
43 | }
44 |
45 | // Get the value of a hex-digit.
46 | func as_hex(b []byte, i int) int {
47 | bi := b[i]
48 | if bi >= 'A' && bi <= 'F' {
49 | return int(bi) - 'A' + 10
50 | }
51 | if bi >= 'a' && bi <= 'f' {
52 | return int(bi) - 'a' + 10
53 | }
54 | return int(bi) - '0'
55 | }
56 |
57 | // Check if the character is ASCII.
58 | func is_ascii(b []byte, i int) bool {
59 | return b[i] <= 0x7F
60 | }
61 |
62 | // Check if the character at the start of the buffer can be printed unescaped.
63 | func is_printable(b []byte, i int) bool {
64 | return ((b[i] == 0x0A) || // . == #x0A
65 | (b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E
66 | (b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF
67 | (b[i] > 0xC2 && b[i] < 0xED) ||
68 | (b[i] == 0xED && b[i+1] < 0xA0) ||
69 | (b[i] == 0xEE) ||
70 | (b[i] == 0xEF && // #xE000 <= . <= #xFFFD
71 | !(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF
72 | !(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))
73 | }
74 |
75 | // Check if the character at the specified position is NUL.
76 | func is_z(b []byte, i int) bool {
77 | return b[i] == 0x00
78 | }
79 |
80 | // Check if the beginning of the buffer is a BOM.
81 | func is_bom(b []byte, i int) bool {
82 | return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
83 | }
84 |
85 | // Check if the character at the specified position is space.
86 | func is_space(b []byte, i int) bool {
87 | return b[i] == ' '
88 | }
89 |
90 | // Check if the character at the specified position is tab.
91 | func is_tab(b []byte, i int) bool {
92 | return b[i] == '\t'
93 | }
94 |
95 | // Check if the character at the specified position is blank (space or tab).
96 | func is_blank(b []byte, i int) bool {
97 | //return is_space(b, i) || is_tab(b, i)
98 | return b[i] == ' ' || b[i] == '\t'
99 | }
100 |
101 | // Check if the character at the specified position is a line break.
102 | func is_break(b []byte, i int) bool {
103 | return (b[i] == '\r' || // CR (#xD)
104 | b[i] == '\n' || // LF (#xA)
105 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
106 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
107 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)
108 | }
109 |
110 | func is_crlf(b []byte, i int) bool {
111 | return b[i] == '\r' && b[i+1] == '\n'
112 | }
113 |
114 | // Check if the character is a line break or NUL.
115 | func is_breakz(b []byte, i int) bool {
116 | //return is_break(b, i) || is_z(b, i)
117 | return ( // is_break:
118 | b[i] == '\r' || // CR (#xD)
119 | b[i] == '\n' || // LF (#xA)
120 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
121 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
122 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
123 | // is_z:
124 | b[i] == 0)
125 | }
126 |
127 | // Check if the character is a line break, space, or NUL.
128 | func is_spacez(b []byte, i int) bool {
129 | //return is_space(b, i) || is_breakz(b, i)
130 | return ( // is_space:
131 | b[i] == ' ' ||
132 | // is_breakz:
133 | b[i] == '\r' || // CR (#xD)
134 | b[i] == '\n' || // LF (#xA)
135 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
136 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
137 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
138 | b[i] == 0)
139 | }
140 |
141 | // Check if the character is a line break, space, tab, or NUL.
142 | func is_blankz(b []byte, i int) bool {
143 | //return is_blank(b, i) || is_breakz(b, i)
144 | return ( // is_blank:
145 | b[i] == ' ' || b[i] == '\t' ||
146 | // is_breakz:
147 | b[i] == '\r' || // CR (#xD)
148 | b[i] == '\n' || // LF (#xA)
149 | b[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)
150 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)
151 | b[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)
152 | b[i] == 0)
153 | }
154 |
155 | // Determine the width of the character.
156 | func width(b byte) int {
157 | // Don't replace these by a switch without first
158 | // confirming that it is being inlined.
159 | if b&0x80 == 0x00 {
160 | return 1
161 | }
162 | if b&0xE0 == 0xC0 {
163 | return 2
164 | }
165 | if b&0xF0 == 0xE0 {
166 | return 3
167 | }
168 | if b&0xF8 == 0xF0 {
169 | return 4
170 | }
171 | return 0
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/vendor/modules.txt:
--------------------------------------------------------------------------------
1 | # github.com/golang/protobuf v1.3.3
2 | github.com/golang/protobuf/proto
3 | # golang.org/x/net v0.0.0-20200202094626-16171245cfb2
4 | golang.org/x/net/context
5 | # google.golang.org/appengine v1.6.5
6 | google.golang.org/appengine
7 | google.golang.org/appengine/internal
8 | google.golang.org/appengine/internal/app_identity
9 | google.golang.org/appengine/internal/base
10 | google.golang.org/appengine/internal/datastore
11 | google.golang.org/appengine/internal/log
12 | google.golang.org/appengine/internal/modules
13 | google.golang.org/appengine/internal/remote_api
14 | # gopkg.in/yaml.v2 v2.2.8
15 | gopkg.in/yaml.v2
16 |
--------------------------------------------------------------------------------